@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,260 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.BUFFER_API_KEY
4
+ const BASE_URL = 'https://api.bufferapp.com/1'
5
+
6
+ if (!API_KEY) {
7
+ console.error(JSON.stringify({ error: 'BUFFER_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
+ 'Accept': 'application/json',
15
+ }
16
+ if (body && method !== 'GET') {
17
+ headers['Content-Type'] = 'application/x-www-form-urlencoded'
18
+ }
19
+ if (args['dry-run']) {
20
+ return { _dry_run: true, method, url: `${BASE_URL}${path}`, headers: { ...headers, 'Authorization': '***' }, body: body || undefined }
21
+ }
22
+ const res = await fetch(`${BASE_URL}${path}`, {
23
+ method,
24
+ headers,
25
+ body: body ? new URLSearchParams(body).toString() : undefined,
26
+ })
27
+ const text = await res.text()
28
+ try {
29
+ return JSON.parse(text)
30
+ } catch {
31
+ return { status: res.status, body: text }
32
+ }
33
+ }
34
+
35
+ async function apiJson(method, path, body) {
36
+ if (args['dry-run']) {
37
+ return { _dry_run: true, method, url: `${BASE_URL}${path}`, headers: { 'Authorization': '***', 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: body || undefined }
38
+ }
39
+ const res = await fetch(`${BASE_URL}${path}`, {
40
+ method,
41
+ headers: {
42
+ 'Authorization': `Bearer ${API_KEY}`,
43
+ 'Content-Type': 'application/json',
44
+ 'Accept': 'application/json',
45
+ },
46
+ body: body ? JSON.stringify(body) : undefined,
47
+ })
48
+ const text = await res.text()
49
+ try {
50
+ return JSON.parse(text)
51
+ } catch {
52
+ return { status: res.status, body: text }
53
+ }
54
+ }
55
+
56
+ function parseArgs(args) {
57
+ const result = { _: [] }
58
+ for (let i = 0; i < args.length; i++) {
59
+ const arg = args[i]
60
+ if (arg.startsWith('--')) {
61
+ const key = arg.slice(2)
62
+ const next = args[i + 1]
63
+ if (next && !next.startsWith('--')) {
64
+ result[key] = next
65
+ i++
66
+ } else {
67
+ result[key] = true
68
+ }
69
+ } else {
70
+ result._.push(arg)
71
+ }
72
+ }
73
+ return result
74
+ }
75
+
76
+ const args = parseArgs(process.argv.slice(2))
77
+ const [cmd, sub, ...rest] = args._
78
+
79
+ async function main() {
80
+ let result
81
+
82
+ switch (cmd) {
83
+ case 'user':
84
+ switch (sub) {
85
+ case 'info':
86
+ result = await api('GET', '/user.json')
87
+ break
88
+ case 'deauthorize':
89
+ result = await api('POST', '/user/deauthorize.json')
90
+ break
91
+ default:
92
+ result = { error: 'Unknown user subcommand. Use: info, deauthorize' }
93
+ }
94
+ break
95
+
96
+ case 'profiles':
97
+ switch (sub) {
98
+ case 'list':
99
+ result = await api('GET', '/profiles.json')
100
+ break
101
+ case 'get': {
102
+ const id = args.id
103
+ if (!id) { result = { error: '--id required' }; break }
104
+ result = await api('GET', `/profiles/${id}.json`)
105
+ break
106
+ }
107
+ case 'schedules': {
108
+ const id = args.id
109
+ if (!id) { result = { error: '--id required (profile ID)' }; break }
110
+ result = await api('GET', `/profiles/${id}/schedules.json`)
111
+ break
112
+ }
113
+ default:
114
+ result = { error: 'Unknown profiles subcommand. Use: list, get, schedules' }
115
+ }
116
+ break
117
+
118
+ case 'updates':
119
+ switch (sub) {
120
+ case 'get': {
121
+ const id = args.id
122
+ if (!id) { result = { error: '--id required (update ID)' }; break }
123
+ result = await api('GET', `/updates/${id}.json`)
124
+ break
125
+ }
126
+ case 'pending': {
127
+ const id = args.id
128
+ if (!id) { result = { error: '--id required (profile ID)' }; break }
129
+ const params = new URLSearchParams()
130
+ if (args.page) params.set('page', args.page)
131
+ if (args.count) params.set('count', args.count)
132
+ if (args.since) params.set('since', args.since)
133
+ const qs = params.toString() ? `?${params.toString()}` : ''
134
+ result = await api('GET', `/profiles/${id}/updates/pending.json${qs}`)
135
+ break
136
+ }
137
+ case 'sent': {
138
+ const id = args.id
139
+ if (!id) { result = { error: '--id required (profile ID)' }; break }
140
+ const params = new URLSearchParams()
141
+ if (args.page) params.set('page', args.page)
142
+ if (args.count) params.set('count', args.count)
143
+ if (args.since) params.set('since', args.since)
144
+ const qs = params.toString() ? `?${params.toString()}` : ''
145
+ result = await api('GET', `/profiles/${id}/updates/sent.json${qs}`)
146
+ break
147
+ }
148
+ case 'create': {
149
+ const profileIds = args['profile-ids']
150
+ const text = args.text
151
+ if (!profileIds) { result = { error: '--profile-ids required (comma-separated)' }; break }
152
+ if (!text) { result = { error: '--text required' }; break }
153
+ const body = { text }
154
+ profileIds.split(',').forEach(id => {
155
+ if (!body['profile_ids[]']) body['profile_ids[]'] = []
156
+ })
157
+ const formBody = new URLSearchParams()
158
+ formBody.append('text', text)
159
+ profileIds.split(',').forEach(id => formBody.append('profile_ids[]', id.trim()))
160
+ if (args['scheduled-at']) formBody.append('scheduled_at', args['scheduled-at'])
161
+ if (args.now) formBody.append('now', 'true')
162
+ if (args.top) formBody.append('top', 'true')
163
+ if (args.shorten) formBody.append('shorten', 'true')
164
+ if (args['dry-run']) {
165
+ result = { _dry_run: true, method: 'POST', url: `${BASE_URL}/updates/create.json`, headers: { 'Authorization': '***', 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json' }, body: formBody.toString() }
166
+ break
167
+ }
168
+ const res = await fetch(`${BASE_URL}/updates/create.json`, {
169
+ method: 'POST',
170
+ headers: {
171
+ 'Authorization': `Bearer ${API_KEY}`,
172
+ 'Content-Type': 'application/x-www-form-urlencoded',
173
+ 'Accept': 'application/json',
174
+ },
175
+ body: formBody.toString(),
176
+ })
177
+ const resText = await res.text()
178
+ try { result = JSON.parse(resText) } catch { result = { status: res.status, body: resText } }
179
+ break
180
+ }
181
+ case 'update': {
182
+ const id = args.id
183
+ const text = args.text
184
+ if (!id) { result = { error: '--id required (update ID)' }; break }
185
+ if (!text) { result = { error: '--text required' }; break }
186
+ const body = { text }
187
+ if (args['scheduled-at']) body.scheduled_at = args['scheduled-at']
188
+ result = await api('POST', `/updates/${id}/update.json`, body)
189
+ break
190
+ }
191
+ case 'share': {
192
+ const id = args.id
193
+ if (!id) { result = { error: '--id required (update ID)' }; break }
194
+ result = await api('POST', `/updates/${id}/share.json`)
195
+ break
196
+ }
197
+ case 'destroy': {
198
+ const id = args.id
199
+ if (!id) { result = { error: '--id required (update ID)' }; break }
200
+ result = await api('POST', `/updates/${id}/destroy.json`)
201
+ break
202
+ }
203
+ case 'reorder': {
204
+ const id = args.id
205
+ const order = args.order
206
+ if (!id) { result = { error: '--id required (profile ID)' }; break }
207
+ if (!order) { result = { error: '--order required (comma-separated update IDs)' }; break }
208
+ const formBody = new URLSearchParams()
209
+ order.split(',').forEach(uid => formBody.append('order[]', uid.trim()))
210
+ if (args['dry-run']) {
211
+ result = { _dry_run: true, method: 'POST', url: `${BASE_URL}/profiles/${id}/updates/reorder.json`, headers: { 'Authorization': '***', 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json' }, body: formBody.toString() }
212
+ break
213
+ }
214
+ const res = await fetch(`${BASE_URL}/profiles/${id}/updates/reorder.json`, {
215
+ method: 'POST',
216
+ headers: {
217
+ 'Authorization': `Bearer ${API_KEY}`,
218
+ 'Content-Type': 'application/x-www-form-urlencoded',
219
+ 'Accept': 'application/json',
220
+ },
221
+ body: formBody.toString(),
222
+ })
223
+ const resText = await res.text()
224
+ try { result = JSON.parse(resText) } catch { result = { status: res.status, body: resText } }
225
+ break
226
+ }
227
+ case 'shuffle': {
228
+ const id = args.id
229
+ if (!id) { result = { error: '--id required (profile ID)' }; break }
230
+ result = await api('POST', `/profiles/${id}/updates/shuffle.json`)
231
+ break
232
+ }
233
+ default:
234
+ result = { error: 'Unknown updates subcommand. Use: get, pending, sent, create, update, share, destroy, reorder, shuffle' }
235
+ }
236
+ break
237
+
238
+ case 'info':
239
+ result = await api('GET', '/info/configuration.json')
240
+ break
241
+
242
+ default:
243
+ result = {
244
+ error: 'Unknown command',
245
+ usage: {
246
+ user: 'user [info | deauthorize]',
247
+ profiles: 'profiles [list | get --id <id> | schedules --id <id>]',
248
+ updates: 'updates [get --id <id> | pending --id <profile-id> | sent --id <profile-id> | create --profile-ids <ids> --text <text> [--scheduled-at <time>] [--now] | update --id <id> --text <text> | share --id <id> | destroy --id <id> | reorder --id <profile-id> --order <id1,id2> | shuffle --id <profile-id>]',
249
+ info: 'info',
250
+ }
251
+ }
252
+ }
253
+
254
+ console.log(JSON.stringify(result, null, 2))
255
+ }
256
+
257
+ main().catch(err => {
258
+ console.error(JSON.stringify({ error: err.message }))
259
+ process.exit(1)
260
+ })
@@ -0,0 +1,253 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.CALENDLY_API_KEY
4
+ const BASE_URL = 'https://api.calendly.com'
5
+
6
+ if (!API_KEY) {
7
+ console.error(JSON.stringify({ error: 'CALENDLY_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 count = args.count ? Number(args.count) : 20
58
+
59
+ switch (cmd) {
60
+ case 'users':
61
+ switch (sub) {
62
+ case 'me':
63
+ result = await api('GET', '/users/me')
64
+ break
65
+ default:
66
+ result = { error: 'Unknown users subcommand. Use: me' }
67
+ }
68
+ break
69
+
70
+ case 'event-types':
71
+ switch (sub) {
72
+ case 'list': {
73
+ const user = args.user
74
+ const org = args.organization
75
+ if (!user && !org) { result = { error: '--user or --organization URI required' }; break }
76
+ const params = new URLSearchParams()
77
+ if (user) params.set('user', user)
78
+ if (org) params.set('organization', org)
79
+ if (args.active) params.set('active', args.active)
80
+ params.set('count', String(count))
81
+ if (args['page-token']) params.set('page_token', args['page-token'])
82
+ result = await api('GET', `/event_types?${params}`)
83
+ break
84
+ }
85
+ case 'get': {
86
+ const uuid = args.uuid
87
+ if (!uuid) { result = { error: '--uuid required' }; break }
88
+ result = await api('GET', `/event_types/${uuid}`)
89
+ break
90
+ }
91
+ default:
92
+ result = { error: 'Unknown event-types subcommand. Use: list, get' }
93
+ }
94
+ break
95
+
96
+ case 'events':
97
+ switch (sub) {
98
+ case 'list': {
99
+ const user = args.user
100
+ const org = args.organization
101
+ if (!user && !org) { result = { error: '--user or --organization URI required' }; break }
102
+ const params = new URLSearchParams()
103
+ if (user) params.set('user', user)
104
+ if (org) params.set('organization', org)
105
+ if (args['min-start']) params.set('min_start_time', args['min-start'])
106
+ if (args['max-start']) params.set('max_start_time', args['max-start'])
107
+ if (args.status) params.set('status', args.status)
108
+ params.set('count', String(count))
109
+ if (args['page-token']) params.set('page_token', args['page-token'])
110
+ if (args.sort) params.set('sort', args.sort)
111
+ result = await api('GET', `/scheduled_events?${params}`)
112
+ break
113
+ }
114
+ case 'get': {
115
+ const uuid = args.uuid
116
+ if (!uuid) { result = { error: '--uuid required' }; break }
117
+ result = await api('GET', `/scheduled_events/${uuid}`)
118
+ break
119
+ }
120
+ case 'cancel': {
121
+ const uuid = args.uuid
122
+ if (!uuid) { result = { error: '--uuid required' }; break }
123
+ const body = {}
124
+ if (args.reason) body.reason = args.reason
125
+ result = await api('POST', `/scheduled_events/${uuid}/cancellation`, body)
126
+ break
127
+ }
128
+ case 'invitees': {
129
+ const uuid = args.uuid
130
+ if (!uuid) { result = { error: '--uuid required (event UUID)' }; break }
131
+ const params = new URLSearchParams()
132
+ params.set('count', String(count))
133
+ if (args['page-token']) params.set('page_token', args['page-token'])
134
+ if (args.email) params.set('email', args.email)
135
+ if (args.status) params.set('status', args.status)
136
+ result = await api('GET', `/scheduled_events/${uuid}/invitees?${params}`)
137
+ break
138
+ }
139
+ default:
140
+ result = { error: 'Unknown events subcommand. Use: list, get, cancel, invitees' }
141
+ }
142
+ break
143
+
144
+ case 'availability':
145
+ switch (sub) {
146
+ case 'times': {
147
+ const eventType = args['event-type']
148
+ if (!eventType) { result = { error: '--event-type URI required' }; break }
149
+ const startTime = args['start-time']
150
+ const endTime = args['end-time']
151
+ if (!startTime || !endTime) { result = { error: '--start-time and --end-time required (ISO 8601)' }; break }
152
+ const params = new URLSearchParams({
153
+ event_type: eventType,
154
+ start_time: startTime,
155
+ end_time: endTime,
156
+ })
157
+ result = await api('GET', `/event_type_available_times?${params}`)
158
+ break
159
+ }
160
+ case 'busy': {
161
+ const user = args.user
162
+ if (!user) { result = { error: '--user URI required' }; break }
163
+ const startTime = args['start-time']
164
+ const endTime = args['end-time']
165
+ if (!startTime || !endTime) { result = { error: '--start-time and --end-time required (ISO 8601)' }; break }
166
+ const params = new URLSearchParams({
167
+ user,
168
+ start_time: startTime,
169
+ end_time: endTime,
170
+ })
171
+ result = await api('GET', `/user_busy_times?${params}`)
172
+ break
173
+ }
174
+ default:
175
+ result = { error: 'Unknown availability subcommand. Use: times, busy' }
176
+ }
177
+ break
178
+
179
+ case 'webhooks':
180
+ switch (sub) {
181
+ case 'list': {
182
+ const org = args.organization
183
+ const scope = args.scope || 'organization'
184
+ if (!org) { result = { error: '--organization URI required' }; break }
185
+ const params = new URLSearchParams({
186
+ organization: org,
187
+ scope,
188
+ })
189
+ params.set('count', String(count))
190
+ if (args['page-token']) params.set('page_token', args['page-token'])
191
+ result = await api('GET', `/webhook_subscriptions?${params}`)
192
+ break
193
+ }
194
+ case 'create': {
195
+ const url = args.url
196
+ const events = args.events?.split(',')
197
+ const org = args.organization
198
+ const scope = args.scope || 'organization'
199
+ if (!url || !events || !org) { result = { error: '--url, --events (comma-separated), and --organization required' }; break }
200
+ const body = { url, events, organization: org, scope }
201
+ if (args.user) body.user = args.user
202
+ result = await api('POST', '/webhook_subscriptions', body)
203
+ break
204
+ }
205
+ case 'delete': {
206
+ const uuid = args.uuid
207
+ if (!uuid) { result = { error: '--uuid required' }; break }
208
+ result = await api('DELETE', `/webhook_subscriptions/${uuid}`)
209
+ break
210
+ }
211
+ default:
212
+ result = { error: 'Unknown webhooks subcommand. Use: list, create, delete' }
213
+ }
214
+ break
215
+
216
+ case 'org':
217
+ switch (sub) {
218
+ case 'members': {
219
+ const org = args.organization
220
+ if (!org) { result = { error: '--organization URI required' }; break }
221
+ const params = new URLSearchParams({ organization: org })
222
+ params.set('count', String(count))
223
+ if (args['page-token']) params.set('page_token', args['page-token'])
224
+ result = await api('GET', `/organization_memberships?${params}`)
225
+ break
226
+ }
227
+ default:
228
+ result = { error: 'Unknown org subcommand. Use: members' }
229
+ }
230
+ break
231
+
232
+ default:
233
+ result = {
234
+ error: 'Unknown command',
235
+ usage: {
236
+ users: 'users me',
237
+ 'event-types': 'event-types [list --user <uri> | get --uuid <id>]',
238
+ events: 'events [list --user <uri> | get --uuid <id> | cancel --uuid <id> | invitees --uuid <id>]',
239
+ availability: 'availability [times --event-type <uri> --start-time <iso> --end-time <iso> | busy --user <uri> --start-time <iso> --end-time <iso>]',
240
+ webhooks: 'webhooks [list --organization <uri> | create --url <url> --events <e1,e2> --organization <uri> | delete --uuid <id>]',
241
+ org: 'org [members --organization <uri>]',
242
+ options: '--count <n> --page-token <token> --status <active|canceled>',
243
+ }
244
+ }
245
+ }
246
+
247
+ console.log(JSON.stringify(result, null, 2))
248
+ }
249
+
250
+ main().catch(err => {
251
+ console.error(JSON.stringify({ error: err.message }))
252
+ process.exit(1)
253
+ })
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.CLEARBIT_API_KEY
4
+
5
+ if (!API_KEY) {
6
+ console.error(JSON.stringify({ error: 'CLEARBIT_API_KEY environment variable required' }))
7
+ process.exit(1)
8
+ }
9
+
10
+ async function api(method, baseUrl, path, body) {
11
+ const auth = 'Basic ' + Buffer.from(`${API_KEY}:`).toString('base64')
12
+ if (args['dry-run']) {
13
+ return { _dry_run: true, method, url: `${baseUrl}${path}`, headers: { 'Authorization': '***', 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: body || undefined }
14
+ }
15
+ const res = await fetch(`${baseUrl}${path}`, {
16
+ method,
17
+ headers: {
18
+ 'Authorization': auth,
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
+
58
+ switch (cmd) {
59
+ case 'person':
60
+ switch (sub) {
61
+ case 'find': {
62
+ const email = args.email
63
+ if (!email) { result = { error: '--email required' }; break }
64
+ result = await api('GET', 'https://person-stream.clearbit.com', `/v2/people/find?email=${encodeURIComponent(email)}`)
65
+ break
66
+ }
67
+ default:
68
+ result = { error: 'Unknown person subcommand. Use: find' }
69
+ }
70
+ break
71
+
72
+ case 'company':
73
+ switch (sub) {
74
+ case 'find': {
75
+ const domain = args.domain
76
+ if (!domain) { result = { error: '--domain required' }; break }
77
+ result = await api('GET', 'https://company-stream.clearbit.com', `/v2/companies/find?domain=${encodeURIComponent(domain)}`)
78
+ break
79
+ }
80
+ default:
81
+ result = { error: 'Unknown company subcommand. Use: find' }
82
+ }
83
+ break
84
+
85
+ case 'combined':
86
+ switch (sub) {
87
+ case 'find': {
88
+ const email = args.email
89
+ if (!email) { result = { error: '--email required' }; break }
90
+ result = await api('GET', 'https://person-stream.clearbit.com', `/v2/combined/find?email=${encodeURIComponent(email)}`)
91
+ break
92
+ }
93
+ default:
94
+ result = { error: 'Unknown combined subcommand. Use: find' }
95
+ }
96
+ break
97
+
98
+ case 'reveal':
99
+ switch (sub) {
100
+ case 'find': {
101
+ const ip = args.ip
102
+ if (!ip) { result = { error: '--ip required' }; break }
103
+ result = await api('GET', 'https://reveal.clearbit.com', `/v1/companies/find?ip=${encodeURIComponent(ip)}`)
104
+ break
105
+ }
106
+ default:
107
+ result = { error: 'Unknown reveal subcommand. Use: find' }
108
+ }
109
+ break
110
+
111
+ case 'name-to-domain':
112
+ switch (sub) {
113
+ case 'find': {
114
+ const name = args.name
115
+ if (!name) { result = { error: '--name required' }; break }
116
+ result = await api('GET', 'https://company.clearbit.com', `/v1/domains/find?name=${encodeURIComponent(name)}`)
117
+ break
118
+ }
119
+ default:
120
+ result = { error: 'Unknown name-to-domain subcommand. Use: find' }
121
+ }
122
+ break
123
+
124
+ case 'prospector':
125
+ switch (sub) {
126
+ case 'search': {
127
+ const domain = args.domain
128
+ if (!domain) { result = { error: '--domain required' }; break }
129
+ const params = new URLSearchParams({ domain })
130
+ if (args.role) params.set('role', args.role)
131
+ if (args.seniority) params.set('seniority', args.seniority)
132
+ if (args.title) params.set('title', args.title)
133
+ if (args.page) params.set('page', args.page)
134
+ if (args['page-size']) params.set('page_size', args['page-size'])
135
+ result = await api('GET', 'https://prospector.clearbit.com', `/v1/people/search?${params.toString()}`)
136
+ break
137
+ }
138
+ default:
139
+ result = { error: 'Unknown prospector subcommand. Use: search' }
140
+ }
141
+ break
142
+
143
+ default:
144
+ result = {
145
+ error: 'Unknown command',
146
+ usage: {
147
+ person: 'person find --email <email>',
148
+ company: 'company find --domain <domain>',
149
+ combined: 'combined find --email <email>',
150
+ reveal: 'reveal find --ip <ip>',
151
+ 'name-to-domain': 'name-to-domain find --name <company_name>',
152
+ prospector: 'prospector search --domain <domain> [--role <role>] [--seniority <level>] [--title <title>]',
153
+ }
154
+ }
155
+ }
156
+
157
+ console.log(JSON.stringify(result, null, 2))
158
+ }
159
+
160
+ main().catch(err => {
161
+ console.error(JSON.stringify({ error: err.message }))
162
+ process.exit(1)
163
+ })