@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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/banner.ts","../../src/cli/commands/auth.ts","../../src/cli/auth-flow.ts","../../src/cli/config.ts","../../src/cli/context.ts","../../src/cli/output.ts","../../src/cli/commands/calendar.ts","../../src/cli/commands/carousel.ts","../../src/cli/input.ts","../../src/cli/commands/comment.ts","../../src/cli/commands/dm.ts","../../src/cli/commands/post.ts","../../src/cli/commands/reddit.ts","../../src/cli/commands/schema.ts","../../src/cli/commands/signals.ts","../../src/cli/commands/style.ts","../../src/cli/commands/voice.ts","../../src/cli/commands/workspace.ts","../../src/cli/commands/x.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { printBanner } from \"./banner.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerCalendarCommands } from \"./commands/calendar.js\";\nimport { registerCarouselCommands } from \"./commands/carousel.js\";\nimport { registerCommentCommands } from \"./commands/comment.js\";\nimport { registerDmCommands } from \"./commands/dm.js\";\nimport { registerPostCommands } from \"./commands/post.js\";\nimport { registerRedditCommands } from \"./commands/reddit.js\";\nimport { registerSchemaCommand } from \"./commands/schema.js\";\nimport { registerSignalsCommands } from \"./commands/signals.js\";\nimport { registerStyleCommands } from \"./commands/style.js\";\nimport { registerVoiceCommands } from \"./commands/voice.js\";\nimport { registerWorkspaceCommands } from \"./commands/workspace.js\";\nimport { registerXCommands } from \"./commands/x.js\";\nimport { fail, setJsonMode } from \"./output.js\";\nimport { ReeplError } from \"../core/index.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"reepl\")\n .description(\"Reepl CLI — manage LinkedIn / X / Reddit content, carousels, signals, and more.\")\n .version(\"0.1.0\")\n .option(\"--json\", \"Output machine-readable JSON (auto-enabled when piped)\")\n .option(\"--no-json\", \"Force human-readable output even when piped\")\n .hook(\"preAction\", (thisCommand) => {\n const opts = thisCommand.opts();\n // Commander sets `json` to false only when --no-json is passed; undefined otherwise.\n setJsonMode(opts.json === undefined ? undefined : Boolean(opts.json));\n });\n\n// Take control of commander's exit/output so usage errors (unknown command, missing\n// required option) render through the same envelope agents rely on, not raw stderr.\nprogram.exitOverride();\nprogram.configureOutput({\n writeOut: (str) => process.stdout.write(str),\n writeErr: () => {}, // suppress commander's default error text; we emit the envelope\n});\n\nregisterAuthCommands(program);\nregisterWorkspaceCommands(program);\nregisterPostCommands(program);\nregisterCalendarCommands(program);\nregisterCommentCommands(program);\nregisterRedditCommands(program);\nregisterSignalsCommands(program);\nregisterCarouselCommands(program);\nregisterStyleCommands(program);\nregisterVoiceCommands(program);\nregisterDmCommands(program);\nregisterXCommands(program);\nregisterSchemaCommand(program); // last: captures all sibling commands\n\n// Bare `reepl` (no subcommand): show the branded screen + a hint, not a raw error.\nif (process.argv.length <= 2) {\n printBanner({ version: program.version() });\n process.stdout.write(\"Run `reepl --help` to see all commands.\\n\");\n process.exit(0);\n}\n\nprogram.parseAsync(process.argv).catch((err) => {\n // --help / --version already wrote their output via writeOut; exit cleanly.\n const code: string | undefined = err?.code;\n if (\n code === \"commander.helpDisplayed\" ||\n code === \"commander.help\" ||\n code === \"commander.version\"\n ) {\n process.exit(0);\n }\n // Everything else here is a commander usage error (unknown command / bad option).\n // Action-handler errors are already caught inside each command via fail().\n const message = String(err?.message ?? \"Invalid command usage.\").replace(/^error:\\s*/i, \"\");\n fail(new ReeplError(\"VALIDATION\", message));\n});\n","/**\n * Branded Reepl terminal screen — shown on install (postinstall) and on a bare `reepl`.\n *\n * The wordmark is figlet \"ANSI Shadow\"; the sparkle echoes the Reepl app icon (a white\n * starburst on brand purple #6d42cc). Colour is truecolor ANSI, auto-disabled when the\n * stream is not a TTY or NO_COLOR is set, so piped/CI output stays clean.\n */\n\nconst BRAND = { r: 109, g: 66, b: 204 }; // #6d42cc\n\nconst WORDMARK = [\n \"██████╗ ███████╗███████╗██████╗ ██╗ \",\n \"██╔══██╗██╔════╝██╔════╝██╔══██╗██║ \",\n \"██████╔╝█████╗ █████╗ ██████╔╝██║ \",\n \"██╔══██╗██╔══╝ ██╔══╝ ██╔═══╝ ██║ \",\n \"██║ ██║███████╗███████╗██║ ███████╗\",\n \"╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚══════╝\",\n];\n\nconst SPARKLE = \" ✦ · ✦\";\n\nfunction supportsColor(stream: NodeJS.WriteStream): boolean {\n if (process.env.NO_COLOR) return false;\n if (process.env.FORCE_COLOR) return true;\n return Boolean(stream.isTTY) && process.env.TERM !== \"dumb\";\n}\n\nfunction purple(text: string, on: boolean): string {\n if (!on) return text;\n return `\\x1b[38;2;${BRAND.r};${BRAND.g};${BRAND.b}m${text}\\x1b[0m`;\n}\n\nfunction dim(text: string, on: boolean): string {\n return on ? `\\x1b[2m${text}\\x1b[0m` : text;\n}\n\nexport interface BannerOptions {\n version?: string;\n /** Extra line(s) below the tagline (e.g. a \"just installed\" note). */\n footer?: string;\n}\n\n/** Build the banner as a string (no I/O) so it is easy to snapshot-test. */\nexport function renderBanner(opts: BannerOptions = {}, color = true): string {\n const v = opts.version ? ` v${opts.version}` : \"\";\n const lines = [\n \"\",\n ...WORDMARK.map((l) => purple(l, color)),\n purple(SPARKLE, color),\n \"\",\n ` ${purple(\"Reepl CLI\", color)}${dim(v, color)} — your content workflow, in the terminal.`,\n ` ${dim(\"LinkedIn · X · Reddit · carousels · signals · writing styles\", color)}`,\n \"\",\n ` ${dim(\"Get started:\", color)} reepl login ${dim(\"·\", color)} reepl --help ${dim(\"·\", color)} reepl schema`,\n ];\n if (opts.footer) lines.push(\"\", ` ${opts.footer}`);\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n/** Print the banner to a stream (defaults to stdout). Never write it to JSON stdout paths. */\nexport function printBanner(opts: BannerOptions = {}, stream: NodeJS.WriteStream = process.stdout): void {\n stream.write(renderBanner(opts, supportsColor(stream)) + \"\\n\");\n}\n","import type { Command } from \"commander\";\nimport open from \"open\";\nimport { jwtExpiryMs, profile as profileApi, type StoredTokens } from \"../../core/index.js\";\nimport { loginViaBrowser } from \"../auth-flow.js\";\nimport { FileTokenStore, writeConfig } from \"../config.js\";\nimport { getContext } from \"../context.js\";\nimport { fail, isJsonMode, success } from \"../output.js\";\n\nexport function registerAuthCommands(program: Command): void {\n program\n .command(\"login\")\n .description(\"Authenticate with Reepl via your browser (or --token/--refresh for headless)\")\n .option(\"--token <idToken>\", \"Provide a Cognito ID token directly (skips the browser)\")\n .option(\"--refresh <refreshToken>\", \"Provide a Cognito refresh token directly\")\n .action(async (opts: { token?: string; refresh?: string }) => {\n try {\n const store = new FileTokenStore();\n let tokens: StoredTokens;\n\n if (opts.token && opts.refresh) {\n // Headless path: caller supplies tokens (e.g. CI extracted from the web app).\n tokens = {\n idToken: opts.token,\n refreshToken: opts.refresh,\n expiresAt: jwtExpiryMs(opts.token) ?? Date.now() + 3600 * 1000,\n };\n } else if (opts.token || opts.refresh) {\n throw new Error(\"--token and --refresh must be provided together.\");\n } else {\n const result = await loginViaBrowser({\n openBrowser: (url) => open(url),\n onUrl: (url) => {\n if (!isJsonMode()) {\n process.stderr.write(\n `Opening your browser to sign in...\\nIf it doesn't open, visit:\\n ${url}\\n\\n`,\n );\n }\n },\n });\n tokens = result.tokens;\n }\n\n await store.save(tokens);\n\n // Fetch profile to confirm the token works and cache the email.\n const { client } = await getContext();\n const me = await profileApi.getProfile(client);\n await writeConfig({ email: me.email });\n\n success(\n { email: me.email, name: me.name, plan: me.subscriptionType },\n (d) => `Logged in as ${d.email ?? \"unknown\"}${d.plan ? ` (${d.plan})` : \"\"}.`,\n );\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"logout\")\n .description(\"Remove stored Reepl credentials from this machine\")\n .action(async () => {\n try {\n await new FileTokenStore().clear();\n await writeConfig({ email: undefined });\n success({ loggedOut: true }, () => \"Logged out. Credentials removed.\");\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"whoami\")\n .description(\"Show the currently authenticated account and plan\")\n .action(async () => {\n try {\n const { client } = await getContext();\n const me = await profileApi.getProfile(client);\n const paid = profileApi.hasActivePlan(me);\n success(\n {\n userID: me.userID,\n email: me.email,\n name: me.name,\n plan: me.subscriptionType,\n hasActivePlan: paid,\n creditsAvailable: me.credits_available,\n },\n (d) =>\n `${d.email ?? \"unknown\"}${d.name ? ` (${d.name})` : \"\"}\\n` +\n `Plan: ${d.plan ?? \"free\"}${d.hasActivePlan ? \"\" : \" (no active purchase)\"}\\n` +\n `Credits: ${d.creditsAvailable ?? \"n/a\"}`,\n );\n } catch (err) {\n fail(err);\n }\n });\n}\n","import { randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport {\n jwtExpiryMs,\n MCP_CONNECT_PATH,\n REEPL_WEB_APP_URL,\n ReeplError,\n type StoredTokens,\n} from \"../core/index.js\";\n\nexport interface LoginResult {\n tokens: StoredTokens;\n email?: string;\n}\n\nconst DONE_HTML = `<!doctype html><meta charset=\"utf-8\"><title>Reepl CLI</title>\n<body style=\"font-family:system-ui;background:#0b0b0f;color:#eaeaf0;display:grid;place-items:center;height:100vh;margin:0\">\n<div style=\"text-align:center\"><h1 style=\"font-weight:600\">You're signed in.</h1>\n<p style=\"color:#9a9aa8\">Return to your terminal — you can close this tab.</p></div></body>`;\n\n/**\n * Browser-loopback login. Opens the web-app handoff (`/mcp-connect`) with a localhost\n * callback; the web app redirects back with `token` + `refresh_token` once the user is\n * authenticated. No callback whitelist exists on the web app, so a 127.0.0.1 callback works.\n */\nexport async function loginViaBrowser(opts: {\n openBrowser: (url: string) => Promise<unknown>;\n timeoutMs?: number;\n onUrl?: (url: string) => void;\n}): Promise<LoginResult> {\n const state = randomBytes(16).toString(\"hex\");\n const timeoutMs = opts.timeoutMs ?? 5 * 60 * 1000;\n\n return new Promise<LoginResult>((resolve, reject) => {\n const server = createServer((req, res) => {\n try {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n if (url.pathname !== \"/callback\") {\n res.writeHead(404).end(\"Not found\");\n return;\n }\n const token = url.searchParams.get(\"token\");\n const refreshToken = url.searchParams.get(\"refresh_token\");\n const returnedState = url.searchParams.get(\"state\");\n\n if (returnedState !== state) {\n res.writeHead(400).end(\"State mismatch\");\n cleanup();\n reject(new ReeplError(\"UNAUTHENTICATED\", \"Login failed: state mismatch (possible CSRF).\"));\n return;\n }\n if (!token || !refreshToken) {\n res.writeHead(400).end(\"Missing token\");\n cleanup();\n reject(\n new ReeplError(\n \"UNAUTHENTICATED\",\n \"Login did not return a refresh token. Ensure you are logged in to app.reepl.io and retry.\",\n ),\n );\n return;\n }\n\n res.writeHead(200, { \"Content-Type\": \"text/html\" }).end(DONE_HTML);\n cleanup();\n\n const expiresAt = jwtExpiryMs(token) ?? Date.now() + 3600 * 1000;\n resolve({ tokens: { idToken: token, refreshToken, expiresAt } });\n } catch (err) {\n cleanup();\n reject(err);\n }\n });\n\n const timer = setTimeout(() => {\n cleanup();\n reject(new ReeplError(\"UNAUTHENTICATED\", \"Login timed out. Run `reepl login` again.\"));\n }, timeoutMs);\n\n function cleanup() {\n clearTimeout(timer);\n server.close();\n }\n\n server.on(\"error\", (err) => {\n cleanup();\n reject(new ReeplError(\"NETWORK\", `Could not start local login listener: ${err.message}`));\n });\n\n server.listen(0, \"127.0.0.1\", () => {\n const { port } = server.address() as AddressInfo;\n const callback = `http://127.0.0.1:${port}/callback`;\n const handoff = new URL(REEPL_WEB_APP_URL + MCP_CONNECT_PATH);\n handoff.searchParams.set(\"state\", state);\n handoff.searchParams.set(\"callback\", callback);\n handoff.searchParams.set(\"app\", \"cli\");\n const href = handoff.toString();\n opts.onUrl?.(href);\n opts.openBrowser(href).catch(() => {\n /* browser open is best-effort; the URL is printed for manual open */\n });\n });\n });\n}\n","import { chmod, mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { StoredTokens, TokenStore } from \"../core/index.js\";\n\n/** Root of the CLI's on-disk state. Override with REEPL_CONFIG_DIR (used by tests). */\nexport function configDir(): string {\n return process.env.REEPL_CONFIG_DIR || join(homedir(), \".reepl\");\n}\n\nconst credentialsPath = () => join(configDir(), \"credentials.json\");\nconst configPath = () => join(configDir(), \"config.json\");\n\nexport interface CliConfig {\n currentWorkspaceId?: string;\n email?: string;\n}\n\nasync function readJson<T>(path: string): Promise<T | null> {\n try {\n return JSON.parse(await readFile(path, \"utf8\")) as T;\n } catch (err: any) {\n if (err?.code === \"ENOENT\") return null;\n throw err;\n }\n}\n\nasync function writeJson(path: string, value: unknown, mode?: number): Promise<void> {\n // 0o700 on the config dir keeps credentials unreadable by other users (defense in depth).\n await mkdir(dirname(path), { recursive: true, mode: 0o700 });\n await writeFile(path, JSON.stringify(value, null, 2), { mode: mode ?? 0o600 });\n if (mode) await chmod(path, mode).catch(() => {});\n}\n\nexport async function readConfig(): Promise<CliConfig> {\n return (await readJson<CliConfig>(configPath())) ?? {};\n}\n\nexport async function writeConfig(patch: Partial<CliConfig>): Promise<CliConfig> {\n const next = { ...(await readConfig()), ...patch };\n await writeJson(configPath(), next, 0o600);\n return next;\n}\n\n/**\n * File-backed TokenStore. Credentials live in ~/.reepl/credentials.json with 0600 perms.\n * (A future enhancement can swap this for an OS keychain without touching core.)\n */\nexport class FileTokenStore implements TokenStore {\n async load(): Promise<StoredTokens | null> {\n return readJson<StoredTokens>(credentialsPath());\n }\n async save(tokens: StoredTokens): Promise<void> {\n await writeJson(credentialsPath(), tokens, 0o600);\n }\n async clear(): Promise<void> {\n await rm(credentialsPath(), { force: true });\n }\n}\n","import { decodeJwt, ReeplClient, ReeplError, TokenManager, workspaces as wsApi } from \"../core/index.js\";\nimport { FileTokenStore, readConfig } from \"./config.js\";\n\n/** Assembled per-invocation context: an authed client scoped to the current workspace. */\nexport interface CliContext {\n client: ReeplClient;\n tokens: TokenManager;\n store: FileTokenStore;\n workspaceId?: string;\n}\n\n/**\n * Build a ReeplClient wired to the file token store and the currently-selected workspace.\n * Does not force a token fetch — that happens lazily on the first request, so `logout`\n * and offline commands don't trigger a refresh.\n */\nexport async function getContext(overrideWorkspaceId?: string): Promise<CliContext> {\n const store = new FileTokenStore();\n // Env overrides keep core pure while letting the CLI point at a mock backend in tests.\n const tokens = new TokenManager(store, {\n cognitoDomain: process.env.REEPL_COGNITO_DOMAIN || undefined,\n clientId: process.env.REEPL_COGNITO_CLIENT_ID || undefined,\n });\n const config = await readConfig();\n const workspaceId = overrideWorkspaceId ?? config.currentWorkspaceId;\n\n const client = new ReeplClient({\n getToken: () => tokens.getIdToken(),\n workspaceId: workspaceId ?? null,\n apiBaseUrl: process.env.REEPL_API_BASE_URL || undefined,\n publicBaseUrl: process.env.REEPL_PUBLIC_API_BASE_URL || undefined,\n });\n\n return { client, tokens, store, workspaceId };\n}\n\n/** Decode the current user's id (`sub`) from the ID token — needed by public endpoints. */\nexport async function currentUserId(ctx: CliContext): Promise<string> {\n const token = await ctx.tokens.getIdToken();\n const sub = decodeJwt(token)?.sub;\n if (!sub) throw new ReeplError(\"UNAUTHENTICATED\", \"Could not read user id from token. Run `reepl login`.\");\n return String(sub);\n}\n\n/**\n * Resolve a workspace id for endpoints that REQUIRE one (e.g. writing styles return 400\n * without it): the selected workspace, else the account default.\n */\nexport async function ensureWorkspaceId(ctx: CliContext): Promise<string> {\n if (ctx.workspaceId) return ctx.workspaceId;\n const def = await wsApi.getDefaultWorkspaceId(ctx.client);\n if (!def) {\n throw new ReeplError(\"CONFIG\", \"No workspace selected and no default found. Run `reepl workspace list`.\");\n }\n return def;\n}\n","import { ReeplError } from \"../core/index.js\";\n\n/**\n * Stable output envelope. Agents branch on `ok` and `error.code`; humans get a rendered\n * view. JSON mode is auto-enabled when stdout is not a TTY (piped/redirected) or via --json.\n */\nexport interface OutputOptions {\n json?: boolean;\n}\n\nlet forceJson: boolean | undefined;\n\n/** Called once from the root command after parsing the global --json flag. */\nexport function setJsonMode(value: boolean | undefined): void {\n forceJson = value;\n}\n\nexport function isJsonMode(): boolean {\n if (forceJson !== undefined) return forceJson;\n return !process.stdout.isTTY;\n}\n\n/** Print a success result and return (caller decides exit). */\nexport function success(data: unknown, render?: (data: any) => string): void {\n if (isJsonMode()) {\n process.stdout.write(JSON.stringify({ ok: true, data }, null, 2) + \"\\n\");\n return;\n }\n if (render) {\n process.stdout.write(render(data) + \"\\n\");\n return;\n }\n process.stdout.write(prettyValue(data) + \"\\n\");\n}\n\n/** Print an error envelope and exit with the mapped code. */\nexport function fail(err: unknown): never {\n const reepl =\n err instanceof ReeplError\n ? err\n : new ReeplError(\"API_ERROR\", err instanceof Error ? err.message : String(err));\n\n if (isJsonMode()) {\n process.stdout.write(\n JSON.stringify({ ok: false, error: reepl.toJSON() }, null, 2) + \"\\n\",\n );\n } else {\n process.stderr.write(`Error [${reepl.code}]: ${reepl.message}\\n`);\n }\n process.exit(reepl.exitCode);\n}\n\nfunction prettyValue(data: unknown): string {\n if (typeof data === \"string\") return data;\n return JSON.stringify(data, null, 2);\n}\n\n/** Minimal fixed-width table for TTY list output. */\nexport function table(rows: Array<Record<string, unknown>>, columns: string[]): string {\n if (rows.length === 0) return \"(none)\";\n const widths = columns.map((c) =>\n Math.max(c.length, ...rows.map((r) => String(r[c] ?? \"\").length)),\n );\n const header = columns.map((c, i) => c.padEnd(widths[i]!)).join(\" \");\n const sep = widths.map((w) => \"-\".repeat(w)).join(\" \");\n const body = rows\n .map((r) => columns.map((c, i) => String(r[c] ?? \"\").padEnd(widths[i]!)).join(\" \"))\n .join(\"\\n\");\n return `${header}\\n${sep}\\n${body}`;\n}\n","import type { Command } from \"commander\";\nimport { calendar } from \"../../core/index.js\";\nimport { getContext } from \"../context.js\";\nimport { fail, success, table } from \"../output.js\";\n\nexport function registerCalendarCommands(program: Command): void {\n program\n .command(\"calendar\")\n .alias(\"schedule\")\n .description(\"Show the content calendar (scheduled posts across LinkedIn and X)\")\n .option(\"-p, --platform <platform>\", \"linkedin | x | all\", \"all\")\n .option(\"--limit <n>\", \"Max results per platform\", (v) => parseInt(v, 10))\n .action(async (opts) => {\n try {\n const platform = (opts.platform ?? \"all\").toLowerCase();\n const { client } = await getContext();\n const items = await calendar.getSchedule(client, {\n platform: platform === \"twitter\" ? \"x\" : platform,\n limit: opts.limit,\n });\n success(items, (rows: any[]) =>\n table(\n rows.map((i) => ({\n platform: i.platform,\n id: i.id,\n scheduledFor: i.scheduledFor ?? \"\",\n content: i.content,\n })),\n [\"platform\", \"id\", \"scheduledFor\", \"content\"],\n ),\n );\n } catch (err) {\n fail(err);\n }\n });\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { Command } from \"commander\";\nimport { carousel, type SlideInput } from \"../../core/index.js\";\nimport { currentUserId, getContext } from \"../context.js\";\nimport { fail, success, table } from \"../output.js\";\n\nasync function loadSlides(opts: { slides?: string; slidesFile?: string }): Promise<SlideInput[]> {\n const raw = opts.slidesFile ? await readFile(opts.slidesFile, \"utf8\") : opts.slides;\n if (!raw) throw new Error(\"Provide slides via --slides <json> or --slides-file <path>.\");\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new Error(\"--slides must be a JSON array of { headline, body, layout? } objects.\");\n }\n if (!Array.isArray(parsed)) throw new Error(\"Slides JSON must be an array.\");\n return parsed as SlideInput[];\n}\n\nexport function registerCarouselCommands(program: Command): void {\n const cmd = program.command(\"carousel\").description(\"Manage carousel drafts\");\n\n cmd\n .command(\"list\")\n .description(\"List carousel drafts\")\n .option(\"--limit <n>\", \"Max results\", (v) => parseInt(v, 10))\n .option(\"--search <q>\", \"Search query\")\n .action(async (opts) => {\n try {\n const { client } = await getContext();\n const result: any = await carousel.listDrafts(client, { limit: opts.limit, search: opts.search });\n success(result, (d) => {\n const drafts: any[] = Array.isArray(d) ? d : d?.drafts ?? [];\n if (!drafts.length) return \"(none)\";\n return table(\n drafts.map((x) => ({\n id: x.draft_id ?? x.id ?? \"\",\n slides: x.slide_count ?? x.carousels?.length ?? \"\",\n title: String(x.title ?? \"\").slice(0, 50),\n })),\n [\"id\", \"slides\", \"title\"],\n );\n });\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"get <draftId>\")\n .description(\"Get a carousel draft\")\n .action(async (draftId: string) => {\n try {\n const { client } = await getContext();\n success(await carousel.getDraft(client, draftId));\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"create\")\n .description(\"Create a carousel draft from slides JSON\")\n .requiredOption(\"--title <title>\", \"Draft title\")\n .option(\"--slides <json>\", \"Slides as a JSON array\")\n .option(\"--slides-file <path>\", \"Read slides JSON from a file\")\n .option(\"--theme <theme>\", \"Theme id\")\n .action(async (opts) => {\n try {\n const slides = await loadSlides(opts);\n const { client } = await getContext();\n const result = await carousel.createDraft(client, { title: opts.title, slides, theme: opts.theme });\n success(result, (d: any) => `Created carousel draft ${d?.draft?.draft_id ?? d?.draft_id ?? \"\"}.`);\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"update <draftId>\")\n .description(\"Update a carousel draft (title, slides, theme, fonts)\")\n .option(\"--title <title>\", \"New title\")\n .option(\"--slides <json>\", \"Replacement slides as a JSON array\")\n .option(\"--slides-file <path>\", \"Read replacement slides JSON from a file\")\n .option(\"--theme <theme>\", \"Theme id\")\n .option(\"--title-font <size>\", \"Title font size\")\n .option(\"--body-font <size>\", \"Body font size\")\n .action(async (draftId: string, opts) => {\n try {\n const slides =\n opts.slides || opts.slidesFile ? await loadSlides(opts) : undefined;\n const { client } = await getContext();\n const result = await carousel.updateDraft(client, draftId, {\n title: opts.title,\n slides,\n theme: opts.theme,\n titleFontSize: opts.titleFont,\n bodyFontSize: opts.bodyFont,\n });\n success(result, () => `Updated carousel draft ${draftId}.`);\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"delete <draftId>\")\n .description(\"Delete a carousel draft\")\n .action(async (draftId: string) => {\n try {\n const { client } = await getContext();\n await carousel.deleteDraft(client, draftId);\n success({ draftId, deleted: true }, () => `Deleted carousel draft ${draftId}.`);\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"generate\")\n .description(\"AI-generate carousel slides from a topic or URL\")\n .option(\"--topic <topic>\", \"Topic to generate from\")\n .option(\"--url <url>\", \"Article/YouTube URL to generate from\")\n .option(\"--slides <n>\", \"Number of slides (1-10)\", (v) => parseInt(v, 10))\n .option(\"--instructions <text>\", \"Extra AI instructions\")\n .action(async (opts) => {\n try {\n const ctx = await getContext();\n const userID = await currentUserId(ctx);\n const result = await carousel.generate(ctx.client, userID, {\n topic: opts.topic,\n url: opts.url,\n numberOfSlides: opts.slides,\n aiInstructions: opts.instructions,\n });\n success(result);\n } catch (err) {\n fail(err);\n }\n });\n}\n","import { readFile } from \"node:fs/promises\";\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\n/**\n * Resolve post text from `--content` (use `-` for stdin), `--file`, or piped stdin.\n * Throws a clear message if none is provided.\n */\nexport async function resolveContent(opts: { content?: string; file?: string }): Promise<string> {\n if (opts.file) return (await readFile(opts.file, \"utf8\")).trim();\n if (opts.content === \"-\") return (await readStdin()).trim();\n if (opts.content !== undefined) return opts.content;\n if (!process.stdin.isTTY) {\n const piped = (await readStdin()).trim();\n if (piped) return piped;\n }\n throw new Error(\"No content provided. Use -c/--content, --file <path>, or pipe via stdin.\");\n}\n\n/** Parse a comma-separated list flag into a trimmed string array. */\nexport function parseList(value?: string): string[] | undefined {\n if (!value) return undefined;\n return value\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n}\n","import type { Command } from \"commander\";\nimport { linkedin, reddit, resolvePostRef, twitter, type PostPlatform } from \"../../core/index.js\";\nimport { getContext } from \"../context.js\";\nimport { resolveContent } from \"../input.js\";\nimport { fail, success } from \"../output.js\";\n\nfunction coercePlatform(p?: string): PostPlatform | undefined {\n if (!p) return undefined;\n const v = p.toLowerCase();\n if (v === \"x\" || v === \"twitter\") return \"x\";\n if (v === \"linkedin\" || v === \"li\") return \"linkedin\";\n if (v === \"reddit\") return \"reddit\";\n throw new Error(`Unknown platform \"${p}\". Use linkedin, x, or reddit.`);\n}\n\nexport function registerCommentCommands(program: Command): void {\n program\n .command(\"comment\")\n .description(\"Comment on / reply to a post by URL or id (LinkedIn, X, Reddit)\")\n .argument(\"[urlOrId]\", \"Post URL or id (alternatively use --url)\")\n .option(\"--url <url>\", \"Post URL or id\")\n .option(\"-t, --text <text>\", \"Comment text (use '-' to read stdin)\")\n .option(\"--file <path>\", \"Read comment text from a file\")\n .option(\"-p, --platform <platform>\", \"Force platform: linkedin | x | reddit\")\n .action(async (urlOrIdArg, opts) => {\n try {\n const ref = opts.url ?? urlOrIdArg;\n if (!ref) throw new Error(\"Provide a post URL or id (positional arg or --url).\");\n const text = await resolveContent({ content: opts.text, file: opts.file });\n const target = resolvePostRef(ref, coercePlatform(opts.platform));\n const { client } = await getContext();\n\n let result: unknown;\n if (target.platform === \"linkedin\") {\n result = await linkedin.addComment(client, target.id, text);\n } else if (target.platform === \"reddit\") {\n result = await reddit.comment(client, target.id, text);\n } else {\n result = await twitter.reply(client, target.id, text);\n }\n\n success({ platform: target.platform, id: target.id, result }, (d) =>\n `Comment posted on ${d.platform} (${d.id}).`,\n );\n } catch (err) {\n fail(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { dms } from \"../../core/index.js\";\nimport { getContext } from \"../context.js\";\nimport { resolveContent } from \"../input.js\";\nimport { fail, success, table } from \"../output.js\";\n\nexport function registerDmCommands(program: Command): void {\n const cmd = program\n .command(\"dm\")\n .description(\"X (Twitter) direct messages — Premium plan required\");\n\n cmd\n .command(\"list\")\n .description(\"List DM conversations\")\n .option(\"--limit <n>\", \"Max results\", (v) => parseInt(v, 10))\n .option(\"--offset <n>\", \"Offset\", (v) => parseInt(v, 10))\n .action(async (opts) => {\n try {\n const { client } = await getContext();\n const result: any = await dms.listConversations(client, { limit: opts.limit, offset: opts.offset });\n success(result, (d) => {\n const convs: any[] = Array.isArray(d) ? d : d?.conversations ?? [];\n if (!convs.length) return \"(no conversations)\";\n return table(\n convs.map((c) => ({\n id: c.participantId ?? c.conversationId ?? c.id ?? \"\",\n with: c.username ?? c.name ?? c.handle ?? \"\",\n last: String(c.lastMessage?.text ?? c.lastMessageText ?? \"\").slice(0, 50),\n })),\n [\"id\", \"with\", \"last\"],\n );\n });\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"messages <conversationId>\")\n .description(\"Show messages in a conversation\")\n .action(async (conversationId: string) => {\n try {\n const { client } = await getContext();\n success(await dms.getMessages(client, conversationId));\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"refresh\")\n .description(\"Pull the latest DMs from X (Premium)\")\n .action(async () => {\n try {\n const { client } = await getContext();\n success(await dms.refresh(client), () => \"DM inbox refreshed.\");\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"reply <conversationId>\")\n .description(\"Send a reply into a DM conversation (Premium)\")\n .option(\"-t, --text <text>\", \"Message text (use '-' to read stdin)\")\n .option(\"--file <path>\", \"Read message text from a file\")\n .action(async (conversationId: string, opts) => {\n try {\n const text = await resolveContent({ content: opts.text, file: opts.file });\n const { client } = await getContext();\n const result = await dms.sendMessage(client, conversationId, text);\n success({ conversationId, result }, () => `Sent DM to ${conversationId}.`);\n } catch (err) {\n fail(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { linkedin, twitter } from \"../../core/index.js\";\nimport { getContext } from \"../context.js\";\nimport { parseList, resolveContent } from \"../input.js\";\nimport { fail, success, table } from \"../output.js\";\n\ntype Platform = \"linkedin\" | \"x\";\n\nfunction platformOf(opt?: string): Platform {\n const p = (opt ?? \"linkedin\").toLowerCase();\n if (p === \"x\" || p === \"twitter\") return \"x\";\n if (p === \"linkedin\" || p === \"li\") return \"linkedin\";\n throw new Error(`Unknown platform \"${opt}\". Use linkedin or x.`);\n}\n\nexport function registerPostCommands(program: Command): void {\n const post = program.command(\"post\").description(\"Create, list, update, and delete posts\");\n\n post\n .command(\"create\")\n .description(\"Create a post as a draft, scheduled, or published now\")\n .option(\"-p, --platform <platform>\", \"linkedin or x\", \"linkedin\")\n .option(\"-c, --content <text>\", \"Post text (use '-' to read stdin)\")\n .option(\"--file <path>\", \"Read post text from a file\")\n .option(\"--title <title>\", \"Draft title (LinkedIn)\")\n .option(\"--media <urls>\", \"Comma-separated media URLs\")\n .option(\"--schedule <iso>\", \"Schedule for an ISO-8601 timestamp\")\n .option(\"--publish\", \"Publish immediately instead of saving a draft\")\n .option(\"--draft\", \"Save as a draft (default)\")\n .action(async (opts) => {\n try {\n const platform = platformOf(opts.platform);\n const content = await resolveContent(opts);\n const media = parseList(opts.media);\n const { client } = await getContext();\n\n let result: unknown;\n if (platform === \"linkedin\") {\n if (opts.schedule) {\n result = await linkedin.schedulePost(client, {\n content,\n scheduledFor: opts.schedule,\n title: opts.title,\n mediaUrls: media,\n });\n } else if (opts.publish) {\n result = await linkedin.publishNow(client, { content, title: opts.title, mediaUrls: media });\n } else {\n result = await linkedin.createDraft(client, { content, title: opts.title, mediaUrls: media });\n }\n } else {\n const threadTweets = [{ text: content, mediaUrls: media }];\n // Default to a DRAFT (like LinkedIn). POST /twitter/posts with no scheduledFor\n // publishes to X LIVE, so only do it when explicitly asked.\n if (opts.schedule) {\n result = await twitter.createPost(client, { threadTweets, scheduledFor: opts.schedule });\n } else if (opts.publish) {\n result = await twitter.createPost(client, { threadTweets });\n } else {\n result = await twitter.createDraft(client, { threadTweets, title: opts.title });\n }\n }\n\n // Both platforms now default to draft, so the label matches the branch taken.\n const mode = opts.schedule ? \"scheduled\" : opts.publish ? \"published\" : \"draft\";\n success({ platform, mode, result }, (d) => `Created ${d.platform} ${d.mode}.`);\n } catch (err) {\n fail(err);\n }\n });\n\n post\n .command(\"list\")\n .description(\"List posts or drafts\")\n .option(\"-p, --platform <platform>\", \"linkedin or x\", \"linkedin\")\n .option(\"-s, --status <status>\", \"scheduled | published | failed | drafts\", \"scheduled\")\n .option(\"--limit <n>\", \"Max results\", (v) => parseInt(v, 10))\n .option(\"--search <q>\", \"Search query\")\n .action(async (opts) => {\n try {\n const platform = platformOf(opts.platform);\n const { client } = await getContext();\n const isDrafts = opts.status === \"drafts\";\n\n let result: unknown;\n if (platform === \"linkedin\") {\n result = isDrafts\n ? await linkedin.listDrafts(client, { limit: opts.limit, search: opts.search })\n : await linkedin.listPosts(client, { status: opts.status, limit: opts.limit, search: opts.search });\n } else {\n result = isDrafts\n ? await twitter.listDrafts(client, { limit: opts.limit, search: opts.search })\n : await twitter.listPosts(client, { status: opts.status, limit: opts.limit, search: opts.search });\n }\n success(result, (d) => renderPostList(d));\n } catch (err) {\n fail(err);\n }\n });\n\n post\n .command(\"update <id>\")\n .description(\"Update a scheduled post or draft\")\n .option(\"-p, --platform <platform>\", \"linkedin or x\", \"linkedin\")\n .option(\"-c, --content <text>\", \"New text (use '-' to read stdin)\")\n .option(\"--file <path>\", \"Read new text from a file\")\n .option(\"--schedule <iso>\", \"Reschedule to an ISO-8601 timestamp\")\n .option(\"--draft\", \"Target a draft instead of a scheduled post (LinkedIn)\")\n .action(async (id, opts) => {\n try {\n const platform = platformOf(opts.platform);\n const content =\n opts.content !== undefined || opts.file ? await resolveContent(opts) : undefined;\n const { client } = await getContext();\n\n let result: unknown;\n if (platform === \"linkedin\") {\n result = opts.draft\n ? await linkedin.updateDraft(client, id, {\n ...(content !== undefined ? { content } : {}),\n })\n : await linkedin.updateScheduledPost(client, id, {\n ...(content !== undefined ? { content } : {}),\n ...(opts.schedule ? { scheduledFor: opts.schedule } : {}),\n });\n } else {\n result = await twitter.updatePost(client, id, {\n ...(content !== undefined ? { threadTweets: [{ text: content }] } : {}),\n ...(opts.schedule ? { scheduledFor: opts.schedule } : {}),\n });\n }\n success({ id, result }, () => `Updated ${platform} post ${id}.`);\n } catch (err) {\n fail(err);\n }\n });\n\n post\n .command(\"delete <id>\")\n .description(\"Delete a scheduled post or draft\")\n .option(\"-p, --platform <platform>\", \"linkedin or x\", \"linkedin\")\n .option(\"--draft\", \"Delete a draft instead of a scheduled post\")\n .action(async (id, opts) => {\n try {\n const platform = platformOf(opts.platform);\n const { client } = await getContext();\n if (platform === \"linkedin\") {\n await (opts.draft ? linkedin.deleteDraft(client, id) : linkedin.deletePost(client, id));\n } else {\n await (opts.draft ? twitter.deleteDraft(client, id) : twitter.deletePost(client, id));\n }\n success({ id, deleted: true }, () => `Deleted ${platform} ${opts.draft ? \"draft\" : \"post\"} ${id}.`);\n } catch (err) {\n fail(err);\n }\n });\n}\n\nfunction renderPostList(raw: any): string {\n const arr: any[] = Array.isArray(raw)\n ? raw\n : raw?.posts ?? raw?.drafts ?? raw?.items ?? [];\n if (!arr.length) return \"(none)\";\n return table(\n arr.map((p) => ({\n id: p.postId ?? p.post_id ?? p.draft_id ?? p.id ?? \"\",\n status: p.status ?? (p.draft_id ? \"draft\" : \"\"),\n when: p.scheduledFor ?? p.publishedAt ?? \"\",\n text: String(p.content ?? p.title ?? \"\").replace(/\\s+/g, \" \").slice(0, 60),\n })),\n [\"id\", \"status\", \"when\", \"text\"],\n );\n}\n","import type { Command } from \"commander\";\nimport { reddit, resolvePostRef } from \"../../core/index.js\";\nimport { getContext } from \"../context.js\";\nimport { resolveContent } from \"../input.js\";\nimport { fail, success, table } from \"../output.js\";\n\nexport function registerRedditCommands(program: Command): void {\n const cmd = program.command(\"reddit\").description(\"Search Reddit and reply to submissions\");\n\n cmd\n .command(\"search <keyword>\")\n .description(\"Search Reddit for signals by keyword (Pro plan required)\")\n .action(async (keyword: string) => {\n try {\n const { client } = await getContext();\n const result: any = await reddit.search(client, keyword);\n success(result, (d) => {\n const posts: any[] = Array.isArray(d) ? d : d?.results ?? d?.posts ?? [];\n if (!posts.length) return \"(no results)\";\n return table(\n posts.map((p) => ({\n subreddit: p.subreddit ?? \"\",\n score: p.score ?? p.opportunityScore ?? \"\",\n title: String(p.title ?? \"\").slice(0, 70),\n url: p.url ?? p.permalink ?? \"\",\n })),\n [\"subreddit\", \"score\", \"title\", \"url\"],\n );\n });\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"status\")\n .description(\"Show remaining Reddit search quota\")\n .action(async () => {\n try {\n const { client } = await getContext();\n success(await reddit.searchStatus(client));\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"reply <postUrlOrId>\")\n .description(\"Reply to a Reddit submission\")\n .option(\"-t, --text <text>\", \"Reply text (use '-' to read stdin)\")\n .option(\"--file <path>\", \"Read reply text from a file\")\n .action(async (postUrlOrId: string, opts) => {\n try {\n const text = await resolveContent({ content: opts.text, file: opts.file });\n const target = resolvePostRef(postUrlOrId, \"reddit\");\n const { client } = await getContext();\n const result = await reddit.comment(client, target.id, text);\n success({ id: target.id, result }, (d) => `Replied to Reddit submission ${d.id}.`);\n } catch (err) {\n fail(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { success } from \"../output.js\";\n\ninterface CommandSchema {\n name: string;\n description: string;\n arguments: Array<{ name: string; required: boolean; description?: string }>;\n options: Array<{ flags: string; description: string; defaultValue?: unknown }>;\n subcommands: CommandSchema[];\n}\n\n/** Serialize a commander Command (and its subtree) into a stable JSON description. */\nfunction serialize(cmd: Command): CommandSchema {\n const args = ((cmd as any).registeredArguments ?? []).map((a: any) => ({\n name: a.name(),\n required: Boolean(a.required),\n description: a.description || undefined,\n }));\n\n return {\n name: cmd.name(),\n description: cmd.description(),\n arguments: args,\n options: cmd.options.map((o) => ({\n flags: o.flags,\n description: o.description,\n ...(o.defaultValue !== undefined ? { defaultValue: o.defaultValue } : {}),\n })),\n subcommands: cmd.commands\n .filter((c) => c.name() !== \"help\")\n .map((c) => serialize(c)),\n };\n}\n\n/**\n * `reepl schema` — emit the full command tree as JSON so an agent can discover every\n * command, argument, and flag without scraping --help. Registered last so it captures\n * all sibling commands.\n */\nexport function registerSchemaCommand(program: Command): void {\n program\n .command(\"schema\")\n .description(\"Print the full command/flag tree as JSON (for agents and tooling)\")\n .action(() => {\n success(serialize(program));\n });\n}\n","import type { Command } from \"commander\";\nimport { signals } from \"../../core/index.js\";\nimport { getContext } from \"../context.js\";\nimport { fail, success, table } from \"../output.js\";\n\nexport function registerSignalsCommands(program: Command): void {\n const cmd = program.command(\"signals\").description(\"Your signals inbox (Reddit / YouTube / RSS / trends)\");\n\n cmd\n .command(\"list\")\n .description(\"List signals in your inbox\")\n .action(async () => {\n try {\n const { client } = await getContext();\n const result: any = await signals.getInbox(client);\n success(result, (d) => {\n const items: any[] = Array.isArray(d) ? d : d?.signals ?? d?.items ?? [];\n if (!items.length) return \"(no signals)\";\n return table(\n items.map((s) => ({\n source: s.source ?? s.type ?? \"\",\n title: String(s.title ?? s.text ?? \"\").slice(0, 70),\n url: s.url ?? s.link ?? \"\",\n })),\n [\"source\", \"title\", \"url\"],\n );\n });\n } catch (err) {\n fail(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { writingStyle } from \"../../core/index.js\";\nimport { ensureWorkspaceId, getContext } from \"../context.js\";\nimport { resolveContent } from \"../input.js\";\nimport { fail, success } from \"../output.js\";\n\n/**\n * Writing-style endpoints require a workspace_id (400 without one), so each command\n * resolves the selected-or-default workspace and scopes a client to it.\n */\nasync function styleContext() {\n const base = await getContext();\n // Already scoped to a workspace — reuse it (no extra /organizations round-trip).\n if (base.workspaceId) return base;\n const workspaceId = await ensureWorkspaceId(base);\n return getContext(workspaceId);\n}\n\nexport function registerStyleCommands(program: Command): void {\n const cmd = program.command(\"style\").description(\"View and train your writing styles\");\n\n cmd\n .command(\"get\")\n .description(\"Show writing-style summary for all facets\")\n .action(async () => {\n try {\n const { client } = await styleContext();\n success(await writingStyle.get(client));\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"set\")\n .description(\"Save override instructions for a facet\")\n .requiredOption(\"--facet <facet>\", \"posts | comments | messages\")\n .option(\"-i, --instructions <text>\", \"Override instructions (use '-' for stdin)\")\n .option(\"--file <path>\", \"Read instructions from a file\")\n .action(async (opts) => {\n try {\n const instructions = await resolveContent({ content: opts.instructions, file: opts.file });\n const { client } = await styleContext();\n const result = await writingStyle.override(client, opts.facet, instructions);\n success(result, () => `Saved ${opts.facet} style override.`);\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"train\")\n .description(\"(Re)synthesize a facet's writing style (Pro+; posts/comments only)\")\n .requiredOption(\"--facet <facet>\", \"posts | comments\")\n .action(async (opts) => {\n try {\n const { client } = await styleContext();\n const result = await writingStyle.train(client, opts.facet);\n success(result, () => `Training started for ${opts.facet}.`);\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"test\")\n .description(\"Playground: compare baseline vs styled generation for a facet\")\n .requiredOption(\"--facet <facet>\", \"posts | comments | messages\")\n .option(\"-i, --input <text>\", \"Prompt input (use '-' for stdin)\")\n .option(\"--file <path>\", \"Read input from a file\")\n .action(async (opts) => {\n try {\n const input = await resolveContent({ content: opts.input, file: opts.file });\n const { client } = await styleContext();\n success(await writingStyle.testVoiceStyle(client, opts.facet, input));\n } catch (err) {\n fail(err);\n }\n });\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { Command } from \"commander\";\nimport { voice } from \"../../core/index.js\";\nimport { getContext } from \"../context.js\";\nimport { fail, success } from \"../output.js\";\n\nexport function registerVoiceCommands(program: Command): void {\n const cmd = program.command(\"voice\").description(\"View and update your voice profile\");\n\n cmd\n .command(\"get\")\n .description(\"Show the current voice profile\")\n .action(async () => {\n try {\n const { client } = await getContext();\n success(await voice.get(client));\n } catch (err) {\n fail(err);\n }\n });\n\n cmd\n .command(\"update\")\n .description(\"Update the voice profile from a JSON file or flags\")\n .option(\"--file <path>\", \"JSON body to deep-merge (allowAutoUpdate, userInstructions, ...)\")\n .option(\"--active\", \"Set isActive true\")\n .option(\"--inactive\", \"Set isActive false\")\n .option(\"--allow-auto-update\", \"Allow the generated profile to auto-update\")\n .action(async (opts) => {\n try {\n let body: Record<string, unknown> = {};\n if (opts.file) {\n const parsed = JSON.parse(await readFile(opts.file, \"utf8\"));\n if (parsed && typeof parsed === \"object\") body = parsed;\n }\n if (opts.active) body.isActive = true;\n if (opts.inactive) body.isActive = false;\n if (opts.allowAutoUpdate) body.allowAutoUpdate = true;\n if (Object.keys(body).length === 0) {\n throw new Error(\"Nothing to update. Pass --file <json> or a flag (--active/--inactive/--allow-auto-update).\");\n }\n const { client } = await getContext();\n success(await voice.update(client, body), () => \"Voice profile updated.\");\n } catch (err) {\n fail(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { workspaces as ws } from \"../../core/index.js\";\nimport { readConfig, writeConfig } from \"../config.js\";\nimport { getContext } from \"../context.js\";\nimport { fail, success, table } from \"../output.js\";\n\nexport function registerWorkspaceCommands(program: Command): void {\n const workspace = program\n .command(\"workspace\")\n .alias(\"ws\")\n .description(\"List and switch the active workspace (organization)\");\n\n workspace\n .command(\"list\")\n .description(\"List your workspaces\")\n .action(async () => {\n try {\n const { client } = await getContext();\n const list = await ws.listWorkspaces(client);\n const current = (await readConfig()).currentWorkspaceId;\n success(\n list.map((w) => ({ ...w, isCurrent: w.id === current })),\n (rows: any[]) =>\n table(\n rows.map((w) => ({\n current: w.isCurrent ? \"*\" : w.isDefault ? \"d\" : \"\",\n id: w.id,\n name: w.name ?? \"\",\n })),\n [\"current\", \"id\", \"name\"],\n ),\n );\n } catch (err) {\n fail(err);\n }\n });\n\n workspace\n .command(\"switch <workspaceId>\")\n .description(\"Set the active workspace used by subsequent commands\")\n .action(async (workspaceId: string) => {\n try {\n // Validate the id against the user's real workspaces before persisting.\n const { client } = await getContext();\n const list = await ws.listWorkspaces(client);\n const match = list.find((w) => w.id === workspaceId);\n if (!match) {\n throw new Error(\n `Workspace \"${workspaceId}\" not found. Run \\`reepl workspace list\\` to see valid ids.`,\n );\n }\n await writeConfig({ currentWorkspaceId: workspaceId });\n success({ currentWorkspaceId: workspaceId, name: match.name }, (d) =>\n `Switched to workspace ${d.currentWorkspaceId}${d.name ? ` (${d.name})` : \"\"}.`,\n );\n } catch (err) {\n fail(err);\n }\n });\n\n workspace\n .command(\"current\")\n .description(\"Show the active workspace\")\n .action(async () => {\n try {\n const config = await readConfig();\n if (!config.currentWorkspaceId) {\n success({ currentWorkspaceId: null }, () => \"No workspace selected (using account default).\");\n return;\n }\n success({ currentWorkspaceId: config.currentWorkspaceId }, (d) =>\n `Current workspace: ${d.currentWorkspaceId}`,\n );\n } catch (err) {\n fail(err);\n }\n });\n}\n","import type { Command } from \"commander\";\nimport { resolvePostRef, twitter } from \"../../core/index.js\";\nimport { getContext } from \"../context.js\";\nimport { resolveContent } from \"../input.js\";\nimport { fail, success } from \"../output.js\";\n\nexport function registerXCommands(program: Command): void {\n const cmd = program.command(\"x\").description(\"X (Twitter) engagement actions\");\n\n cmd\n .command(\"reply <tweetUrlOrId>\")\n .description(\"Publish a reply to a tweet (Premium)\")\n .option(\"-t, --text <text>\", \"Reply text (use '-' to read stdin)\")\n .option(\"--file <path>\", \"Read reply text from a file\")\n .action(async (tweetUrlOrId: string, opts) => {\n try {\n const text = await resolveContent({ content: opts.text, file: opts.file });\n const { id } = resolvePostRef(tweetUrlOrId, \"x\");\n const { client } = await getContext();\n const result = await twitter.reply(client, id, text);\n success({ tweetId: id, result }, (d) => `Replied to tweet ${d.tweetId}.`);\n } catch (err) {\n fail(err);\n }\n });\n}\n"],"mappings":"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","names":["program","program","readFile","readFile","program","readFile","program","program","program","program","program","program","program","readFile","program","readFile","program","program"]}