@reepl/cli 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.
- package/README.md +104 -0
- package/dist/chunk-QSNFNE5Z.js +719 -0
- package/dist/chunk-QSNFNE5Z.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +982 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/index.d.ts +525 -0
- package/dist/core/index.js +57 -0
- package/dist/core/index.js.map +1 -0
- package/package.json +49 -0
- package/scripts/postinstall.mjs +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/constants.ts","../src/core/errors.ts","../src/core/client.ts","../src/core/auth/cognito.ts","../src/core/auth/tokenManager.ts","../src/core/endpoints/profile.ts","../src/core/endpoints/workspaces.ts","../src/core/endpoints/linkedin.ts","../src/core/endpoints/twitter.ts","../src/core/endpoints/calendar.ts","../src/core/endpoints/reddit.ts","../src/core/endpoints/signals.ts","../src/core/endpoints/carousel.ts","../src/core/endpoints/writingStyle.ts","../src/core/endpoints/voice.ts","../src/core/endpoints/dms.ts","../src/core/postref.ts"],"sourcesContent":["/**\n * Canonical Reepl endpoints and auth identifiers.\n *\n * These mirror the values the Reepl MCP server uses (reepl-mcp-server/wrangler.toml).\n * The Cognito web-app client is a PUBLIC client (no secret) — safe to ship in a CLI.\n */\nexport const REEPL_API_BASE_URL = \"https://api.reepl.io/v1\";\n\n/** HTTP API v2 used only by unauthenticated carousel generation (userID in body). */\nexport const REEPL_PUBLIC_API_BASE_URL =\n \"https://4n7fgax35e.execute-api.eu-north-1.amazonaws.com/v1\";\n\nexport const COGNITO_DOMAIN = \"https://auth.reepl.io\";\n\n/** Public Cognito app client (no secret) — the one the web app / MCP server refresh with. */\nexport const COGNITO_WEB_APP_CLIENT_ID = \"7np7fkkg920i4pqvgsmbct7bnn\";\n\n/** Web app that performs the login handoff and returns Cognito tokens. */\nexport const REEPL_WEB_APP_URL = \"https://app.reepl.io\";\n\n/** Path on the web app that brokers the token handoff for external clients. */\nexport const MCP_CONNECT_PATH = \"/mcp-connect\";\n\n/** Refresh the ID token this many ms before it actually expires. */\nexport const TOKEN_REFRESH_BUFFER_MS = 10 * 60 * 1000;\n","/**\n * Typed error hierarchy so both humans and agents can branch on a stable `code`.\n *\n * Every error carries a machine-readable `code` and a process `exitCode` the CLI maps\n * straight to `process.exit`. Gating responses (plan/premium/reconnect) become distinct\n * codes rather than an opaque HTTP 403.\n */\nexport type ReeplErrorCode =\n | \"UNAUTHENTICATED\"\n | \"REFRESH_TOKEN_INVALID\"\n | \"PLAN_REQUIRED\"\n | \"PREMIUM_REQUIRED\"\n | \"RECONNECT_REQUIRED\"\n | \"MISSING_DM_SCOPES\"\n | \"GEMINI_NOT_LINKED\"\n | \"RATE_LIMITED\"\n | \"NOT_FOUND\"\n | \"VALIDATION\"\n | \"VERSION_CONFLICT\"\n | \"API_ERROR\"\n | \"NETWORK\"\n | \"CONFIG\";\n\n/** Exit codes are grouped so scripts can react by class without parsing text. */\nconst EXIT_CODES: Record<ReeplErrorCode, number> = {\n UNAUTHENTICATED: 4,\n REFRESH_TOKEN_INVALID: 4,\n CONFIG: 4,\n PLAN_REQUIRED: 5,\n PREMIUM_REQUIRED: 5,\n RECONNECT_REQUIRED: 6,\n MISSING_DM_SCOPES: 6,\n GEMINI_NOT_LINKED: 6,\n RATE_LIMITED: 7,\n NOT_FOUND: 8,\n VALIDATION: 9,\n VERSION_CONFLICT: 9,\n API_ERROR: 1,\n NETWORK: 2,\n};\n\nexport class ReeplError extends Error {\n readonly code: ReeplErrorCode;\n readonly status?: number;\n readonly details?: unknown;\n\n constructor(\n code: ReeplErrorCode,\n message: string,\n opts: { status?: number; details?: unknown; cause?: unknown } = {},\n ) {\n super(message, opts.cause !== undefined ? { cause: opts.cause } : undefined);\n this.name = \"ReeplError\";\n this.code = code;\n this.status = opts.status;\n this.details = opts.details;\n }\n\n get exitCode(): number {\n return EXIT_CODES[this.code] ?? 1;\n }\n\n toJSON() {\n return { code: this.code, message: this.message, ...(this.status ? { status: this.status } : {}) };\n }\n}\n\n/**\n * Map a raw backend error payload + HTTP status onto a typed ReeplError.\n *\n * The backend is inconsistent about where the machine code lives (`code`, `error`,\n * `errorCode`), so we probe a few shapes and fall back to status-based classification.\n */\nexport function parseApiError(status: number, raw: string): ReeplError {\n let body: any = raw;\n try {\n body = JSON.parse(raw);\n } catch {\n // not JSON — keep the string\n }\n\n // A machine code is a bare token (no spaces). `body.error` is sometimes a code\n // (e.g. \"reddit_not_connected\") and sometimes a human sentence — only treat the\n // token-shaped form as a code so a sentence isn't misclassified.\n const isCodeToken = (v: unknown): v is string =>\n typeof v === \"string\" && /^[a-z0-9_]+$/i.test(v.trim());\n const backendCode: string | undefined =\n typeof body === \"object\" && body\n ? body.code || body.errorCode || (isCodeToken(body.error) ? body.error : undefined)\n : undefined;\n const message: string =\n (typeof body === \"object\" && body && (body.message || body.error)) ||\n (typeof body === \"string\" && body) ||\n `Request failed with status ${status}`;\n\n const codeStr = String(backendCode ?? \"\").toUpperCase();\n\n // Explicit backend codes take priority.\n if (codeStr === \"UPGRADE_REQUIRED\" || codeStr === \"PLAN_REQUIRED\") {\n return new ReeplError(\"PLAN_REQUIRED\", message || \"This action requires a paid Reepl plan.\", { status, details: body });\n }\n if (codeStr.includes(\"PREMIUM\") || codeStr === \"REQUIRES_PREMIUM\") {\n return new ReeplError(\"PREMIUM_REQUIRED\", message || \"This action requires a Reepl Premium plan.\", { status, details: body });\n }\n if (codeStr === \"MISSING_DM_SCOPES\") {\n return new ReeplError(\"MISSING_DM_SCOPES\", message || \"Reconnect X with DM permissions to continue.\", { status, details: body });\n }\n if (codeStr === \"GEMINI_NOT_LINKED\") {\n return new ReeplError(\"GEMINI_NOT_LINKED\", message || \"Link your Gemini API key in Reepl settings.\", { status, details: body });\n }\n if (codeStr.includes(\"RECONNECT\") || codeStr.includes(\"NOT_CONNECTED\")) {\n return new ReeplError(\"RECONNECT_REQUIRED\", message || \"Reconnect the integration to continue.\", { status, details: body });\n }\n if (codeStr === \"VERSION_CONFLICT\") {\n return new ReeplError(\"VERSION_CONFLICT\", message || \"The record changed since you fetched it. Refetch and retry.\", { status, details: body });\n }\n\n // Status-based fallback.\n if (status === 401) return new ReeplError(\"UNAUTHENTICATED\", message || \"Not authenticated. Run `reepl login`.\", { status, details: body });\n if (status === 402) return new ReeplError(\"PLAN_REQUIRED\", message, { status, details: body });\n if (status === 403) {\n // A bare 403 with premium-ish wording still routes to PREMIUM_REQUIRED for X features.\n if (/premium/i.test(message)) return new ReeplError(\"PREMIUM_REQUIRED\", message, { status, details: body });\n return new ReeplError(\"PLAN_REQUIRED\", message, { status, details: body });\n }\n if (status === 404) return new ReeplError(\"NOT_FOUND\", message, { status, details: body });\n if (status === 409) return new ReeplError(\"VERSION_CONFLICT\", message, { status, details: body });\n if (status === 422 || status === 400) return new ReeplError(\"VALIDATION\", message, { status, details: body });\n if (status === 429) return new ReeplError(\"RATE_LIMITED\", message || \"Rate limited. Try again shortly.\", { status, details: body });\n\n return new ReeplError(\"API_ERROR\", message, { status, details: body });\n}\n","import { REEPL_API_BASE_URL, REEPL_PUBLIC_API_BASE_URL } from \"./constants.js\";\nimport { parseApiError, ReeplError } from \"./errors.js\";\nimport type { HttpMethod, RequestOptions } from \"./types.js\";\n\nexport interface ReeplClientOptions {\n /** Returns a valid ID token. Usually TokenManager.getIdToken bound. */\n getToken: () => Promise<string>;\n /** Default workspace injected into every scoped call unless overridden per-request. */\n workspaceId?: string | null;\n apiBaseUrl?: string;\n publicBaseUrl?: string;\n fetchImpl?: typeof fetch;\n}\n\nconst METHODS_WITH_BODY = new Set<HttpMethod>([\"POST\", \"PUT\", \"PATCH\"]);\n\n/**\n * Thin, typed HTTP client for the Reepl backend. All endpoint modules build on `request`.\n * This is the single place that knows about auth headers, workspace placement, and error\n * normalization — the reusable heart of api-core.\n */\nexport class ReeplClient {\n private getToken: () => Promise<string>;\n private workspaceId: string | null;\n private apiBaseUrl: string;\n private publicBaseUrl: string;\n private fetchImpl: typeof fetch;\n\n constructor(opts: ReeplClientOptions) {\n this.getToken = opts.getToken;\n this.workspaceId = opts.workspaceId ?? null;\n this.apiBaseUrl = opts.apiBaseUrl ?? REEPL_API_BASE_URL;\n this.publicBaseUrl = opts.publicBaseUrl ?? REEPL_PUBLIC_API_BASE_URL;\n this.fetchImpl = opts.fetchImpl ?? fetch;\n }\n\n async request<T = unknown>(opts: RequestOptions): Promise<T> {\n const auth = opts.auth ?? true;\n const base = opts.base === \"public\" ? this.publicBaseUrl : this.apiBaseUrl;\n\n // Resolve workspace scoping. `null` explicitly disables; `undefined` falls back to default.\n const workspace = opts.workspace === undefined ? this.workspaceId : opts.workspace;\n const hasBody = METHODS_WITH_BODY.has(opts.method);\n\n const query: Record<string, string | number | boolean | undefined | null> = {\n ...(opts.query ?? {}),\n };\n let body = opts.body;\n\n if (workspace) {\n if (hasBody) {\n body = { ...(body as Record<string, unknown> | undefined), workspace_id: workspace };\n } else {\n query.workspace_id = workspace;\n }\n }\n\n const url = new URL(base + opts.path);\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined && v !== null) url.searchParams.set(k, String(v));\n }\n\n const headers: Record<string, string> = {};\n if (hasBody && body !== undefined) headers[\"Content-Type\"] = \"application/json\";\n if (auth) headers[\"Authorization\"] = `Bearer ${await this.getToken()}`;\n\n let response: Response;\n try {\n response = await this.fetchImpl(url.toString(), {\n method: opts.method,\n headers,\n body: hasBody && body !== undefined ? JSON.stringify(body) : undefined,\n });\n } catch (cause) {\n throw new ReeplError(\"NETWORK\", `Could not reach ${url.host}.`, { cause });\n }\n\n const text = await response.text();\n if (!response.ok) throw parseApiError(response.status, text);\n\n if (!text) return undefined as T;\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as unknown as T;\n }\n }\n\n // Convenience verbs.\n get<T = unknown>(path: string, opts: Omit<RequestOptions, \"method\" | \"path\"> = {}) {\n return this.request<T>({ method: \"GET\", path, ...opts });\n }\n post<T = unknown>(path: string, opts: Omit<RequestOptions, \"method\" | \"path\"> = {}) {\n return this.request<T>({ method: \"POST\", path, ...opts });\n }\n put<T = unknown>(path: string, opts: Omit<RequestOptions, \"method\" | \"path\"> = {}) {\n return this.request<T>({ method: \"PUT\", path, ...opts });\n }\n delete<T = unknown>(path: string, opts: Omit<RequestOptions, \"method\" | \"path\"> = {}) {\n return this.request<T>({ method: \"DELETE\", path, ...opts });\n }\n}\n","import { COGNITO_DOMAIN, COGNITO_WEB_APP_CLIENT_ID } from \"../constants.js\";\nimport { ReeplError } from \"../errors.js\";\n\nexport interface RefreshResult {\n idToken: string;\n accessToken?: string;\n /** Seconds until the new ID token expires. */\n expiresIn: number;\n}\n\n/**\n * Decode a JWT payload without verifying the signature (we only need `exp`/claims,\n * verification is the backend's job). Returns null on any malformed token.\n */\nexport function decodeJwt(token: string): Record<string, unknown> | null {\n const parts = token.split(\".\");\n if (parts.length < 2) return null;\n try {\n const payload = parts[1]!.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const json = Buffer.from(payload, \"base64\").toString(\"utf8\");\n return JSON.parse(json);\n } catch {\n return null;\n }\n}\n\n/** Epoch ms at which this ID token expires, or null if it has no `exp`. */\nexport function jwtExpiryMs(token: string): number | null {\n const claims = decodeJwt(token);\n const exp = claims?.exp;\n return typeof exp === \"number\" ? exp * 1000 : null;\n}\n\n/**\n * Exchange a Cognito refresh token for a fresh ID/access token via the public app client.\n * Mirrors the MCP server's getValidIdToken refresh call (no Basic auth — public client).\n */\nexport async function refreshIdToken(\n refreshToken: string,\n opts: { clientId?: string; cognitoDomain?: string; fetchImpl?: typeof fetch } = {},\n): Promise<RefreshResult> {\n const clientId = opts.clientId ?? COGNITO_WEB_APP_CLIENT_ID;\n const domain = opts.cognitoDomain ?? COGNITO_DOMAIN;\n const doFetch = opts.fetchImpl ?? fetch;\n\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: clientId,\n refresh_token: refreshToken,\n });\n\n let response: Response;\n try {\n response = await doFetch(`${domain}/oauth2/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n } catch (cause) {\n throw new ReeplError(\"NETWORK\", \"Could not reach Cognito to refresh the session.\", { cause });\n }\n\n const text = await response.text();\n if (!response.ok) {\n // Only invalid_grant means the refresh token itself is dead (force re-login). Other\n // 400s (invalid_request/invalid_client/malformed) are generic auth failures — don't\n // mislead the user into thinking their session expired.\n if (/invalid_grant/i.test(text)) {\n throw new ReeplError(\"REFRESH_TOKEN_INVALID\", \"Your session expired. Run `reepl login` again.\", {\n status: response.status,\n });\n }\n throw new ReeplError(\"UNAUTHENTICATED\", `Token refresh failed (${response.status}).`, {\n status: response.status,\n details: text,\n });\n }\n\n let json: any;\n try {\n json = JSON.parse(text);\n } catch {\n throw new ReeplError(\"UNAUTHENTICATED\", \"Malformed token response from Cognito.\");\n }\n\n if (!json.id_token) {\n throw new ReeplError(\"UNAUTHENTICATED\", \"Cognito response did not include an id_token.\");\n }\n\n return {\n idToken: json.id_token,\n accessToken: json.access_token,\n expiresIn: typeof json.expires_in === \"number\" ? json.expires_in : 3600,\n };\n}\n","import { TOKEN_REFRESH_BUFFER_MS } from \"../constants.js\";\nimport { ReeplError } from \"../errors.js\";\nimport type { StoredTokens, TokenStore } from \"../types.js\";\nimport { jwtExpiryMs, refreshIdToken } from \"./cognito.js\";\n\nexport interface TokenManagerOptions {\n clientId?: string;\n cognitoDomain?: string;\n bufferMs?: number;\n fetchImpl?: typeof fetch;\n /** For deterministic tests. Defaults to Date.now. */\n now?: () => number;\n}\n\n/**\n * Returns a valid ID token, refreshing (and persisting) it when it is within the expiry\n * buffer. Storage-agnostic: it delegates load/save to the injected TokenStore, so the CLI\n * can back it with a file or OS keychain while core stays portable.\n */\nexport class TokenManager {\n private store: TokenStore;\n private opts: TokenManagerOptions;\n private inflight: Promise<string> | null = null;\n\n constructor(store: TokenStore, opts: TokenManagerOptions = {}) {\n this.store = store;\n this.opts = opts;\n }\n\n private now(): number {\n return this.opts.now ? this.opts.now() : Date.now();\n }\n\n /** Get a valid ID token or throw UNAUTHENTICATED if there are no stored credentials. */\n async getIdToken(): Promise<string> {\n // Coalesce concurrent callers onto a single refresh.\n if (this.inflight) return this.inflight;\n this.inflight = this.resolveToken().finally(() => {\n this.inflight = null;\n });\n return this.inflight;\n }\n\n private async resolveToken(): Promise<string> {\n const tokens = await this.store.load();\n if (!tokens) {\n throw new ReeplError(\"UNAUTHENTICATED\", \"Not authenticated. Run `reepl login` first.\");\n }\n\n const buffer = this.opts.bufferMs ?? TOKEN_REFRESH_BUFFER_MS;\n if (tokens.expiresAt - this.now() > buffer) {\n return tokens.idToken;\n }\n\n const refreshed = await refreshIdToken(tokens.refreshToken, {\n clientId: this.opts.clientId,\n cognitoDomain: this.opts.cognitoDomain,\n fetchImpl: this.opts.fetchImpl,\n });\n\n const expiresAt =\n jwtExpiryMs(refreshed.idToken) ?? this.now() + refreshed.expiresIn * 1000;\n\n const next: StoredTokens = {\n idToken: refreshed.idToken,\n // Cognito refresh does not return a new refresh token — keep the existing one.\n refreshToken: tokens.refreshToken,\n accessToken: refreshed.accessToken ?? tokens.accessToken,\n expiresAt,\n };\n await this.store.save(next);\n return next.idToken;\n }\n}\n","import type { ReeplClient } from \"../client.js\";\nimport type { AccountProfile } from \"../types.js\";\n\n/** GET /account/profile — current authenticated user. */\nexport function getProfile(client: ReeplClient): Promise<AccountProfile> {\n return client.get<AccountProfile>(\"/account/profile\");\n}\n\n/** Coarse paid/free signal derived from the profile, for gating hints in `whoami`. */\nexport function hasActivePlan(profile: AccountProfile): boolean {\n return Boolean(profile.subscription_status?.hasActivePurchase);\n}\n","import type { ReeplClient } from \"../client.js\";\nimport type { Workspace } from \"../types.js\";\n\ninterface OrganizationsResponse {\n organizations?: Array<Record<string, any>>;\n default_organisationID?: string;\n [key: string]: unknown;\n}\n\n/**\n * GET /organizations — list the user's workspaces (Cognito \"organizations\").\n * Field names vary across the backend (organisationID/organization_id/id), so we\n * normalize to a stable {id,name,isDefault} shape and flag the default.\n */\nexport async function listWorkspaces(client: ReeplClient): Promise<Workspace[]> {\n const data = await client.get<OrganizationsResponse>(\"/organizations\");\n const defaultId = data.default_organisationID;\n const orgs = Array.isArray(data.organizations) ? data.organizations : [];\n return orgs.map((o) => {\n const id = String(o.organisationID ?? o.organization_id ?? o.organizationID ?? o.id ?? \"\");\n return {\n ...o,\n id,\n name: o.name ?? o.organisationName ?? o.workspaceName,\n isDefault: Boolean(defaultId && id === defaultId),\n };\n });\n}\n\n/** Resolve the default workspace id (or null if none is marked). */\nexport async function getDefaultWorkspaceId(client: ReeplClient): Promise<string | null> {\n const data = await client.get<OrganizationsResponse>(\"/organizations\");\n return data.default_organisationID ?? null;\n}\n","import type { ReeplClient } from \"../client.js\";\n\nexport interface DraftInput {\n content: string;\n title?: string;\n mediaUrls?: string[];\n tags?: string[];\n}\n\nexport interface ScheduleInput {\n content: string;\n /** ISO-8601 timestamp. */\n scheduledFor: string;\n title?: string;\n mediaUrls?: string[];\n}\n\n/** POST /post/drafts — create a LinkedIn post draft. */\nexport function createDraft(client: ReeplClient, input: DraftInput) {\n return client.post(\"/post/drafts\", {\n body: { ...input, generatedVia: \"CLI\" },\n });\n}\n\n/** GET /post/drafts — list drafts. */\nexport function listDrafts(\n client: ReeplClient,\n opts: { limit?: number; search?: string; sortOrder?: string } = {},\n) {\n return client.get(\"/post/drafts\", {\n query: { limit: opts.limit, search: opts.search, sortOrder: opts.sortOrder },\n });\n}\n\n/** PUT /post/drafts — update a draft by id. */\nexport function updateDraft(\n client: ReeplClient,\n draftId: string,\n patch: Partial<DraftInput>,\n) {\n return client.put(\"/post/drafts\", { body: { draft_id: draftId, ...patch } });\n}\n\n/** DELETE /post/drafts?draftId= */\nexport function deleteDraft(client: ReeplClient, draftId: string) {\n return client.delete(\"/post/drafts\", { query: { draftId } });\n}\n\n/** POST /linkedin/posts — publish immediately. */\nexport function publishNow(client: ReeplClient, input: DraftInput) {\n return client.post(\"/linkedin/posts\", { body: { ...input, generatedVia: \"CLI\" } });\n}\n\n/** POST /linkedin/posts/schedule — schedule for a future time. */\nexport function schedulePost(client: ReeplClient, input: ScheduleInput) {\n return client.post(\"/linkedin/posts/schedule\", {\n body: { ...input, generatedVia: \"CLI\" },\n });\n}\n\n/** GET /linkedin/posts?status= — list published/scheduled/failed posts. */\nexport function listPosts(\n client: ReeplClient,\n opts: { status?: \"scheduled\" | \"published\" | \"failed\" | \"all\"; limit?: number; search?: string; nextToken?: string; userId?: string } = {},\n) {\n return client.get(\"/linkedin/posts\", {\n query: {\n status: opts.status,\n limit: opts.limit,\n search: opts.search,\n nextToken: opts.nextToken,\n userId: opts.userId,\n },\n });\n}\n\n/** PUT /linkedin/posts/{id}/schedule — reschedule (also used for publish-now = now). */\nexport function updateScheduledPost(\n client: ReeplClient,\n postId: string,\n patch: { content?: string; scheduledFor?: string; mediaUrls?: string[] },\n) {\n return client.put(`/linkedin/posts/${encodeURIComponent(postId)}/schedule`, { body: patch });\n}\n\n/** DELETE /linkedin/posts/{id} */\nexport function deletePost(client: ReeplClient, postId: string) {\n return client.delete(`/linkedin/posts/${encodeURIComponent(postId)}`);\n}\n\n/**\n * POST /linkedin/posts/{id}/comments — comment on a LinkedIn post.\n * NOTE: `postId` is Reepl's internal post id (resolved via the postId-index GSI), NOT a\n * public LinkedIn activity URL. Only posts published/tracked through Reepl are commentable\n * via this API; arbitrary public LinkedIn URLs are not addressable here.\n */\nexport function addComment(client: ReeplClient, postId: string, commentText: string) {\n return client.post(`/linkedin/posts/${encodeURIComponent(postId)}/comments`, {\n body: { commentText },\n });\n}\n","import type { ReeplClient } from \"../client.js\";\n\nexport interface Tweet {\n text: string;\n mediaUrls?: string[];\n}\n\nexport interface TwitterPostInput {\n /** One entry per tweet in the thread. A single tweet = a one-element array. */\n threadTweets: Tweet[];\n scheduledFor?: string;\n quoteTweetId?: string;\n linkedPostId?: string;\n}\n\n/** POST /twitter/posts — create/schedule a tweet or thread. `twitter_create_post` is paid-gated. */\nexport function createPost(client: ReeplClient, input: TwitterPostInput) {\n return client.post(\"/twitter/posts\", { body: { ...input, generatedVia: \"CLI\" } });\n}\n\n/** GET /twitter/posts?status= */\nexport function listPosts(\n client: ReeplClient,\n opts: { status?: string; limit?: number; search?: string; nextToken?: string } = {},\n) {\n return client.get(\"/twitter/posts\", {\n query: { status: opts.status, limit: opts.limit, search: opts.search, nextToken: opts.nextToken },\n });\n}\n\n/** PUT /twitter/posts/{id} */\nexport function updatePost(\n client: ReeplClient,\n postId: string,\n patch: Partial<TwitterPostInput>,\n) {\n return client.put(`/twitter/posts/${encodeURIComponent(postId)}`, { body: patch });\n}\n\n/** DELETE /twitter/posts/{id} */\nexport function deletePost(client: ReeplClient, postId: string) {\n return client.delete(`/twitter/posts/${encodeURIComponent(postId)}`);\n}\n\n/** POST /twitter/drafts — create a draft tweet/thread. */\nexport function createDraft(client: ReeplClient, input: TwitterPostInput & { title?: string }) {\n return client.post(\"/twitter/drafts\", { body: { ...input, generatedVia: \"CLI\" } });\n}\n\n/** GET /twitter/drafts */\nexport function listDrafts(client: ReeplClient, opts: { limit?: number; search?: string } = {}) {\n return client.get(\"/twitter/drafts\", { query: { limit: opts.limit, search: opts.search } });\n}\n\n/** DELETE /twitter/drafts?draftId= */\nexport function deleteDraft(client: ReeplClient, draftId: string) {\n return client.delete(\"/twitter/drafts\", { query: { draftId } });\n}\n\n/**\n * POST /twitter/engagement/reply — publish a reply to a tweet by id.\n * Premium-gated; costs engagement credits. Works for any tweet id (extractable from a URL).\n */\nexport function reply(client: ReeplClient, tweetId: string, text: string) {\n return client.post(\"/twitter/engagement/reply\", { body: { tweetId, text } });\n}\n","import type { ReeplClient } from \"../client.js\";\nimport { ReeplError, type ReeplErrorCode } from \"../errors.js\";\nimport * as linkedin from \"./linkedin.js\";\nimport * as twitter from \"./twitter.js\";\n\n/**\n * Only these expected per-platform conditions are swallowed (a platform not being\n * connected / not on the right plan shouldn't blank the whole calendar). Everything else\n * — 5xx (API_ERROR), 429 (RATE_LIMITED), 400 (VALIDATION), auth/network — propagates so a\n * real failure is never silently reported as an empty calendar.\n */\nconst TOLERATED_CODES = new Set<ReeplErrorCode>([\n \"PLAN_REQUIRED\",\n \"PREMIUM_REQUIRED\",\n \"RECONNECT_REQUIRED\",\n \"MISSING_DM_SCOPES\",\n \"NOT_FOUND\",\n]);\n\nfunction tolerate(err: unknown): ScheduledItem[] {\n if (err instanceof ReeplError && TOLERATED_CODES.has(err.code)) return [];\n throw err;\n}\n\nexport interface ScheduledItem {\n platform: \"linkedin\" | \"x\";\n id: string;\n scheduledFor?: string;\n status?: string;\n content: string;\n}\n\n/** Pull an array of posts out of the various response envelopes the backend returns. */\nfunction coercePosts(raw: unknown): Array<Record<string, any>> {\n if (Array.isArray(raw)) return raw;\n if (raw && typeof raw === \"object\") {\n const obj = raw as Record<string, any>;\n for (const key of [\"posts\", \"items\", \"scheduledPosts\", \"data\"]) {\n if (Array.isArray(obj[key])) return obj[key];\n }\n }\n return [];\n}\n\nfunction normalizeLinkedIn(raw: unknown): ScheduledItem[] {\n return coercePosts(raw).map((p) => ({\n platform: \"linkedin\" as const,\n id: String(p.postId ?? p.id ?? p.post_id ?? \"\"),\n scheduledFor: p.scheduledFor ?? p.scheduled_for,\n status: p.status,\n content: String(p.content ?? p.text ?? \"\").slice(0, 140),\n }));\n}\n\nfunction normalizeTwitter(raw: unknown): ScheduledItem[] {\n return coercePosts(raw).map((p) => ({\n platform: \"x\" as const,\n id: String(p.postId ?? p.id ?? \"\"),\n scheduledFor: p.scheduledFor ?? p.scheduled_for,\n status: p.status,\n content: String(\n p.content ?? (Array.isArray(p.threadTweets) ? p.threadTweets.map((t: any) => t.text).join(\" | \") : \"\"),\n ).slice(0, 140),\n }));\n}\n\n/**\n * Aggregate the content calendar (scheduled posts) across LinkedIn and X. There is no\n * dedicated calendar endpoint — it is built from each platform's scheduled feed.\n * X errors (e.g. account not connected) are swallowed so LinkedIn still renders.\n */\nexport async function getSchedule(\n client: ReeplClient,\n opts: { platform?: \"linkedin\" | \"x\" | \"all\"; limit?: number } = {},\n): Promise<ScheduledItem[]> {\n const platform = opts.platform ?? \"all\";\n const tasks: Array<Promise<ScheduledItem[]>> = [];\n\n if (platform === \"all\" || platform === \"linkedin\") {\n tasks.push(\n linkedin\n .listPosts(client, { status: \"scheduled\", limit: opts.limit })\n .then(normalizeLinkedIn)\n .catch(tolerate),\n );\n }\n if (platform === \"all\" || platform === \"x\") {\n tasks.push(\n twitter\n .listPosts(client, { status: \"scheduled\", limit: opts.limit })\n .then(normalizeTwitter)\n .catch(tolerate),\n );\n }\n\n const results = (await Promise.all(tasks)).flat();\n // Sort by scheduled time ascending; undefined times sink to the end.\n return results.sort((a, b) => (a.scheduledFor ?? \"~\").localeCompare(b.scheduledFor ?? \"~\"));\n}\n","import type { ReeplClient } from \"../client.js\";\n\n/**\n * GET /reddit/discovery/search?keyword= — on-demand Reddit keyword discovery.\n * Pro-gated (403 UPGRADE_REQUIRED -> PLAN_REQUIRED); rate-limited per user.\n */\nexport function search(client: ReeplClient, keyword: string) {\n return client.get(\"/reddit/discovery/search\", { query: { keyword } });\n}\n\n/** GET /reddit/discovery/status — remaining search quota / status. */\nexport function searchStatus(client: ReeplClient) {\n return client.get(\"/reddit/discovery/status\");\n}\n\n/**\n * POST /reddit/comment — comment on (reply to) a Reddit submission.\n * `postId` may be a bare id or a `t3_`-prefixed thing id (backend normalizes).\n * No plan gate; requires a connected Reddit integration (403 reddit_not_connected).\n */\nexport function comment(client: ReeplClient, postId: string, text: string) {\n return client.post(\"/reddit/comment\", { body: { postId, text } });\n}\n","import type { ReeplClient } from \"../client.js\";\n\n/**\n * GET /signals — the user's personalized signals inbox (Reddit / YouTube / RSS / trends).\n * NOTE: the route is `/signals`, not `/signals/inbox`. The live MCP server calls\n * `/signals/inbox`, but that route isn't Cognito-authorized (AWS returns an auth-header\n * error) and the MCP tool silently reports \"no signals\" — verified against the live API.\n */\nexport function getInbox(client: ReeplClient) {\n return client.get(\"/signals\");\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { ReeplClient } from \"../client.js\";\n\nexport interface SlideInput {\n headline?: string;\n title?: string;\n body?: string;\n content?: string;\n layout?: string;\n layoutType?: string;\n}\n\n/** Map user-facing slide shapes to the backend `carousels[]` item shape. */\nexport function mapSlides(slides: SlideInput[]): Array<Record<string, unknown>> {\n return slides.map((s) => ({\n id: randomUUID(),\n title: s.headline ?? s.title ?? \"\",\n body: s.body ?? s.content ?? \"\",\n ...((s.layout || s.layoutType) && { layoutType: s.layout ?? s.layoutType }),\n bgImage: null,\n backgroundTemplate: null,\n showUserDetails: true,\n }));\n}\n\n/** GET /carousel/drafts — list drafts. */\nexport function listDrafts(client: ReeplClient, opts: { limit?: number; search?: string } = {}) {\n return client.get(\"/carousel/drafts\", { query: { limit: opts.limit, search: opts.search } });\n}\n\n/** GET /carousel/drafts?draftId= — get a single draft. */\nexport function getDraft(client: ReeplClient, draftId: string) {\n return client.get(\"/carousel/drafts\", { query: { draftId } });\n}\n\nexport interface CarouselDraftInput {\n title: string;\n slides: SlideInput[];\n theme?: string;\n titleFontSize?: string;\n bodyFontSize?: string;\n}\n\n/** POST /carousel/drafts — create a carousel draft. */\nexport function createDraft(client: ReeplClient, input: CarouselDraftInput) {\n const carousels = mapSlides(input.slides);\n return client.post(\"/carousel/drafts\", {\n body: {\n title: input.title,\n carousels,\n slide_count: carousels.length,\n ...(input.theme !== undefined ? { theme: input.theme } : {}),\n ...(input.titleFontSize !== undefined ? { titleFontSize: input.titleFontSize } : {}),\n ...(input.bodyFontSize !== undefined ? { bodyFontSize: input.bodyFontSize } : {}),\n generatedVia: \"CLI\",\n },\n });\n}\n\nexport interface CarouselUpdateInput {\n title?: string;\n slides?: SlideInput[];\n theme?: string;\n titleFontSize?: string;\n bodyFontSize?: string;\n}\n\n/** PUT /carousel/drafts — update a draft. Only provided fields change. */\nexport function updateDraft(client: ReeplClient, draftId: string, patch: CarouselUpdateInput) {\n const updates: Record<string, unknown> = {};\n if (patch.title !== undefined) updates.title = patch.title;\n if (patch.theme !== undefined) updates.theme = patch.theme;\n if (patch.titleFontSize !== undefined) updates.titleFontSize = patch.titleFontSize;\n if (patch.bodyFontSize !== undefined) updates.bodyFontSize = patch.bodyFontSize;\n if (patch.slides !== undefined) {\n const carousels = mapSlides(patch.slides);\n updates.carousels = carousels;\n updates.slide_count = carousels.length;\n }\n return client.put(\"/carousel/drafts\", { body: { draft_id: draftId, ...updates } });\n}\n\n/** DELETE /carousel/drafts?draftId= */\nexport function deleteDraft(client: ReeplClient, draftId: string) {\n return client.delete(\"/carousel/drafts\", { query: { draftId } });\n}\n\nexport interface GenerateInput {\n topic?: string;\n url?: string;\n numberOfSlides?: number;\n aiInstructions?: string;\n}\n\n/**\n * POST /carousel (public HTTP API) — AI-generate slides. Unauthenticated: the caller's\n * userID goes in the body. Returns generated slides (not a saved draft).\n */\nexport function generate(client: ReeplClient, userID: string, input: GenerateInput) {\n if (!input.topic && !input.url) throw new Error(\"Provide --topic or --url to generate.\");\n const contentType = input.url\n ? /youtube\\.com|youtu\\.be/.test(input.url)\n ? \"youtube\"\n : \"article\"\n : \"text\";\n return client.post(\"/carousel\", {\n base: \"public\",\n auth: false,\n workspace: null,\n body: {\n userID,\n contentType,\n content: input.url ?? input.topic,\n numberOfSlides: Math.min(Math.max(1, input.numberOfSlides ?? 5), 10),\n ...(input.aiInstructions ? { aiInstructions: input.aiInstructions } : {}),\n },\n });\n}\n","import type { ReeplClient } from \"../client.js\";\n\n/** Facets are plural in the backend: posts | comments | messages (singular is normalized). */\nexport type StyleFacet = \"posts\" | \"comments\" | \"messages\";\n\n/** GET /writing-style — summary of all facets + visibility. Requires workspace_id. */\nexport function get(client: ReeplClient) {\n return client.get(\"/writing-style\");\n}\n\n/** POST /writing-style/override — save per-facet override instructions. */\nexport function override(client: ReeplClient, facet: string, instructions: string) {\n return client.post(\"/writing-style/override\", { body: { facet, instructions } });\n}\n\n/** POST /writing-style/visibility — set visibility. */\nexport function setVisibility(client: ReeplClient, visibility: string) {\n return client.post(\"/writing-style/visibility\", { body: { visibility } });\n}\n\n/** POST /writing-style/train — (re)synthesize a facet's style. Pro+; posts/comments only. */\nexport function train(client: ReeplClient, facet: string) {\n return client.post(\"/writing-style/train\", { body: { facet } });\n}\n\n/** POST /ai/test-voice-style — faceted playground: baseline vs styled generation. */\nexport function testVoiceStyle(client: ReeplClient, facet: string, input: string) {\n return client.post(\"/ai/test-voice-style\", { body: { facet, input } });\n}\n","import type { ReeplClient } from \"../client.js\";\n\n/** GET /profile/voice-profile — current user's voice profile. */\nexport function get(client: ReeplClient) {\n return client.get<{ voiceProfile?: unknown; hasProfile?: boolean }>(\"/profile/voice-profile\");\n}\n\n/**\n * PUT /profile/voice-profile — deep-merge update. Body may include allowAutoUpdate,\n * isActive, userInstructions{...}, generatedProfile{...}, positioningProfile{...}.\n */\nexport function update(client: ReeplClient, body: Record<string, unknown>) {\n return client.put(\"/profile/voice-profile\", { body });\n}\n","import type { ReeplClient } from \"../client.js\";\n\n/**\n * X (Twitter) DM inbox. All write/refresh operations are Premium-gated\n * (403 UPGRADE_REQUIRED). Note: the conversation id in the path is the participant's X\n * user id, which is what both the read and send endpoints expect.\n */\n\n/** POST /inbox/twitter/refresh — pull the latest DM events from X (Premium). */\nexport function refresh(client: ReeplClient) {\n return client.post(\"/inbox/twitter/refresh\");\n}\n\n/** GET /inbox/twitter/refresh-status — throttle / last-refresh status. */\nexport function refreshStatus(client: ReeplClient) {\n return client.get(\"/inbox/twitter/refresh-status\");\n}\n\n/** GET /inbox/twitter/conversations — cached conversation list. */\nexport function listConversations(client: ReeplClient, opts: { limit?: number; offset?: number } = {}) {\n return client.get(\"/inbox/twitter/conversations\", { query: { limit: opts.limit, offset: opts.offset } });\n}\n\n/** GET /inbox/twitter/conversations/{id}/messages — messages in one conversation. */\nexport function getMessages(client: ReeplClient, conversationId: string) {\n return client.get(`/inbox/twitter/conversations/${encodeURIComponent(conversationId)}/messages`);\n}\n\n/**\n * POST /inbox/twitter/conversations/{participantId}/messages — send/reply in a DM thread\n * (Premium; costs credits). `participantId` is the conversation id from listConversations.\n */\nexport function sendMessage(client: ReeplClient, participantId: string, text: string) {\n return client.post(`/inbox/twitter/conversations/${encodeURIComponent(participantId)}/messages`, {\n body: { text },\n });\n}\n","/**\n * Resolve a post reference (URL or raw id) to a platform + addressable id.\n * Used by `comment add` to route to the right endpoint from a single --url/--post arg.\n */\nexport type PostPlatform = \"linkedin\" | \"x\" | \"reddit\";\n\nexport interface PostRef {\n platform: PostPlatform;\n /** The id passed to the platform's comment/reply endpoint. */\n id: string;\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** Parse a Reddit submission id from a URL or return a bare/t3_ id unchanged. */\nfunction redditId(input: string): string | null {\n const m = input.match(/\\/comments\\/([a-z0-9]+)/i);\n if (m) return m[1]!;\n if (/^t3_[a-z0-9]+$/i.test(input) || /^[a-z0-9]{5,8}$/i.test(input)) return input;\n return null;\n}\n\n/** Parse a tweet id from an x.com/twitter.com status URL, or return a bare numeric id. */\nfunction tweetId(input: string): string | null {\n const m = input.match(/status(?:es)?\\/(\\d+)/);\n if (m) return m[1]!;\n if (/^\\d{5,}$/.test(input)) return input;\n return null;\n}\n\n/**\n * Resolve a reference. `hint` forces a platform when the input is ambiguous (bare id).\n * Throws with actionable guidance when it can't be resolved.\n */\nexport function resolvePostRef(input: string, hint?: PostPlatform): PostRef {\n const value = input.trim();\n let host = \"\";\n try {\n host = new URL(value).host.toLowerCase();\n } catch {\n // not a URL — fall through to hint/id heuristics\n }\n\n const isReddit = hint === \"reddit\" || host.includes(\"reddit.com\");\n const isX = hint === \"x\" || host.includes(\"x.com\") || host.includes(\"twitter.com\");\n const isLinkedIn = hint === \"linkedin\" || host.includes(\"linkedin.com\");\n\n if (isReddit) {\n const id = redditId(value);\n if (id) return { platform: \"reddit\", id };\n throw new Error(`Could not parse a Reddit submission id from \"${value}\".`);\n }\n if (isX) {\n const id = tweetId(value);\n if (id) return { platform: \"x\", id };\n throw new Error(`Could not parse a tweet id from \"${value}\".`);\n }\n if (isLinkedIn) {\n // Only Reepl-internal post ids (UUIDs) are addressable via the API.\n if (UUID_RE.test(value)) return { platform: \"linkedin\", id: value };\n throw new Error(\n \"Commenting on a public LinkedIn URL is not supported via the API — the endpoint only \" +\n \"addresses posts published through Reepl (by their Reepl post id). Use the Chrome \" +\n \"extension to comment on arbitrary LinkedIn posts.\",\n );\n }\n\n // No host and no hint: guess by shape.\n if (/^\\d{5,}$/.test(value)) return { platform: \"x\", id: value };\n if (/^t3_[a-z0-9]+$/i.test(value)) return { platform: \"reddit\", id: value };\n if (UUID_RE.test(value)) return { platform: \"linkedin\", id: value };\n throw new Error(\n `Could not determine the platform for \"${value}\". Pass --platform linkedin|x|reddit.`,\n );\n}\n"],"mappings":"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","names":["createDraft","deleteDraft","deletePost","listDrafts","listPosts","tweetId","listPosts","createDraft","deleteDraft","listDrafts","updateDraft","get"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|