@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,399 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.INTERCOM_API_KEY
4
+ const BASE_URL = 'https://api.intercom.io'
5
+
6
+ if (!API_KEY) {
7
+ console.error(JSON.stringify({ error: 'INTERCOM_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', 'Intercom-Version': '2.11' }, 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
+ 'Intercom-Version': '2.11',
22
+ },
23
+ body: body ? JSON.stringify(body) : undefined,
24
+ })
25
+ const text = await res.text()
26
+ try {
27
+ return JSON.parse(text)
28
+ } catch {
29
+ return { status: res.status, body: text }
30
+ }
31
+ }
32
+
33
+ function parseArgs(args) {
34
+ const result = { _: [] }
35
+ for (let i = 0; i < args.length; i++) {
36
+ const arg = args[i]
37
+ if (arg.startsWith('--')) {
38
+ const key = arg.slice(2)
39
+ const next = args[i + 1]
40
+ if (next && !next.startsWith('--')) {
41
+ result[key] = next
42
+ i++
43
+ } else {
44
+ result[key] = true
45
+ }
46
+ } else {
47
+ result._.push(arg)
48
+ }
49
+ }
50
+ return result
51
+ }
52
+
53
+ const args = parseArgs(process.argv.slice(2))
54
+ const [cmd, sub, ...rest] = args._
55
+
56
+ async function main() {
57
+ let result
58
+ const perPage = args['per-page'] ? Number(args['per-page']) : undefined
59
+
60
+ switch (cmd) {
61
+ case 'contacts':
62
+ switch (sub) {
63
+ case 'list': {
64
+ const params = new URLSearchParams()
65
+ if (perPage) params.set('per_page', String(perPage))
66
+ if (args['starting-after']) params.set('starting_after', args['starting-after'])
67
+ const qs = params.toString()
68
+ result = await api('GET', `/contacts${qs ? '?' + qs : ''}`)
69
+ break
70
+ }
71
+ case 'get': {
72
+ const id = args.id
73
+ if (!id) { result = { error: '--id required' }; break }
74
+ result = await api('GET', `/contacts/${id}`)
75
+ break
76
+ }
77
+ case 'create': {
78
+ const email = args.email
79
+ if (!email) { result = { error: '--email required' }; break }
80
+ const body = {
81
+ role: args.role || 'user',
82
+ email,
83
+ }
84
+ if (args.name) body.name = args.name
85
+ if (args.phone) body.phone = args.phone
86
+ result = await api('POST', '/contacts', body)
87
+ break
88
+ }
89
+ case 'update': {
90
+ const id = args.id
91
+ if (!id) { result = { error: '--id required' }; break }
92
+ const body = {}
93
+ if (args.name) body.name = args.name
94
+ if (args.email) body.email = args.email
95
+ if (args.phone) body.phone = args.phone
96
+ if (args.role) body.role = args.role
97
+ result = await api('PUT', `/contacts/${id}`, body)
98
+ break
99
+ }
100
+ case 'search': {
101
+ const field = args.field
102
+ const operator = args.operator || '='
103
+ const value = args.value
104
+ if (!field || !value) { result = { error: '--field and --value required' }; break }
105
+ const body = {
106
+ query: { field, operator, value },
107
+ }
108
+ if (perPage) body.pagination = { per_page: perPage }
109
+ result = await api('POST', '/contacts/search', body)
110
+ break
111
+ }
112
+ case 'delete': {
113
+ const id = args.id
114
+ if (!id) { result = { error: '--id required' }; break }
115
+ result = await api('DELETE', `/contacts/${id}`)
116
+ break
117
+ }
118
+ case 'tag': {
119
+ const id = args.id
120
+ const tagId = args['tag-id']
121
+ if (!id || !tagId) { result = { error: '--id (contact ID) and --tag-id required' }; break }
122
+ result = await api('POST', `/contacts/${id}/tags`, { id: tagId })
123
+ break
124
+ }
125
+ case 'untag': {
126
+ const id = args.id
127
+ const tagId = args['tag-id']
128
+ if (!id || !tagId) { result = { error: '--id (contact ID) and --tag-id required' }; break }
129
+ result = await api('DELETE', `/contacts/${id}/tags/${tagId}`)
130
+ break
131
+ }
132
+ default:
133
+ result = { error: 'Unknown contacts subcommand. Use: list, get, create, update, search, delete, tag, untag' }
134
+ }
135
+ break
136
+
137
+ case 'conversations':
138
+ switch (sub) {
139
+ case 'list': {
140
+ const params = new URLSearchParams()
141
+ if (perPage) params.set('per_page', String(perPage))
142
+ if (args['starting-after']) params.set('starting_after', args['starting-after'])
143
+ const qs = params.toString()
144
+ result = await api('GET', `/conversations${qs ? '?' + qs : ''}`)
145
+ break
146
+ }
147
+ case 'get': {
148
+ const id = args.id
149
+ if (!id) { result = { error: '--id required' }; break }
150
+ result = await api('GET', `/conversations/${id}`)
151
+ break
152
+ }
153
+ case 'search': {
154
+ const field = args.field
155
+ const operator = args.operator || '='
156
+ const value = args.value
157
+ if (!field || value === undefined) { result = { error: '--field and --value required' }; break }
158
+ const body = {
159
+ query: { field, operator, value },
160
+ }
161
+ if (perPage) body.pagination = { per_page: perPage }
162
+ result = await api('POST', '/conversations/search', body)
163
+ break
164
+ }
165
+ case 'reply': {
166
+ const id = args.id
167
+ const body = args.body
168
+ const adminId = args['admin-id']
169
+ if (!id || !body || !adminId) { result = { error: '--id, --body, and --admin-id required' }; break }
170
+ result = await api('POST', `/conversations/${id}/reply`, {
171
+ message_type: 'comment',
172
+ type: 'admin',
173
+ admin_id: adminId,
174
+ body,
175
+ })
176
+ break
177
+ }
178
+ case 'close': {
179
+ const id = args.id
180
+ const adminId = args['admin-id']
181
+ if (!id || !adminId) { result = { error: '--id and --admin-id required' }; break }
182
+ result = await api('POST', `/conversations/${id}/parts`, {
183
+ message_type: 'close',
184
+ type: 'admin',
185
+ admin_id: adminId,
186
+ body: args.body || '',
187
+ })
188
+ break
189
+ }
190
+ default:
191
+ result = { error: 'Unknown conversations subcommand. Use: list, get, search, reply, close' }
192
+ }
193
+ break
194
+
195
+ case 'messages':
196
+ switch (sub) {
197
+ case 'create': {
198
+ const messageType = args.type || 'inapp'
199
+ const body = args.body
200
+ const adminId = args['admin-id']
201
+ const to = args.to
202
+ if (!body || !adminId || !to) { result = { error: '--body, --admin-id, and --to (user ID) required' }; break }
203
+ result = await api('POST', '/messages', {
204
+ message_type: messageType,
205
+ body,
206
+ from: { type: 'admin', id: adminId },
207
+ to: { type: 'user', id: to },
208
+ })
209
+ break
210
+ }
211
+ default:
212
+ result = { error: 'Unknown messages subcommand. Use: create --body <text> --admin-id <id> --to <user_id> [--type inapp|email]' }
213
+ }
214
+ break
215
+
216
+ case 'companies':
217
+ switch (sub) {
218
+ case 'list': {
219
+ const params = new URLSearchParams()
220
+ if (perPage) params.set('per_page', String(perPage))
221
+ if (args.page) params.set('page', args.page)
222
+ const qs = params.toString()
223
+ result = await api('GET', `/companies${qs ? '?' + qs : ''}`)
224
+ break
225
+ }
226
+ case 'get': {
227
+ const id = args.id
228
+ if (!id) { result = { error: '--id required' }; break }
229
+ result = await api('GET', `/companies/${id}`)
230
+ break
231
+ }
232
+ case 'create': {
233
+ const companyId = args['company-id']
234
+ const name = args.name
235
+ if (!companyId) { result = { error: '--company-id required' }; break }
236
+ const body = { company_id: companyId }
237
+ if (name) body.name = name
238
+ if (args.plan) body.plan = args.plan
239
+ if (args.industry) body.industry = args.industry
240
+ result = await api('POST', '/companies', body)
241
+ break
242
+ }
243
+ case 'update': {
244
+ const id = args.id
245
+ if (!id) { result = { error: '--id required' }; break }
246
+ const body = {}
247
+ if (args.name) body.name = args.name
248
+ if (args.plan) body.plan = args.plan
249
+ if (args.industry) body.industry = args.industry
250
+ result = await api('PUT', `/companies/${id}`, body)
251
+ break
252
+ }
253
+ default:
254
+ result = { error: 'Unknown companies subcommand. Use: list, get, create, update' }
255
+ }
256
+ break
257
+
258
+ case 'tags':
259
+ switch (sub) {
260
+ case 'list':
261
+ result = await api('GET', '/tags')
262
+ break
263
+ case 'create': {
264
+ const name = args.name
265
+ if (!name) { result = { error: '--name required' }; break }
266
+ result = await api('POST', '/tags', { name })
267
+ break
268
+ }
269
+ case 'delete': {
270
+ const id = args.id
271
+ if (!id) { result = { error: '--id required' }; break }
272
+ result = await api('DELETE', `/tags/${id}`)
273
+ break
274
+ }
275
+ default:
276
+ result = { error: 'Unknown tags subcommand. Use: list, create, delete' }
277
+ }
278
+ break
279
+
280
+ case 'articles':
281
+ switch (sub) {
282
+ case 'list': {
283
+ const params = new URLSearchParams()
284
+ if (perPage) params.set('per_page', String(perPage))
285
+ if (args.page) params.set('page', args.page)
286
+ const qs = params.toString()
287
+ result = await api('GET', `/articles${qs ? '?' + qs : ''}`)
288
+ break
289
+ }
290
+ case 'get': {
291
+ const id = args.id
292
+ if (!id) { result = { error: '--id required' }; break }
293
+ result = await api('GET', `/articles/${id}`)
294
+ break
295
+ }
296
+ case 'create': {
297
+ const title = args.title
298
+ const authorId = args['author-id']
299
+ if (!title || !authorId) { result = { error: '--title and --author-id required' }; break }
300
+ const body = {
301
+ title,
302
+ author_id: Number(authorId),
303
+ state: args.state || 'draft',
304
+ }
305
+ if (args.body) body.body = args.body
306
+ result = await api('POST', '/articles', body)
307
+ break
308
+ }
309
+ case 'update': {
310
+ const id = args.id
311
+ if (!id) { result = { error: '--id required' }; break }
312
+ const body = {}
313
+ if (args.title) body.title = args.title
314
+ if (args.body) body.body = args.body
315
+ if (args.state) body.state = args.state
316
+ result = await api('PUT', `/articles/${id}`, body)
317
+ break
318
+ }
319
+ case 'delete': {
320
+ const id = args.id
321
+ if (!id) { result = { error: '--id required' }; break }
322
+ result = await api('DELETE', `/articles/${id}`)
323
+ break
324
+ }
325
+ default:
326
+ result = { error: 'Unknown articles subcommand. Use: list, get, create, update, delete' }
327
+ }
328
+ break
329
+
330
+ case 'admins':
331
+ switch (sub) {
332
+ case 'list':
333
+ result = await api('GET', '/admins')
334
+ break
335
+ case 'get': {
336
+ const id = args.id
337
+ if (!id) { result = { error: '--id required' }; break }
338
+ result = await api('GET', `/admins/${id}`)
339
+ break
340
+ }
341
+ default:
342
+ result = { error: 'Unknown admins subcommand. Use: list, get' }
343
+ }
344
+ break
345
+
346
+ case 'events':
347
+ switch (sub) {
348
+ case 'create': {
349
+ const eventName = args.name
350
+ const userId = args['user-id']
351
+ if (!eventName || !userId) { result = { error: '--name and --user-id required' }; break }
352
+ const body = {
353
+ event_name: eventName,
354
+ user_id: userId,
355
+ created_at: args['created-at'] ? Number(args['created-at']) : Math.floor(Date.now() / 1000),
356
+ }
357
+ if (args.metadata) {
358
+ try { body.metadata = JSON.parse(args.metadata) } catch { body.metadata = {} }
359
+ }
360
+ result = await api('POST', '/events', body)
361
+ break
362
+ }
363
+ case 'list': {
364
+ const userId = args['user-id']
365
+ if (!userId) { result = { error: '--user-id required' }; break }
366
+ const params = new URLSearchParams({ type: 'user', user_id: userId })
367
+ if (perPage) params.set('per_page', String(perPage))
368
+ result = await api('GET', `/events?${params}`)
369
+ break
370
+ }
371
+ default:
372
+ result = { error: 'Unknown events subcommand. Use: create, list' }
373
+ }
374
+ break
375
+
376
+ default:
377
+ result = {
378
+ error: 'Unknown command',
379
+ usage: {
380
+ contacts: 'contacts [list | get --id <id> | create --email <email> | update --id <id> | search --field <f> --value <v> | delete --id <id> | tag --id <id> --tag-id <id> | untag --id <id> --tag-id <id>]',
381
+ conversations: 'conversations [list | get --id <id> | search --field <f> --value <v> | reply --id <id> --body <text> --admin-id <id> | close --id <id> --admin-id <id>]',
382
+ messages: 'messages [create --body <text> --admin-id <id> --to <user_id>]',
383
+ companies: 'companies [list | get --id <id> | create --company-id <id> --name <name> | update --id <id>]',
384
+ tags: 'tags [list | create --name <name> | delete --id <id>]',
385
+ articles: 'articles [list | get --id <id> | create --title <title> --author-id <id> | update --id <id> | delete --id <id>]',
386
+ admins: 'admins [list | get --id <id>]',
387
+ events: 'events [create --name <name> --user-id <id> | list --user-id <id>]',
388
+ options: '--per-page <n> --starting-after <cursor> --page <n>',
389
+ }
390
+ }
391
+ }
392
+
393
+ console.log(JSON.stringify(result, null, 2))
394
+ }
395
+
396
+ main().catch(err => {
397
+ console.error(JSON.stringify({ error: err.message }))
398
+ process.exit(1)
399
+ })
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.KEYWORDS_EVERYWHERE_API_KEY
4
+ const BASE_URL = 'https://api.keywordseverywhere.com/v1'
5
+
6
+ if (!API_KEY) {
7
+ console.error(JSON.stringify({ error: 'KEYWORDS_EVERYWHERE_API_KEY environment variable required' }))
8
+ process.exit(1)
9
+ }
10
+
11
+ async function api(method, path, body) {
12
+ const headers = {
13
+ 'Authorization': `Bearer ${API_KEY}`,
14
+ 'Content-Type': 'application/json',
15
+ 'Accept': 'application/json',
16
+ }
17
+ if (args['dry-run']) {
18
+ return { _dry_run: true, method, url: `${BASE_URL}${path}`, headers: { ...headers, Authorization: '***' }, body: body || undefined }
19
+ }
20
+ const res = await fetch(`${BASE_URL}${path}`, {
21
+ method,
22
+ headers,
23
+ body: body ? JSON.stringify(body) : undefined,
24
+ })
25
+ const text = await res.text()
26
+ try {
27
+ return JSON.parse(text)
28
+ } catch {
29
+ return { status: res.status, body: text }
30
+ }
31
+ }
32
+
33
+ function parseArgs(args) {
34
+ const result = { _: [] }
35
+ for (let i = 0; i < args.length; i++) {
36
+ const arg = args[i]
37
+ if (arg.startsWith('--')) {
38
+ const key = arg.slice(2)
39
+ const next = args[i + 1]
40
+ if (next && !next.startsWith('--')) {
41
+ result[key] = next
42
+ i++
43
+ } else {
44
+ result[key] = true
45
+ }
46
+ } else {
47
+ result._.push(arg)
48
+ }
49
+ }
50
+ return result
51
+ }
52
+
53
+ const args = parseArgs(process.argv.slice(2))
54
+ const [cmd, sub, ...rest] = args._
55
+
56
+ async function main() {
57
+ let result
58
+ const country = args.country || 'us'
59
+ const currency = args.currency || 'USD'
60
+ const dataSource = args['data-source'] || 'gkp'
61
+
62
+ switch (cmd) {
63
+ case 'keywords':
64
+ switch (sub) {
65
+ case 'data': {
66
+ const kw = args.kw?.split(',')
67
+ if (!kw) { result = { error: '--kw required (comma-separated keywords, max 100)' }; break }
68
+ result = await api('POST', '/get_keyword_data', { country, currency, dataSource, kw })
69
+ break
70
+ }
71
+ case 'related': {
72
+ const kw = args.kw?.split(',')
73
+ if (!kw) { result = { error: '--kw required (comma-separated keywords)' }; break }
74
+ result = await api('POST', '/get_related_keywords', { country, currency, dataSource, kw })
75
+ break
76
+ }
77
+ case 'pasf': {
78
+ const kw = args.kw?.split(',')
79
+ if (!kw) { result = { error: '--kw required (comma-separated keywords)' }; break }
80
+ result = await api('POST', '/get_pasf_keywords', { country, currency, dataSource, kw })
81
+ break
82
+ }
83
+ default:
84
+ result = { error: 'Unknown keywords subcommand. Use: data, related, pasf' }
85
+ }
86
+ break
87
+
88
+ case 'domain':
89
+ switch (sub) {
90
+ case 'keywords': {
91
+ const domain = args.domain
92
+ if (!domain) { result = { error: '--domain required' }; break }
93
+ result = await api('POST', '/get_domain_keywords', { country, currency, domain })
94
+ break
95
+ }
96
+ case 'traffic': {
97
+ const domain = args.domain
98
+ if (!domain) { result = { error: '--domain required' }; break }
99
+ result = await api('POST', '/get_domain_traffic', { country, domain })
100
+ break
101
+ }
102
+ case 'backlinks': {
103
+ const domain = args.domain
104
+ if (!domain) { result = { error: '--domain required' }; break }
105
+ result = await api('POST', '/get_domain_backlinks', { domain })
106
+ break
107
+ }
108
+ case 'unique-backlinks': {
109
+ const domain = args.domain
110
+ if (!domain) { result = { error: '--domain required' }; break }
111
+ result = await api('POST', '/get_unique_domain_backlinks', { domain })
112
+ break
113
+ }
114
+ default:
115
+ result = { error: 'Unknown domain subcommand. Use: keywords, traffic, backlinks, unique-backlinks' }
116
+ }
117
+ break
118
+
119
+ case 'url':
120
+ switch (sub) {
121
+ case 'keywords': {
122
+ const url = args.url
123
+ if (!url) { result = { error: '--url required' }; break }
124
+ result = await api('POST', '/get_url_keywords', { country, currency, url })
125
+ break
126
+ }
127
+ case 'traffic': {
128
+ const url = args.url
129
+ if (!url) { result = { error: '--url required' }; break }
130
+ result = await api('POST', '/get_url_traffic', { country, url })
131
+ break
132
+ }
133
+ case 'backlinks': {
134
+ const url = args.url
135
+ if (!url) { result = { error: '--url required' }; break }
136
+ result = await api('POST', '/get_page_backlinks', { url })
137
+ break
138
+ }
139
+ case 'unique-backlinks': {
140
+ const url = args.url
141
+ if (!url) { result = { error: '--url required' }; break }
142
+ result = await api('POST', '/get_unique_page_backlinks', { url })
143
+ break
144
+ }
145
+ default:
146
+ result = { error: 'Unknown url subcommand. Use: keywords, traffic, backlinks, unique-backlinks' }
147
+ }
148
+ break
149
+
150
+ case 'account':
151
+ switch (sub) {
152
+ case 'credits':
153
+ result = await api('GET', '/get_credits')
154
+ break
155
+ case 'countries':
156
+ result = await api('GET', '/get_countries')
157
+ break
158
+ case 'currencies':
159
+ result = await api('GET', '/get_currencies')
160
+ break
161
+ default:
162
+ result = { error: 'Unknown account subcommand. Use: credits, countries, currencies' }
163
+ }
164
+ break
165
+
166
+ default:
167
+ result = {
168
+ error: 'Unknown command',
169
+ usage: {
170
+ keywords: 'keywords [data|related|pasf] --kw <kw1,kw2,...>',
171
+ domain: 'domain [keywords|traffic|backlinks|unique-backlinks] --domain <domain>',
172
+ url: 'url [keywords|traffic|backlinks|unique-backlinks] --url <url>',
173
+ account: 'account [credits|countries|currencies]',
174
+ options: '--country <us> --currency <USD> --data-source <gkp>',
175
+ }
176
+ }
177
+ }
178
+
179
+ console.log(JSON.stringify(result, null, 2))
180
+ }
181
+
182
+ main().catch(err => {
183
+ console.error(JSON.stringify({ error: err.message }))
184
+ process.exit(1)
185
+ })