@miranda0808/maya-claude 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-claude.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,223 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.SAVVYCAL_API_KEY
4
+ const BASE_URL = 'https://api.savvycal.com/v1'
5
+
6
+ if (!API_KEY) {
7
+ console.error(JSON.stringify({ error: 'SAVVYCAL_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 limit = args.limit ? Number(args.limit) : 20
58
+
59
+ switch (cmd) {
60
+ case 'me':
61
+ result = await api('GET', '/me')
62
+ break
63
+
64
+ case 'links':
65
+ switch (sub) {
66
+ case 'list': {
67
+ const params = new URLSearchParams()
68
+ params.set('limit', String(limit))
69
+ if (args.after) params.set('after', args.after)
70
+ if (args.before) params.set('before', args.before)
71
+ result = await api('GET', `/scheduling-links?${params}`)
72
+ break
73
+ }
74
+ case 'get': {
75
+ const id = args.id
76
+ if (!id) { result = { error: '--id required' }; break }
77
+ result = await api('GET', `/scheduling-links/${id}`)
78
+ break
79
+ }
80
+ case 'create': {
81
+ const name = args.name
82
+ if (!name) { result = { error: '--name required' }; break }
83
+ const body = { name }
84
+ if (args.slug) body.slug = args.slug
85
+ if (args.duration) body.duration_minutes = Number(args.duration)
86
+ result = await api('POST', '/scheduling-links', 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.slug) body.slug = args.slug
95
+ if (args.duration) body.duration_minutes = Number(args.duration)
96
+ result = await api('PATCH', `/scheduling-links/${id}`, body)
97
+ break
98
+ }
99
+ case 'delete': {
100
+ const id = args.id
101
+ if (!id) { result = { error: '--id required' }; break }
102
+ result = await api('DELETE', `/scheduling-links/${id}`)
103
+ break
104
+ }
105
+ case 'duplicate': {
106
+ const id = args.id
107
+ if (!id) { result = { error: '--id required' }; break }
108
+ result = await api('POST', `/scheduling-links/${id}/duplicate`)
109
+ break
110
+ }
111
+ case 'toggle': {
112
+ const id = args.id
113
+ if (!id) { result = { error: '--id required' }; break }
114
+ result = await api('POST', `/scheduling-links/${id}/toggle`)
115
+ break
116
+ }
117
+ case 'slots': {
118
+ const id = args.id
119
+ if (!id) { result = { error: '--id required' }; break }
120
+ const params = new URLSearchParams()
121
+ if (args['start-time']) params.set('start_time', args['start-time'])
122
+ if (args['end-time']) params.set('end_time', args['end-time'])
123
+ const qs = params.toString()
124
+ result = await api('GET', `/scheduling-links/${id}/slots${qs ? '?' + qs : ''}`)
125
+ break
126
+ }
127
+ default:
128
+ result = { error: 'Unknown links subcommand. Use: list, get, create, update, delete, duplicate, toggle, slots' }
129
+ }
130
+ break
131
+
132
+ case 'events':
133
+ switch (sub) {
134
+ case 'list': {
135
+ const params = new URLSearchParams()
136
+ params.set('limit', String(limit))
137
+ if (args.after) params.set('after', args.after)
138
+ if (args.before) params.set('before', args.before)
139
+ result = await api('GET', `/events?${params}`)
140
+ break
141
+ }
142
+ case 'get': {
143
+ const id = args.id
144
+ if (!id) { result = { error: '--id required' }; break }
145
+ result = await api('GET', `/events/${id}`)
146
+ break
147
+ }
148
+ case 'create': {
149
+ const linkId = args['link-id']
150
+ const startAt = args['start-at']
151
+ const name = args.name
152
+ const email = args.email
153
+ if (!linkId || !startAt || !name || !email) {
154
+ result = { error: '--link-id, --start-at, --name, and --email required' }
155
+ break
156
+ }
157
+ result = await api('POST', '/events', {
158
+ scheduling_link_id: linkId,
159
+ start_at: startAt,
160
+ name,
161
+ email,
162
+ })
163
+ break
164
+ }
165
+ case 'cancel': {
166
+ const id = args.id
167
+ if (!id) { result = { error: '--id required' }; break }
168
+ result = await api('POST', `/events/${id}/cancel`)
169
+ break
170
+ }
171
+ default:
172
+ result = { error: 'Unknown events subcommand. Use: list, get, create, cancel' }
173
+ }
174
+ break
175
+
176
+ case 'webhooks':
177
+ switch (sub) {
178
+ case 'list': {
179
+ const params = new URLSearchParams()
180
+ params.set('limit', String(limit))
181
+ if (args.after) params.set('after', args.after)
182
+ if (args.before) params.set('before', args.before)
183
+ result = await api('GET', `/webhooks?${params}`)
184
+ break
185
+ }
186
+ case 'create': {
187
+ const url = args.url
188
+ const events = args.events?.split(',')
189
+ if (!url || !events) { result = { error: '--url and --events (comma-separated) required' }; break }
190
+ result = await api('POST', '/webhooks', { url, events })
191
+ break
192
+ }
193
+ case 'delete': {
194
+ const id = args.id
195
+ if (!id) { result = { error: '--id required' }; break }
196
+ result = await api('DELETE', `/webhooks/${id}`)
197
+ break
198
+ }
199
+ default:
200
+ result = { error: 'Unknown webhooks subcommand. Use: list, create, delete' }
201
+ }
202
+ break
203
+
204
+ default:
205
+ result = {
206
+ error: 'Unknown command',
207
+ usage: {
208
+ me: 'me',
209
+ links: 'links [list | get --id <id> | create --name <name> | update --id <id> | delete --id <id> | duplicate --id <id> | toggle --id <id> | slots --id <id>]',
210
+ events: 'events [list | get --id <id> | create --link-id <id> --start-at <iso> --name <name> --email <email> | cancel --id <id>]',
211
+ webhooks: 'webhooks [list | create --url <url> --events <e1,e2> | delete --id <id>]',
212
+ options: '--limit <n> --after <cursor> --before <cursor>',
213
+ }
214
+ }
215
+ }
216
+
217
+ console.log(JSON.stringify(result, null, 2))
218
+ }
219
+
220
+ main().catch(err => {
221
+ console.error(JSON.stringify({ error: err.message }))
222
+ process.exit(1)
223
+ })
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env node
2
+
3
+ const WRITE_KEY = process.env.SEGMENT_WRITE_KEY
4
+ const ACCESS_TOKEN = process.env.SEGMENT_ACCESS_TOKEN
5
+ const TRACKING_URL = 'https://api.segment.io/v1'
6
+ const PROFILE_URL = 'https://profiles.segment.com/v1'
7
+
8
+ if (!WRITE_KEY && !ACCESS_TOKEN) {
9
+ console.error(JSON.stringify({ error: 'SEGMENT_WRITE_KEY (for tracking) or SEGMENT_ACCESS_TOKEN (for profiles) environment variable required' }))
10
+ process.exit(1)
11
+ }
12
+
13
+ async function trackApi(method, path, body) {
14
+ if (!WRITE_KEY) {
15
+ return { error: 'SEGMENT_WRITE_KEY required for tracking operations' }
16
+ }
17
+ if (args['dry-run']) {
18
+ return { _dry_run: true, method, url: `${TRACKING_URL}${path}`, headers: { Authorization: '***', 'Content-Type': 'application/json' }, body: body || undefined }
19
+ }
20
+ const auth = Buffer.from(`${WRITE_KEY}:`).toString('base64')
21
+ const res = await fetch(`${TRACKING_URL}${path}`, {
22
+ method,
23
+ headers: {
24
+ 'Authorization': `Basic ${auth}`,
25
+ 'Content-Type': 'application/json',
26
+ },
27
+ body: body ? JSON.stringify(body) : undefined,
28
+ })
29
+ const text = await res.text()
30
+ try {
31
+ return JSON.parse(text)
32
+ } catch {
33
+ return { status: res.status, body: text }
34
+ }
35
+ }
36
+
37
+ async function profileApi(method, path) {
38
+ if (!ACCESS_TOKEN) {
39
+ return { error: 'SEGMENT_ACCESS_TOKEN required for profile operations' }
40
+ }
41
+ if (args['dry-run']) {
42
+ return { _dry_run: true, method, url: `${PROFILE_URL}${path}`, headers: { Authorization: '***', 'Content-Type': 'application/json' } }
43
+ }
44
+ const auth = Buffer.from(`${ACCESS_TOKEN}:`).toString('base64')
45
+ const res = await fetch(`${PROFILE_URL}${path}`, {
46
+ method,
47
+ headers: {
48
+ 'Authorization': `Basic ${auth}`,
49
+ 'Content-Type': 'application/json',
50
+ },
51
+ })
52
+ const text = await res.text()
53
+ try {
54
+ return JSON.parse(text)
55
+ } catch {
56
+ return { status: res.status, body: text }
57
+ }
58
+ }
59
+
60
+ function parseArgs(args) {
61
+ const result = { _: [] }
62
+ for (let i = 0; i < args.length; i++) {
63
+ const arg = args[i]
64
+ if (arg.startsWith('--')) {
65
+ const key = arg.slice(2)
66
+ const next = args[i + 1]
67
+ if (next && !next.startsWith('--')) {
68
+ result[key] = next
69
+ i++
70
+ } else {
71
+ result[key] = true
72
+ }
73
+ } else {
74
+ result._.push(arg)
75
+ }
76
+ }
77
+ return result
78
+ }
79
+
80
+ const args = parseArgs(process.argv.slice(2))
81
+ const [cmd, sub, ...rest] = args._
82
+
83
+ async function main() {
84
+ let result
85
+
86
+ switch (cmd) {
87
+ case 'track':
88
+ switch (sub) {
89
+ case 'event': {
90
+ if (!args['user-id']) { result = { error: '--user-id required' }; break }
91
+ if (!args.event) { result = { error: '--event required' }; break }
92
+ const body = {
93
+ userId: args['user-id'],
94
+ event: args.event,
95
+ }
96
+ if (args.properties) {
97
+ try { body.properties = JSON.parse(args.properties) } catch { result = { error: 'Invalid JSON in --properties' }; break }
98
+ }
99
+ result = await trackApi('POST', '/track', body)
100
+ break
101
+ }
102
+ default:
103
+ result = { error: 'Unknown track subcommand. Use: event' }
104
+ }
105
+ break
106
+
107
+ case 'identify':
108
+ switch (sub) {
109
+ case 'user': {
110
+ if (!args['user-id']) { result = { error: '--user-id required' }; break }
111
+ const body = { userId: args['user-id'] }
112
+ if (args.traits) {
113
+ try { body.traits = JSON.parse(args.traits) } catch { result = { error: 'Invalid JSON in --traits' }; break }
114
+ }
115
+ result = await trackApi('POST', '/identify', body)
116
+ break
117
+ }
118
+ default:
119
+ result = { error: 'Unknown identify subcommand. Use: user' }
120
+ }
121
+ break
122
+
123
+ case 'page':
124
+ switch (sub) {
125
+ case 'view': {
126
+ if (!args['user-id']) { result = { error: '--user-id required' }; break }
127
+ const body = { userId: args['user-id'] }
128
+ if (args.name) body.name = args.name
129
+ if (args.properties) {
130
+ try { body.properties = JSON.parse(args.properties) } catch { result = { error: 'Invalid JSON in --properties' }; break }
131
+ }
132
+ result = await trackApi('POST', '/page', body)
133
+ break
134
+ }
135
+ default:
136
+ result = { error: 'Unknown page subcommand. Use: view' }
137
+ }
138
+ break
139
+
140
+ case 'batch':
141
+ switch (sub) {
142
+ case 'send': {
143
+ if (!args.events) { result = { error: '--events required (JSON array)' }; break }
144
+ let batch
145
+ try { batch = JSON.parse(args.events) } catch { result = { error: 'Invalid JSON in --events' }; break }
146
+ result = await trackApi('POST', '/batch', { batch })
147
+ break
148
+ }
149
+ default:
150
+ result = { error: 'Unknown batch subcommand. Use: send' }
151
+ }
152
+ break
153
+
154
+ case 'profiles':
155
+ switch (sub) {
156
+ case 'traits': {
157
+ if (!args['space-id']) { result = { error: '--space-id required' }; break }
158
+ if (!args['user-id']) { result = { error: '--user-id required' }; break }
159
+ result = await profileApi('GET', `/spaces/${args['space-id']}/collections/users/profiles/user_id:${args['user-id']}/traits`)
160
+ break
161
+ }
162
+ case 'events': {
163
+ if (!args['space-id']) { result = { error: '--space-id required' }; break }
164
+ if (!args['user-id']) { result = { error: '--user-id required' }; break }
165
+ result = await profileApi('GET', `/spaces/${args['space-id']}/collections/users/profiles/user_id:${args['user-id']}/events`)
166
+ break
167
+ }
168
+ default:
169
+ result = { error: 'Unknown profiles subcommand. Use: traits, events' }
170
+ }
171
+ break
172
+
173
+ default:
174
+ result = {
175
+ error: 'Unknown command',
176
+ usage: {
177
+ track: 'track event --user-id <id> --event <name> [--properties <json>]',
178
+ identify: 'identify user --user-id <id> [--traits <json>]',
179
+ page: 'page view --user-id <id> [--name <name>] [--properties <json>]',
180
+ batch: 'batch send --events <json_array>',
181
+ profiles: 'profiles [traits|events] --space-id <id> --user-id <id>',
182
+ }
183
+ }
184
+ }
185
+
186
+ console.log(JSON.stringify(result, null, 2))
187
+ }
188
+
189
+ main().catch(err => {
190
+ console.error(JSON.stringify({ error: err.message }))
191
+ process.exit(1)
192
+ })
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.SEMRUSH_API_KEY
4
+ const BASE_URL = 'https://api.semrush.com/'
5
+
6
+ if (!API_KEY) {
7
+ console.error(JSON.stringify({ error: 'SEMRUSH_API_KEY environment variable required' }))
8
+ process.exit(1)
9
+ }
10
+
11
+ function parseCSV(text) {
12
+ const lines = text.trim().split('\n')
13
+ if (lines.length < 2) return []
14
+ const headers = lines[0].split(';')
15
+ const rows = []
16
+ for (let i = 1; i < lines.length; i++) {
17
+ if (!lines[i].trim()) continue
18
+ const values = lines[i].split(';')
19
+ const row = {}
20
+ for (let j = 0; j < headers.length; j++) {
21
+ row[headers[j]] = values[j] || ''
22
+ }
23
+ rows.push(row)
24
+ }
25
+ return rows
26
+ }
27
+
28
+ async function api(params) {
29
+ params.set('key', API_KEY)
30
+ params.set('export_escape', '1')
31
+ if (args['dry-run']) {
32
+ const maskedParams = new URLSearchParams(params)
33
+ maskedParams.set('key', '***')
34
+ return { _dry_run: true, method: 'GET', url: `${BASE_URL}?${maskedParams}`, headers: {}, body: undefined }
35
+ }
36
+ const res = await fetch(`${BASE_URL}?${params}`)
37
+ const text = await res.text()
38
+ if (!res.ok) {
39
+ return { error: text.trim(), status: res.status }
40
+ }
41
+ if (text.startsWith('ERROR')) {
42
+ return { error: text.trim() }
43
+ }
44
+ return parseCSV(text)
45
+ }
46
+
47
+ function parseArgs(args) {
48
+ const result = { _: [] }
49
+ for (let i = 0; i < args.length; i++) {
50
+ const arg = args[i]
51
+ if (arg.startsWith('--')) {
52
+ const key = arg.slice(2)
53
+ const next = args[i + 1]
54
+ if (next && !next.startsWith('--')) {
55
+ result[key] = next
56
+ i++
57
+ } else {
58
+ result[key] = true
59
+ }
60
+ } else {
61
+ result._.push(arg)
62
+ }
63
+ }
64
+ return result
65
+ }
66
+
67
+ const args = parseArgs(process.argv.slice(2))
68
+ const [cmd, sub, ...rest] = args._
69
+
70
+ async function main() {
71
+ let result
72
+ const database = args.database || 'us'
73
+
74
+ switch (cmd) {
75
+ case 'domain':
76
+ switch (sub) {
77
+ case 'overview': {
78
+ if (!args.domain) { result = { error: '--domain required' }; break }
79
+ const params = new URLSearchParams({
80
+ type: 'domain_ranks',
81
+ export_columns: 'Db,Dn,Rk,Or,Ot,Oc,Ad,At,Ac',
82
+ domain: args.domain,
83
+ })
84
+ result = await api(params)
85
+ break
86
+ }
87
+ case 'organic': {
88
+ if (!args.domain) { result = { error: '--domain required' }; break }
89
+ const params = new URLSearchParams({
90
+ type: 'domain_organic',
91
+ export_columns: 'Ph,Po,Pp,Pd,Nq,Cp,Ur,Tr,Tc,Co,Nr',
92
+ domain: args.domain,
93
+ database,
94
+ })
95
+ if (args.limit) params.set('display_limit', args.limit)
96
+ result = await api(params)
97
+ break
98
+ }
99
+ case 'competitors': {
100
+ if (!args.domain) { result = { error: '--domain required' }; break }
101
+ const params = new URLSearchParams({
102
+ type: 'domain_organic_organic',
103
+ export_columns: 'Dn,Cr,Np,Or,Ot,Oc,Ad',
104
+ domain: args.domain,
105
+ database,
106
+ })
107
+ if (args.limit) params.set('display_limit', args.limit)
108
+ result = await api(params)
109
+ break
110
+ }
111
+ default:
112
+ result = { error: 'Unknown domain subcommand. Use: overview, organic, competitors' }
113
+ }
114
+ break
115
+
116
+ case 'keywords':
117
+ switch (sub) {
118
+ case 'overview': {
119
+ if (!args.phrase) { result = { error: '--phrase required' }; break }
120
+ const params = new URLSearchParams({
121
+ type: 'phrase_all',
122
+ export_columns: 'Ph,Nq,Cp,Co,Nr',
123
+ phrase: args.phrase,
124
+ database,
125
+ })
126
+ result = await api(params)
127
+ break
128
+ }
129
+ case 'related': {
130
+ if (!args.phrase) { result = { error: '--phrase required' }; break }
131
+ const params = new URLSearchParams({
132
+ type: 'phrase_related',
133
+ export_columns: 'Ph,Nq,Cp,Co,Nr,Td',
134
+ phrase: args.phrase,
135
+ database,
136
+ })
137
+ if (args.limit) params.set('display_limit', args.limit)
138
+ result = await api(params)
139
+ break
140
+ }
141
+ case 'difficulty': {
142
+ if (!args.phrase) { result = { error: '--phrase required' }; break }
143
+ const params = new URLSearchParams({
144
+ type: 'phrase_kdi',
145
+ export_columns: 'Ph,Kd',
146
+ phrase: args.phrase,
147
+ database,
148
+ })
149
+ result = await api(params)
150
+ break
151
+ }
152
+ default:
153
+ result = { error: 'Unknown keywords subcommand. Use: overview, related, difficulty' }
154
+ }
155
+ break
156
+
157
+ case 'backlinks':
158
+ switch (sub) {
159
+ case 'overview': {
160
+ const params = new URLSearchParams({
161
+ type: 'backlinks_overview',
162
+ target: args.target,
163
+ target_type: 'root_domain',
164
+ })
165
+ result = await api(params)
166
+ break
167
+ }
168
+ case 'list': {
169
+ const params = new URLSearchParams({
170
+ type: 'backlinks',
171
+ target: args.target,
172
+ target_type: 'root_domain',
173
+ export_columns: 'source_url,source_title,target_url,anchor',
174
+ })
175
+ if (args.limit) params.set('display_limit', args.limit)
176
+ result = await api(params)
177
+ break
178
+ }
179
+ default:
180
+ result = { error: 'Unknown backlinks subcommand. Use: overview, list' }
181
+ }
182
+ break
183
+
184
+ default:
185
+ result = {
186
+ error: 'Unknown command',
187
+ usage: {
188
+ 'domain overview': 'domain overview --domain <domain>',
189
+ 'domain organic': 'domain organic --domain <domain> [--database <db>] [--limit <n>]',
190
+ 'domain competitors': 'domain competitors --domain <domain> [--database <db>] [--limit <n>]',
191
+ 'keywords overview': 'keywords overview --phrase <phrase> [--database <db>]',
192
+ 'keywords related': 'keywords related --phrase <phrase> [--database <db>] [--limit <n>]',
193
+ 'keywords difficulty': 'keywords difficulty --phrase <phrase> [--database <db>]',
194
+ 'backlinks overview': 'backlinks overview --target <domain>',
195
+ 'backlinks list': 'backlinks list --target <domain> [--limit <n>]',
196
+ 'databases': 'us (default), uk, de, fr, ca, au, etc.',
197
+ }
198
+ }
199
+ }
200
+
201
+ console.log(JSON.stringify(result, null, 2))
202
+ }
203
+
204
+ main().catch(err => {
205
+ console.error(JSON.stringify({ error: err.message }))
206
+ process.exit(1)
207
+ })