@letterapp/cli 0.5.0 → 0.6.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/dist/index.js CHANGED
@@ -1487,6 +1487,11 @@ var SEQUENCE_SCHEMA = {
1487
1487
  "templateId?": "uuid | null (omit for project default)"
1488
1488
  },
1489
1489
  wait: { type: "wait", duration: { value: 1, unit: "minutes | hours | days" } },
1490
+ wait_event: {
1491
+ type: "wait_event",
1492
+ eventName: "completed_onboarding",
1493
+ timeout: { value: 7, unit: "minutes | hours | days" }
1494
+ },
1490
1495
  branch: {
1491
1496
  type: "branch",
1492
1497
  condition: {
@@ -1500,15 +1505,16 @@ var SEQUENCE_SCHEMA = {
1500
1505
  id: "e1",
1501
1506
  source: "trigger",
1502
1507
  target: "email1",
1503
- "branch?": "yes | no \u2014 only on edges leaving a branch node"
1508
+ "branch?": "yes | no (branch node) \xB7 received | timeout (wait_event node) \u2014 omit for single-leg nodes"
1504
1509
  },
1505
1510
  notes: [
1506
1511
  "config.type must equal the node's type.",
1507
- "The email body field is `bodyDoc` (camelCase); a wait nests `duration`.",
1512
+ "The email body field is `bodyDoc` (camelCase); a wait nests `duration`; a wait_event nests `timeout`.",
1508
1513
  "Draft saves reject unknown / mis-cased keys with a 400.",
1509
1514
  'Trait/filter values compare as strings: use value:"false" (not false) for a boolean trait. `letter traits list` shows keys + types.',
1510
1515
  "Event triggers can also gate on the event's own properties via `where` (e.g. only plan=free).",
1511
- "Publish requires: one trigger, every node reachable, every path ends at an exit, each branch has one yes + one no edge, and each email has a subject + non-empty bodyDoc.",
1516
+ "wait_event pauses the contact until `eventName` fires (the `received` leg) or `timeout` elapses (the `timeout` leg). Only events that occur after the contact reaches the step count.",
1517
+ "Publish requires: one trigger, every node reachable, every path ends at an exit, each branch has one yes + one no edge, each wait_event has one received + one timeout edge, and each email has a subject + non-empty bodyDoc.",
1512
1518
  "`sequences validate <id>` dry-runs those publish checks; `sequences scaffold` builds a valid trigger \u2192 [wait] \u2192 email \u2192 exit graph in one command."
1513
1519
  ],
1514
1520
  example: {
@@ -1877,7 +1883,7 @@ function registerResourceCommands(program2) {
1877
1883
 
1878
1884
  // src/index.ts
1879
1885
  var program = new Command();
1880
- program.name("letter").description("Connect your app to Letter, then manage it from the command line").version("0.5.0").option("--json", "Output raw JSON (for scripting / agents)").hook("preAction", (thisCommand) => {
1886
+ program.name("letter").description("Connect your app to Letter, then manage it from the command line").version("0.6.0").option("--json", "Output raw JSON (for scripting / agents)").hook("preAction", (thisCommand) => {
1881
1887
  if (thisCommand.opts().json) setJsonMode(true);
1882
1888
  });
1883
1889
  registerLoginCommand(program);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/output.ts","../src/config.ts","../src/client.ts","../src/browser.ts","../src/env-file.ts","../src/pm.ts","../src/commands/login.ts","../src/commands/auth.ts","../src/commands/status.ts","../src/commands/config.ts","../src/commands/resources.ts","../src/markdown.ts"],"sourcesContent":["declare const PKG_VERSION: string;\nimport { Command } from \"commander\";\nimport { setJsonMode } from \"./output.js\";\nimport { registerLoginCommand } from \"./commands/login.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerStatusCommand } from \"./commands/status.js\";\nimport { registerConfigCommands } from \"./commands/config.js\";\nimport { registerResourceCommands } from \"./commands/resources.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"letter\")\n .description(\"Connect your app to Letter, then manage it from the command line\")\n .version(PKG_VERSION)\n .option(\"--json\", \"Output raw JSON (for scripting / agents)\")\n .hook(\"preAction\", (thisCommand) => {\n if (thisCommand.opts().json) setJsonMode(true);\n });\n\n// Two layers, one login:\n// - login/auth/status/config wire up the project and its ingestion key\n// (lt_live_*, written to the project env as LETTER_API_KEY).\n// - the resource groups drive the Management API with the workspace PAT\n// (lt_pat_*, stored in ~/.letter/credentials.json). Both credentials are\n// minted by `letter login`; each command picks the right one on its own.\nregisterLoginCommand(program); // default command (`letter` == `letter login`)\nregisterAuthCommands(program);\nregisterStatusCommand(program);\nregisterConfigCommands(program);\nregisterResourceCommands(program); // control-plane resource groups (PAT-backed)\n\nprogram.parseAsync();\n","import chalk from \"chalk\";\nimport ora, { type Ora } from \"ora\";\nimport { createInterface } from \"node:readline\";\n\nlet jsonMode = false;\n\nexport function setJsonMode(enabled: boolean) {\n jsonMode = enabled;\n}\nexport function isJsonMode() {\n return jsonMode;\n}\n\nexport function printJson(data: unknown) {\n console.log(JSON.stringify(data, null, 2));\n}\n\n/**\n * The command users should repeat to run us again, so printed hints are\n * copy-pasteable. When launched through `npx`, Node runs us from the npx cache\n * (`…/_npx/<hash>/…`) and there's no `letter` on PATH, so suggest the npx form;\n * a global install resolves the bare `letter` binary.\n */\nexport function cliCommand(): string {\n return (process.argv[1] ?? \"\").includes(\"_npx\") ? \"npx @letterapp/cli\" : \"letter\";\n}\n\nexport function log(msg = \"\") {\n if (jsonMode) return;\n console.log(msg);\n}\n\nexport function printSuccess(msg: string) {\n if (jsonMode) return;\n console.log(chalk.green(\"✓\") + \" \" + msg);\n}\n\nexport function printInfo(msg: string) {\n if (jsonMode) return;\n console.log(chalk.cyan(\"›\") + \" \" + msg);\n}\n\nexport function printWarning(msg: string) {\n if (jsonMode) return;\n console.log(chalk.yellow(\"!\") + \" \" + msg);\n}\n\nexport type ApiIssue = { path?: string; message?: string };\n\nexport function printError(err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n const issues = (err as { issues?: ApiIssue[] })?.issues;\n if (jsonMode) {\n printJson({ error: msg, ...(issues?.length ? { issues } : {}) });\n return;\n }\n console.error(chalk.red(\"✗\") + \" \" + msg);\n // Validation 400s carry field-level issues; print them so callers don't\n // have to re-probe the API to learn which key/shape was wrong.\n if (Array.isArray(issues)) {\n for (const i of issues) {\n const path = i.path ? chalk.dim(`${i.path}: `) : \"\";\n console.error(\" \" + path + (i.message ?? \"\"));\n }\n }\n}\n\n/** The Letter wordmark banner. Suppressed in JSON mode. */\nexport function banner() {\n if (jsonMode) return;\n console.log(\"\");\n console.log(\" \" + chalk.bold(\"Letter\") + chalk.red(\".\") + \" \" + chalk.dim(\"CLI\"));\n console.log(\"\");\n}\n\nexport function spinner(text: string): Ora {\n return ora({ text, color: \"cyan\", isEnabled: !jsonMode });\n}\n\n/**\n * Prompts the user and resolves with their input. Returns \"\" immediately on a\n * non-interactive stdin so automated/agent runs don't hang.\n */\nexport function prompt(question: string): Promise<string> {\n if (!process.stdin.isTTY) return Promise.resolve(\"\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Print a management API result. In `--json` mode, emits the raw payload so\n * agents/scripts can parse it. In human mode, renders list envelopes as a\n * compact `id label` table and single resources as pretty JSON.\n */\nexport function emit(data: unknown) {\n if (jsonMode) {\n printJson(data);\n return;\n }\n if (data && typeof data === \"object\" && Array.isArray((data as { data?: unknown }).data)) {\n const env = data as { data: Record<string, unknown>[]; next_cursor?: string | null };\n if (env.data.length === 0) {\n console.log(chalk.dim(\"(none)\"));\n } else {\n for (const row of env.data) {\n const id = String(row.id ?? row.slug ?? row.external_id ?? \"\");\n const label =\n (row.name as string) ??\n (row.email as string) ??\n (row.domain as string) ??\n (row.subject as string) ??\n \"\";\n console.log(`${chalk.bold(id)}${label ? \" \" + label : \"\"}`);\n }\n }\n if (env.next_cursor) {\n console.log(chalk.dim(`\\n› more: --cursor ${env.next_cursor}`));\n }\n return;\n }\n printJson(data);\n}\n\nexport const c = chalk;\n","import Conf from \"conf\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { mkdir, readFile, writeFile, rm } from \"node:fs/promises\";\nimport { cliCommand } from \"./output.js\";\n\n/** The SDK / API default. When the resolved base equals this we don't bother\n * writing LETTER_BASE_URL into the project env. */\nexport const DEFAULT_BASE_URL = \"https://api.letter.app\";\n\n/* -------------------------------------------------------------------------- */\n/* Non-secret CLI preferences (base URL). */\n/* Stored with `conf`, mirroring how the SDK/MCP resolve their endpoint. */\n/* -------------------------------------------------------------------------- */\n\nconst config = new Conf({\n projectName: \"letterapp-cli\",\n schema: {\n baseUrl: { type: \"string\", default: DEFAULT_BASE_URL },\n },\n});\n\n/** Resolve the API base: explicit flag > env > stored config > prod default. */\nexport function getBaseUrl(flag?: string): string {\n const raw =\n flag ||\n process.env.LETTER_BASE_URL ||\n (config.get(\"baseUrl\") as string) ||\n DEFAULT_BASE_URL;\n return raw.replace(/\\/$/, \"\");\n}\n\nexport function setBaseUrl(url: string): void {\n config.set(\"baseUrl\", url.replace(/\\/$/, \"\"));\n}\n\nexport function getConfigPath(): string {\n return config.path;\n}\n\nexport function resetConfig(): void {\n config.clear();\n}\n\n/* -------------------------------------------------------------------------- */\n/* Secret credential store (~/.letter/credentials.json). */\n/* Written here, read by @letterapp/mcp so the secret never lands in an MCP */\n/* config. Kept separate from `conf` and locked to owner-only permissions. */\n/* -------------------------------------------------------------------------- */\n\nexport type StoredCredential = {\n apiKey: string;\n /** Workspace Personal Access Token (lt_pat_*) for the management API/CLI. */\n pat?: string;\n baseUrl: string;\n project: { slug: string; name: string };\n workspace?: { id: string; name: string };\n savedAt: string;\n};\n\n/**\n * Resolve the project slug a management command should target: explicit\n * `--project` flag > `LETTER_PROJECT` env (for scripts/CI) > the connected\n * project from `letter login`. Throws a clear error when none is available so\n * scripts fail loudly.\n */\nexport async function resolveProjectSlug(flag?: string): Promise<string> {\n if (flag) return flag;\n if (process.env.LETTER_PROJECT) return process.env.LETTER_PROJECT;\n const cred = await readCredential();\n if (cred?.project?.slug) return cred.project.slug;\n throw new Error(\n `No project. Pass --project <slug>, set LETTER_PROJECT, or run \\`${cliCommand()} login\\`.`,\n );\n}\n\nexport function credentialsPath(): string {\n return path.join(homedir(), \".letter\", \"credentials.json\");\n}\n\nexport async function saveCredential(cred: StoredCredential): Promise<string> {\n const file = credentialsPath();\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n await writeFile(file, `${JSON.stringify(cred, null, 2)}\\n`, { mode: 0o600 });\n return file;\n}\n\nexport async function readCredential(): Promise<StoredCredential | null> {\n try {\n const raw = await readFile(credentialsPath(), \"utf8\");\n return JSON.parse(raw) as StoredCredential;\n } catch {\n return null;\n }\n}\n\nexport async function clearCredential(): Promise<void> {\n await rm(credentialsPath(), { force: true });\n}\n","import { getBaseUrl, readCredential } from \"./config.js\";\nimport { cliCommand } from \"./output.js\";\n\nconst USER_AGENT = \"@letterapp/cli\";\n\n/* -------------------------------------------------------------------------- */\n/* Device authorization (RFC 8628 style). No secret ever passes through argv. */\n/* -------------------------------------------------------------------------- */\n\nexport type StartResponse = {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete: string;\n interval: number;\n expires_in: number;\n};\n\nexport type PollResponse =\n | { status: \"authorization_pending\" }\n | { status: \"slow_down\"; retryAfter?: number }\n | { status: \"access_denied\" }\n | { status: \"expired_token\" }\n | {\n status: \"approved\";\n api_key: string;\n /** Workspace PAT for the management API (lt_pat_*). */\n pat: string;\n base_url: string;\n project: { slug: string; name: string };\n workspace?: { id: string; name: string };\n };\n\n/** Starts a device-authorization flow against the given API base. */\nexport async function startDeviceAuth(base: string): Promise<StartResponse> {\n const res = await fetch(`${base}/v1/cli/auth/start`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", \"user-agent\": USER_AGENT },\n body: \"{}\",\n });\n if (!res.ok) {\n throw new Error(\n `Could not start login (HTTP ${res.status}). Is ${base} reachable?`,\n );\n }\n return (await res.json()) as StartResponse;\n}\n\n/** Polls once for approval. */\nexport async function pollDeviceAuth(\n base: string,\n deviceCode: string,\n): Promise<PollResponse> {\n const res = await fetch(`${base}/v1/cli/auth/poll`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", \"user-agent\": USER_AGENT },\n body: JSON.stringify({ device_code: deviceCode }),\n });\n\n if (res.status === 429) {\n const retryAfter = Number(res.headers.get(\"retry-after\") ?? \"5\");\n return { status: \"slow_down\", retryAfter };\n }\n if (!res.ok) {\n throw new Error(`Login poll failed (HTTP ${res.status}).`);\n }\n return (await res.json()) as PollResponse;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Authenticated client. Resolves the key from the stored credential (written */\n/* by `letter login`) or LETTER_API_KEY. Used by data commands like `status`. */\n/* -------------------------------------------------------------------------- */\n\nexport interface ApiResponse<T = unknown> {\n status: number;\n data: T;\n}\n\nclass LetterClient {\n private maxRetries = 3;\n\n private async resolveAuth(): Promise<{ base: string; token: string }> {\n const cred = await readCredential();\n const token = process.env.LETTER_API_KEY || cred?.apiKey || \"\";\n if (!token) {\n throw new Error(\n `Not connected. Run \\`${cliCommand()} login\\` (or set LETTER_API_KEY) first.`,\n );\n }\n const base = getBaseUrl(process.env.LETTER_API_KEY ? undefined : cred?.baseUrl);\n return { base, token };\n }\n\n private async request<T = unknown>(\n method: string,\n path: string,\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n const { base, token } = await this.resolveAuth();\n const res = await fetch(`${base}${path}`, {\n method,\n headers: {\n authorization: `Bearer ${token}`,\n accept: \"application/json\",\n \"user-agent\": USER_AGENT,\n },\n });\n\n if (res.status === 429 && attempt <= this.maxRetries) {\n const retryAfter = Number(res.headers.get(\"retry-after\") || 2);\n await new Promise((r) => setTimeout(r, retryAfter * 1000 * attempt));\n return this.request<T>(method, path, attempt + 1);\n }\n\n const data = (res.status === 204 ? {} : await res.json()) as T;\n if (!res.ok) {\n throw apiErrorFrom(data, res.status);\n }\n return { status: res.status, data };\n }\n\n get<T = unknown>(path: string) {\n return this.request<T>(\"GET\", path);\n }\n}\n\nexport type ApiIssue = { path?: string; message?: string };\n\n/** Build an Error carrying the API's `error.message` + field-level `issues`. */\nfunction apiErrorFrom(data: unknown, status: number): Error {\n const errObj = (data as {\n error?: { message?: string; issues?: ApiIssue[] };\n })?.error;\n const msg = errObj?.message || `HTTP ${status}`;\n const err = new Error(msg) as Error & {\n status: number;\n issues?: ApiIssue[];\n };\n err.status = status;\n if (Array.isArray(errObj?.issues) && errObj.issues.length > 0) {\n err.issues = errObj.issues;\n }\n return err;\n}\n\nexport const client = new LetterClient();\n\n/* -------------------------------------------------------------------------- */\n/* Management client. Authenticates with the workspace PAT (lt_pat_*) and */\n/* drives the control-plane (/v1/projects, sequences, broadcasts, ...). Used by */\n/* the resource command groups. */\n/* -------------------------------------------------------------------------- */\n\nexport type RequestInitLite = {\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n form?: FormData;\n};\n\nclass ManagementClient {\n private maxRetries = 3;\n\n private async resolveAuth(): Promise<{ base: string; token: string }> {\n const cred = await readCredential();\n const token = process.env.LETTER_PAT || cred?.pat || \"\";\n if (!token) {\n throw new Error(\n `Not connected for management. Run \\`${cliCommand()} login\\` (or set LETTER_PAT) first.`,\n );\n }\n const base = getBaseUrl(process.env.LETTER_PAT ? undefined : cred?.baseUrl);\n return { base, token };\n }\n\n async request<T = unknown>(\n method: string,\n path: string,\n init: RequestInitLite = {},\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n const { base, token } = await this.resolveAuth();\n\n let url = `${base}${path}`;\n if (init.query) {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined && v !== \"\") qs.set(k, String(v));\n }\n const s = qs.toString();\n if (s) url += `?${s}`;\n }\n\n const headers: Record<string, string> = {\n authorization: `Bearer ${token}`,\n accept: \"application/json\",\n \"user-agent\": USER_AGENT,\n };\n let body: BodyInit | undefined;\n if (init.form) {\n body = init.form;\n } else if (init.body !== undefined) {\n headers[\"content-type\"] = \"application/json\";\n body = JSON.stringify(init.body);\n }\n\n const res = await fetch(url, { method, headers, body });\n\n if (res.status === 429 && attempt <= this.maxRetries) {\n const retryAfter = Number(res.headers.get(\"retry-after\") || 2);\n await new Promise((r) => setTimeout(r, retryAfter * 1000 * attempt));\n return this.request<T>(method, path, init, attempt + 1);\n }\n\n const text = await res.text();\n const data = (text ? JSON.parse(text) : {}) as T;\n if (!res.ok) {\n throw apiErrorFrom(data, res.status);\n }\n return { status: res.status, data };\n }\n\n get<T = unknown>(path: string, query?: RequestInitLite[\"query\"]) {\n return this.request<T>(\"GET\", path, { query });\n }\n post<T = unknown>(path: string, body?: unknown) {\n return this.request<T>(\"POST\", path, { body });\n }\n postForm<T = unknown>(path: string, form: FormData) {\n return this.request<T>(\"POST\", path, { form });\n }\n patch<T = unknown>(path: string, body?: unknown) {\n return this.request<T>(\"PATCH\", path, { body });\n }\n put<T = unknown>(path: string, body?: unknown) {\n return this.request<T>(\"PUT\", path, { body });\n }\n delete<T = unknown>(path: string) {\n return this.request<T>(\"DELETE\", path);\n }\n}\n\nexport const mgmt = new ManagementClient();\n","import { spawn } from \"node:child_process\";\n\n/**\n * Opens `url` in the default browser. Best-effort and non-blocking: if it fails\n * (headless box, no DISPLAY) the caller has already printed the URL so the user\n * can open it manually. Returns true if a launcher was spawned.\n */\nexport function openUrl(url: string): boolean {\n const platform = process.platform;\n let command: string;\n let args: string[];\n\n if (platform === \"darwin\") {\n command = \"open\";\n args = [url];\n } else if (platform === \"win32\") {\n command = \"cmd\";\n // `start` needs an empty title arg; the comma-free form avoids quoting woes.\n args = [\"/c\", \"start\", \"\", url];\n } else {\n command = \"xdg-open\";\n args = [url];\n }\n\n try {\n const child = spawn(command, args, { stdio: \"ignore\", detached: true });\n child.on(\"error\", () => {});\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n","import path from \"node:path\";\nimport { readFile, writeFile, stat } from \"node:fs/promises\";\n\n/**\n * Upserts `key=value` in an env file, creating it if needed. Existing keys are\n * replaced in place; new keys are appended. Returns the file path. The value is\n * never logged by this module - callers print only the key name.\n */\nexport async function upsertEnv(\n cwd: string,\n file: string,\n entries: Record<string, string>,\n): Promise<string> {\n const filePath = path.join(cwd, file);\n let contents = \"\";\n try {\n contents = await readFile(filePath, \"utf8\");\n } catch {\n contents = \"\";\n }\n\n let next = contents;\n for (const [key, value] of Object.entries(entries)) {\n const line = `${key}=${value}`;\n const re = new RegExp(`^${escapeRegExp(key)}=.*$`, \"m\");\n if (re.test(next)) {\n next = next.replace(re, line);\n } else {\n if (next.length && !next.endsWith(\"\\n\")) next += \"\\n\";\n next += `${line}\\n`;\n }\n }\n\n await writeFile(filePath, next, \"utf8\");\n return filePath;\n}\n\n/** True if a file exists at `cwd/name`. */\nexport async function fileExists(cwd: string, name: string): Promise<boolean> {\n try {\n await stat(path.join(cwd, name));\n return true;\n } catch {\n return false;\n }\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { spawn } from \"node:child_process\";\nimport { readFile, readdir } from \"node:fs/promises\";\nimport { fileExists } from \"./env-file.js\";\n\nexport type PackageManager = \"pnpm\" | \"yarn\" | \"bun\" | \"npm\";\n\n/**\n * Detects the package manager from lockfiles (then the `npm_config_user_agent`\n * of the running process), defaulting to npm.\n */\nexport async function detectPackageManager(\n cwd: string,\n): Promise<PackageManager> {\n if (await fileExists(cwd, \"pnpm-lock.yaml\")) return \"pnpm\";\n if (await fileExists(cwd, \"yarn.lock\")) return \"yarn\";\n if (await fileExists(cwd, \"bun.lockb\")) return \"bun\";\n if (await fileExists(cwd, \"package-lock.json\")) return \"npm\";\n\n const ua = process.env.npm_config_user_agent ?? \"\";\n if (ua.startsWith(\"pnpm\")) return \"pnpm\";\n if (ua.startsWith(\"yarn\")) return \"yarn\";\n if (ua.startsWith(\"bun\")) return \"bun\";\n return \"npm\";\n}\n\n/** Detects a likely Node web framework for friendlier guidance. */\nexport async function detectFramework(cwd: string): Promise<string | null> {\n try {\n const pkg = JSON.parse(await readFile(`${cwd}/package.json`, \"utf8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (deps.next) return \"Next.js\";\n if (deps.nuxt) return \"Nuxt\";\n if (deps[\"@remix-run/node\"] || deps[\"@remix-run/react\"]) return \"Remix\";\n if (deps.express) return \"Express\";\n if (deps.fastify) return \"Fastify\";\n if (deps.hono) return \"Hono\";\n if (deps[\"@sveltejs/kit\"]) return \"SvelteKit\";\n return null;\n } catch {\n return null;\n }\n}\n\nexport type Runtime = \"node\" | \"python\" | \"ruby\" | \"go\" | \"php\" | \"other\";\nexport type Stack = { runtime: Runtime; framework: string | null };\n\n/**\n * Detects the project's language/runtime so the CLI installs the right thing\n * (only Node has an SDK today) and prints instructions in the right language.\n * Node is checked first since it's this CLI's primary audience.\n */\nexport async function detectStack(cwd: string): Promise<Stack> {\n if (await fileExists(cwd, \"package.json\")) {\n return { runtime: \"node\", framework: await detectFramework(cwd) };\n }\n if (\n (await fileExists(cwd, \"pyproject.toml\")) ||\n (await fileExists(cwd, \"requirements.txt\")) ||\n (await fileExists(cwd, \"Pipfile\")) ||\n (await fileExists(cwd, \"setup.py\"))\n ) {\n return { runtime: \"python\", framework: await detectPythonFramework(cwd) };\n }\n if ((await fileExists(cwd, \"Gemfile\")) || (await hasGemspec(cwd))) {\n return { runtime: \"ruby\", framework: await detectRubyFramework(cwd) };\n }\n if (await fileExists(cwd, \"go.mod\")) return { runtime: \"go\", framework: null };\n if (await fileExists(cwd, \"composer.json\")) {\n return { runtime: \"php\", framework: await detectPhpFramework(cwd) };\n }\n return { runtime: \"other\", framework: null };\n}\n\n/** Human-friendly label for the detected stack (framework if known). */\nexport function stackLabel(stack: Stack): string {\n if (stack.framework) return stack.framework;\n switch (stack.runtime) {\n case \"node\":\n return \"a Node.js project\";\n case \"python\":\n return \"a Python project\";\n case \"ruby\":\n return \"a Ruby project\";\n case \"go\":\n return \"a Go project\";\n case \"php\":\n return \"a PHP project\";\n default:\n return \"your project\";\n }\n}\n\n/** The language name to tell the agent to write in. */\nexport function languageName(stack: Stack): string {\n switch (stack.runtime) {\n case \"node\":\n return \"TypeScript\";\n case \"python\":\n return \"Python\";\n case \"ruby\":\n return \"Ruby\";\n case \"go\":\n return \"Go\";\n case \"php\":\n return \"PHP\";\n default:\n return \"your language\";\n }\n}\n\nasync function readIf(cwd: string, name: string): Promise<string> {\n try {\n return await readFile(`${cwd}/${name}`, \"utf8\");\n } catch {\n return \"\";\n }\n}\n\nasync function hasGemspec(cwd: string): Promise<boolean> {\n try {\n return (await readdir(cwd)).some((f) => f.endsWith(\".gemspec\"));\n } catch {\n return false;\n }\n}\n\nasync function detectPythonFramework(cwd: string): Promise<string | null> {\n const txt = (\n (await readIf(cwd, \"requirements.txt\")) +\n (await readIf(cwd, \"pyproject.toml\")) +\n (await readIf(cwd, \"Pipfile\"))\n ).toLowerCase();\n if (txt.includes(\"django\")) return \"Django\";\n if (txt.includes(\"fastapi\")) return \"FastAPI\";\n if (txt.includes(\"flask\")) return \"Flask\";\n return null;\n}\n\nasync function detectRubyFramework(cwd: string): Promise<string | null> {\n const txt = (await readIf(cwd, \"Gemfile\")).toLowerCase();\n if (txt.includes(\"rails\")) return \"Rails\";\n if (txt.includes(\"sinatra\")) return \"Sinatra\";\n return null;\n}\n\nasync function detectPhpFramework(cwd: string): Promise<string | null> {\n const txt = (await readIf(cwd, \"composer.json\")).toLowerCase();\n if (txt.includes(\"laravel\")) return \"Laravel\";\n if (txt.includes(\"symfony\")) return \"Symfony\";\n return null;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Non-Node SDK installs (letterapp on PyPI / RubyGems) */\n/* -------------------------------------------------------------------------- */\n\nconst SDK_PYPI = \"letterapp\";\nconst SDK_GEM = \"letterapp\";\n\nexport type SdkInstall = { cmd: string; args: string[]; display: string };\n\nfunction sdkInstall(cmd: string, args: string[]): SdkInstall {\n return { cmd, args, display: `${cmd} ${args.join(\" \")}` };\n}\n\n/**\n * Picks the right Python installer for the project: uv > poetry > pipenv > pip.\n * Returns the command we'd run to add `letterapp`.\n */\nexport async function pythonSdkInstall(cwd: string): Promise<SdkInstall> {\n if (await fileExists(cwd, \"uv.lock\")) return sdkInstall(\"uv\", [\"add\", SDK_PYPI]);\n const pyproject = (await readIf(cwd, \"pyproject.toml\")).toLowerCase();\n if (\n (await fileExists(cwd, \"poetry.lock\")) ||\n pyproject.includes(\"[tool.poetry]\")\n ) {\n return sdkInstall(\"poetry\", [\"add\", SDK_PYPI]);\n }\n if (await fileExists(cwd, \"Pipfile\")) {\n return sdkInstall(\"pipenv\", [\"install\", SDK_PYPI]);\n }\n return sdkInstall(\"pip\", [\"install\", SDK_PYPI]);\n}\n\n/** Bundler when there's a Gemfile, otherwise a plain `gem install`. */\nexport async function rubySdkInstall(cwd: string): Promise<SdkInstall> {\n if (await fileExists(cwd, \"Gemfile\")) {\n return sdkInstall(\"bundle\", [\"add\", SDK_GEM]);\n }\n return sdkInstall(\"gem\", [\"install\", SDK_GEM]);\n}\n\n/** Runs an SdkInstall command, streaming output. Resolves to the exit code. */\nexport function runSdkInstall(\n install: SdkInstall,\n cwd: string,\n): Promise<number> {\n return new Promise((resolve) => {\n const child = spawn(install.cmd, install.args, {\n cwd,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n });\n child.on(\"error\", () => resolve(1));\n child.on(\"close\", (code) => resolve(code ?? 1));\n });\n}\n\nexport function installCommand(pm: PackageManager, pkg: string): string {\n switch (pm) {\n case \"pnpm\":\n return `pnpm add ${pkg}`;\n case \"yarn\":\n return `yarn add ${pkg}`;\n case \"bun\":\n return `bun add ${pkg}`;\n default:\n return `npm install ${pkg}`;\n }\n}\n\n/** Runs the install command, streaming output. Resolves to the exit code. */\nexport function runInstall(\n pm: PackageManager,\n pkg: string,\n cwd: string,\n): Promise<number> {\n const args = pm === \"npm\" ? [\"install\", pkg] : [\"add\", pkg];\n return new Promise((resolve) => {\n const child = spawn(pm, args, {\n cwd,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n });\n child.on(\"error\", () => resolve(1));\n child.on(\"close\", (code) => resolve(code ?? 1));\n });\n}\n","import { Command } from \"commander\";\nimport {\n getBaseUrl,\n DEFAULT_BASE_URL,\n saveCredential,\n} from \"../config.js\";\nimport { startDeviceAuth, pollDeviceAuth } from \"../client.js\";\nimport { openUrl } from \"../browser.js\";\nimport { upsertEnv } from \"../env-file.js\";\nimport {\n detectPackageManager,\n detectStack,\n installCommand,\n languageName,\n pythonSdkInstall,\n rubySdkInstall,\n runInstall,\n runSdkInstall,\n stackLabel,\n type SdkInstall,\n type Stack,\n} from \"../pm.js\";\nimport {\n banner,\n c,\n cliCommand,\n log,\n printError,\n printInfo,\n printSuccess,\n printWarning,\n prompt,\n} from \"../output.js\";\n\nconst SDK_PACKAGE = \"@letterapp/node\";\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n// Node projects use .env.local (Next.js convention, gitignored by default);\n// everything else uses the more universal .env.\nfunction envFileFor(stack: Stack): string {\n return stack.runtime === \"node\" ? \".env.local\" : \".env\";\n}\n\ninterface LoginOptions {\n open: boolean;\n install: boolean;\n yes?: boolean;\n baseUrl?: string;\n apiKey?: string;\n}\n\nexport function registerLoginCommand(program: Command) {\n program\n .command(\"login\", { isDefault: true })\n .alias(\"init\")\n .description(\"Connect this project to Letter (interactive device login)\")\n .option(\"--no-open\", \"Don't open the browser; print the URL to open manually\")\n .option(\"-y, --yes\", \"Non-interactive: don't wait for Enter (agents/CI)\")\n .option(\"--no-install\", \"Skip installing the SDK\")\n .option(\"--base-url <url>\", \"Target a self-hosted or local Letter instance\")\n .option(\n \"--api-key <key>\",\n \"CI only: write a key without the device flow (never use in chat)\",\n )\n .action(async (opts: LoginOptions) => {\n const code = await runLogin(opts);\n if (code !== 0) process.exitCode = code;\n });\n}\n\nasync function runLogin(opts: LoginOptions): Promise<number> {\n const base = getBaseUrl(opts.baseUrl);\n const cwd = process.cwd();\n const interactive = process.stdin.isTTY && !opts.yes;\n\n banner();\n\n // CI escape hatch: write the provided key non-interactively. Documented as\n // automation-only; interactive/agent use should rely on the device flow so\n // no secret passes through the command line or chat.\n if (opts.apiKey) {\n const envFile = envFileFor(await detectStack(cwd));\n const entries: Record<string, string> = { LETTER_API_KEY: opts.apiKey };\n if (base !== DEFAULT_BASE_URL) entries.LETTER_BASE_URL = base;\n const file = await upsertEnv(cwd, envFile, entries);\n printSuccess(`Saved LETTER_API_KEY to ${rel(cwd, file)} (--api-key).`);\n printWarning(\n `--api-key is for CI. For interactive setup, run \\`${cliCommand()} login\\`.`,\n );\n return 0;\n }\n\n // 1. Begin the flow.\n let flow;\n try {\n flow = await startDeviceAuth(base);\n } catch (err) {\n printError(err);\n return 1;\n }\n\n log(c.bold(\"Confirm this code in your browser:\"));\n log();\n log(\" \" + c.cyan(c.bold(flow.user_code)));\n log();\n\n // 2. Open the browser (interactive: wait for Enter; otherwise auto/print).\n if (interactive && opts.open) {\n await prompt(c.dim(\"Press Enter to open your browser… \"));\n }\n if (opts.open) openUrl(flow.verification_uri_complete);\n printInfo(\"If your browser didn't open, visit:\");\n log(\" \" + c.blue(flow.verification_uri_complete));\n log();\n printInfo(\"Waiting for you to approve… (Ctrl+C to cancel)\");\n\n // 3. Poll until the user approves/denies or the code expires.\n const deadline = Date.now() + flow.expires_in * 1000;\n let intervalMs = Math.max(1, flow.interval) * 1000;\n\n while (Date.now() < deadline) {\n await sleep(intervalMs);\n let res;\n try {\n res = await pollDeviceAuth(base, flow.device_code);\n } catch (err) {\n printError(err);\n return 1;\n }\n\n if (res.status === \"authorization_pending\") continue;\n if (res.status === \"slow_down\") {\n intervalMs += 1000;\n continue;\n }\n if (res.status === \"access_denied\") {\n printError(new Error(\"Request denied in the browser. Nothing was changed.\"));\n return 1;\n }\n if (res.status === \"expired_token\") {\n printError(new Error(\"This login expired. Run the command again to retry.\"));\n return 1;\n }\n\n return finish(res, cwd, opts.install);\n }\n\n printError(new Error(\"Timed out waiting for approval. Run the command again.\"));\n return 1;\n}\n\nasync function finish(\n approved: {\n api_key: string;\n pat: string;\n base_url: string;\n project: { slug: string; name: string };\n workspace?: { id: string; name: string };\n },\n cwd: string,\n doInstall: boolean,\n): Promise<number> {\n const { api_key: apiKey, pat, base_url: baseUrl, project, workspace } = approved;\n log();\n printSuccess(`Approved for project ${c.bold(project.name)}.`);\n\n const stack = await detectStack(cwd);\n const isNode = stack.runtime === \"node\";\n const envFile = envFileFor(stack);\n\n // Write the key to the project env (value never printed) + shared store.\n const entries: Record<string, string> = { LETTER_API_KEY: apiKey };\n if (baseUrl && baseUrl !== DEFAULT_BASE_URL) entries.LETTER_BASE_URL = baseUrl;\n const written = await upsertEnv(cwd, envFile, entries);\n printSuccess(`Saved LETTER_API_KEY to ${rel(cwd, written)}.`);\n\n try {\n const credFile = await saveCredential({\n apiKey,\n pat,\n baseUrl: baseUrl || DEFAULT_BASE_URL,\n project,\n workspace,\n savedAt: new Date().toISOString(),\n });\n printSuccess(`Stored credentials in ${tildify(credFile)} for tooling (MCP + CLI).`);\n } catch {\n printWarning(\"Could not write ~/.letter/credentials.json (continuing).\");\n }\n\n // Install the SDK for the detected language. Node, Python, and Ruby have\n // official SDKs; everything else integrates over the HTTP API. We capture a\n // one-line `sdkNote` per path and hand the agent a single, language-agnostic\n // prompt - the agent knows the repo and writes idiomatic calls itself.\n let sdkNote: string;\n if (isNode) {\n const pm = await detectPackageManager(cwd);\n if (doInstall) {\n printInfo(`Installing ${SDK_PACKAGE} with ${pm}…`);\n const code = await runInstall(pm, SDK_PACKAGE, cwd);\n if (code === 0) printSuccess(`Installed ${SDK_PACKAGE}.`);\n else printWarning(`Install failed. Run: ${installCommand(pm, SDK_PACKAGE)}`);\n } else {\n printInfo(`Skipped install. Run: ${installCommand(pm, SDK_PACKAGE)}`);\n }\n sdkNote = `the ${SDK_PACKAGE} SDK is installed`;\n } else if (stack.runtime === \"python\" || stack.runtime === \"ruby\") {\n const install =\n stack.runtime === \"python\"\n ? await pythonSdkInstall(cwd)\n : await rubySdkInstall(cwd);\n await installSdk(install, doInstall);\n sdkNote =\n stack.runtime === \"python\"\n ? \"the letterapp Python SDK is installed\"\n : \"the letterapp Ruby gem is installed\";\n } else {\n printInfo(\n `Detected ${stackLabel(stack)}. No ${languageName(stack)} SDK yet, so the agent should use the HTTP API.`,\n );\n sdkNote =\n `there's no official ${languageName(stack)} SDK, so call the HTTP ingestion ` +\n \"API directly (POST /v1/identify and /v1/track with \" +\n \"Authorization: Bearer LETTER_API_KEY and Content-Type: application/json)\";\n }\n\n printAgentHandoff(sdkNote, envFile, cliCommand());\n return 0;\n}\n\n/** Shared install-or-print step for the non-Node SDKs (letterapp). */\nasync function installSdk(install: SdkInstall, doInstall: boolean): Promise<void> {\n if (doInstall) {\n printInfo(`Installing letterapp (${install.display})…`);\n const code = await runSdkInstall(install, process.cwd());\n if (code === 0) printSuccess(\"Installed letterapp.\");\n else printWarning(`Install failed. Run: ${install.display}`);\n } else {\n printInfo(`Skipped install. Run: ${install.display}`);\n }\n}\n\nconst AGENT_DOCS = \"https://letter.app/docs/agent-setup\";\n\n/**\n * Language-agnostic handoff for the last mile. The CLI does the mechanical setup\n * (key in the env, SDK installed where one exists) but deliberately does NOT\n * edit source - the coding agent has the repo context to write idiomatic calls.\n * So we print one ready-to-paste prompt that works for any stack plus a link to\n * the full guide, instead of language-specific snippets.\n */\nfunction printAgentHandoff(\n sdkNote: string,\n envFile: string,\n verifyCmd: string,\n): void {\n const rule = \" \" + \"─\".repeat(68);\n log();\n log(c.bold(\"Next: finish setup with your coding agent\"));\n log();\n log(c.dim(\" Paste this to your agent (Cursor, Claude Code, Codex, OpenClaw, Hermes, …):\"));\n log(c.dim(rule));\n // Plain (uncolored) so it copies cleanly into an agent prompt.\n log(\" Integrate Letter (product email automation) into this app. The CLI\");\n log(` already did setup: LETTER_API_KEY is in ${envFile} and ${sdkNote}.`);\n log(\" Using the right idioms for this codebase:\");\n log(\" - create a shared, server-side Letter client that reads\");\n log(\" LETTER_API_KEY from the environment (only set baseUrl/base_url\");\n log(\" when LETTER_BASE_URL is present),\");\n log(\" - call identify({ userId, email }) where users sign up or log in,\");\n log(\" - call track({ userId, event }) on the 2-3 most important actions,\");\n log(\" - flush before serverless handlers or scripts exit.\");\n log(\" Never print or commit the key. Then verify with the command below.\");\n log(` Full guide: ${AGENT_DOCS}`);\n log(c.dim(rule));\n log();\n log(c.dim(` Prefer to wire it up yourself? Same guide: ${AGENT_DOCS}`));\n log();\n log(c.dim(\"Verify it landed: \") + c.bold(`${verifyCmd} status`));\n log(\n c.dim(\n `Your API key is in ${envFile} - keep it out of source control, and don't echo its value.`,\n ),\n );\n log();\n}\n\nfunction rel(cwd: string, file: string): string {\n return file.startsWith(cwd) ? file.slice(cwd.length + 1) || file : file;\n}\n\nfunction tildify(file: string): string {\n const home = process.env.HOME || process.env.USERPROFILE;\n return home && file.startsWith(home) ? `~${file.slice(home.length)}` : file;\n}\n","import { Command } from \"commander\";\nimport { readCredential, clearCredential } from \"../config.js\";\nimport { c, cliCommand, isJsonMode, printJson, printInfo, printSuccess } from \"../output.js\";\n\nfunction mask(key: string): string {\n return key.length > 12 ? key.slice(0, 8) + \"…\" + key.slice(-4) : \"set\";\n}\n\nexport function registerAuthCommands(program: Command) {\n const auth = program.command(\"auth\").description(\"Manage the stored Letter connection\");\n\n auth\n .command(\"status\")\n .description(\"Show whether this machine is connected to Letter\")\n .action(async () => {\n const cred = await readCredential();\n const envKey = process.env.LETTER_API_KEY;\n\n if (!cred && !envKey) {\n if (isJsonMode()) printJson({ connected: false });\n else printInfo(\"Not connected. Run \" + c.bold(`${cliCommand()} login`) + \" to set up.\");\n return;\n }\n\n if (isJsonMode()) {\n printJson({\n connected: true,\n source: envKey ? \"env\" : \"credentials\",\n project: cred?.project ?? null,\n base_url: cred?.baseUrl ?? null,\n key: envKey ? \"env\" : cred ? mask(cred.apiKey) : null,\n });\n return;\n }\n\n printSuccess(\"Connected\" + (cred ? ` to ${c.bold(cred.project.name)}` : \"\"));\n if (cred) {\n console.log(c.dim(\" Project: \") + cred.project.slug);\n console.log(c.dim(\" Key: \") + mask(cred.apiKey));\n console.log(c.dim(\" API: \") + cred.baseUrl);\n }\n if (envKey) console.log(c.dim(\" LETTER_API_KEY is set in the environment.\"));\n });\n\n auth\n .command(\"logout\")\n .description(\"Remove the stored credential (~/.letter/credentials.json)\")\n .action(async () => {\n await clearCredential();\n printSuccess(\"Removed stored credential.\");\n });\n}\n","import { Command } from \"commander\";\nimport { client } from \"../client.js\";\nimport { readCredential } from \"../config.js\";\nimport { c, isJsonMode, printError, printInfo, printJson, printSuccess, spinner } from \"../output.js\";\n\ntype StatusResponse = {\n contacts?: number;\n events?: number;\n [k: string]: unknown;\n};\n\nexport function registerStatusCommand(program: Command) {\n program\n .command(\"status\")\n .description(\"Check whether your project has received any contacts or events\")\n .action(async () => {\n const spin = spinner(\"Checking your Letter project…\").start();\n try {\n const { data } = await client.get<StatusResponse>(\"/v1/status\");\n spin.stop();\n\n if (isJsonMode()) {\n printJson(data);\n return;\n }\n\n const cred = await readCredential();\n const contacts = data.contacts ?? 0;\n const events = data.events ?? 0;\n\n if (cred) printInfo(`Project ${c.bold(cred.project.name)}`);\n if (contacts > 0 || events > 0) {\n printSuccess(`Connected. ${contacts} contact(s), ${events} event(s) received.`);\n } else {\n printInfo(\"Connected, but no data yet. Fire your first identify/track call.\");\n }\n } catch (err) {\n spin.stop();\n printError(err);\n process.exitCode = 1;\n }\n });\n}\n","import { Command } from \"commander\";\nimport {\n getBaseUrl,\n setBaseUrl,\n getConfigPath,\n resetConfig,\n} from \"../config.js\";\nimport { c, isJsonMode, printError, printJson, printSuccess } from \"../output.js\";\n\nexport function registerConfigCommands(program: Command) {\n const cfg = program.command(\"config\").description(\"Manage CLI configuration\");\n\n cfg\n .command(\"set\")\n .description(\"Set a config value\")\n .argument(\"<key>\", \"Config key: base-url\")\n .argument(\"<value>\", \"Value to set\")\n .action((key: string, value: string) => {\n switch (key) {\n case \"base-url\":\n setBaseUrl(value);\n printSuccess(`Base URL set to ${getBaseUrl()}`);\n break;\n default:\n printError(new Error(`Unknown config key: ${key}. Valid keys: base-url`));\n process.exitCode = 1;\n }\n });\n\n cfg\n .command(\"get\")\n .description(\"Show CLI configuration\")\n .argument(\"[key]\", \"Config key (omit to show all)\")\n .action((key?: string) => {\n const all = { base_url: getBaseUrl(), config_path: getConfigPath() };\n if (key && key !== \"base-url\" && key !== \"path\") {\n printError(new Error(`Unknown config key: ${key}`));\n process.exitCode = 1;\n return;\n }\n if (isJsonMode()) {\n printJson(key === \"base-url\" ? { base_url: all.base_url } : key === \"path\" ? { config_path: all.config_path } : all);\n return;\n }\n if (key === \"base-url\") console.log(all.base_url);\n else if (key === \"path\") console.log(all.config_path);\n else for (const [k, v] of Object.entries(all)) console.log(c.bold(k + \":\") + \" \" + v);\n });\n\n cfg\n .command(\"reset\")\n .description(\"Reset CLI configuration to defaults\")\n .action(() => {\n resetConfig();\n printSuccess(\"Configuration reset.\");\n });\n}\n","import { readFile } from \"node:fs/promises\";\nimport { Command } from \"commander\";\nimport { mgmt } from \"../client.js\";\nimport { resolveProjectSlug } from \"../config.js\";\nimport {\n c,\n cliCommand,\n emit,\n isJsonMode,\n log,\n printError,\n printInfo,\n printJson,\n printSuccess,\n} from \"../output.js\";\nimport { markdownToTipTap } from \"../markdown.js\";\n\n/**\n * Resource command groups for the management API. Each group wraps the same\n * REST endpoints the dashboard uses (`/v1/...`), so the whole app is operable\n * from the terminal. Everything honors the global `--json` flag (see\n * `output.emit`) and project-scoped groups take `--project <slug>` (defaulting\n * to the project connected by `letter login`).\n *\n * The shape is data-driven: one `ResourceSpec` per resource, expanded into\n * `list/get/create/update/delete` + custom verb subcommands by `register()`.\n * Keeping it declarative means a new endpoint is a few lines, not a new file.\n */\n\ntype Field = {\n /** commander option flag, e.g. \"--name <name>\". */\n flag: string;\n /** request-body key, e.g. \"name\". */\n key: string;\n /** parse the value as JSON (supports `@file.json` to read from disk). */\n json?: boolean;\n /** coerce to a number. */\n number?: boolean;\n /** coerce to a boolean. */\n boolean?: boolean;\n /** (multipart only) read the value as a file path and upload its bytes. */\n file?: boolean;\n description?: string;\n};\n\ntype Action = {\n name: string;\n describe: string;\n method: \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\";\n /** Path suffix appended after the resource (and id, if `needsId`). */\n suffix: string;\n /** Whether the verb operates on a single item (default true). */\n needsId?: boolean;\n fields?: Field[];\n /** Query params for GET verbs. */\n query?: Field[];\n /** Send fields as multipart/form-data (for file uploads). */\n multipart?: boolean;\n};\n\ntype ResourceSpec = {\n /** Command group name (also the default path segment). */\n name: string;\n describe: string;\n /** Nested under /v1/projects/{slug} when true. */\n scoped: boolean;\n /** Path segment if different from `name`. */\n segment?: string;\n /** Hidden back-compat alias for the group name. */\n alias?: string;\n /** Positional id arg name (e.g. \"externalId\", \"email\"). Default \"id\". */\n idName?: string;\n list?: { paginated?: boolean; query?: Field[] };\n get?: boolean;\n create?: Field[];\n update?: Field[];\n remove?: boolean;\n actions?: Action[];\n};\n\nasync function readValue(raw: string): Promise<string> {\n if (raw.startsWith(\"@\")) return (await readFile(raw.slice(1), \"utf8\")).trim();\n return raw;\n}\n\nasync function buildBody(\n fields: Field[],\n opts: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = {};\n for (const f of fields) {\n const v = opts[camel(f.key)];\n if (v === undefined) continue;\n if (f.json) {\n body[f.key] = JSON.parse(await readValue(String(v)));\n } else if (f.number) {\n body[f.key] = Number(v);\n } else if (f.boolean) {\n body[f.key] = v === true || v === \"true\";\n } else {\n body[f.key] = await readValue(String(v));\n }\n }\n return body;\n}\n\nasync function buildForm(\n fields: Field[],\n opts: Record<string, unknown>,\n): Promise<FormData> {\n const form = new FormData();\n for (const f of fields) {\n const v = opts[camel(f.key)];\n if (v === undefined) continue;\n if (f.file) {\n const path = String(v);\n const bytes = await readFile(path);\n const name = path.split(\"/\").pop() || f.key;\n form.append(f.key, new Blob([new Uint8Array(bytes)]), name);\n } else if (f.json) {\n // The server parses these fields with JSON.parse; keep them as strings.\n form.append(f.key, await readValue(String(v)));\n } else {\n form.append(f.key, String(v));\n }\n }\n return form;\n}\n\nfunction buildQuery(\n fields: Field[],\n opts: Record<string, unknown>,\n): Record<string, string | number | undefined> {\n const q: Record<string, string | number | undefined> = {};\n for (const f of fields) {\n const v = opts[camel(f.key)];\n if (v === undefined) continue;\n q[f.key] = f.number ? Number(v) : String(v);\n }\n return q;\n}\n\n/** \"external-id\" / \"external_id\" → \"externalId\" (commander camelCases flags). */\nfunction camel(key: string): string {\n return key.replace(/[-_]([a-z])/g, (_, ch: string) => ch.toUpperCase());\n}\n\nfunction applyFields(cmd: Command, fields: Field[]) {\n for (const f of fields) {\n cmd.option(f.flag, f.description ?? f.key);\n }\n}\n\nasync function basePath(spec: ResourceSpec, project?: string): Promise<string> {\n const seg = spec.segment ?? spec.name;\n if (!spec.scoped) return `/v1/${seg}`;\n const slug = await resolveProjectSlug(project);\n return `/v1/projects/${slug}/${seg}`;\n}\n\nfunction withProject(cmd: Command, scoped: boolean): Command {\n if (scoped) {\n cmd.option(\"-p, --project <slug>\", \"Project slug (default: connected project)\");\n }\n return cmd;\n}\n\nfunction fail(err: unknown) {\n printError(err);\n process.exitCode = 1;\n}\n\nfunction register(program: Command, spec: ResourceSpec) {\n const group = program.command(spec.name).description(spec.describe);\n if (spec.alias) group.alias(spec.alias);\n const idName = spec.idName ?? \"id\";\n\n if (spec.list) {\n const cmd = withProject(\n group.command(\"list\").description(`List ${spec.name}`),\n spec.scoped,\n );\n if (spec.list.paginated) {\n cmd.option(\"--limit <n>\", \"Max items (1-100)\");\n cmd.option(\"--cursor <cursor>\", \"Pagination cursor\");\n }\n if (spec.list.query) applyFields(cmd, spec.list.query);\n cmd.action(async (opts) => {\n try {\n const query: Record<string, string | number | undefined> = {};\n if (spec.list?.paginated) {\n if (opts.limit) query.limit = Number(opts.limit);\n if (opts.cursor) query.cursor = opts.cursor;\n }\n if (spec.list?.query) Object.assign(query, buildQuery(spec.list.query, opts));\n const { data } = await mgmt.get(await basePath(spec, opts.project), query);\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n }\n\n if (spec.get) {\n const cmd = withProject(\n group\n .command(\"get\")\n .description(`Get a ${spec.name} by ${idName}`)\n .argument(`<${idName}>`, idName),\n spec.scoped,\n );\n cmd.action(async (idValue: string, opts) => {\n try {\n const path = `${await basePath(spec, opts.project)}/${encodeURIComponent(idValue)}`;\n const { data } = await mgmt.get(path);\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n }\n\n if (spec.create) {\n const cmd = withProject(\n group.command(\"create\").description(`Create a ${spec.name}`),\n spec.scoped,\n );\n applyFields(cmd, spec.create);\n cmd.action(async (opts) => {\n try {\n const body = await buildBody(spec.create!, opts);\n const { data } = await mgmt.post(await basePath(spec, opts.project), body);\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n }\n\n if (spec.update) {\n const cmd = withProject(\n group\n .command(\"update\")\n .description(`Update a ${spec.name}`)\n .argument(`<${idName}>`, idName),\n spec.scoped,\n );\n applyFields(cmd, spec.update);\n cmd.action(async (idValue: string, opts) => {\n try {\n const body = await buildBody(spec.update!, opts);\n const path = `${await basePath(spec, opts.project)}/${encodeURIComponent(idValue)}`;\n const { data } = await mgmt.patch(path, body);\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n }\n\n if (spec.remove) {\n const cmd = withProject(\n group\n .command(\"delete\")\n .description(`Delete a ${spec.name}`)\n .argument(`<${idName}>`, idName),\n spec.scoped,\n );\n cmd.action(async (idValue: string, opts) => {\n try {\n const path = `${await basePath(spec, opts.project)}/${encodeURIComponent(idValue)}`;\n await mgmt.delete(path);\n printSuccess(`Deleted ${spec.name.replace(/s$/, \"\")} ${idValue}.`);\n } catch (err) {\n fail(err);\n }\n });\n }\n\n for (const action of spec.actions ?? []) {\n const needsId = action.needsId ?? true;\n const cmd = withProject(\n needsId\n ? group\n .command(action.name)\n .description(action.describe)\n .argument(`<${idName}>`, idName)\n : group.command(action.name).description(action.describe),\n spec.scoped,\n );\n if (action.fields) applyFields(cmd, action.fields);\n if (action.query) applyFields(cmd, action.query);\n\n const handler = async (...args: unknown[]) => {\n // commander passes (idValue?, opts, command). Last arg is the Command.\n const opts = args[args.length - 2] as Record<string, unknown>;\n const idValue = needsId ? (args[0] as string) : undefined;\n try {\n let path = await basePath(spec, opts.project as string | undefined);\n if (needsId) path += `/${encodeURIComponent(idValue!)}`;\n path += action.suffix;\n\n if (action.method === \"get\") {\n const query = action.query ? buildQuery(action.query, opts) : undefined;\n const { data } = await mgmt.get(path, query);\n emit(data);\n return;\n }\n if (action.multipart && action.fields) {\n const form = await buildForm(action.fields, opts);\n const { data, status } = await mgmt.request(\n action.method.toUpperCase(),\n path,\n { form },\n );\n if (status === 204) printSuccess(`${action.name} ok.`);\n else emit(data);\n return;\n }\n const body = action.fields ? await buildBody(action.fields, opts) : undefined;\n const { data, status } = await mgmt.request(\n action.method.toUpperCase(),\n path,\n { body },\n );\n if (status === 204) printSuccess(`${action.name} ok.`);\n else emit(data);\n } catch (err) {\n fail(err);\n }\n };\n cmd.action(handler);\n }\n}\n\nconst cursor = { paginated: true } as const;\n\nconst SPECS: ResourceSpec[] = [\n // -- Workspace ------------------------------------------------------------\n {\n name: \"projects\",\n describe: \"Manage projects\",\n scoped: false,\n idName: \"slug\",\n list: {},\n get: true,\n create: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--timezone <tz>\", key: \"timezone\" },\n ],\n update: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--timezone <tz>\", key: \"timezone\" },\n ],\n remove: true,\n },\n {\n name: \"members\",\n describe: \"Manage workspace members\",\n scoped: false,\n idName: \"userId\",\n list: {},\n create: [\n { flag: \"--email <email>\", key: \"email\" },\n { flag: \"--role <role>\", key: \"role\", description: \"member | admin\" },\n ],\n remove: true,\n },\n {\n name: \"invitations\",\n describe: \"Manage workspace invitations\",\n scoped: false,\n list: {},\n create: [\n { flag: \"--email <email>\", key: \"email\" },\n { flag: \"--role <role>\", key: \"role\", description: \"member | admin\" },\n ],\n remove: true,\n },\n {\n // Personal access tokens (lt_pat_*) authenticate the CLI / Management API.\n // The dashboard calls these \"API keys\"; `tokens` stays as a hidden alias.\n name: \"api-keys\",\n alias: \"tokens\",\n segment: \"tokens\",\n describe: \"Manage your personal access tokens (lt_pat_*, the CLI/API credential)\",\n scoped: false,\n list: {},\n create: [\n { flag: \"--name <name>\", key: \"name\" },\n {\n flag: \"--expires-at <iso>\",\n key: \"expires_at\",\n description: \"Expiry as an ISO 8601 datetime (default: never)\",\n },\n ],\n remove: true,\n },\n // -- Contacts & data ------------------------------------------------------\n {\n name: \"contacts\",\n describe: \"Manage contacts\",\n scoped: true,\n idName: \"externalId\",\n list: { ...cursor },\n get: true,\n actions: [\n {\n name: \"suppress\",\n describe: \"Suppress a contact\",\n method: \"post\",\n suffix: \"/suppress\",\n },\n {\n name: \"resubscribe\",\n describe: \"Resubscribe a contact\",\n method: \"post\",\n suffix: \"/resubscribe\",\n },\n {\n name: \"import\",\n describe: \"Upload a CSV import (--file <path> --mapping <json|@file>)\",\n method: \"post\",\n needsId: false,\n suffix: \"/imports\",\n multipart: true,\n fields: [\n { flag: \"--file <path>\", key: \"file\", file: true },\n { flag: \"--mapping <json>\", key: \"mapping\", json: true },\n { flag: \"--dedupe <strategy>\", key: \"dedupe\", description: \"update | skip\" },\n { flag: \"--row-count <n>\", key: \"rowCount\" },\n ],\n },\n ],\n },\n {\n name: \"accounts\",\n describe: \"Inspect accounts\",\n scoped: true,\n idName: \"externalId\",\n list: { ...cursor },\n get: true,\n },\n {\n name: \"events\",\n describe: \"List events\",\n scoped: true,\n list: { ...cursor, query: [{ flag: \"--name <name>\", key: \"name\" }] },\n },\n {\n name: \"suppressions\",\n describe: \"Manage the suppression list\",\n scoped: true,\n idName: \"email\",\n list: { ...cursor },\n create: [{ flag: \"--email <email>\", key: \"email\" }],\n remove: true,\n },\n {\n name: \"segments\",\n describe: \"Manage segments\",\n scoped: true,\n list: {},\n get: true,\n create: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--filter <json>\", key: \"filter\", json: true },\n ],\n update: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--filter <json>\", key: \"filter\", json: true },\n ],\n remove: true,\n actions: [\n {\n name: \"preview\",\n describe: \"Count contacts matching a filter (--filter <json|@file>)\",\n method: \"post\",\n needsId: false,\n suffix: \"/preview\",\n fields: [{ flag: \"--filter <json>\", key: \"filter\", json: true }],\n },\n ],\n },\n // -- Sequences ------------------------------------------------------------\n {\n name: \"sequences\",\n describe: \"Manage drip sequences\",\n scoped: true,\n list: {},\n get: true,\n create: [{ flag: \"--name <name>\", key: \"name\" }],\n update: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--status <status>\", key: \"status\", description: \"active | archived\" },\n ],\n remove: true,\n // `draft`, `preview`, `test-email`, `validate`, `schema`, and `scaffold`\n // are hand-written in `attachSequenceExtras` (they need draft-aware\n // behaviour the generic machinery can't express).\n actions: [\n {\n name: \"publish\",\n describe: \"Publish the current draft\",\n method: \"post\",\n suffix: \"/publish\",\n },\n {\n name: \"activity\",\n describe: \"Show enrollment activity\",\n method: \"get\",\n suffix: \"/activity\",\n },\n {\n name: \"versions\",\n describe: \"List published versions\",\n method: \"get\",\n suffix: \"/versions\",\n },\n ],\n },\n // -- Broadcasts -----------------------------------------------------------\n {\n name: \"broadcasts\",\n describe: \"Manage broadcasts\",\n scoped: true,\n list: {},\n get: true,\n create: [{ flag: \"--name <name>\", key: \"name\" }],\n update: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--subject <subject>\", key: \"subject\" },\n { flag: \"--preview <preview>\", key: \"preview\" },\n { flag: \"--audience <json>\", key: \"audience\", json: true },\n { flag: \"--template-id <id>\", key: \"template_id\" },\n { flag: \"--body-doc <json>\", key: \"body_doc\", json: true },\n ],\n remove: true,\n actions: [\n {\n name: \"preflight\",\n describe: \"Validate before sending\",\n method: \"post\",\n suffix: \"/preflight\",\n },\n {\n name: \"schedule\",\n describe: \"Schedule (--scheduled-at <iso>) or send now (omit)\",\n method: \"post\",\n suffix: \"/schedule\",\n fields: [{ flag: \"--scheduled-at <iso>\", key: \"scheduled_at\" }],\n },\n {\n name: \"cancel\",\n describe: \"Cancel a scheduled or sending broadcast\",\n method: \"post\",\n suffix: \"/cancel\",\n },\n {\n name: \"live\",\n describe: \"Live status, stats, and recent activity\",\n method: \"get\",\n suffix: \"/live\",\n },\n ],\n },\n // -- Templates ------------------------------------------------------------\n {\n name: \"templates\",\n describe: \"Manage email templates\",\n scoped: true,\n list: {},\n get: true,\n create: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--design <json>\", key: \"design\", json: true },\n ],\n update: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--design <json>\", key: \"design\", json: true },\n ],\n remove: true,\n actions: [\n {\n name: \"default\",\n describe: \"Set as the project default\",\n method: \"post\",\n suffix: \"/default\",\n },\n {\n name: \"reset\",\n describe: \"Reset design to a preset (--preset plain|branded)\",\n method: \"post\",\n suffix: \"/reset\",\n fields: [{ flag: \"--preset <preset>\", key: \"preset\" }],\n },\n {\n name: \"logo\",\n describe: \"Upload a logo (--file <path>)\",\n method: \"post\",\n suffix: \"/logo\",\n multipart: true,\n fields: [{ flag: \"--file <path>\", key: \"file\", file: true }],\n },\n {\n name: \"remove-logo\",\n describe: \"Remove the template logo\",\n method: \"delete\",\n suffix: \"/logo\",\n },\n ],\n },\n // -- Settings -------------------------------------------------------------\n {\n name: \"domains\",\n describe: \"Manage sending domains\",\n scoped: true,\n list: {},\n create: [{ flag: \"--domain <domain>\", key: \"domain\" }],\n remove: true,\n actions: [\n {\n name: \"verify\",\n describe: \"Re-check DKIM verification\",\n method: \"post\",\n suffix: \"/verify\",\n },\n ],\n },\n {\n // Project ingestion keys (lt_live_*) authenticate the SDKs / ingestion API.\n // The dashboard calls these \"Project tokens\"; `keys` stays as a hidden alias.\n name: \"project-tokens\",\n alias: \"keys\",\n segment: \"keys\",\n describe: \"Manage project ingestion keys (lt_live_*, the SDK/ingestion credential)\",\n scoped: true,\n list: {},\n create: [{ flag: \"--name <name>\", key: \"name\" }],\n remove: true,\n },\n];\n\n/**\n * Canonical sequence shapes, printed by `sequences schema`. This is the\n * reference an agent reaches for instead of reverse-engineering the graph\n * from 400s. Mirrors the strict server validation + the /docs/sequences guide.\n */\nconst SEQUENCE_SCHEMA = {\n trigger: {\n event: {\n type: \"event\",\n eventName: \"modification_limit_reached\",\n oncePerContact: true,\n \"filter?\": \"FilterSpec — optional audience filter on the contact's traits/history\",\n \"where?\":\n \"Condition(s) on the firing event's own properties, e.g. { property: 'plan', op: 'eq', value: 'free' } (single object or array, AND-ed)\",\n },\n contact_created: {\n type: \"contact_created\",\n \"filter?\": \"FilterSpec — optional audience filter on the contact\",\n },\n },\n nodeConfigs: {\n trigger: { type: \"trigger\" },\n email: {\n type: \"email\",\n subject: \"You hit your limit\",\n \"preview?\": \"Here's how to lift it\",\n \"bodyDoc?\": { type: \"doc\", content: [\"…TipTap nodes…\"] },\n \"templateId?\": \"uuid | null (omit for project default)\",\n },\n wait: { type: \"wait\", duration: { value: 1, unit: \"minutes | hours | days\" } },\n branch: {\n type: \"branch\",\n condition: {\n event: { kind: \"event\", eventName: \"Upgraded\", occurred: true, \"window?\": { value: 2, unit: \"days\" } },\n trait: { kind: \"trait\", scope: \"contact | account\", path: \"plan\", op: \"eq | neq | contains | not_contains | exists | not_exists\", \"value?\": \"pro\" },\n },\n },\n exit: { type: \"exit\", \"reason?\": \"done\" },\n },\n edge: {\n id: \"e1\",\n source: \"trigger\",\n target: \"email1\",\n \"branch?\": \"yes | no — only on edges leaving a branch node\",\n },\n notes: [\n \"config.type must equal the node's type.\",\n \"The email body field is `bodyDoc` (camelCase); a wait nests `duration`.\",\n \"Draft saves reject unknown / mis-cased keys with a 400.\",\n \"Trait/filter values compare as strings: use value:\\\"false\\\" (not false) for a boolean trait. `letter traits list` shows keys + types.\",\n \"Event triggers can also gate on the event's own properties via `where` (e.g. only plan=free).\",\n \"Publish requires: one trigger, every node reachable, every path ends at an exit, each branch has one yes + one no edge, and each email has a subject + non-empty bodyDoc.\",\n \"`sequences validate <id>` dry-runs those publish checks; `sequences scaffold` builds a valid trigger → [wait] → email → exit graph in one command.\",\n ],\n example: {\n trigger: {\n type: \"event\",\n eventName: \"modification_limit_reached\",\n oncePerContact: true,\n filter: { kind: \"trait\", path: \"plan\", op: \"eq\", value: \"free\" },\n },\n graph: {\n nodes: [\n { id: \"trigger\", type: \"trigger\", position: { x: 280, y: 80 }, config: { type: \"trigger\" } },\n { id: \"wait1\", type: \"wait\", position: { x: 280, y: 200 }, config: { type: \"wait\", duration: { value: 1, unit: \"hours\" } } },\n {\n id: \"email1\",\n type: \"email\",\n position: { x: 280, y: 320 },\n config: {\n type: \"email\",\n subject: \"You hit your limit\",\n bodyDoc: { type: \"doc\", content: [{ type: \"paragraph\", content: [{ type: \"text\", text: \"Upgrade to keep going.\" }] }] },\n },\n },\n { id: \"exit1\", type: \"exit\", position: { x: 280, y: 440 }, config: { type: \"exit\" } },\n ],\n edges: [\n { id: \"e1\", source: \"trigger\", target: \"wait1\" },\n { id: \"e2\", source: \"wait1\", target: \"email1\" },\n { id: \"e3\", source: \"email1\", target: \"exit1\" },\n ],\n },\n },\n} as const;\n\nfunction printSequenceSchemaHuman() {\n log(\"Sequence authoring shapes (see /docs/sequences for the full guide).\\n\");\n log(\"Trigger (how contacts enter):\");\n log(JSON.stringify(SEQUENCE_SCHEMA.trigger, null, 2));\n log(\"\\nNode configs (config.type must match the node type):\");\n log(JSON.stringify(SEQUENCE_SCHEMA.nodeConfigs, null, 2));\n log(\"\\nEdge:\");\n log(JSON.stringify(SEQUENCE_SCHEMA.edge, null, 2));\n log(\"\\nNotes:\");\n for (const n of SEQUENCE_SCHEMA.notes) log(` • ${n}`);\n log(\"\\nKnown-good example (trigger + graph):\");\n log(JSON.stringify(SEQUENCE_SCHEMA.example, null, 2));\n log(`\\nScaffold one in a single command:`);\n log(\n ` ${cliCommand()} sequences scaffold --name \"Limit reached\" \\\\\\n` +\n ` --event modification_limit_reached --audience-trait plan=free \\\\\\n` +\n ` --wait 1h --subject \"You hit your limit\" \\\\\\n` +\n ` --body-md \"Upgrade to **keep going**.\" --publish`,\n );\n}\n\n/** Parse a human duration like `30m`, `1h`, `2d` into the wait/branch shape. */\nfunction parseDuration(raw: string): {\n value: number;\n unit: \"minutes\" | \"hours\" | \"days\";\n} {\n const m = /^(\\d+)\\s*(m|min|mins|minute|minutes|h|hr|hrs|hour|hours|d|day|days)$/i.exec(\n raw.trim(),\n );\n if (!m) {\n throw new Error(`Invalid --wait \"${raw}\". Use e.g. 30m, 1h, or 2d.`);\n }\n const u = (m[2] ?? \"\").toLowerCase();\n const unit = u.startsWith(\"d\") ? \"days\" : u.startsWith(\"h\") ? \"hours\" : \"minutes\";\n return { value: Number(m[1]), unit };\n}\n\n/** Trait shorthand `path=value` (also `!=` and `~` for contains). Values are\n * always strings — Letter compares trait values as strings, so `isPro=false`\n * matches the boolean trait `false`. Use `--audience @file.json` for the full\n * FilterSpec (exists / groups / event history). */\nfunction parseAudienceTrait(raw: string): Record<string, unknown> {\n const m = /^([^=!~]+?)\\s*(!=|~|=)\\s*(.*)$/.exec(raw);\n if (!m) {\n throw new Error(\n \"--audience-trait must be path=value (also path!=value or path~value), e.g. plan=free\",\n );\n }\n const op = m[2] === \"!=\" ? \"neq\" : m[2] === \"~\" ? \"contains\" : \"eq\";\n return { kind: \"trait\", path: (m[1] ?? \"\").trim(), op, value: m[3] ?? \"\" };\n}\n\nfunction attachSequenceExtras(program: Command) {\n const seq = program.commands.find((cmd) => cmd.name() === \"sequences\");\n if (!seq) return;\n\n seq\n .command(\"draft <id>\")\n .description(\n \"Save the draft graph + trigger (auto-fetches the current revision unless --expected-revision is given)\",\n )\n .option(\"--graph <json>\", \"Graph JSON (inline or @file.json)\")\n .option(\"--trigger <json>\", \"Trigger JSON (inline or @file.json)\")\n .option(\n \"--expected-revision <n>\",\n \"Optimistic-concurrency revision (default: current; use a number to assert)\",\n )\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (id: string, opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const base = `/v1/projects/${slug}/sequences`;\n const body: Record<string, unknown> = {};\n if (opts.graph !== undefined) {\n body.graph = JSON.parse(await readValue(String(opts.graph)));\n }\n if (opts.trigger !== undefined) {\n body.trigger = JSON.parse(await readValue(String(opts.trigger)));\n }\n const explicit = opts.expectedRevision;\n if (explicit !== undefined && String(explicit) !== \"auto\") {\n body.expected_revision = Number(explicit);\n } else {\n const { data } = await mgmt.get(`${base}/${encodeURIComponent(id)}`);\n body.expected_revision =\n (data as { draft_revision?: number }).draft_revision ?? 0;\n }\n const { data } = await mgmt.put(\n `${base}/${encodeURIComponent(id)}/draft`,\n body,\n );\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n\n seq\n .command(\"preview <id>\")\n .description(\"Render an email node to HTML/text\")\n .requiredOption(\"--node-id <id>\", \"Email node id (e.g. email1)\")\n .option(\n \"--config <json>\",\n \"Inline email config (inline or @file.json); omit to render the saved draft\",\n )\n .option(\"--to <email>\", \"Recipient address to cast in the preview\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (id: string, opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const base = `/v1/projects/${slug}/sequences`;\n const body: Record<string, unknown> = { node_id: String(opts.nodeId) };\n if (opts.config !== undefined) {\n body.config = JSON.parse(await readValue(String(opts.config)));\n }\n if (opts.to !== undefined) body.recipient_email = String(opts.to);\n const { data } = await mgmt.post(\n `${base}/${encodeURIComponent(id)}/preview`,\n body,\n );\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n\n seq\n .command(\"test-email <id>\")\n .description(\"Send a [Test] copy of an email node\")\n .requiredOption(\"--node-id <id>\", \"Email node id (e.g. email1)\")\n .option(\"--to <email>\", \"Recipient (default: your account email)\")\n .option(\n \"--config <json>\",\n \"Inline email config (inline or @file.json); omit to send the saved draft\",\n )\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (id: string, opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const base = `/v1/projects/${slug}/sequences`;\n const body: Record<string, unknown> = { node_id: String(opts.nodeId) };\n if (opts.to !== undefined) body.recipient_email = String(opts.to);\n if (opts.config !== undefined) {\n body.config = JSON.parse(await readValue(String(opts.config)));\n }\n const { data } = await mgmt.post(\n `${base}/${encodeURIComponent(id)}/test-email`,\n body,\n );\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n\n seq\n .command(\"validate <id>\")\n .description(\"Dry-run the publish checks against the current draft (no changes)\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (id: string, opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const { data } = await mgmt.get(\n `/v1/projects/${slug}/sequences/${encodeURIComponent(id)}/validate`,\n );\n if (isJsonMode()) {\n printJson(data);\n return;\n }\n const result = data as {\n ok: boolean;\n errors: { code: string; message: string; nodeId?: string }[];\n };\n if (result.ok) {\n printSuccess(\"Draft is publish-ready.\");\n return;\n }\n printError(`Not publish-ready (${result.errors.length} issue(s)):`);\n for (const e of result.errors) {\n const where = e.nodeId ? c.dim(` [${e.nodeId}]`) : \"\";\n log(` • ${e.message}${where}`);\n }\n process.exitCode = 1;\n } catch (err) {\n fail(err);\n }\n });\n\n seq\n .command(\"schema\")\n .description(\"Print the canonical trigger / node / edge shapes + an example\")\n .action(() => {\n if (isJsonMode()) printJson(SEQUENCE_SCHEMA);\n else printSequenceSchemaHuman();\n });\n\n seq\n .command(\"scaffold\")\n .description(\n \"Create + draft (and optionally publish) a trigger → [wait] → email → exit sequence\",\n )\n .requiredOption(\"--name <name>\", \"Sequence name\")\n .option(\n \"--event <name>\",\n \"Event-trigger name (omit for a contact_created trigger)\",\n )\n .option(\"--no-once-per-contact\", \"Allow re-enrolment on every event\")\n .option(\"--audience <json>\", \"Audience FilterSpec (inline JSON or @file.json)\")\n .option(\n \"--audience-trait <path=value>\",\n \"Shorthand audience filter: trait equals value (e.g. plan=free)\",\n )\n .option(\"--wait <duration>\", \"Delay before the email, e.g. 30m, 1h, 2d\")\n .requiredOption(\"--subject <subject>\", \"Email subject\")\n .option(\"--body-md <markdown>\", \"Email body as Markdown (converted to rich text)\")\n .option(\"--body-text <text>\", \"Email body as plain text\")\n .option(\"--publish\", \"Publish immediately after drafting\")\n .option(\"--dry-run\", \"Print the trigger + graph it would create, without creating anything\")\n .option(\"--if-not-exists\", \"Reuse an existing sequence with the same name instead of duplicating\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const base = `/v1/projects/${slug}/sequences`;\n\n // Audience filter (full FilterSpec wins over the trait shorthand).\n let filter: unknown;\n if (opts.audience !== undefined) {\n filter = JSON.parse(await readValue(String(opts.audience)));\n } else if (opts.audienceTrait !== undefined) {\n filter = parseAudienceTrait(String(opts.audienceTrait));\n }\n\n const trigger = opts.event\n ? {\n type: \"event\",\n eventName: String(opts.event),\n oncePerContact: opts.oncePerContact !== false,\n ...(filter ? { filter } : {}),\n }\n : { type: \"contact_created\", ...(filter ? { filter } : {}) };\n\n const bodyDoc =\n opts.bodyMd !== undefined\n ? markdownToTipTap(String(opts.bodyMd))\n : opts.bodyText !== undefined\n ? markdownToTipTap(String(opts.bodyText))\n : undefined;\n\n const nodes: Record<string, unknown>[] = [\n { id: \"trigger\", type: \"trigger\", position: { x: 280, y: 80 }, config: { type: \"trigger\" } },\n ];\n const edges: Record<string, unknown>[] = [];\n let prev = \"trigger\";\n let y = 200;\n if (opts.wait !== undefined) {\n nodes.push({\n id: \"wait1\",\n type: \"wait\",\n position: { x: 280, y },\n config: { type: \"wait\", duration: parseDuration(String(opts.wait)) },\n });\n edges.push({ id: \"e_wait\", source: prev, target: \"wait1\" });\n prev = \"wait1\";\n y += 120;\n }\n nodes.push({\n id: \"email1\",\n type: \"email\",\n position: { x: 280, y },\n config: {\n type: \"email\",\n subject: String(opts.subject),\n ...(bodyDoc ? { bodyDoc } : {}),\n },\n });\n edges.push({ id: \"e_email\", source: prev, target: \"email1\" });\n prev = \"email1\";\n y += 120;\n nodes.push({\n id: \"exit1\",\n type: \"exit\",\n position: { x: 280, y },\n config: { type: \"exit\" },\n });\n edges.push({ id: \"e_exit\", source: prev, target: \"exit1\" });\n const graph = { nodes, edges };\n\n // --dry-run: show exactly what would be sent, mutate nothing.\n if (opts.dryRun) {\n if (isJsonMode()) printJson({ slug, name: String(opts.name), trigger, graph });\n else {\n log(\"Would create sequence \" + c.bold(String(opts.name)) + \" with:\\n\");\n log(\"trigger:\");\n log(JSON.stringify(trigger, null, 2));\n log(\"\\ngraph:\");\n log(JSON.stringify(graph, null, 2));\n }\n return;\n }\n\n // --if-not-exists: reuse a same-named sequence instead of duplicating.\n let id: string | undefined;\n let reused = false;\n if (opts.ifNotExists) {\n const { data } = await mgmt.get(base);\n const rows = (data as { data?: { id: string; name: string }[] }).data ?? [];\n const match = rows.find((r) => r.name === String(opts.name));\n if (match) {\n id = match.id;\n reused = true;\n }\n }\n if (!id) {\n const created = await mgmt.post(base, { name: String(opts.name) });\n id = (created.data as { id: string }).id;\n }\n // Save the draft at the sequence's current revision (0 for brand-new).\n const detail = await mgmt.get(`${base}/${id}`);\n const rev = (detail.data as { draft_revision?: number }).draft_revision ?? 0;\n await mgmt.put(`${base}/${id}/draft`, {\n graph,\n trigger,\n expected_revision: rev,\n });\n let published = false;\n if (opts.publish) {\n await mgmt.request(\"POST\", `${base}/${id}/publish`, {});\n published = true;\n }\n\n if (isJsonMode()) {\n printJson({ id, slug, reused, published, trigger, graph });\n return;\n }\n const verb = reused ? \"Updated existing sequence\" : \"Created sequence\";\n printSuccess(\n `${verb} ${id}${published ? \" and published it\" : \" (draft saved)\"}.`,\n );\n if (!published) {\n printInfo(`Publish when ready: ${cliCommand()} sequences publish ${id}`);\n printInfo(`Dry-run the publish checks: ${cliCommand()} sequences validate ${id}`);\n }\n printInfo(\n `Tweak it on the canvas, or re-draft with ${cliCommand()} sequences draft ${id} --graph @graph.json`,\n );\n } catch (err) {\n fail(err);\n }\n });\n}\n\nfunction attachTraits(program: Command) {\n const traits = program\n .command(\"traits\")\n .description(\"Discover trait keys for audience filters and branch conditions\");\n traits\n .command(\"list\")\n .description(\"List distinct contact/account trait keys with type + sample\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const { data } = await mgmt.get(`/v1/projects/${slug}/traits`);\n const rows =\n (data as {\n data?: {\n key: string;\n scope: string;\n type: string;\n count: number;\n sample: string | null;\n }[];\n }).data ?? [];\n if (isJsonMode()) {\n printJson(rows);\n return;\n }\n if (rows.length === 0) {\n log(c.dim(\"(no traits yet)\"));\n return;\n }\n log(c.dim(\"Values are compared as strings (e.g. boolean false → \\\"false\\\").\\n\"));\n for (const r of rows) {\n const head = `${c.bold(r.key)} ${c.dim(`(${r.scope} ${r.type})`)}`;\n const sample = r.sample != null ? ` e.g. ${JSON.stringify(r.sample)}` : \"\";\n log(`${head} ×${r.count}${sample}`);\n }\n } catch (err) {\n fail(err);\n }\n });\n}\n\nexport function registerResourceCommands(program: Command) {\n for (const spec of SPECS) register(program, spec);\n attachSequenceExtras(program);\n attachTraits(program);\n\n // `letter me` — the token's identity (handy sanity check).\n program\n .command(\"me\")\n .description(\"Show the token's user, workspace, and role\")\n .action(async () => {\n try {\n const { data } = await mgmt.get(\"/v1/me\");\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n\n // Sender identity + sending mode don't fit the CRUD mold: register directly.\n program\n .command(\"sender-identity\")\n .description(\"Set From / From-name / Reply-To (--from-email, --from-name, --reply-to-email)\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .option(\"--from-email <email>\", \"From address\")\n .option(\"--from-name <name>\", \"From display name\")\n .option(\"--reply-to-email <email>\", \"Reply-To address\")\n .action(async (opts) => {\n try {\n const slug = await resolveProjectSlug(opts.project);\n const body: Record<string, unknown> = {};\n if (opts.fromEmail !== undefined) body.from_email = opts.fromEmail;\n if (opts.fromName !== undefined) body.from_name = opts.fromName;\n if (opts.replyToEmail !== undefined) body.reply_to_email = opts.replyToEmail;\n const { data } = await mgmt.put(`/v1/projects/${slug}/sender-identity`, body);\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"sending-mode\")\n .description(\"Set the sending mode (letter_subdomain | byo_domain)\")\n .argument(\"<mode>\", \"letter_subdomain | byo_domain\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (mode: string, opts) => {\n try {\n const slug = await resolveProjectSlug(opts.project);\n const { data } = await mgmt.put(`/v1/projects/${slug}/sending-mode`, {\n sending_mode: mode,\n });\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n}\n","/**\n * Minimal Markdown -> TipTap/ProseMirror converter, so email bodies can be\n * authored from the CLI without hand-writing ProseMirror JSON.\n *\n * It targets the subset the Letter email renderer (TipTap StarterKit + Link)\n * understands: headings (#..###), paragraphs, bullet/ordered lists,\n * blockquotes, horizontal rules, and inline **bold**, *italic*, `code`, and\n * [links](url) plus hard line breaks. It is intentionally small - for anything\n * richer, pass a full `bodyDoc` JSON to `sequences draft` instead.\n */\n\nexport type TipTapMark = { type: string; attrs?: Record<string, unknown> };\nexport type TipTapNode = {\n type: string;\n attrs?: Record<string, unknown>;\n marks?: TipTapMark[];\n text?: string;\n content?: TipTapNode[];\n};\nexport type TipTapDoc = { type: \"doc\"; content: TipTapNode[] };\n\nconst HR = /^\\s*([-*_])\\1{2,}\\s*$/;\nconst HEADING = /^(#{1,3})\\s+(.*)$/;\nconst QUOTE = /^\\s*>\\s?/;\nconst BULLET = /^\\s*[-*+]\\s+/;\nconst ORDERED = /^\\s*\\d+\\.\\s+/;\n\nfunction isBlockStart(line: string): boolean {\n return (\n /^#{1,3}\\s+/.test(line) ||\n BULLET.test(line) ||\n ORDERED.test(line) ||\n QUOTE.test(line) ||\n HR.test(line)\n );\n}\n\nfunction pushText(nodes: TipTapNode[], text: string, marks?: TipTapMark[]) {\n if (!text) return;\n nodes.push(marks ? { type: \"text\", text, marks } : { type: \"text\", text });\n}\n\n/**\n * Parse inline marks within a single line. Recursive so marks nest correctly:\n * `**[text](url)**` becomes one text node carrying both `bold` and `link`,\n * rather than a literal `[text](url)` string inside a bold run. `carried` is\n * the set of marks inherited from the enclosing span.\n */\nfunction inline(text: string, carried: TipTapMark[] = []): TipTapNode[] {\n const nodes: TipTapNode[] = [];\n // Non-greedy bodies so `**a** **b**` splits into two runs and an outer\n // mark can contain a nested token (e.g. a link inside bold). Code first so\n // `**` inside backticks isn't treated as bold; then links, bold, italic.\n const token =\n /(`[^`]+`)|(\\[[^\\]]+\\]\\([^)]+\\))|(\\*\\*[\\s\\S]+?\\*\\*)|(__[\\s\\S]+?__)|(\\*[\\s\\S]+?\\*)|(_[\\s\\S]+?_)/;\n let rest = text;\n while (rest.length > 0) {\n const m = token.exec(rest);\n if (!m) {\n pushText(nodes, rest, carried.length ? carried : undefined);\n break;\n }\n if (m.index > 0) {\n pushText(nodes, rest.slice(0, m.index), carried.length ? carried : undefined);\n }\n const tok = m[0];\n if (tok.startsWith(\"`\")) {\n pushText(nodes, tok.slice(1, -1), [...carried, { type: \"code\" }]);\n } else if (tok.startsWith(\"[\")) {\n const lm = /\\[([^\\]]+)\\]\\(([^)]+)\\)/.exec(tok);\n if (lm) {\n nodes.push(\n ...inline(lm[1] ?? \"\", [\n ...carried,\n { type: \"link\", attrs: { href: lm[2] ?? \"\" } },\n ]),\n );\n }\n } else if (tok.startsWith(\"**\") || tok.startsWith(\"__\")) {\n nodes.push(...inline(tok.slice(2, -2), [...carried, { type: \"bold\" }]));\n } else {\n nodes.push(...inline(tok.slice(1, -1), [...carried, { type: \"italic\" }]));\n }\n rest = rest.slice(m.index + tok.length);\n }\n return nodes;\n}\n\n/** Inline-parse multiple lines, joining them with hard breaks. */\nfunction inlineMultiline(lines: string[]): TipTapNode[] {\n const out: TipTapNode[] = [];\n lines.forEach((line, idx) => {\n if (idx > 0) out.push({ type: \"hardBreak\" });\n out.push(...inline(line));\n });\n return out;\n}\n\nfunction listItems(\n lines: string[],\n start: number,\n marker: RegExp,\n): { items: TipTapNode[]; next: number } {\n const items: TipTapNode[] = [];\n let i = start;\n for (let cur = lines[i]; cur !== undefined && marker.test(cur); cur = lines[i]) {\n items.push({\n type: \"listItem\",\n content: [{ type: \"paragraph\", content: inline(cur.replace(marker, \"\")) }],\n });\n i++;\n }\n return { items, next: i };\n}\n\nexport function markdownToTipTap(input: string): TipTapDoc {\n // Shells don't expand `\\n` inside double quotes, so accept literal escapes.\n const src = input.replace(/\\\\n/g, \"\\n\").replace(/\\\\t/g, \"\\t\");\n const lines = src.split(\"\\n\");\n const blocks: TipTapNode[] = [];\n let i = 0;\n while (i < lines.length) {\n const line = lines[i] ?? \"\";\n if (line.trim() === \"\") {\n i++;\n continue;\n }\n if (HR.test(line)) {\n blocks.push({ type: \"horizontalRule\" });\n i++;\n continue;\n }\n const h = HEADING.exec(line);\n if (h) {\n blocks.push({\n type: \"heading\",\n attrs: { level: (h[1] ?? \"#\").length },\n content: inline(h[2] ?? \"\"),\n });\n i++;\n continue;\n }\n if (QUOTE.test(line)) {\n const quote: string[] = [];\n for (let cur = lines[i]; cur !== undefined && QUOTE.test(cur); cur = lines[i]) {\n quote.push(cur.replace(QUOTE, \"\"));\n i++;\n }\n blocks.push({\n type: \"blockquote\",\n content: [{ type: \"paragraph\", content: inline(quote.join(\" \")) }],\n });\n continue;\n }\n if (BULLET.test(line)) {\n const { items, next } = listItems(lines, i, BULLET);\n blocks.push({ type: \"bulletList\", content: items });\n i = next;\n continue;\n }\n if (ORDERED.test(line)) {\n const { items, next } = listItems(lines, i, ORDERED);\n blocks.push({ type: \"orderedList\", content: items });\n i = next;\n continue;\n }\n // Paragraph: gather consecutive plain lines, join with hard breaks.\n const para: string[] = [];\n for (let cur = lines[i]; cur !== undefined && cur.trim() !== \"\" && !isBlockStart(cur); cur = lines[i]) {\n para.push(cur);\n i++;\n }\n blocks.push({ type: \"paragraph\", content: inlineMultiline(para) });\n }\n return { type: \"doc\", content: blocks };\n}\n"],"mappings":"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","names":["path","path","path","readFile","writeFile","spawn","readFile","readFile","spawn","program","program","program","program","readFile","readFile","path","program","data","status"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/output.ts","../src/config.ts","../src/client.ts","../src/browser.ts","../src/env-file.ts","../src/pm.ts","../src/commands/login.ts","../src/commands/auth.ts","../src/commands/status.ts","../src/commands/config.ts","../src/commands/resources.ts","../src/markdown.ts"],"sourcesContent":["declare const PKG_VERSION: string;\nimport { Command } from \"commander\";\nimport { setJsonMode } from \"./output.js\";\nimport { registerLoginCommand } from \"./commands/login.js\";\nimport { registerAuthCommands } from \"./commands/auth.js\";\nimport { registerStatusCommand } from \"./commands/status.js\";\nimport { registerConfigCommands } from \"./commands/config.js\";\nimport { registerResourceCommands } from \"./commands/resources.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"letter\")\n .description(\"Connect your app to Letter, then manage it from the command line\")\n .version(PKG_VERSION)\n .option(\"--json\", \"Output raw JSON (for scripting / agents)\")\n .hook(\"preAction\", (thisCommand) => {\n if (thisCommand.opts().json) setJsonMode(true);\n });\n\n// Two layers, one login:\n// - login/auth/status/config wire up the project and its ingestion key\n// (lt_live_*, written to the project env as LETTER_API_KEY).\n// - the resource groups drive the Management API with the workspace PAT\n// (lt_pat_*, stored in ~/.letter/credentials.json). Both credentials are\n// minted by `letter login`; each command picks the right one on its own.\nregisterLoginCommand(program); // default command (`letter` == `letter login`)\nregisterAuthCommands(program);\nregisterStatusCommand(program);\nregisterConfigCommands(program);\nregisterResourceCommands(program); // control-plane resource groups (PAT-backed)\n\nprogram.parseAsync();\n","import chalk from \"chalk\";\nimport ora, { type Ora } from \"ora\";\nimport { createInterface } from \"node:readline\";\n\nlet jsonMode = false;\n\nexport function setJsonMode(enabled: boolean) {\n jsonMode = enabled;\n}\nexport function isJsonMode() {\n return jsonMode;\n}\n\nexport function printJson(data: unknown) {\n console.log(JSON.stringify(data, null, 2));\n}\n\n/**\n * The command users should repeat to run us again, so printed hints are\n * copy-pasteable. When launched through `npx`, Node runs us from the npx cache\n * (`…/_npx/<hash>/…`) and there's no `letter` on PATH, so suggest the npx form;\n * a global install resolves the bare `letter` binary.\n */\nexport function cliCommand(): string {\n return (process.argv[1] ?? \"\").includes(\"_npx\") ? \"npx @letterapp/cli\" : \"letter\";\n}\n\nexport function log(msg = \"\") {\n if (jsonMode) return;\n console.log(msg);\n}\n\nexport function printSuccess(msg: string) {\n if (jsonMode) return;\n console.log(chalk.green(\"✓\") + \" \" + msg);\n}\n\nexport function printInfo(msg: string) {\n if (jsonMode) return;\n console.log(chalk.cyan(\"›\") + \" \" + msg);\n}\n\nexport function printWarning(msg: string) {\n if (jsonMode) return;\n console.log(chalk.yellow(\"!\") + \" \" + msg);\n}\n\nexport type ApiIssue = { path?: string; message?: string };\n\nexport function printError(err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n const issues = (err as { issues?: ApiIssue[] })?.issues;\n if (jsonMode) {\n printJson({ error: msg, ...(issues?.length ? { issues } : {}) });\n return;\n }\n console.error(chalk.red(\"✗\") + \" \" + msg);\n // Validation 400s carry field-level issues; print them so callers don't\n // have to re-probe the API to learn which key/shape was wrong.\n if (Array.isArray(issues)) {\n for (const i of issues) {\n const path = i.path ? chalk.dim(`${i.path}: `) : \"\";\n console.error(\" \" + path + (i.message ?? \"\"));\n }\n }\n}\n\n/** The Letter wordmark banner. Suppressed in JSON mode. */\nexport function banner() {\n if (jsonMode) return;\n console.log(\"\");\n console.log(\" \" + chalk.bold(\"Letter\") + chalk.red(\".\") + \" \" + chalk.dim(\"CLI\"));\n console.log(\"\");\n}\n\nexport function spinner(text: string): Ora {\n return ora({ text, color: \"cyan\", isEnabled: !jsonMode });\n}\n\n/**\n * Prompts the user and resolves with their input. Returns \"\" immediately on a\n * non-interactive stdin so automated/agent runs don't hang.\n */\nexport function prompt(question: string): Promise<string> {\n if (!process.stdin.isTTY) return Promise.resolve(\"\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Print a management API result. In `--json` mode, emits the raw payload so\n * agents/scripts can parse it. In human mode, renders list envelopes as a\n * compact `id label` table and single resources as pretty JSON.\n */\nexport function emit(data: unknown) {\n if (jsonMode) {\n printJson(data);\n return;\n }\n if (data && typeof data === \"object\" && Array.isArray((data as { data?: unknown }).data)) {\n const env = data as { data: Record<string, unknown>[]; next_cursor?: string | null };\n if (env.data.length === 0) {\n console.log(chalk.dim(\"(none)\"));\n } else {\n for (const row of env.data) {\n const id = String(row.id ?? row.slug ?? row.external_id ?? \"\");\n const label =\n (row.name as string) ??\n (row.email as string) ??\n (row.domain as string) ??\n (row.subject as string) ??\n \"\";\n console.log(`${chalk.bold(id)}${label ? \" \" + label : \"\"}`);\n }\n }\n if (env.next_cursor) {\n console.log(chalk.dim(`\\n› more: --cursor ${env.next_cursor}`));\n }\n return;\n }\n printJson(data);\n}\n\nexport const c = chalk;\n","import Conf from \"conf\";\nimport { homedir } from \"node:os\";\nimport path from \"node:path\";\nimport { mkdir, readFile, writeFile, rm } from \"node:fs/promises\";\nimport { cliCommand } from \"./output.js\";\n\n/** The SDK / API default. When the resolved base equals this we don't bother\n * writing LETTER_BASE_URL into the project env. */\nexport const DEFAULT_BASE_URL = \"https://api.letter.app\";\n\n/* -------------------------------------------------------------------------- */\n/* Non-secret CLI preferences (base URL). */\n/* Stored with `conf`, mirroring how the SDK/MCP resolve their endpoint. */\n/* -------------------------------------------------------------------------- */\n\nconst config = new Conf({\n projectName: \"letterapp-cli\",\n schema: {\n baseUrl: { type: \"string\", default: DEFAULT_BASE_URL },\n },\n});\n\n/** Resolve the API base: explicit flag > env > stored config > prod default. */\nexport function getBaseUrl(flag?: string): string {\n const raw =\n flag ||\n process.env.LETTER_BASE_URL ||\n (config.get(\"baseUrl\") as string) ||\n DEFAULT_BASE_URL;\n return raw.replace(/\\/$/, \"\");\n}\n\nexport function setBaseUrl(url: string): void {\n config.set(\"baseUrl\", url.replace(/\\/$/, \"\"));\n}\n\nexport function getConfigPath(): string {\n return config.path;\n}\n\nexport function resetConfig(): void {\n config.clear();\n}\n\n/* -------------------------------------------------------------------------- */\n/* Secret credential store (~/.letter/credentials.json). */\n/* Written here, read by @letterapp/mcp so the secret never lands in an MCP */\n/* config. Kept separate from `conf` and locked to owner-only permissions. */\n/* -------------------------------------------------------------------------- */\n\nexport type StoredCredential = {\n apiKey: string;\n /** Workspace Personal Access Token (lt_pat_*) for the management API/CLI. */\n pat?: string;\n baseUrl: string;\n project: { slug: string; name: string };\n workspace?: { id: string; name: string };\n savedAt: string;\n};\n\n/**\n * Resolve the project slug a management command should target: explicit\n * `--project` flag > `LETTER_PROJECT` env (for scripts/CI) > the connected\n * project from `letter login`. Throws a clear error when none is available so\n * scripts fail loudly.\n */\nexport async function resolveProjectSlug(flag?: string): Promise<string> {\n if (flag) return flag;\n if (process.env.LETTER_PROJECT) return process.env.LETTER_PROJECT;\n const cred = await readCredential();\n if (cred?.project?.slug) return cred.project.slug;\n throw new Error(\n `No project. Pass --project <slug>, set LETTER_PROJECT, or run \\`${cliCommand()} login\\`.`,\n );\n}\n\nexport function credentialsPath(): string {\n return path.join(homedir(), \".letter\", \"credentials.json\");\n}\n\nexport async function saveCredential(cred: StoredCredential): Promise<string> {\n const file = credentialsPath();\n await mkdir(path.dirname(file), { recursive: true, mode: 0o700 });\n await writeFile(file, `${JSON.stringify(cred, null, 2)}\\n`, { mode: 0o600 });\n return file;\n}\n\nexport async function readCredential(): Promise<StoredCredential | null> {\n try {\n const raw = await readFile(credentialsPath(), \"utf8\");\n return JSON.parse(raw) as StoredCredential;\n } catch {\n return null;\n }\n}\n\nexport async function clearCredential(): Promise<void> {\n await rm(credentialsPath(), { force: true });\n}\n","import { getBaseUrl, readCredential } from \"./config.js\";\nimport { cliCommand } from \"./output.js\";\n\nconst USER_AGENT = \"@letterapp/cli\";\n\n/* -------------------------------------------------------------------------- */\n/* Device authorization (RFC 8628 style). No secret ever passes through argv. */\n/* -------------------------------------------------------------------------- */\n\nexport type StartResponse = {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete: string;\n interval: number;\n expires_in: number;\n};\n\nexport type PollResponse =\n | { status: \"authorization_pending\" }\n | { status: \"slow_down\"; retryAfter?: number }\n | { status: \"access_denied\" }\n | { status: \"expired_token\" }\n | {\n status: \"approved\";\n api_key: string;\n /** Workspace PAT for the management API (lt_pat_*). */\n pat: string;\n base_url: string;\n project: { slug: string; name: string };\n workspace?: { id: string; name: string };\n };\n\n/** Starts a device-authorization flow against the given API base. */\nexport async function startDeviceAuth(base: string): Promise<StartResponse> {\n const res = await fetch(`${base}/v1/cli/auth/start`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", \"user-agent\": USER_AGENT },\n body: \"{}\",\n });\n if (!res.ok) {\n throw new Error(\n `Could not start login (HTTP ${res.status}). Is ${base} reachable?`,\n );\n }\n return (await res.json()) as StartResponse;\n}\n\n/** Polls once for approval. */\nexport async function pollDeviceAuth(\n base: string,\n deviceCode: string,\n): Promise<PollResponse> {\n const res = await fetch(`${base}/v1/cli/auth/poll`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", \"user-agent\": USER_AGENT },\n body: JSON.stringify({ device_code: deviceCode }),\n });\n\n if (res.status === 429) {\n const retryAfter = Number(res.headers.get(\"retry-after\") ?? \"5\");\n return { status: \"slow_down\", retryAfter };\n }\n if (!res.ok) {\n throw new Error(`Login poll failed (HTTP ${res.status}).`);\n }\n return (await res.json()) as PollResponse;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Authenticated client. Resolves the key from the stored credential (written */\n/* by `letter login`) or LETTER_API_KEY. Used by data commands like `status`. */\n/* -------------------------------------------------------------------------- */\n\nexport interface ApiResponse<T = unknown> {\n status: number;\n data: T;\n}\n\nclass LetterClient {\n private maxRetries = 3;\n\n private async resolveAuth(): Promise<{ base: string; token: string }> {\n const cred = await readCredential();\n const token = process.env.LETTER_API_KEY || cred?.apiKey || \"\";\n if (!token) {\n throw new Error(\n `Not connected. Run \\`${cliCommand()} login\\` (or set LETTER_API_KEY) first.`,\n );\n }\n const base = getBaseUrl(process.env.LETTER_API_KEY ? undefined : cred?.baseUrl);\n return { base, token };\n }\n\n private async request<T = unknown>(\n method: string,\n path: string,\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n const { base, token } = await this.resolveAuth();\n const res = await fetch(`${base}${path}`, {\n method,\n headers: {\n authorization: `Bearer ${token}`,\n accept: \"application/json\",\n \"user-agent\": USER_AGENT,\n },\n });\n\n if (res.status === 429 && attempt <= this.maxRetries) {\n const retryAfter = Number(res.headers.get(\"retry-after\") || 2);\n await new Promise((r) => setTimeout(r, retryAfter * 1000 * attempt));\n return this.request<T>(method, path, attempt + 1);\n }\n\n const data = (res.status === 204 ? {} : await res.json()) as T;\n if (!res.ok) {\n throw apiErrorFrom(data, res.status);\n }\n return { status: res.status, data };\n }\n\n get<T = unknown>(path: string) {\n return this.request<T>(\"GET\", path);\n }\n}\n\nexport type ApiIssue = { path?: string; message?: string };\n\n/** Build an Error carrying the API's `error.message` + field-level `issues`. */\nfunction apiErrorFrom(data: unknown, status: number): Error {\n const errObj = (data as {\n error?: { message?: string; issues?: ApiIssue[] };\n })?.error;\n const msg = errObj?.message || `HTTP ${status}`;\n const err = new Error(msg) as Error & {\n status: number;\n issues?: ApiIssue[];\n };\n err.status = status;\n if (Array.isArray(errObj?.issues) && errObj.issues.length > 0) {\n err.issues = errObj.issues;\n }\n return err;\n}\n\nexport const client = new LetterClient();\n\n/* -------------------------------------------------------------------------- */\n/* Management client. Authenticates with the workspace PAT (lt_pat_*) and */\n/* drives the control-plane (/v1/projects, sequences, broadcasts, ...). Used by */\n/* the resource command groups. */\n/* -------------------------------------------------------------------------- */\n\nexport type RequestInitLite = {\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n form?: FormData;\n};\n\nclass ManagementClient {\n private maxRetries = 3;\n\n private async resolveAuth(): Promise<{ base: string; token: string }> {\n const cred = await readCredential();\n const token = process.env.LETTER_PAT || cred?.pat || \"\";\n if (!token) {\n throw new Error(\n `Not connected for management. Run \\`${cliCommand()} login\\` (or set LETTER_PAT) first.`,\n );\n }\n const base = getBaseUrl(process.env.LETTER_PAT ? undefined : cred?.baseUrl);\n return { base, token };\n }\n\n async request<T = unknown>(\n method: string,\n path: string,\n init: RequestInitLite = {},\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n const { base, token } = await this.resolveAuth();\n\n let url = `${base}${path}`;\n if (init.query) {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(init.query)) {\n if (v !== undefined && v !== \"\") qs.set(k, String(v));\n }\n const s = qs.toString();\n if (s) url += `?${s}`;\n }\n\n const headers: Record<string, string> = {\n authorization: `Bearer ${token}`,\n accept: \"application/json\",\n \"user-agent\": USER_AGENT,\n };\n let body: BodyInit | undefined;\n if (init.form) {\n body = init.form;\n } else if (init.body !== undefined) {\n headers[\"content-type\"] = \"application/json\";\n body = JSON.stringify(init.body);\n }\n\n const res = await fetch(url, { method, headers, body });\n\n if (res.status === 429 && attempt <= this.maxRetries) {\n const retryAfter = Number(res.headers.get(\"retry-after\") || 2);\n await new Promise((r) => setTimeout(r, retryAfter * 1000 * attempt));\n return this.request<T>(method, path, init, attempt + 1);\n }\n\n const text = await res.text();\n const data = (text ? JSON.parse(text) : {}) as T;\n if (!res.ok) {\n throw apiErrorFrom(data, res.status);\n }\n return { status: res.status, data };\n }\n\n get<T = unknown>(path: string, query?: RequestInitLite[\"query\"]) {\n return this.request<T>(\"GET\", path, { query });\n }\n post<T = unknown>(path: string, body?: unknown) {\n return this.request<T>(\"POST\", path, { body });\n }\n postForm<T = unknown>(path: string, form: FormData) {\n return this.request<T>(\"POST\", path, { form });\n }\n patch<T = unknown>(path: string, body?: unknown) {\n return this.request<T>(\"PATCH\", path, { body });\n }\n put<T = unknown>(path: string, body?: unknown) {\n return this.request<T>(\"PUT\", path, { body });\n }\n delete<T = unknown>(path: string) {\n return this.request<T>(\"DELETE\", path);\n }\n}\n\nexport const mgmt = new ManagementClient();\n","import { spawn } from \"node:child_process\";\n\n/**\n * Opens `url` in the default browser. Best-effort and non-blocking: if it fails\n * (headless box, no DISPLAY) the caller has already printed the URL so the user\n * can open it manually. Returns true if a launcher was spawned.\n */\nexport function openUrl(url: string): boolean {\n const platform = process.platform;\n let command: string;\n let args: string[];\n\n if (platform === \"darwin\") {\n command = \"open\";\n args = [url];\n } else if (platform === \"win32\") {\n command = \"cmd\";\n // `start` needs an empty title arg; the comma-free form avoids quoting woes.\n args = [\"/c\", \"start\", \"\", url];\n } else {\n command = \"xdg-open\";\n args = [url];\n }\n\n try {\n const child = spawn(command, args, { stdio: \"ignore\", detached: true });\n child.on(\"error\", () => {});\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n","import path from \"node:path\";\nimport { readFile, writeFile, stat } from \"node:fs/promises\";\n\n/**\n * Upserts `key=value` in an env file, creating it if needed. Existing keys are\n * replaced in place; new keys are appended. Returns the file path. The value is\n * never logged by this module - callers print only the key name.\n */\nexport async function upsertEnv(\n cwd: string,\n file: string,\n entries: Record<string, string>,\n): Promise<string> {\n const filePath = path.join(cwd, file);\n let contents = \"\";\n try {\n contents = await readFile(filePath, \"utf8\");\n } catch {\n contents = \"\";\n }\n\n let next = contents;\n for (const [key, value] of Object.entries(entries)) {\n const line = `${key}=${value}`;\n const re = new RegExp(`^${escapeRegExp(key)}=.*$`, \"m\");\n if (re.test(next)) {\n next = next.replace(re, line);\n } else {\n if (next.length && !next.endsWith(\"\\n\")) next += \"\\n\";\n next += `${line}\\n`;\n }\n }\n\n await writeFile(filePath, next, \"utf8\");\n return filePath;\n}\n\n/** True if a file exists at `cwd/name`. */\nexport async function fileExists(cwd: string, name: string): Promise<boolean> {\n try {\n await stat(path.join(cwd, name));\n return true;\n } catch {\n return false;\n }\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { spawn } from \"node:child_process\";\nimport { readFile, readdir } from \"node:fs/promises\";\nimport { fileExists } from \"./env-file.js\";\n\nexport type PackageManager = \"pnpm\" | \"yarn\" | \"bun\" | \"npm\";\n\n/**\n * Detects the package manager from lockfiles (then the `npm_config_user_agent`\n * of the running process), defaulting to npm.\n */\nexport async function detectPackageManager(\n cwd: string,\n): Promise<PackageManager> {\n if (await fileExists(cwd, \"pnpm-lock.yaml\")) return \"pnpm\";\n if (await fileExists(cwd, \"yarn.lock\")) return \"yarn\";\n if (await fileExists(cwd, \"bun.lockb\")) return \"bun\";\n if (await fileExists(cwd, \"package-lock.json\")) return \"npm\";\n\n const ua = process.env.npm_config_user_agent ?? \"\";\n if (ua.startsWith(\"pnpm\")) return \"pnpm\";\n if (ua.startsWith(\"yarn\")) return \"yarn\";\n if (ua.startsWith(\"bun\")) return \"bun\";\n return \"npm\";\n}\n\n/** Detects a likely Node web framework for friendlier guidance. */\nexport async function detectFramework(cwd: string): Promise<string | null> {\n try {\n const pkg = JSON.parse(await readFile(`${cwd}/package.json`, \"utf8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (deps.next) return \"Next.js\";\n if (deps.nuxt) return \"Nuxt\";\n if (deps[\"@remix-run/node\"] || deps[\"@remix-run/react\"]) return \"Remix\";\n if (deps.express) return \"Express\";\n if (deps.fastify) return \"Fastify\";\n if (deps.hono) return \"Hono\";\n if (deps[\"@sveltejs/kit\"]) return \"SvelteKit\";\n return null;\n } catch {\n return null;\n }\n}\n\nexport type Runtime = \"node\" | \"python\" | \"ruby\" | \"go\" | \"php\" | \"other\";\nexport type Stack = { runtime: Runtime; framework: string | null };\n\n/**\n * Detects the project's language/runtime so the CLI installs the right thing\n * (only Node has an SDK today) and prints instructions in the right language.\n * Node is checked first since it's this CLI's primary audience.\n */\nexport async function detectStack(cwd: string): Promise<Stack> {\n if (await fileExists(cwd, \"package.json\")) {\n return { runtime: \"node\", framework: await detectFramework(cwd) };\n }\n if (\n (await fileExists(cwd, \"pyproject.toml\")) ||\n (await fileExists(cwd, \"requirements.txt\")) ||\n (await fileExists(cwd, \"Pipfile\")) ||\n (await fileExists(cwd, \"setup.py\"))\n ) {\n return { runtime: \"python\", framework: await detectPythonFramework(cwd) };\n }\n if ((await fileExists(cwd, \"Gemfile\")) || (await hasGemspec(cwd))) {\n return { runtime: \"ruby\", framework: await detectRubyFramework(cwd) };\n }\n if (await fileExists(cwd, \"go.mod\")) return { runtime: \"go\", framework: null };\n if (await fileExists(cwd, \"composer.json\")) {\n return { runtime: \"php\", framework: await detectPhpFramework(cwd) };\n }\n return { runtime: \"other\", framework: null };\n}\n\n/** Human-friendly label for the detected stack (framework if known). */\nexport function stackLabel(stack: Stack): string {\n if (stack.framework) return stack.framework;\n switch (stack.runtime) {\n case \"node\":\n return \"a Node.js project\";\n case \"python\":\n return \"a Python project\";\n case \"ruby\":\n return \"a Ruby project\";\n case \"go\":\n return \"a Go project\";\n case \"php\":\n return \"a PHP project\";\n default:\n return \"your project\";\n }\n}\n\n/** The language name to tell the agent to write in. */\nexport function languageName(stack: Stack): string {\n switch (stack.runtime) {\n case \"node\":\n return \"TypeScript\";\n case \"python\":\n return \"Python\";\n case \"ruby\":\n return \"Ruby\";\n case \"go\":\n return \"Go\";\n case \"php\":\n return \"PHP\";\n default:\n return \"your language\";\n }\n}\n\nasync function readIf(cwd: string, name: string): Promise<string> {\n try {\n return await readFile(`${cwd}/${name}`, \"utf8\");\n } catch {\n return \"\";\n }\n}\n\nasync function hasGemspec(cwd: string): Promise<boolean> {\n try {\n return (await readdir(cwd)).some((f) => f.endsWith(\".gemspec\"));\n } catch {\n return false;\n }\n}\n\nasync function detectPythonFramework(cwd: string): Promise<string | null> {\n const txt = (\n (await readIf(cwd, \"requirements.txt\")) +\n (await readIf(cwd, \"pyproject.toml\")) +\n (await readIf(cwd, \"Pipfile\"))\n ).toLowerCase();\n if (txt.includes(\"django\")) return \"Django\";\n if (txt.includes(\"fastapi\")) return \"FastAPI\";\n if (txt.includes(\"flask\")) return \"Flask\";\n return null;\n}\n\nasync function detectRubyFramework(cwd: string): Promise<string | null> {\n const txt = (await readIf(cwd, \"Gemfile\")).toLowerCase();\n if (txt.includes(\"rails\")) return \"Rails\";\n if (txt.includes(\"sinatra\")) return \"Sinatra\";\n return null;\n}\n\nasync function detectPhpFramework(cwd: string): Promise<string | null> {\n const txt = (await readIf(cwd, \"composer.json\")).toLowerCase();\n if (txt.includes(\"laravel\")) return \"Laravel\";\n if (txt.includes(\"symfony\")) return \"Symfony\";\n return null;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Non-Node SDK installs (letterapp on PyPI / RubyGems) */\n/* -------------------------------------------------------------------------- */\n\nconst SDK_PYPI = \"letterapp\";\nconst SDK_GEM = \"letterapp\";\n\nexport type SdkInstall = { cmd: string; args: string[]; display: string };\n\nfunction sdkInstall(cmd: string, args: string[]): SdkInstall {\n return { cmd, args, display: `${cmd} ${args.join(\" \")}` };\n}\n\n/**\n * Picks the right Python installer for the project: uv > poetry > pipenv > pip.\n * Returns the command we'd run to add `letterapp`.\n */\nexport async function pythonSdkInstall(cwd: string): Promise<SdkInstall> {\n if (await fileExists(cwd, \"uv.lock\")) return sdkInstall(\"uv\", [\"add\", SDK_PYPI]);\n const pyproject = (await readIf(cwd, \"pyproject.toml\")).toLowerCase();\n if (\n (await fileExists(cwd, \"poetry.lock\")) ||\n pyproject.includes(\"[tool.poetry]\")\n ) {\n return sdkInstall(\"poetry\", [\"add\", SDK_PYPI]);\n }\n if (await fileExists(cwd, \"Pipfile\")) {\n return sdkInstall(\"pipenv\", [\"install\", SDK_PYPI]);\n }\n return sdkInstall(\"pip\", [\"install\", SDK_PYPI]);\n}\n\n/** Bundler when there's a Gemfile, otherwise a plain `gem install`. */\nexport async function rubySdkInstall(cwd: string): Promise<SdkInstall> {\n if (await fileExists(cwd, \"Gemfile\")) {\n return sdkInstall(\"bundle\", [\"add\", SDK_GEM]);\n }\n return sdkInstall(\"gem\", [\"install\", SDK_GEM]);\n}\n\n/** Runs an SdkInstall command, streaming output. Resolves to the exit code. */\nexport function runSdkInstall(\n install: SdkInstall,\n cwd: string,\n): Promise<number> {\n return new Promise((resolve) => {\n const child = spawn(install.cmd, install.args, {\n cwd,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n });\n child.on(\"error\", () => resolve(1));\n child.on(\"close\", (code) => resolve(code ?? 1));\n });\n}\n\nexport function installCommand(pm: PackageManager, pkg: string): string {\n switch (pm) {\n case \"pnpm\":\n return `pnpm add ${pkg}`;\n case \"yarn\":\n return `yarn add ${pkg}`;\n case \"bun\":\n return `bun add ${pkg}`;\n default:\n return `npm install ${pkg}`;\n }\n}\n\n/** Runs the install command, streaming output. Resolves to the exit code. */\nexport function runInstall(\n pm: PackageManager,\n pkg: string,\n cwd: string,\n): Promise<number> {\n const args = pm === \"npm\" ? [\"install\", pkg] : [\"add\", pkg];\n return new Promise((resolve) => {\n const child = spawn(pm, args, {\n cwd,\n stdio: \"inherit\",\n shell: process.platform === \"win32\",\n });\n child.on(\"error\", () => resolve(1));\n child.on(\"close\", (code) => resolve(code ?? 1));\n });\n}\n","import { Command } from \"commander\";\nimport {\n getBaseUrl,\n DEFAULT_BASE_URL,\n saveCredential,\n} from \"../config.js\";\nimport { startDeviceAuth, pollDeviceAuth } from \"../client.js\";\nimport { openUrl } from \"../browser.js\";\nimport { upsertEnv } from \"../env-file.js\";\nimport {\n detectPackageManager,\n detectStack,\n installCommand,\n languageName,\n pythonSdkInstall,\n rubySdkInstall,\n runInstall,\n runSdkInstall,\n stackLabel,\n type SdkInstall,\n type Stack,\n} from \"../pm.js\";\nimport {\n banner,\n c,\n cliCommand,\n log,\n printError,\n printInfo,\n printSuccess,\n printWarning,\n prompt,\n} from \"../output.js\";\n\nconst SDK_PACKAGE = \"@letterapp/node\";\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n// Node projects use .env.local (Next.js convention, gitignored by default);\n// everything else uses the more universal .env.\nfunction envFileFor(stack: Stack): string {\n return stack.runtime === \"node\" ? \".env.local\" : \".env\";\n}\n\ninterface LoginOptions {\n open: boolean;\n install: boolean;\n yes?: boolean;\n baseUrl?: string;\n apiKey?: string;\n}\n\nexport function registerLoginCommand(program: Command) {\n program\n .command(\"login\", { isDefault: true })\n .alias(\"init\")\n .description(\"Connect this project to Letter (interactive device login)\")\n .option(\"--no-open\", \"Don't open the browser; print the URL to open manually\")\n .option(\"-y, --yes\", \"Non-interactive: don't wait for Enter (agents/CI)\")\n .option(\"--no-install\", \"Skip installing the SDK\")\n .option(\"--base-url <url>\", \"Target a self-hosted or local Letter instance\")\n .option(\n \"--api-key <key>\",\n \"CI only: write a key without the device flow (never use in chat)\",\n )\n .action(async (opts: LoginOptions) => {\n const code = await runLogin(opts);\n if (code !== 0) process.exitCode = code;\n });\n}\n\nasync function runLogin(opts: LoginOptions): Promise<number> {\n const base = getBaseUrl(opts.baseUrl);\n const cwd = process.cwd();\n const interactive = process.stdin.isTTY && !opts.yes;\n\n banner();\n\n // CI escape hatch: write the provided key non-interactively. Documented as\n // automation-only; interactive/agent use should rely on the device flow so\n // no secret passes through the command line or chat.\n if (opts.apiKey) {\n const envFile = envFileFor(await detectStack(cwd));\n const entries: Record<string, string> = { LETTER_API_KEY: opts.apiKey };\n if (base !== DEFAULT_BASE_URL) entries.LETTER_BASE_URL = base;\n const file = await upsertEnv(cwd, envFile, entries);\n printSuccess(`Saved LETTER_API_KEY to ${rel(cwd, file)} (--api-key).`);\n printWarning(\n `--api-key is for CI. For interactive setup, run \\`${cliCommand()} login\\`.`,\n );\n return 0;\n }\n\n // 1. Begin the flow.\n let flow;\n try {\n flow = await startDeviceAuth(base);\n } catch (err) {\n printError(err);\n return 1;\n }\n\n log(c.bold(\"Confirm this code in your browser:\"));\n log();\n log(\" \" + c.cyan(c.bold(flow.user_code)));\n log();\n\n // 2. Open the browser (interactive: wait for Enter; otherwise auto/print).\n if (interactive && opts.open) {\n await prompt(c.dim(\"Press Enter to open your browser… \"));\n }\n if (opts.open) openUrl(flow.verification_uri_complete);\n printInfo(\"If your browser didn't open, visit:\");\n log(\" \" + c.blue(flow.verification_uri_complete));\n log();\n printInfo(\"Waiting for you to approve… (Ctrl+C to cancel)\");\n\n // 3. Poll until the user approves/denies or the code expires.\n const deadline = Date.now() + flow.expires_in * 1000;\n let intervalMs = Math.max(1, flow.interval) * 1000;\n\n while (Date.now() < deadline) {\n await sleep(intervalMs);\n let res;\n try {\n res = await pollDeviceAuth(base, flow.device_code);\n } catch (err) {\n printError(err);\n return 1;\n }\n\n if (res.status === \"authorization_pending\") continue;\n if (res.status === \"slow_down\") {\n intervalMs += 1000;\n continue;\n }\n if (res.status === \"access_denied\") {\n printError(new Error(\"Request denied in the browser. Nothing was changed.\"));\n return 1;\n }\n if (res.status === \"expired_token\") {\n printError(new Error(\"This login expired. Run the command again to retry.\"));\n return 1;\n }\n\n return finish(res, cwd, opts.install);\n }\n\n printError(new Error(\"Timed out waiting for approval. Run the command again.\"));\n return 1;\n}\n\nasync function finish(\n approved: {\n api_key: string;\n pat: string;\n base_url: string;\n project: { slug: string; name: string };\n workspace?: { id: string; name: string };\n },\n cwd: string,\n doInstall: boolean,\n): Promise<number> {\n const { api_key: apiKey, pat, base_url: baseUrl, project, workspace } = approved;\n log();\n printSuccess(`Approved for project ${c.bold(project.name)}.`);\n\n const stack = await detectStack(cwd);\n const isNode = stack.runtime === \"node\";\n const envFile = envFileFor(stack);\n\n // Write the key to the project env (value never printed) + shared store.\n const entries: Record<string, string> = { LETTER_API_KEY: apiKey };\n if (baseUrl && baseUrl !== DEFAULT_BASE_URL) entries.LETTER_BASE_URL = baseUrl;\n const written = await upsertEnv(cwd, envFile, entries);\n printSuccess(`Saved LETTER_API_KEY to ${rel(cwd, written)}.`);\n\n try {\n const credFile = await saveCredential({\n apiKey,\n pat,\n baseUrl: baseUrl || DEFAULT_BASE_URL,\n project,\n workspace,\n savedAt: new Date().toISOString(),\n });\n printSuccess(`Stored credentials in ${tildify(credFile)} for tooling (MCP + CLI).`);\n } catch {\n printWarning(\"Could not write ~/.letter/credentials.json (continuing).\");\n }\n\n // Install the SDK for the detected language. Node, Python, and Ruby have\n // official SDKs; everything else integrates over the HTTP API. We capture a\n // one-line `sdkNote` per path and hand the agent a single, language-agnostic\n // prompt - the agent knows the repo and writes idiomatic calls itself.\n let sdkNote: string;\n if (isNode) {\n const pm = await detectPackageManager(cwd);\n if (doInstall) {\n printInfo(`Installing ${SDK_PACKAGE} with ${pm}…`);\n const code = await runInstall(pm, SDK_PACKAGE, cwd);\n if (code === 0) printSuccess(`Installed ${SDK_PACKAGE}.`);\n else printWarning(`Install failed. Run: ${installCommand(pm, SDK_PACKAGE)}`);\n } else {\n printInfo(`Skipped install. Run: ${installCommand(pm, SDK_PACKAGE)}`);\n }\n sdkNote = `the ${SDK_PACKAGE} SDK is installed`;\n } else if (stack.runtime === \"python\" || stack.runtime === \"ruby\") {\n const install =\n stack.runtime === \"python\"\n ? await pythonSdkInstall(cwd)\n : await rubySdkInstall(cwd);\n await installSdk(install, doInstall);\n sdkNote =\n stack.runtime === \"python\"\n ? \"the letterapp Python SDK is installed\"\n : \"the letterapp Ruby gem is installed\";\n } else {\n printInfo(\n `Detected ${stackLabel(stack)}. No ${languageName(stack)} SDK yet, so the agent should use the HTTP API.`,\n );\n sdkNote =\n `there's no official ${languageName(stack)} SDK, so call the HTTP ingestion ` +\n \"API directly (POST /v1/identify and /v1/track with \" +\n \"Authorization: Bearer LETTER_API_KEY and Content-Type: application/json)\";\n }\n\n printAgentHandoff(sdkNote, envFile, cliCommand());\n return 0;\n}\n\n/** Shared install-or-print step for the non-Node SDKs (letterapp). */\nasync function installSdk(install: SdkInstall, doInstall: boolean): Promise<void> {\n if (doInstall) {\n printInfo(`Installing letterapp (${install.display})…`);\n const code = await runSdkInstall(install, process.cwd());\n if (code === 0) printSuccess(\"Installed letterapp.\");\n else printWarning(`Install failed. Run: ${install.display}`);\n } else {\n printInfo(`Skipped install. Run: ${install.display}`);\n }\n}\n\nconst AGENT_DOCS = \"https://letter.app/docs/agent-setup\";\n\n/**\n * Language-agnostic handoff for the last mile. The CLI does the mechanical setup\n * (key in the env, SDK installed where one exists) but deliberately does NOT\n * edit source - the coding agent has the repo context to write idiomatic calls.\n * So we print one ready-to-paste prompt that works for any stack plus a link to\n * the full guide, instead of language-specific snippets.\n */\nfunction printAgentHandoff(\n sdkNote: string,\n envFile: string,\n verifyCmd: string,\n): void {\n const rule = \" \" + \"─\".repeat(68);\n log();\n log(c.bold(\"Next: finish setup with your coding agent\"));\n log();\n log(c.dim(\" Paste this to your agent (Cursor, Claude Code, Codex, OpenClaw, Hermes, …):\"));\n log(c.dim(rule));\n // Plain (uncolored) so it copies cleanly into an agent prompt.\n log(\" Integrate Letter (product email automation) into this app. The CLI\");\n log(` already did setup: LETTER_API_KEY is in ${envFile} and ${sdkNote}.`);\n log(\" Using the right idioms for this codebase:\");\n log(\" - create a shared, server-side Letter client that reads\");\n log(\" LETTER_API_KEY from the environment (only set baseUrl/base_url\");\n log(\" when LETTER_BASE_URL is present),\");\n log(\" - call identify({ userId, email }) where users sign up or log in,\");\n log(\" - call track({ userId, event }) on the 2-3 most important actions,\");\n log(\" - flush before serverless handlers or scripts exit.\");\n log(\" Never print or commit the key. Then verify with the command below.\");\n log(` Full guide: ${AGENT_DOCS}`);\n log(c.dim(rule));\n log();\n log(c.dim(` Prefer to wire it up yourself? Same guide: ${AGENT_DOCS}`));\n log();\n log(c.dim(\"Verify it landed: \") + c.bold(`${verifyCmd} status`));\n log(\n c.dim(\n `Your API key is in ${envFile} - keep it out of source control, and don't echo its value.`,\n ),\n );\n log();\n}\n\nfunction rel(cwd: string, file: string): string {\n return file.startsWith(cwd) ? file.slice(cwd.length + 1) || file : file;\n}\n\nfunction tildify(file: string): string {\n const home = process.env.HOME || process.env.USERPROFILE;\n return home && file.startsWith(home) ? `~${file.slice(home.length)}` : file;\n}\n","import { Command } from \"commander\";\nimport { readCredential, clearCredential } from \"../config.js\";\nimport { c, cliCommand, isJsonMode, printJson, printInfo, printSuccess } from \"../output.js\";\n\nfunction mask(key: string): string {\n return key.length > 12 ? key.slice(0, 8) + \"…\" + key.slice(-4) : \"set\";\n}\n\nexport function registerAuthCommands(program: Command) {\n const auth = program.command(\"auth\").description(\"Manage the stored Letter connection\");\n\n auth\n .command(\"status\")\n .description(\"Show whether this machine is connected to Letter\")\n .action(async () => {\n const cred = await readCredential();\n const envKey = process.env.LETTER_API_KEY;\n\n if (!cred && !envKey) {\n if (isJsonMode()) printJson({ connected: false });\n else printInfo(\"Not connected. Run \" + c.bold(`${cliCommand()} login`) + \" to set up.\");\n return;\n }\n\n if (isJsonMode()) {\n printJson({\n connected: true,\n source: envKey ? \"env\" : \"credentials\",\n project: cred?.project ?? null,\n base_url: cred?.baseUrl ?? null,\n key: envKey ? \"env\" : cred ? mask(cred.apiKey) : null,\n });\n return;\n }\n\n printSuccess(\"Connected\" + (cred ? ` to ${c.bold(cred.project.name)}` : \"\"));\n if (cred) {\n console.log(c.dim(\" Project: \") + cred.project.slug);\n console.log(c.dim(\" Key: \") + mask(cred.apiKey));\n console.log(c.dim(\" API: \") + cred.baseUrl);\n }\n if (envKey) console.log(c.dim(\" LETTER_API_KEY is set in the environment.\"));\n });\n\n auth\n .command(\"logout\")\n .description(\"Remove the stored credential (~/.letter/credentials.json)\")\n .action(async () => {\n await clearCredential();\n printSuccess(\"Removed stored credential.\");\n });\n}\n","import { Command } from \"commander\";\nimport { client } from \"../client.js\";\nimport { readCredential } from \"../config.js\";\nimport { c, isJsonMode, printError, printInfo, printJson, printSuccess, spinner } from \"../output.js\";\n\ntype StatusResponse = {\n contacts?: number;\n events?: number;\n [k: string]: unknown;\n};\n\nexport function registerStatusCommand(program: Command) {\n program\n .command(\"status\")\n .description(\"Check whether your project has received any contacts or events\")\n .action(async () => {\n const spin = spinner(\"Checking your Letter project…\").start();\n try {\n const { data } = await client.get<StatusResponse>(\"/v1/status\");\n spin.stop();\n\n if (isJsonMode()) {\n printJson(data);\n return;\n }\n\n const cred = await readCredential();\n const contacts = data.contacts ?? 0;\n const events = data.events ?? 0;\n\n if (cred) printInfo(`Project ${c.bold(cred.project.name)}`);\n if (contacts > 0 || events > 0) {\n printSuccess(`Connected. ${contacts} contact(s), ${events} event(s) received.`);\n } else {\n printInfo(\"Connected, but no data yet. Fire your first identify/track call.\");\n }\n } catch (err) {\n spin.stop();\n printError(err);\n process.exitCode = 1;\n }\n });\n}\n","import { Command } from \"commander\";\nimport {\n getBaseUrl,\n setBaseUrl,\n getConfigPath,\n resetConfig,\n} from \"../config.js\";\nimport { c, isJsonMode, printError, printJson, printSuccess } from \"../output.js\";\n\nexport function registerConfigCommands(program: Command) {\n const cfg = program.command(\"config\").description(\"Manage CLI configuration\");\n\n cfg\n .command(\"set\")\n .description(\"Set a config value\")\n .argument(\"<key>\", \"Config key: base-url\")\n .argument(\"<value>\", \"Value to set\")\n .action((key: string, value: string) => {\n switch (key) {\n case \"base-url\":\n setBaseUrl(value);\n printSuccess(`Base URL set to ${getBaseUrl()}`);\n break;\n default:\n printError(new Error(`Unknown config key: ${key}. Valid keys: base-url`));\n process.exitCode = 1;\n }\n });\n\n cfg\n .command(\"get\")\n .description(\"Show CLI configuration\")\n .argument(\"[key]\", \"Config key (omit to show all)\")\n .action((key?: string) => {\n const all = { base_url: getBaseUrl(), config_path: getConfigPath() };\n if (key && key !== \"base-url\" && key !== \"path\") {\n printError(new Error(`Unknown config key: ${key}`));\n process.exitCode = 1;\n return;\n }\n if (isJsonMode()) {\n printJson(key === \"base-url\" ? { base_url: all.base_url } : key === \"path\" ? { config_path: all.config_path } : all);\n return;\n }\n if (key === \"base-url\") console.log(all.base_url);\n else if (key === \"path\") console.log(all.config_path);\n else for (const [k, v] of Object.entries(all)) console.log(c.bold(k + \":\") + \" \" + v);\n });\n\n cfg\n .command(\"reset\")\n .description(\"Reset CLI configuration to defaults\")\n .action(() => {\n resetConfig();\n printSuccess(\"Configuration reset.\");\n });\n}\n","import { readFile } from \"node:fs/promises\";\nimport { Command } from \"commander\";\nimport { mgmt } from \"../client.js\";\nimport { resolveProjectSlug } from \"../config.js\";\nimport {\n c,\n cliCommand,\n emit,\n isJsonMode,\n log,\n printError,\n printInfo,\n printJson,\n printSuccess,\n} from \"../output.js\";\nimport { markdownToTipTap } from \"../markdown.js\";\n\n/**\n * Resource command groups for the management API. Each group wraps the same\n * REST endpoints the dashboard uses (`/v1/...`), so the whole app is operable\n * from the terminal. Everything honors the global `--json` flag (see\n * `output.emit`) and project-scoped groups take `--project <slug>` (defaulting\n * to the project connected by `letter login`).\n *\n * The shape is data-driven: one `ResourceSpec` per resource, expanded into\n * `list/get/create/update/delete` + custom verb subcommands by `register()`.\n * Keeping it declarative means a new endpoint is a few lines, not a new file.\n */\n\ntype Field = {\n /** commander option flag, e.g. \"--name <name>\". */\n flag: string;\n /** request-body key, e.g. \"name\". */\n key: string;\n /** parse the value as JSON (supports `@file.json` to read from disk). */\n json?: boolean;\n /** coerce to a number. */\n number?: boolean;\n /** coerce to a boolean. */\n boolean?: boolean;\n /** (multipart only) read the value as a file path and upload its bytes. */\n file?: boolean;\n description?: string;\n};\n\ntype Action = {\n name: string;\n describe: string;\n method: \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\";\n /** Path suffix appended after the resource (and id, if `needsId`). */\n suffix: string;\n /** Whether the verb operates on a single item (default true). */\n needsId?: boolean;\n fields?: Field[];\n /** Query params for GET verbs. */\n query?: Field[];\n /** Send fields as multipart/form-data (for file uploads). */\n multipart?: boolean;\n};\n\ntype ResourceSpec = {\n /** Command group name (also the default path segment). */\n name: string;\n describe: string;\n /** Nested under /v1/projects/{slug} when true. */\n scoped: boolean;\n /** Path segment if different from `name`. */\n segment?: string;\n /** Hidden back-compat alias for the group name. */\n alias?: string;\n /** Positional id arg name (e.g. \"externalId\", \"email\"). Default \"id\". */\n idName?: string;\n list?: { paginated?: boolean; query?: Field[] };\n get?: boolean;\n create?: Field[];\n update?: Field[];\n remove?: boolean;\n actions?: Action[];\n};\n\nasync function readValue(raw: string): Promise<string> {\n if (raw.startsWith(\"@\")) return (await readFile(raw.slice(1), \"utf8\")).trim();\n return raw;\n}\n\nasync function buildBody(\n fields: Field[],\n opts: Record<string, unknown>,\n): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = {};\n for (const f of fields) {\n const v = opts[camel(f.key)];\n if (v === undefined) continue;\n if (f.json) {\n body[f.key] = JSON.parse(await readValue(String(v)));\n } else if (f.number) {\n body[f.key] = Number(v);\n } else if (f.boolean) {\n body[f.key] = v === true || v === \"true\";\n } else {\n body[f.key] = await readValue(String(v));\n }\n }\n return body;\n}\n\nasync function buildForm(\n fields: Field[],\n opts: Record<string, unknown>,\n): Promise<FormData> {\n const form = new FormData();\n for (const f of fields) {\n const v = opts[camel(f.key)];\n if (v === undefined) continue;\n if (f.file) {\n const path = String(v);\n const bytes = await readFile(path);\n const name = path.split(\"/\").pop() || f.key;\n form.append(f.key, new Blob([new Uint8Array(bytes)]), name);\n } else if (f.json) {\n // The server parses these fields with JSON.parse; keep them as strings.\n form.append(f.key, await readValue(String(v)));\n } else {\n form.append(f.key, String(v));\n }\n }\n return form;\n}\n\nfunction buildQuery(\n fields: Field[],\n opts: Record<string, unknown>,\n): Record<string, string | number | undefined> {\n const q: Record<string, string | number | undefined> = {};\n for (const f of fields) {\n const v = opts[camel(f.key)];\n if (v === undefined) continue;\n q[f.key] = f.number ? Number(v) : String(v);\n }\n return q;\n}\n\n/** \"external-id\" / \"external_id\" → \"externalId\" (commander camelCases flags). */\nfunction camel(key: string): string {\n return key.replace(/[-_]([a-z])/g, (_, ch: string) => ch.toUpperCase());\n}\n\nfunction applyFields(cmd: Command, fields: Field[]) {\n for (const f of fields) {\n cmd.option(f.flag, f.description ?? f.key);\n }\n}\n\nasync function basePath(spec: ResourceSpec, project?: string): Promise<string> {\n const seg = spec.segment ?? spec.name;\n if (!spec.scoped) return `/v1/${seg}`;\n const slug = await resolveProjectSlug(project);\n return `/v1/projects/${slug}/${seg}`;\n}\n\nfunction withProject(cmd: Command, scoped: boolean): Command {\n if (scoped) {\n cmd.option(\"-p, --project <slug>\", \"Project slug (default: connected project)\");\n }\n return cmd;\n}\n\nfunction fail(err: unknown) {\n printError(err);\n process.exitCode = 1;\n}\n\nfunction register(program: Command, spec: ResourceSpec) {\n const group = program.command(spec.name).description(spec.describe);\n if (spec.alias) group.alias(spec.alias);\n const idName = spec.idName ?? \"id\";\n\n if (spec.list) {\n const cmd = withProject(\n group.command(\"list\").description(`List ${spec.name}`),\n spec.scoped,\n );\n if (spec.list.paginated) {\n cmd.option(\"--limit <n>\", \"Max items (1-100)\");\n cmd.option(\"--cursor <cursor>\", \"Pagination cursor\");\n }\n if (spec.list.query) applyFields(cmd, spec.list.query);\n cmd.action(async (opts) => {\n try {\n const query: Record<string, string | number | undefined> = {};\n if (spec.list?.paginated) {\n if (opts.limit) query.limit = Number(opts.limit);\n if (opts.cursor) query.cursor = opts.cursor;\n }\n if (spec.list?.query) Object.assign(query, buildQuery(spec.list.query, opts));\n const { data } = await mgmt.get(await basePath(spec, opts.project), query);\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n }\n\n if (spec.get) {\n const cmd = withProject(\n group\n .command(\"get\")\n .description(`Get a ${spec.name} by ${idName}`)\n .argument(`<${idName}>`, idName),\n spec.scoped,\n );\n cmd.action(async (idValue: string, opts) => {\n try {\n const path = `${await basePath(spec, opts.project)}/${encodeURIComponent(idValue)}`;\n const { data } = await mgmt.get(path);\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n }\n\n if (spec.create) {\n const cmd = withProject(\n group.command(\"create\").description(`Create a ${spec.name}`),\n spec.scoped,\n );\n applyFields(cmd, spec.create);\n cmd.action(async (opts) => {\n try {\n const body = await buildBody(spec.create!, opts);\n const { data } = await mgmt.post(await basePath(spec, opts.project), body);\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n }\n\n if (spec.update) {\n const cmd = withProject(\n group\n .command(\"update\")\n .description(`Update a ${spec.name}`)\n .argument(`<${idName}>`, idName),\n spec.scoped,\n );\n applyFields(cmd, spec.update);\n cmd.action(async (idValue: string, opts) => {\n try {\n const body = await buildBody(spec.update!, opts);\n const path = `${await basePath(spec, opts.project)}/${encodeURIComponent(idValue)}`;\n const { data } = await mgmt.patch(path, body);\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n }\n\n if (spec.remove) {\n const cmd = withProject(\n group\n .command(\"delete\")\n .description(`Delete a ${spec.name}`)\n .argument(`<${idName}>`, idName),\n spec.scoped,\n );\n cmd.action(async (idValue: string, opts) => {\n try {\n const path = `${await basePath(spec, opts.project)}/${encodeURIComponent(idValue)}`;\n await mgmt.delete(path);\n printSuccess(`Deleted ${spec.name.replace(/s$/, \"\")} ${idValue}.`);\n } catch (err) {\n fail(err);\n }\n });\n }\n\n for (const action of spec.actions ?? []) {\n const needsId = action.needsId ?? true;\n const cmd = withProject(\n needsId\n ? group\n .command(action.name)\n .description(action.describe)\n .argument(`<${idName}>`, idName)\n : group.command(action.name).description(action.describe),\n spec.scoped,\n );\n if (action.fields) applyFields(cmd, action.fields);\n if (action.query) applyFields(cmd, action.query);\n\n const handler = async (...args: unknown[]) => {\n // commander passes (idValue?, opts, command). Last arg is the Command.\n const opts = args[args.length - 2] as Record<string, unknown>;\n const idValue = needsId ? (args[0] as string) : undefined;\n try {\n let path = await basePath(spec, opts.project as string | undefined);\n if (needsId) path += `/${encodeURIComponent(idValue!)}`;\n path += action.suffix;\n\n if (action.method === \"get\") {\n const query = action.query ? buildQuery(action.query, opts) : undefined;\n const { data } = await mgmt.get(path, query);\n emit(data);\n return;\n }\n if (action.multipart && action.fields) {\n const form = await buildForm(action.fields, opts);\n const { data, status } = await mgmt.request(\n action.method.toUpperCase(),\n path,\n { form },\n );\n if (status === 204) printSuccess(`${action.name} ok.`);\n else emit(data);\n return;\n }\n const body = action.fields ? await buildBody(action.fields, opts) : undefined;\n const { data, status } = await mgmt.request(\n action.method.toUpperCase(),\n path,\n { body },\n );\n if (status === 204) printSuccess(`${action.name} ok.`);\n else emit(data);\n } catch (err) {\n fail(err);\n }\n };\n cmd.action(handler);\n }\n}\n\nconst cursor = { paginated: true } as const;\n\nconst SPECS: ResourceSpec[] = [\n // -- Workspace ------------------------------------------------------------\n {\n name: \"projects\",\n describe: \"Manage projects\",\n scoped: false,\n idName: \"slug\",\n list: {},\n get: true,\n create: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--timezone <tz>\", key: \"timezone\" },\n ],\n update: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--timezone <tz>\", key: \"timezone\" },\n ],\n remove: true,\n },\n {\n name: \"members\",\n describe: \"Manage workspace members\",\n scoped: false,\n idName: \"userId\",\n list: {},\n create: [\n { flag: \"--email <email>\", key: \"email\" },\n { flag: \"--role <role>\", key: \"role\", description: \"member | admin\" },\n ],\n remove: true,\n },\n {\n name: \"invitations\",\n describe: \"Manage workspace invitations\",\n scoped: false,\n list: {},\n create: [\n { flag: \"--email <email>\", key: \"email\" },\n { flag: \"--role <role>\", key: \"role\", description: \"member | admin\" },\n ],\n remove: true,\n },\n {\n // Personal access tokens (lt_pat_*) authenticate the CLI / Management API.\n // The dashboard calls these \"API keys\"; `tokens` stays as a hidden alias.\n name: \"api-keys\",\n alias: \"tokens\",\n segment: \"tokens\",\n describe: \"Manage your personal access tokens (lt_pat_*, the CLI/API credential)\",\n scoped: false,\n list: {},\n create: [\n { flag: \"--name <name>\", key: \"name\" },\n {\n flag: \"--expires-at <iso>\",\n key: \"expires_at\",\n description: \"Expiry as an ISO 8601 datetime (default: never)\",\n },\n ],\n remove: true,\n },\n // -- Contacts & data ------------------------------------------------------\n {\n name: \"contacts\",\n describe: \"Manage contacts\",\n scoped: true,\n idName: \"externalId\",\n list: { ...cursor },\n get: true,\n actions: [\n {\n name: \"suppress\",\n describe: \"Suppress a contact\",\n method: \"post\",\n suffix: \"/suppress\",\n },\n {\n name: \"resubscribe\",\n describe: \"Resubscribe a contact\",\n method: \"post\",\n suffix: \"/resubscribe\",\n },\n {\n name: \"import\",\n describe: \"Upload a CSV import (--file <path> --mapping <json|@file>)\",\n method: \"post\",\n needsId: false,\n suffix: \"/imports\",\n multipart: true,\n fields: [\n { flag: \"--file <path>\", key: \"file\", file: true },\n { flag: \"--mapping <json>\", key: \"mapping\", json: true },\n { flag: \"--dedupe <strategy>\", key: \"dedupe\", description: \"update | skip\" },\n { flag: \"--row-count <n>\", key: \"rowCount\" },\n ],\n },\n ],\n },\n {\n name: \"accounts\",\n describe: \"Inspect accounts\",\n scoped: true,\n idName: \"externalId\",\n list: { ...cursor },\n get: true,\n },\n {\n name: \"events\",\n describe: \"List events\",\n scoped: true,\n list: { ...cursor, query: [{ flag: \"--name <name>\", key: \"name\" }] },\n },\n {\n name: \"suppressions\",\n describe: \"Manage the suppression list\",\n scoped: true,\n idName: \"email\",\n list: { ...cursor },\n create: [{ flag: \"--email <email>\", key: \"email\" }],\n remove: true,\n },\n {\n name: \"segments\",\n describe: \"Manage segments\",\n scoped: true,\n list: {},\n get: true,\n create: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--filter <json>\", key: \"filter\", json: true },\n ],\n update: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--filter <json>\", key: \"filter\", json: true },\n ],\n remove: true,\n actions: [\n {\n name: \"preview\",\n describe: \"Count contacts matching a filter (--filter <json|@file>)\",\n method: \"post\",\n needsId: false,\n suffix: \"/preview\",\n fields: [{ flag: \"--filter <json>\", key: \"filter\", json: true }],\n },\n ],\n },\n // -- Sequences ------------------------------------------------------------\n {\n name: \"sequences\",\n describe: \"Manage drip sequences\",\n scoped: true,\n list: {},\n get: true,\n create: [{ flag: \"--name <name>\", key: \"name\" }],\n update: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--status <status>\", key: \"status\", description: \"active | archived\" },\n ],\n remove: true,\n // `draft`, `preview`, `test-email`, `validate`, `schema`, and `scaffold`\n // are hand-written in `attachSequenceExtras` (they need draft-aware\n // behaviour the generic machinery can't express).\n actions: [\n {\n name: \"publish\",\n describe: \"Publish the current draft\",\n method: \"post\",\n suffix: \"/publish\",\n },\n {\n name: \"activity\",\n describe: \"Show enrollment activity\",\n method: \"get\",\n suffix: \"/activity\",\n },\n {\n name: \"versions\",\n describe: \"List published versions\",\n method: \"get\",\n suffix: \"/versions\",\n },\n ],\n },\n // -- Broadcasts -----------------------------------------------------------\n {\n name: \"broadcasts\",\n describe: \"Manage broadcasts\",\n scoped: true,\n list: {},\n get: true,\n create: [{ flag: \"--name <name>\", key: \"name\" }],\n update: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--subject <subject>\", key: \"subject\" },\n { flag: \"--preview <preview>\", key: \"preview\" },\n { flag: \"--audience <json>\", key: \"audience\", json: true },\n { flag: \"--template-id <id>\", key: \"template_id\" },\n { flag: \"--body-doc <json>\", key: \"body_doc\", json: true },\n ],\n remove: true,\n actions: [\n {\n name: \"preflight\",\n describe: \"Validate before sending\",\n method: \"post\",\n suffix: \"/preflight\",\n },\n {\n name: \"schedule\",\n describe: \"Schedule (--scheduled-at <iso>) or send now (omit)\",\n method: \"post\",\n suffix: \"/schedule\",\n fields: [{ flag: \"--scheduled-at <iso>\", key: \"scheduled_at\" }],\n },\n {\n name: \"cancel\",\n describe: \"Cancel a scheduled or sending broadcast\",\n method: \"post\",\n suffix: \"/cancel\",\n },\n {\n name: \"live\",\n describe: \"Live status, stats, and recent activity\",\n method: \"get\",\n suffix: \"/live\",\n },\n ],\n },\n // -- Templates ------------------------------------------------------------\n {\n name: \"templates\",\n describe: \"Manage email templates\",\n scoped: true,\n list: {},\n get: true,\n create: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--design <json>\", key: \"design\", json: true },\n ],\n update: [\n { flag: \"--name <name>\", key: \"name\" },\n { flag: \"--design <json>\", key: \"design\", json: true },\n ],\n remove: true,\n actions: [\n {\n name: \"default\",\n describe: \"Set as the project default\",\n method: \"post\",\n suffix: \"/default\",\n },\n {\n name: \"reset\",\n describe: \"Reset design to a preset (--preset plain|branded)\",\n method: \"post\",\n suffix: \"/reset\",\n fields: [{ flag: \"--preset <preset>\", key: \"preset\" }],\n },\n {\n name: \"logo\",\n describe: \"Upload a logo (--file <path>)\",\n method: \"post\",\n suffix: \"/logo\",\n multipart: true,\n fields: [{ flag: \"--file <path>\", key: \"file\", file: true }],\n },\n {\n name: \"remove-logo\",\n describe: \"Remove the template logo\",\n method: \"delete\",\n suffix: \"/logo\",\n },\n ],\n },\n // -- Settings -------------------------------------------------------------\n {\n name: \"domains\",\n describe: \"Manage sending domains\",\n scoped: true,\n list: {},\n create: [{ flag: \"--domain <domain>\", key: \"domain\" }],\n remove: true,\n actions: [\n {\n name: \"verify\",\n describe: \"Re-check DKIM verification\",\n method: \"post\",\n suffix: \"/verify\",\n },\n ],\n },\n {\n // Project ingestion keys (lt_live_*) authenticate the SDKs / ingestion API.\n // The dashboard calls these \"Project tokens\"; `keys` stays as a hidden alias.\n name: \"project-tokens\",\n alias: \"keys\",\n segment: \"keys\",\n describe: \"Manage project ingestion keys (lt_live_*, the SDK/ingestion credential)\",\n scoped: true,\n list: {},\n create: [{ flag: \"--name <name>\", key: \"name\" }],\n remove: true,\n },\n];\n\n/**\n * Canonical sequence shapes, printed by `sequences schema`. This is the\n * reference an agent reaches for instead of reverse-engineering the graph\n * from 400s. Mirrors the strict server validation + the /docs/sequences guide.\n */\nconst SEQUENCE_SCHEMA = {\n trigger: {\n event: {\n type: \"event\",\n eventName: \"modification_limit_reached\",\n oncePerContact: true,\n \"filter?\": \"FilterSpec — optional audience filter on the contact's traits/history\",\n \"where?\":\n \"Condition(s) on the firing event's own properties, e.g. { property: 'plan', op: 'eq', value: 'free' } (single object or array, AND-ed)\",\n },\n contact_created: {\n type: \"contact_created\",\n \"filter?\": \"FilterSpec — optional audience filter on the contact\",\n },\n },\n nodeConfigs: {\n trigger: { type: \"trigger\" },\n email: {\n type: \"email\",\n subject: \"You hit your limit\",\n \"preview?\": \"Here's how to lift it\",\n \"bodyDoc?\": { type: \"doc\", content: [\"…TipTap nodes…\"] },\n \"templateId?\": \"uuid | null (omit for project default)\",\n },\n wait: { type: \"wait\", duration: { value: 1, unit: \"minutes | hours | days\" } },\n wait_event: {\n type: \"wait_event\",\n eventName: \"completed_onboarding\",\n timeout: { value: 7, unit: \"minutes | hours | days\" },\n },\n branch: {\n type: \"branch\",\n condition: {\n event: { kind: \"event\", eventName: \"Upgraded\", occurred: true, \"window?\": { value: 2, unit: \"days\" } },\n trait: { kind: \"trait\", scope: \"contact | account\", path: \"plan\", op: \"eq | neq | contains | not_contains | exists | not_exists\", \"value?\": \"pro\" },\n },\n },\n exit: { type: \"exit\", \"reason?\": \"done\" },\n },\n edge: {\n id: \"e1\",\n source: \"trigger\",\n target: \"email1\",\n \"branch?\":\n \"yes | no (branch node) · received | timeout (wait_event node) — omit for single-leg nodes\",\n },\n notes: [\n \"config.type must equal the node's type.\",\n \"The email body field is `bodyDoc` (camelCase); a wait nests `duration`; a wait_event nests `timeout`.\",\n \"Draft saves reject unknown / mis-cased keys with a 400.\",\n \"Trait/filter values compare as strings: use value:\\\"false\\\" (not false) for a boolean trait. `letter traits list` shows keys + types.\",\n \"Event triggers can also gate on the event's own properties via `where` (e.g. only plan=free).\",\n \"wait_event pauses the contact until `eventName` fires (the `received` leg) or `timeout` elapses (the `timeout` leg). Only events that occur after the contact reaches the step count.\",\n \"Publish requires: one trigger, every node reachable, every path ends at an exit, each branch has one yes + one no edge, each wait_event has one received + one timeout edge, and each email has a subject + non-empty bodyDoc.\",\n \"`sequences validate <id>` dry-runs those publish checks; `sequences scaffold` builds a valid trigger → [wait] → email → exit graph in one command.\",\n ],\n example: {\n trigger: {\n type: \"event\",\n eventName: \"modification_limit_reached\",\n oncePerContact: true,\n filter: { kind: \"trait\", path: \"plan\", op: \"eq\", value: \"free\" },\n },\n graph: {\n nodes: [\n { id: \"trigger\", type: \"trigger\", position: { x: 280, y: 80 }, config: { type: \"trigger\" } },\n { id: \"wait1\", type: \"wait\", position: { x: 280, y: 200 }, config: { type: \"wait\", duration: { value: 1, unit: \"hours\" } } },\n {\n id: \"email1\",\n type: \"email\",\n position: { x: 280, y: 320 },\n config: {\n type: \"email\",\n subject: \"You hit your limit\",\n bodyDoc: { type: \"doc\", content: [{ type: \"paragraph\", content: [{ type: \"text\", text: \"Upgrade to keep going.\" }] }] },\n },\n },\n { id: \"exit1\", type: \"exit\", position: { x: 280, y: 440 }, config: { type: \"exit\" } },\n ],\n edges: [\n { id: \"e1\", source: \"trigger\", target: \"wait1\" },\n { id: \"e2\", source: \"wait1\", target: \"email1\" },\n { id: \"e3\", source: \"email1\", target: \"exit1\" },\n ],\n },\n },\n} as const;\n\nfunction printSequenceSchemaHuman() {\n log(\"Sequence authoring shapes (see /docs/sequences for the full guide).\\n\");\n log(\"Trigger (how contacts enter):\");\n log(JSON.stringify(SEQUENCE_SCHEMA.trigger, null, 2));\n log(\"\\nNode configs (config.type must match the node type):\");\n log(JSON.stringify(SEQUENCE_SCHEMA.nodeConfigs, null, 2));\n log(\"\\nEdge:\");\n log(JSON.stringify(SEQUENCE_SCHEMA.edge, null, 2));\n log(\"\\nNotes:\");\n for (const n of SEQUENCE_SCHEMA.notes) log(` • ${n}`);\n log(\"\\nKnown-good example (trigger + graph):\");\n log(JSON.stringify(SEQUENCE_SCHEMA.example, null, 2));\n log(`\\nScaffold one in a single command:`);\n log(\n ` ${cliCommand()} sequences scaffold --name \"Limit reached\" \\\\\\n` +\n ` --event modification_limit_reached --audience-trait plan=free \\\\\\n` +\n ` --wait 1h --subject \"You hit your limit\" \\\\\\n` +\n ` --body-md \"Upgrade to **keep going**.\" --publish`,\n );\n}\n\n/** Parse a human duration like `30m`, `1h`, `2d` into the wait/branch shape. */\nfunction parseDuration(raw: string): {\n value: number;\n unit: \"minutes\" | \"hours\" | \"days\";\n} {\n const m = /^(\\d+)\\s*(m|min|mins|minute|minutes|h|hr|hrs|hour|hours|d|day|days)$/i.exec(\n raw.trim(),\n );\n if (!m) {\n throw new Error(`Invalid --wait \"${raw}\". Use e.g. 30m, 1h, or 2d.`);\n }\n const u = (m[2] ?? \"\").toLowerCase();\n const unit = u.startsWith(\"d\") ? \"days\" : u.startsWith(\"h\") ? \"hours\" : \"minutes\";\n return { value: Number(m[1]), unit };\n}\n\n/** Trait shorthand `path=value` (also `!=` and `~` for contains). Values are\n * always strings — Letter compares trait values as strings, so `isPro=false`\n * matches the boolean trait `false`. Use `--audience @file.json` for the full\n * FilterSpec (exists / groups / event history). */\nfunction parseAudienceTrait(raw: string): Record<string, unknown> {\n const m = /^([^=!~]+?)\\s*(!=|~|=)\\s*(.*)$/.exec(raw);\n if (!m) {\n throw new Error(\n \"--audience-trait must be path=value (also path!=value or path~value), e.g. plan=free\",\n );\n }\n const op = m[2] === \"!=\" ? \"neq\" : m[2] === \"~\" ? \"contains\" : \"eq\";\n return { kind: \"trait\", path: (m[1] ?? \"\").trim(), op, value: m[3] ?? \"\" };\n}\n\nfunction attachSequenceExtras(program: Command) {\n const seq = program.commands.find((cmd) => cmd.name() === \"sequences\");\n if (!seq) return;\n\n seq\n .command(\"draft <id>\")\n .description(\n \"Save the draft graph + trigger (auto-fetches the current revision unless --expected-revision is given)\",\n )\n .option(\"--graph <json>\", \"Graph JSON (inline or @file.json)\")\n .option(\"--trigger <json>\", \"Trigger JSON (inline or @file.json)\")\n .option(\n \"--expected-revision <n>\",\n \"Optimistic-concurrency revision (default: current; use a number to assert)\",\n )\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (id: string, opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const base = `/v1/projects/${slug}/sequences`;\n const body: Record<string, unknown> = {};\n if (opts.graph !== undefined) {\n body.graph = JSON.parse(await readValue(String(opts.graph)));\n }\n if (opts.trigger !== undefined) {\n body.trigger = JSON.parse(await readValue(String(opts.trigger)));\n }\n const explicit = opts.expectedRevision;\n if (explicit !== undefined && String(explicit) !== \"auto\") {\n body.expected_revision = Number(explicit);\n } else {\n const { data } = await mgmt.get(`${base}/${encodeURIComponent(id)}`);\n body.expected_revision =\n (data as { draft_revision?: number }).draft_revision ?? 0;\n }\n const { data } = await mgmt.put(\n `${base}/${encodeURIComponent(id)}/draft`,\n body,\n );\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n\n seq\n .command(\"preview <id>\")\n .description(\"Render an email node to HTML/text\")\n .requiredOption(\"--node-id <id>\", \"Email node id (e.g. email1)\")\n .option(\n \"--config <json>\",\n \"Inline email config (inline or @file.json); omit to render the saved draft\",\n )\n .option(\"--to <email>\", \"Recipient address to cast in the preview\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (id: string, opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const base = `/v1/projects/${slug}/sequences`;\n const body: Record<string, unknown> = { node_id: String(opts.nodeId) };\n if (opts.config !== undefined) {\n body.config = JSON.parse(await readValue(String(opts.config)));\n }\n if (opts.to !== undefined) body.recipient_email = String(opts.to);\n const { data } = await mgmt.post(\n `${base}/${encodeURIComponent(id)}/preview`,\n body,\n );\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n\n seq\n .command(\"test-email <id>\")\n .description(\"Send a [Test] copy of an email node\")\n .requiredOption(\"--node-id <id>\", \"Email node id (e.g. email1)\")\n .option(\"--to <email>\", \"Recipient (default: your account email)\")\n .option(\n \"--config <json>\",\n \"Inline email config (inline or @file.json); omit to send the saved draft\",\n )\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (id: string, opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const base = `/v1/projects/${slug}/sequences`;\n const body: Record<string, unknown> = { node_id: String(opts.nodeId) };\n if (opts.to !== undefined) body.recipient_email = String(opts.to);\n if (opts.config !== undefined) {\n body.config = JSON.parse(await readValue(String(opts.config)));\n }\n const { data } = await mgmt.post(\n `${base}/${encodeURIComponent(id)}/test-email`,\n body,\n );\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n\n seq\n .command(\"validate <id>\")\n .description(\"Dry-run the publish checks against the current draft (no changes)\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (id: string, opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const { data } = await mgmt.get(\n `/v1/projects/${slug}/sequences/${encodeURIComponent(id)}/validate`,\n );\n if (isJsonMode()) {\n printJson(data);\n return;\n }\n const result = data as {\n ok: boolean;\n errors: { code: string; message: string; nodeId?: string }[];\n };\n if (result.ok) {\n printSuccess(\"Draft is publish-ready.\");\n return;\n }\n printError(`Not publish-ready (${result.errors.length} issue(s)):`);\n for (const e of result.errors) {\n const where = e.nodeId ? c.dim(` [${e.nodeId}]`) : \"\";\n log(` • ${e.message}${where}`);\n }\n process.exitCode = 1;\n } catch (err) {\n fail(err);\n }\n });\n\n seq\n .command(\"schema\")\n .description(\"Print the canonical trigger / node / edge shapes + an example\")\n .action(() => {\n if (isJsonMode()) printJson(SEQUENCE_SCHEMA);\n else printSequenceSchemaHuman();\n });\n\n seq\n .command(\"scaffold\")\n .description(\n \"Create + draft (and optionally publish) a trigger → [wait] → email → exit sequence\",\n )\n .requiredOption(\"--name <name>\", \"Sequence name\")\n .option(\n \"--event <name>\",\n \"Event-trigger name (omit for a contact_created trigger)\",\n )\n .option(\"--no-once-per-contact\", \"Allow re-enrolment on every event\")\n .option(\"--audience <json>\", \"Audience FilterSpec (inline JSON or @file.json)\")\n .option(\n \"--audience-trait <path=value>\",\n \"Shorthand audience filter: trait equals value (e.g. plan=free)\",\n )\n .option(\"--wait <duration>\", \"Delay before the email, e.g. 30m, 1h, 2d\")\n .requiredOption(\"--subject <subject>\", \"Email subject\")\n .option(\"--body-md <markdown>\", \"Email body as Markdown (converted to rich text)\")\n .option(\"--body-text <text>\", \"Email body as plain text\")\n .option(\"--publish\", \"Publish immediately after drafting\")\n .option(\"--dry-run\", \"Print the trigger + graph it would create, without creating anything\")\n .option(\"--if-not-exists\", \"Reuse an existing sequence with the same name instead of duplicating\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const base = `/v1/projects/${slug}/sequences`;\n\n // Audience filter (full FilterSpec wins over the trait shorthand).\n let filter: unknown;\n if (opts.audience !== undefined) {\n filter = JSON.parse(await readValue(String(opts.audience)));\n } else if (opts.audienceTrait !== undefined) {\n filter = parseAudienceTrait(String(opts.audienceTrait));\n }\n\n const trigger = opts.event\n ? {\n type: \"event\",\n eventName: String(opts.event),\n oncePerContact: opts.oncePerContact !== false,\n ...(filter ? { filter } : {}),\n }\n : { type: \"contact_created\", ...(filter ? { filter } : {}) };\n\n const bodyDoc =\n opts.bodyMd !== undefined\n ? markdownToTipTap(String(opts.bodyMd))\n : opts.bodyText !== undefined\n ? markdownToTipTap(String(opts.bodyText))\n : undefined;\n\n const nodes: Record<string, unknown>[] = [\n { id: \"trigger\", type: \"trigger\", position: { x: 280, y: 80 }, config: { type: \"trigger\" } },\n ];\n const edges: Record<string, unknown>[] = [];\n let prev = \"trigger\";\n let y = 200;\n if (opts.wait !== undefined) {\n nodes.push({\n id: \"wait1\",\n type: \"wait\",\n position: { x: 280, y },\n config: { type: \"wait\", duration: parseDuration(String(opts.wait)) },\n });\n edges.push({ id: \"e_wait\", source: prev, target: \"wait1\" });\n prev = \"wait1\";\n y += 120;\n }\n nodes.push({\n id: \"email1\",\n type: \"email\",\n position: { x: 280, y },\n config: {\n type: \"email\",\n subject: String(opts.subject),\n ...(bodyDoc ? { bodyDoc } : {}),\n },\n });\n edges.push({ id: \"e_email\", source: prev, target: \"email1\" });\n prev = \"email1\";\n y += 120;\n nodes.push({\n id: \"exit1\",\n type: \"exit\",\n position: { x: 280, y },\n config: { type: \"exit\" },\n });\n edges.push({ id: \"e_exit\", source: prev, target: \"exit1\" });\n const graph = { nodes, edges };\n\n // --dry-run: show exactly what would be sent, mutate nothing.\n if (opts.dryRun) {\n if (isJsonMode()) printJson({ slug, name: String(opts.name), trigger, graph });\n else {\n log(\"Would create sequence \" + c.bold(String(opts.name)) + \" with:\\n\");\n log(\"trigger:\");\n log(JSON.stringify(trigger, null, 2));\n log(\"\\ngraph:\");\n log(JSON.stringify(graph, null, 2));\n }\n return;\n }\n\n // --if-not-exists: reuse a same-named sequence instead of duplicating.\n let id: string | undefined;\n let reused = false;\n if (opts.ifNotExists) {\n const { data } = await mgmt.get(base);\n const rows = (data as { data?: { id: string; name: string }[] }).data ?? [];\n const match = rows.find((r) => r.name === String(opts.name));\n if (match) {\n id = match.id;\n reused = true;\n }\n }\n if (!id) {\n const created = await mgmt.post(base, { name: String(opts.name) });\n id = (created.data as { id: string }).id;\n }\n // Save the draft at the sequence's current revision (0 for brand-new).\n const detail = await mgmt.get(`${base}/${id}`);\n const rev = (detail.data as { draft_revision?: number }).draft_revision ?? 0;\n await mgmt.put(`${base}/${id}/draft`, {\n graph,\n trigger,\n expected_revision: rev,\n });\n let published = false;\n if (opts.publish) {\n await mgmt.request(\"POST\", `${base}/${id}/publish`, {});\n published = true;\n }\n\n if (isJsonMode()) {\n printJson({ id, slug, reused, published, trigger, graph });\n return;\n }\n const verb = reused ? \"Updated existing sequence\" : \"Created sequence\";\n printSuccess(\n `${verb} ${id}${published ? \" and published it\" : \" (draft saved)\"}.`,\n );\n if (!published) {\n printInfo(`Publish when ready: ${cliCommand()} sequences publish ${id}`);\n printInfo(`Dry-run the publish checks: ${cliCommand()} sequences validate ${id}`);\n }\n printInfo(\n `Tweak it on the canvas, or re-draft with ${cliCommand()} sequences draft ${id} --graph @graph.json`,\n );\n } catch (err) {\n fail(err);\n }\n });\n}\n\nfunction attachTraits(program: Command) {\n const traits = program\n .command(\"traits\")\n .description(\"Discover trait keys for audience filters and branch conditions\");\n traits\n .command(\"list\")\n .description(\"List distinct contact/account trait keys with type + sample\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (opts: Record<string, unknown>) => {\n try {\n const slug = await resolveProjectSlug(opts.project as string | undefined);\n const { data } = await mgmt.get(`/v1/projects/${slug}/traits`);\n const rows =\n (data as {\n data?: {\n key: string;\n scope: string;\n type: string;\n count: number;\n sample: string | null;\n }[];\n }).data ?? [];\n if (isJsonMode()) {\n printJson(rows);\n return;\n }\n if (rows.length === 0) {\n log(c.dim(\"(no traits yet)\"));\n return;\n }\n log(c.dim(\"Values are compared as strings (e.g. boolean false → \\\"false\\\").\\n\"));\n for (const r of rows) {\n const head = `${c.bold(r.key)} ${c.dim(`(${r.scope} ${r.type})`)}`;\n const sample = r.sample != null ? ` e.g. ${JSON.stringify(r.sample)}` : \"\";\n log(`${head} ×${r.count}${sample}`);\n }\n } catch (err) {\n fail(err);\n }\n });\n}\n\nexport function registerResourceCommands(program: Command) {\n for (const spec of SPECS) register(program, spec);\n attachSequenceExtras(program);\n attachTraits(program);\n\n // `letter me` — the token's identity (handy sanity check).\n program\n .command(\"me\")\n .description(\"Show the token's user, workspace, and role\")\n .action(async () => {\n try {\n const { data } = await mgmt.get(\"/v1/me\");\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n\n // Sender identity + sending mode don't fit the CRUD mold: register directly.\n program\n .command(\"sender-identity\")\n .description(\"Set From / From-name / Reply-To (--from-email, --from-name, --reply-to-email)\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .option(\"--from-email <email>\", \"From address\")\n .option(\"--from-name <name>\", \"From display name\")\n .option(\"--reply-to-email <email>\", \"Reply-To address\")\n .action(async (opts) => {\n try {\n const slug = await resolveProjectSlug(opts.project);\n const body: Record<string, unknown> = {};\n if (opts.fromEmail !== undefined) body.from_email = opts.fromEmail;\n if (opts.fromName !== undefined) body.from_name = opts.fromName;\n if (opts.replyToEmail !== undefined) body.reply_to_email = opts.replyToEmail;\n const { data } = await mgmt.put(`/v1/projects/${slug}/sender-identity`, body);\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"sending-mode\")\n .description(\"Set the sending mode (letter_subdomain | byo_domain)\")\n .argument(\"<mode>\", \"letter_subdomain | byo_domain\")\n .option(\"-p, --project <slug>\", \"Project slug (default: connected project)\")\n .action(async (mode: string, opts) => {\n try {\n const slug = await resolveProjectSlug(opts.project);\n const { data } = await mgmt.put(`/v1/projects/${slug}/sending-mode`, {\n sending_mode: mode,\n });\n emit(data);\n } catch (err) {\n fail(err);\n }\n });\n}\n","/**\n * Minimal Markdown -> TipTap/ProseMirror converter, so email bodies can be\n * authored from the CLI without hand-writing ProseMirror JSON.\n *\n * It targets the subset the Letter email renderer (TipTap StarterKit + Link)\n * understands: headings (#..###), paragraphs, bullet/ordered lists,\n * blockquotes, horizontal rules, and inline **bold**, *italic*, `code`, and\n * [links](url) plus hard line breaks. It is intentionally small - for anything\n * richer, pass a full `bodyDoc` JSON to `sequences draft` instead.\n */\n\nexport type TipTapMark = { type: string; attrs?: Record<string, unknown> };\nexport type TipTapNode = {\n type: string;\n attrs?: Record<string, unknown>;\n marks?: TipTapMark[];\n text?: string;\n content?: TipTapNode[];\n};\nexport type TipTapDoc = { type: \"doc\"; content: TipTapNode[] };\n\nconst HR = /^\\s*([-*_])\\1{2,}\\s*$/;\nconst HEADING = /^(#{1,3})\\s+(.*)$/;\nconst QUOTE = /^\\s*>\\s?/;\nconst BULLET = /^\\s*[-*+]\\s+/;\nconst ORDERED = /^\\s*\\d+\\.\\s+/;\n\nfunction isBlockStart(line: string): boolean {\n return (\n /^#{1,3}\\s+/.test(line) ||\n BULLET.test(line) ||\n ORDERED.test(line) ||\n QUOTE.test(line) ||\n HR.test(line)\n );\n}\n\nfunction pushText(nodes: TipTapNode[], text: string, marks?: TipTapMark[]) {\n if (!text) return;\n nodes.push(marks ? { type: \"text\", text, marks } : { type: \"text\", text });\n}\n\n/**\n * Parse inline marks within a single line. Recursive so marks nest correctly:\n * `**[text](url)**` becomes one text node carrying both `bold` and `link`,\n * rather than a literal `[text](url)` string inside a bold run. `carried` is\n * the set of marks inherited from the enclosing span.\n */\nfunction inline(text: string, carried: TipTapMark[] = []): TipTapNode[] {\n const nodes: TipTapNode[] = [];\n // Non-greedy bodies so `**a** **b**` splits into two runs and an outer\n // mark can contain a nested token (e.g. a link inside bold). Code first so\n // `**` inside backticks isn't treated as bold; then links, bold, italic.\n const token =\n /(`[^`]+`)|(\\[[^\\]]+\\]\\([^)]+\\))|(\\*\\*[\\s\\S]+?\\*\\*)|(__[\\s\\S]+?__)|(\\*[\\s\\S]+?\\*)|(_[\\s\\S]+?_)/;\n let rest = text;\n while (rest.length > 0) {\n const m = token.exec(rest);\n if (!m) {\n pushText(nodes, rest, carried.length ? carried : undefined);\n break;\n }\n if (m.index > 0) {\n pushText(nodes, rest.slice(0, m.index), carried.length ? carried : undefined);\n }\n const tok = m[0];\n if (tok.startsWith(\"`\")) {\n pushText(nodes, tok.slice(1, -1), [...carried, { type: \"code\" }]);\n } else if (tok.startsWith(\"[\")) {\n const lm = /\\[([^\\]]+)\\]\\(([^)]+)\\)/.exec(tok);\n if (lm) {\n nodes.push(\n ...inline(lm[1] ?? \"\", [\n ...carried,\n { type: \"link\", attrs: { href: lm[2] ?? \"\" } },\n ]),\n );\n }\n } else if (tok.startsWith(\"**\") || tok.startsWith(\"__\")) {\n nodes.push(...inline(tok.slice(2, -2), [...carried, { type: \"bold\" }]));\n } else {\n nodes.push(...inline(tok.slice(1, -1), [...carried, { type: \"italic\" }]));\n }\n rest = rest.slice(m.index + tok.length);\n }\n return nodes;\n}\n\n/** Inline-parse multiple lines, joining them with hard breaks. */\nfunction inlineMultiline(lines: string[]): TipTapNode[] {\n const out: TipTapNode[] = [];\n lines.forEach((line, idx) => {\n if (idx > 0) out.push({ type: \"hardBreak\" });\n out.push(...inline(line));\n });\n return out;\n}\n\nfunction listItems(\n lines: string[],\n start: number,\n marker: RegExp,\n): { items: TipTapNode[]; next: number } {\n const items: TipTapNode[] = [];\n let i = start;\n for (let cur = lines[i]; cur !== undefined && marker.test(cur); cur = lines[i]) {\n items.push({\n type: \"listItem\",\n content: [{ type: \"paragraph\", content: inline(cur.replace(marker, \"\")) }],\n });\n i++;\n }\n return { items, next: i };\n}\n\nexport function markdownToTipTap(input: string): TipTapDoc {\n // Shells don't expand `\\n` inside double quotes, so accept literal escapes.\n const src = input.replace(/\\\\n/g, \"\\n\").replace(/\\\\t/g, \"\\t\");\n const lines = src.split(\"\\n\");\n const blocks: TipTapNode[] = [];\n let i = 0;\n while (i < lines.length) {\n const line = lines[i] ?? \"\";\n if (line.trim() === \"\") {\n i++;\n continue;\n }\n if (HR.test(line)) {\n blocks.push({ type: \"horizontalRule\" });\n i++;\n continue;\n }\n const h = HEADING.exec(line);\n if (h) {\n blocks.push({\n type: \"heading\",\n attrs: { level: (h[1] ?? \"#\").length },\n content: inline(h[2] ?? \"\"),\n });\n i++;\n continue;\n }\n if (QUOTE.test(line)) {\n const quote: string[] = [];\n for (let cur = lines[i]; cur !== undefined && QUOTE.test(cur); cur = lines[i]) {\n quote.push(cur.replace(QUOTE, \"\"));\n i++;\n }\n blocks.push({\n type: \"blockquote\",\n content: [{ type: \"paragraph\", content: inline(quote.join(\" \")) }],\n });\n continue;\n }\n if (BULLET.test(line)) {\n const { items, next } = listItems(lines, i, BULLET);\n blocks.push({ type: \"bulletList\", content: items });\n i = next;\n continue;\n }\n if (ORDERED.test(line)) {\n const { items, next } = listItems(lines, i, ORDERED);\n blocks.push({ type: \"orderedList\", content: items });\n i = next;\n continue;\n }\n // Paragraph: gather consecutive plain lines, join with hard breaks.\n const para: string[] = [];\n for (let cur = lines[i]; cur !== undefined && cur.trim() !== \"\" && !isBlockStart(cur); cur = lines[i]) {\n para.push(cur);\n i++;\n }\n blocks.push({ type: \"paragraph\", content: inlineMultiline(para) });\n }\n return { type: \"doc\", content: blocks };\n}\n"],"mappings":"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","names":["path","path","path","readFile","writeFile","spawn","readFile","readFile","spawn","program","program","program","program","readFile","readFile","path","program","data","status"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letterapp/cli",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Letter CLI - connect your app to Letter in one command. Interactive, secure device login: no API key ever touches your shell or chat.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://letter.app",