@program-video/cli 0.1.0 → 0.1.2
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 +1 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -204,14 +204,7 @@ var BASE_URL = getEnvOrDefault(
|
|
|
204
204
|
"BASE_URL",
|
|
205
205
|
"https://program.video"
|
|
206
206
|
);
|
|
207
|
-
|
|
208
|
-
const override = process.env.PROGRAM_CONVEX_URL;
|
|
209
|
-
if (override) return override;
|
|
210
|
-
const convexUrl = process.env.NEXT_PUBLIC_CONVEX_URL;
|
|
211
|
-
if (convexUrl) return convexUrl;
|
|
212
|
-
return "https://mild-hyena-697.convex.cloud";
|
|
213
|
-
}
|
|
214
|
-
var CONVEX_URL = getConvexUrl();
|
|
207
|
+
var CONVEX_URL = "https://keen-eel-920.convex.cloud";
|
|
215
208
|
var oauthConfig = {
|
|
216
209
|
baseUrl: BASE_URL
|
|
217
210
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/auth/login.ts","../src/lib/auth/credentials.ts","../src/lib/auth/device.ts","../src/lib/config.ts","../src/lib/output.ts","../src/commands/auth/logout.ts","../src/commands/auth/status.ts","../src/commands/project/create.ts","../src/lib/auth/oauth.ts","../src/lib/auth/pkce.ts","../src/lib/auth/callback-server.ts","../src/lib/convex.ts","../src/commands/project/get.ts","../src/commands/project/list.ts","../src/commands/workflow/list.ts","../src/commands/workflow/run.ts","../src/commands/workflow/status.ts","../src/commands/tool/execute.ts","../src/lib/agent-detect.ts","../src/commands/tool/list.ts","../src/commands/message/send.ts","../src/commands/message/list.ts","../src/commands/docs.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { loginCommand } from \"./commands/auth/login.js\";\nimport type { LoginOptions } from \"./commands/auth/login.js\";\nimport { logoutCommand } from \"./commands/auth/logout.js\";\nimport type { LogoutOptions } from \"./commands/auth/logout.js\";\nimport { statusCommand as authStatusCommand } from \"./commands/auth/status.js\";\nimport type { StatusOptions as AuthStatusOptions } from \"./commands/auth/status.js\";\nimport { createCommand as projectCreateCommand } from \"./commands/project/create.js\";\nimport type { CreateOptions } from \"./commands/project/create.js\";\nimport { getCommand as projectGetCommand } from \"./commands/project/get.js\";\nimport type { GetOptions } from \"./commands/project/get.js\";\nimport { listCommand as projectListCommand } from \"./commands/project/list.js\";\nimport type { ListOptions as ProjectListOptions } from \"./commands/project/list.js\";\nimport { listCommand as workflowListCommand } from \"./commands/workflow/list.js\";\nimport type { ListOptions as WorkflowListOptions } from \"./commands/workflow/list.js\";\nimport { runCommand as workflowRunCommand } from \"./commands/workflow/run.js\";\nimport type { RunOptions } from \"./commands/workflow/run.js\";\nimport { statusCommand as workflowStatusCommand } from \"./commands/workflow/status.js\";\nimport type { StatusOptions as WorkflowStatusOptions } from \"./commands/workflow/status.js\";\nimport { executeCommand as toolExecuteCommand } from \"./commands/tool/execute.js\";\nimport type { ExecuteOptions } from \"./commands/tool/execute.js\";\nimport { listCommand as toolListCommand } from \"./commands/tool/list.js\";\nimport type { ListOptions as ToolListOptions } from \"./commands/tool/list.js\";\nimport { sendCommand as messageSendCommand } from \"./commands/message/send.js\";\nimport type { SendMessageOptions } from \"./commands/message/send.js\";\nimport { listCommand as messageListCommand } from \"./commands/message/list.js\";\nimport type { ListMessageOptions } from \"./commands/message/list.js\";\nimport { docsCommand } from \"./commands/docs.js\";\nimport type { DocsOptions } from \"./commands/docs.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"program\")\n .description(\"CLI for the Program video creation platform\")\n .version(\"0.1.0\");\n\n// Auth commands\nconst auth = program.command(\"auth\").description(\"Authentication commands\");\n\nauth\n .command(\"login\")\n .description(\"Authenticate with the Program platform\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: LoginOptions) => {\n await loginCommand(options);\n });\n\nauth\n .command(\"logout\")\n .description(\"Log out from the Program platform\")\n .option(\"--json\", \"Output as JSON\")\n .action((options: LogoutOptions) => {\n logoutCommand(options);\n });\n\nauth\n .command(\"status\")\n .description(\"Check authentication status\")\n .option(\"--json\", \"Output as JSON\")\n .action((options: AuthStatusOptions) => {\n authStatusCommand(options);\n });\n\n// Project commands\nconst project = program.command(\"project\").description(\"Project management commands\");\n\nproject\n .command(\"create\")\n .description(\"Create a new project\")\n .option(\"--title <title>\", \"Project title\")\n .option(\"--description <description>\", \"Project description\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: CreateOptions) => {\n await projectCreateCommand(options);\n });\n\nproject\n .command(\"list\")\n .description(\"List projects\")\n .option(\"--limit <limit>\", \"Maximum number of projects to return\", parseInt)\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: ProjectListOptions) => {\n await projectListCommand(options);\n });\n\nproject\n .command(\"get <id>\")\n .description(\"Get project details including composition\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (id: string, options: GetOptions) => {\n await projectGetCommand(id, options);\n });\n\n// Workflow commands\nconst workflow = program.command(\"workflow\").description(\"Workflow template commands\");\n\nworkflow\n .command(\"list\")\n .description(\"List available workflow templates\")\n .option(\"--limit <limit>\", \"Maximum number of templates to return\", parseInt)\n .option(\"--public-only\", \"Only show public templates\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: WorkflowListOptions) => {\n await workflowListCommand(options);\n });\n\nworkflow\n .command(\"run <templateId>\")\n .description(\"Execute a workflow template\")\n .option(\"--project <projectId>\", \"Project ID to associate with execution\")\n .option(\"--input <json>\", \"JSON input for the workflow\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (templateId: string, options: RunOptions) => {\n await workflowRunCommand(templateId, options);\n });\n\nworkflow\n .command(\"status <executionId>\")\n .description(\"Check workflow execution status\")\n .option(\"--watch\", \"Continuously poll for status updates\")\n .option(\"--interval <ms>\", \"Poll interval in milliseconds\", parseInt)\n .option(\"--json\", \"Output as JSON\")\n .action(async (executionId: string, options: WorkflowStatusOptions) => {\n await workflowStatusCommand(executionId, options);\n });\n\n// Tool commands (direct agent tool access)\nconst tool = program.command(\"tool\").description(\"Execute agent tools directly\");\n\ntool\n .command(\"list\")\n .description(\"List available agent tools\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: ToolListOptions) => {\n await toolListCommand(options);\n });\n\ntool\n .command(\"exec <toolName>\")\n .description(\"Execute an agent tool\")\n .requiredOption(\"--project <projectId>\", \"Project ID to execute tool against\")\n .option(\"--params <json>\", \"JSON parameters for the tool\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (toolName: string, options: ExecuteOptions) => {\n await toolExecuteCommand(toolName, options);\n });\n\n// Message commands (send and list messages in project chat)\nconst message = program.command(\"message\").description(\"Manage messages in project chat\");\n\nmessage\n .command(\"list\")\n .description(\"List messages in the project chat\")\n .requiredOption(\"--project <projectId>\", \"Project ID to list messages from\")\n .option(\"--limit <limit>\", \"Maximum number of messages to return\", parseInt)\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: ListMessageOptions) => {\n await messageListCommand(options);\n });\n\nmessage\n .command(\"send <text>\")\n .description(\n \"Log a text message to the project chat. NOTE: This only adds a message to the chat history - it does NOT trigger the AI agent. To perform actions, use 'tool exec' instead.\",\n )\n .requiredOption(\"--project <projectId>\", \"Project ID to send message to\")\n .option(\"--role <role>\", \"Message role: user or assistant (default: assistant)\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (text: string, options: SendMessageOptions) => {\n await messageSendCommand(text, options);\n });\n\n// Docs command\nprogram\n .command(\"docs\")\n .description(\"Display CLI documentation and command schema\")\n .option(\"--schema\", \"Output full command schema as JSON\")\n .option(\"--json\", \"Output as JSON\")\n .action((options: DocsOptions) => {\n docsCommand(options);\n });\n\n// Parse arguments\nprogram.parse();\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { startDeviceAuth } from \"../../lib/auth/device.js\";\nimport { oauthConfig } from \"../../lib/config.js\";\nimport { formatSuccess, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type { OutputOptions } from \"../../lib/output.js\";\n\nexport type LoginOptions = OutputOptions;\n\n/**\n * Format user code with dash for readability (ABCD1234 -> ABCD-1234)\n */\nfunction formatUserCode(code: string): string {\n if (code.length === 8) {\n return `${code.slice(0, 4)}-${code.slice(4)}`;\n }\n return code;\n}\n\n/**\n * Device authorization flow - works everywhere including headless environments\n * User visits a URL on any device and enters the code shown in the terminal\n */\nexport async function loginCommand(options: LoginOptions): Promise<void> {\n const spinner = ora(\"Requesting device code...\").start();\n\n try {\n const deviceAuth = await startDeviceAuth(oauthConfig);\n spinner.stop();\n\n // Display the code and URL for the user\n console.log();\n console.log(chalk.bold(\" Sign in to Program\"));\n console.log();\n console.log(` Visit: ${chalk.cyan(deviceAuth.verificationUrl)}`);\n console.log();\n console.log(` Enter code: ${chalk.bold.yellow(formatUserCode(deviceAuth.userCode))}`);\n console.log();\n\n // If there's a complete URL with the code embedded, also show that\n if (deviceAuth.verificationUrlComplete) {\n console.log(chalk.dim(` Or open: ${deviceAuth.verificationUrlComplete}`));\n console.log();\n }\n\n const waitingSpinner = ora(\"Waiting for authorization...\").start();\n\n // Poll until the user completes auth\n const credentials = await deviceAuth.pollForCompletion();\n\n waitingSpinner.stop();\n\n if (options.json) {\n outputSuccess(\n {\n authenticated: true,\n email: credentials.email,\n userId: credentials.userId,\n organizationId: credentials.organizationId,\n },\n options\n );\n } else {\n console.log(formatSuccess(`Authenticated as ${chalk.cyan(credentials.email)}`));\n if (credentials.organizationId) {\n console.log(chalk.dim(` Organization: ${credentials.organizationId}`));\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Authentication failed\";\n outputError(message, options);\n process.exit(1);\n }\n}\n","import Conf from \"conf\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\n\nexport interface Credentials {\n accessToken: string;\n refreshToken: string;\n expiresAt: number;\n userId: string;\n organizationId: string;\n email: string;\n}\n\n// Use ~/.program/ for credentials storage\nconst CREDENTIALS_DIR = path.join(os.homedir(), \".program\");\nconst CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, \"credentials.json\");\n\n// Ensure directory exists with proper permissions\nfunction ensureCredentialsDir(): void {\n if (!fs.existsSync(CREDENTIALS_DIR)) {\n fs.mkdirSync(CREDENTIALS_DIR, { mode: 0o700, recursive: true });\n }\n}\n\n// Using conf for secure credential storage with automatic file permissions\nconst store = new Conf<{ credentials: Credentials | null }>({\n projectName: \"program-cli\",\n cwd: CREDENTIALS_DIR,\n configName: \"credentials\",\n fileExtension: \"json\",\n defaults: {\n credentials: null,\n },\n});\n\nexport function saveCredentials(credentials: Credentials): void {\n ensureCredentialsDir();\n store.set(\"credentials\", credentials);\n\n // Ensure file has restrictive permissions (owner read/write only)\n try {\n fs.chmodSync(CREDENTIALS_FILE, 0o600);\n } catch {\n // Ignore chmod errors on Windows\n }\n}\n\nexport function getCredentials(): Credentials | null {\n return store.get(\"credentials\");\n}\n\nexport function clearCredentials(): void {\n store.delete(\"credentials\");\n}\n\nexport function isAuthenticated(): boolean {\n const creds = getCredentials();\n if (!creds) return false;\n\n // Check if token is expired (with 5 minute buffer)\n const now = Date.now();\n const expiresAt = creds.expiresAt * 1000; // Convert to milliseconds\n const bufferMs = 5 * 60 * 1000; // 5 minutes\n\n return now < expiresAt - bufferMs;\n}\n\nexport function needsRefresh(): boolean {\n const creds = getCredentials();\n if (!creds) return false;\n\n // Needs refresh if within 5 minutes of expiry\n const now = Date.now();\n const expiresAt = creds.expiresAt * 1000;\n const bufferMs = 5 * 60 * 1000;\n\n return now >= expiresAt - bufferMs && now < expiresAt;\n}\n","import { saveCredentials, getCredentials } from \"./credentials.js\";\nimport type { Credentials } from \"./credentials.js\";\n\n// OAuth client ID - same as the main oauth.ts\nconst CLIENT_ID = \"program-cli\";\nconst SCOPES = [\"openid\", \"profile\", \"email\", \"offline_access\"];\n\nexport interface DeviceAuthConfig {\n baseUrl: string;\n}\n\ninterface DeviceCodeResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete?: string;\n expires_in: number;\n interval: number;\n}\n\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n token_type?: string;\n scope?: string;\n}\n\ninterface TokenErrorResponse {\n error: string;\n error_description?: string;\n}\n\ninterface UserInfo {\n id: string;\n email: string;\n name: string;\n organizationId?: string;\n}\n\n/**\n * Request a device code from the server\n */\nexport async function requestDeviceCode(\n config: DeviceAuthConfig\n): Promise<DeviceCodeResponse> {\n const url = new URL(\"/api/auth/device/code\", config.baseUrl);\n\n const response = await fetch(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n client_id: CLIENT_ID,\n scope: SCOPES.join(\" \"),\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to get device code: ${response.status} ${errorText}`);\n }\n\n return response.json() as Promise<DeviceCodeResponse>;\n}\n\n/**\n * Poll for the token after user authorizes\n * Returns the token response or an error code\n */\nexport async function pollForToken(\n config: DeviceAuthConfig,\n deviceCode: string\n): Promise<TokenResponse | TokenErrorResponse> {\n const url = new URL(\"/api/auth/device/token\", config.baseUrl);\n\n const response = await fetch(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n device_code: deviceCode,\n client_id: CLIENT_ID,\n }),\n });\n\n // Device flow uses 400 status for pending/slow_down errors\n const data = (await response.json()) as TokenResponse | TokenErrorResponse;\n\n if (!response.ok) {\n // Check if it's an expected error (authorization_pending, slow_down)\n if (\"error\" in data) {\n return data;\n }\n throw new Error(`Token request failed: ${response.status}`);\n }\n\n return data as TokenResponse;\n}\n\n/**\n * Get user info from the BetterAuth session endpoint\n * Device authorization returns a BetterAuth token, not an OIDC token\n */\nasync function getUserInfo(\n config: DeviceAuthConfig,\n accessToken: string\n): Promise<UserInfo> {\n // Use the BetterAuth get-session endpoint with Bearer token\n const sessionUrl = new URL(\"/api/auth/get-session\", config.baseUrl);\n\n const response = await fetch(sessionUrl.toString(), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!response.ok) {\n // Try the token/session endpoint if get-session doesn't work\n const tokenUrl = new URL(\"/api/auth/token\", config.baseUrl);\n const tokenResponse = await fetch(tokenUrl.toString(), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!tokenResponse.ok) {\n throw new Error(`Failed to get user info: ${response.status}`);\n }\n\n const tokenData = (await tokenResponse.json()) as {\n user?: { id?: string; email?: string; name?: string };\n session?: { activeOrganizationId?: string };\n };\n\n if (!tokenData.user?.id || !tokenData.user.email) {\n throw new Error(\"Invalid token response: missing user info\");\n }\n\n return {\n id: tokenData.user.id,\n email: tokenData.user.email,\n name: tokenData.user.name ?? tokenData.user.email,\n organizationId: tokenData.session?.activeOrganizationId,\n };\n }\n\n const data = (await response.json()) as {\n user?: {\n id?: string;\n email?: string;\n name?: string;\n };\n session?: {\n activeOrganizationId?: string;\n };\n };\n\n if (!data.user?.id || !data.user.email) {\n throw new Error(\"Invalid session response: missing user info\");\n }\n\n return {\n id: data.user.id,\n email: data.user.email,\n name: data.user.name ?? data.user.email,\n organizationId: data.session?.activeOrganizationId,\n };\n}\n\n/**\n * Start the device authorization flow\n * Returns display info for the CLI to show the user\n */\nexport interface DeviceAuthDisplay {\n userCode: string;\n verificationUrl: string;\n verificationUrlComplete?: string;\n expiresIn: number;\n interval: number;\n pollForCompletion: () => Promise<Credentials>;\n}\n\nexport async function startDeviceAuth(\n config: DeviceAuthConfig\n): Promise<DeviceAuthDisplay> {\n const deviceCode = await requestDeviceCode(config);\n\n return {\n userCode: deviceCode.user_code,\n verificationUrl: deviceCode.verification_uri,\n verificationUrlComplete: deviceCode.verification_uri_complete,\n expiresIn: deviceCode.expires_in,\n interval: deviceCode.interval,\n pollForCompletion: async () => {\n return pollUntilComplete(config, deviceCode);\n },\n };\n}\n\n/**\n * Poll until the user completes authorization or the code expires\n */\nasync function pollUntilComplete(\n config: DeviceAuthConfig,\n deviceCode: DeviceCodeResponse\n): Promise<Credentials> {\n const startTime = Date.now();\n const expiresAt = startTime + deviceCode.expires_in * 1000;\n let interval = deviceCode.interval * 1000;\n\n while (Date.now() < expiresAt) {\n // Wait for the interval before polling\n await new Promise((resolve) => setTimeout(resolve, interval));\n\n const result = await pollForToken(config, deviceCode.device_code);\n\n // Check if it's an error response\n if (\"error\" in result) {\n switch (result.error) {\n case \"authorization_pending\":\n // User hasn't completed authorization yet, continue polling\n continue;\n\n case \"slow_down\":\n // Server asked us to slow down, increase interval\n interval += 5000;\n continue;\n\n case \"expired_token\":\n throw new Error(\"Device code expired. Please start a new login.\");\n\n case \"access_denied\":\n throw new Error(\"Access denied. You denied the authorization request.\");\n\n default:\n throw new Error(\n result.error_description ?? `Authorization failed: ${result.error}`\n );\n }\n }\n\n // Success! We got tokens\n const tokens = result;\n\n // Get user info\n const userInfo = await getUserInfo(config, tokens.access_token);\n\n // Calculate expiry timestamp (default to 1 hour if not provided)\n const expiresIn = tokens.expires_in ?? 3600;\n const expiresAtTimestamp = Math.floor(Date.now() / 1000) + expiresIn;\n\n // Save credentials (refresh token may not be present for device flow)\n const credentials: Credentials = {\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? \"\",\n expiresAt: expiresAtTimestamp,\n userId: userInfo.id,\n organizationId: userInfo.organizationId ?? \"\",\n email: userInfo.email,\n };\n\n saveCredentials(credentials);\n\n return credentials;\n }\n\n throw new Error(\"Device code expired. Please start a new login.\");\n}\n\n/**\n * Check if we have valid credentials\n */\nexport function hasValidCredentials(): boolean {\n const creds = getCredentials();\n if (!creds) return false;\n\n // Check if token is expired (with 5 min buffer)\n const now = Date.now();\n const expiresAt = creds.expiresAt * 1000;\n const bufferMs = 5 * 60 * 1000;\n\n return now < expiresAt - bufferMs;\n}\n","import type { OAuthConfig } from \"./auth/index.js\";\nimport type { ConvexConfig } from \"./convex.js\";\n\n// Environment-based configuration\n// These can be overridden via environment variables\n\nfunction getEnvOrDefault(key: string, defaultValue: string): string {\n return process.env[key] ?? defaultValue;\n}\n\n// Base URL for the web app (OAuth provider)\n// Set via BASE_URL environment variable\nexport const BASE_URL = getEnvOrDefault(\n \"BASE_URL\",\n \"https://program.video\"\n);\n\n// Convex deployment URL\n// Uses NEXT_PUBLIC_CONVEX_URL from .env - the .convex.cloud URL for API calls\nfunction getConvexUrl(): string {\n const override = process.env.PROGRAM_CONVEX_URL;\n if (override) return override;\n\n const convexUrl = process.env.NEXT_PUBLIC_CONVEX_URL;\n if (convexUrl) return convexUrl;\n\n // Fallback for local development\n return \"https://mild-hyena-697.convex.cloud\";\n}\n\nexport const CONVEX_URL = getConvexUrl();\n\nexport const oauthConfig: OAuthConfig = {\n baseUrl: BASE_URL,\n};\n\nexport const convexConfig: ConvexConfig = {\n convexUrl: CONVEX_URL,\n oauthConfig,\n};\n","import chalk from \"chalk\";\n\nexport interface OutputOptions {\n json?: boolean;\n}\n\nexport interface SuccessResult<T> {\n success: true;\n data: T;\n}\n\nexport interface ErrorResult {\n success: false;\n error: string;\n}\n\nexport type Result<T> = SuccessResult<T> | ErrorResult;\n\n/**\n * Output a success result in the appropriate format\n */\nexport function outputSuccess<T>(data: T, options: OutputOptions = {}): void {\n if (options.json) {\n const result: SuccessResult<T> = { success: true, data };\n console.log(JSON.stringify(result, null, 2));\n } else {\n // For human-readable output, we'll handle this per-command\n // This is a fallback that just pretty-prints\n console.log(data);\n }\n}\n\n/**\n * Output an error result in the appropriate format\n */\nexport function outputError(error: string, options: OutputOptions = {}): void {\n if (options.json) {\n const result: ErrorResult = { success: false, error };\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.error(chalk.red(\"Error:\"), error);\n }\n}\n\n/**\n * Format a table for human-readable output\n */\nexport function formatTable(\n headers: string[],\n rows: string[][],\n options: { indent?: number } = {}\n): string {\n const indent = \" \".repeat(options.indent ?? 0);\n\n // Calculate column widths\n const widths = headers.map((h, i) => {\n const maxRow = Math.max(...rows.map((r) => (r[i] ?? \"\").length));\n return Math.max(h.length, maxRow);\n });\n\n // Format header\n const headerLine = headers\n .map((h, i) => chalk.bold(h.padEnd(widths[i] ?? 0)))\n .join(\" \");\n\n // Format separator\n const separator = widths.map((w) => \"-\".repeat(w)).join(\" \");\n\n // Format rows\n const formattedRows = rows.map((row) =>\n row.map((cell, i) => (cell || \"\").padEnd(widths[i] ?? 0)).join(\" \")\n );\n\n return [indent + headerLine, indent + separator, ...formattedRows.map((r) => indent + r)].join(\n \"\\n\"\n );\n}\n\n/**\n * Format a key-value list for human-readable output\n */\nexport function formatKeyValue(\n items: { key: string; value: string }[],\n options: { indent?: number } = {}\n): string {\n const indent = \" \".repeat(options.indent ?? 0);\n const maxKeyLength = Math.max(...items.map((item) => item.key.length));\n\n return items\n .map(\n (item) =>\n indent + chalk.dim(item.key.padEnd(maxKeyLength) + \":\") + \" \" + item.value\n )\n .join(\"\\n\");\n}\n\n/**\n * Format a success message\n */\nexport function formatSuccess(message: string): string {\n return chalk.green(\"✓\") + \" \" + message;\n}\n\n/**\n * Format a warning message\n */\nexport function formatWarning(message: string): string {\n return chalk.yellow(\"⚠\") + \" \" + message;\n}\n\n/**\n * Format an info message\n */\nexport function formatInfo(message: string): string {\n return chalk.blue(\"ℹ\") + \" \" + message;\n}\n","import { clearCredentials, getCredentials } from \"../../lib/auth/credentials.js\";\nimport { formatSuccess, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport type LogoutOptions = OutputOptions;\n\nexport function logoutCommand(options: LogoutOptions): void {\n const credentials = getCredentials();\n\n if (!credentials) {\n if (options.json) {\n outputSuccess({ loggedOut: true, wasAuthenticated: false }, options);\n } else {\n console.log(\"Not currently logged in.\");\n }\n return;\n }\n\n const email = credentials.email;\n clearCredentials();\n\n if (options.json) {\n outputSuccess({ loggedOut: true, wasAuthenticated: true, email }, options);\n } else {\n console.log(formatSuccess(`Logged out from ${email}`));\n }\n}\n","import chalk from \"chalk\";\nimport { getCredentials, isAuthenticated, needsRefresh } from \"../../lib/auth/credentials.js\";\nimport { formatKeyValue, formatSuccess, formatWarning, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport type StatusOptions = OutputOptions;\n\nexport function statusCommand(options: StatusOptions): void {\n const credentials = getCredentials();\n\n if (!credentials) {\n if (options.json) {\n outputSuccess({ authenticated: false }, options);\n } else {\n console.log(\"Not logged in. Run 'program auth login' to authenticate.\");\n }\n return;\n }\n\n const authenticated = isAuthenticated();\n const expiresAt = credentials.expiresAt;\n const now = Math.floor(Date.now() / 1000);\n const expiresIn = expiresAt - now;\n\n if (options.json) {\n outputSuccess(\n {\n authenticated,\n user: credentials.email,\n userId: credentials.userId,\n organizationId: credentials.organizationId,\n expiresAt,\n expiresIn,\n needsRefresh: needsRefresh(),\n },\n options\n );\n } else {\n if (!authenticated) {\n console.log(formatWarning(\"Token expired. Run 'program auth login' to re-authenticate.\"));\n return;\n }\n\n console.log(formatSuccess(\"Logged in\"));\n console.log();\n console.log(\n formatKeyValue([\n { key: \"Email\", value: credentials.email },\n { key: \"User ID\", value: credentials.userId },\n { key: \"Organization\", value: credentials.organizationId || chalk.dim(\"(none)\") },\n { key: \"Token expires\", value: formatExpiresIn(expiresIn) },\n ])\n );\n }\n}\n\nfunction formatExpiresIn(seconds: number): string {\n if (seconds <= 0) {\n return chalk.red(\"expired\");\n }\n\n if (seconds < 60) {\n return chalk.yellow(`in ${seconds} seconds`);\n }\n\n if (seconds < 3600) {\n const minutes = Math.floor(seconds / 60);\n return chalk.green(`in ${minutes} minute${minutes === 1 ? \"\" : \"s\"}`);\n }\n\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n return chalk.green(`in ${hours}h ${minutes}m`);\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatSuccess, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport interface CreateOptions extends OutputOptions {\n title?: string;\n description?: string;\n}\n\ninterface CreateResult {\n id: string;\n title: string;\n}\n\nexport async function createCommand(options: CreateOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Creating project...\").start();\n\n const client = createConvexClient(convexConfig);\n\n const result = await client.mutation<string>(\"projects.create\", {\n title: options.title,\n description: options.description,\n });\n\n spinner?.stop();\n\n if (!result.success || !result.data) {\n outputError(result.error ?? \"Failed to create project\", options);\n process.exit(1);\n }\n\n const projectData: CreateResult = {\n id: result.data,\n title: options.title ?? \"Untitled Project\",\n };\n\n if (options.json) {\n outputSuccess(projectData, options);\n } else {\n console.log(formatSuccess(`Created project ${chalk.cyan(projectData.title)}`));\n console.log(chalk.dim(` ID: ${projectData.id}`));\n }\n}\n","import open from \"open\";\nimport { generateCodeChallenge, generateCodeVerifier, generateState } from \"./pkce.js\";\nimport { startCallbackServer } from \"./callback-server.js\";\nimport { saveCredentials, getCredentials } from \"./credentials.js\";\nimport type {Credentials} from \"./credentials.js\";\n\n// OAuth configuration\nconst CALLBACK_PORT = 8976;\nconst REDIRECT_URI = `http://localhost:${CALLBACK_PORT}/callback`;\n// Use standard OAuth scopes - email is required to identify the user\nconst SCOPES = [\"openid\", \"profile\", \"email\", \"offline_access\"];\n\n// OAuth client ID - same for all agents\n// Agent source is detected at runtime per-request (see lib/agent-detect.ts)\nconst CLIENT_ID = \"program-cli\";\n\nexport interface OAuthConfig {\n baseUrl: string;\n}\n\nexport interface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n token_type: string;\n scope?: string;\n}\n\nexport interface UserInfo {\n id: string;\n email: string;\n name: string;\n organizationId?: string;\n}\n\n/**\n * Start the OAuth login flow\n * Opens browser for authentication and waits for callback\n */\nexport async function login(config: OAuthConfig): Promise<Credentials> {\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n // Build authorization URL (use the page that handles the redirect properly)\n const authUrl = new URL(\"/oauth/authorize\", config.baseUrl);\n authUrl.searchParams.set(\"client_id\", CLIENT_ID);\n authUrl.searchParams.set(\"redirect_uri\", REDIRECT_URI);\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"scope\", SCOPES.join(\" \"));\n authUrl.searchParams.set(\"state\", state);\n authUrl.searchParams.set(\"code_challenge\", codeChallenge);\n authUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n\n // Start callback server before opening browser\n const callbackPromise = startCallbackServer(CALLBACK_PORT, state);\n\n // Open browser to authorization URL\n await open(authUrl.toString());\n\n // Wait for callback with authorization code\n const { code } = await callbackPromise;\n\n // Exchange code for tokens\n const tokens = await exchangeCodeForTokens(config, code, codeVerifier);\n\n // Get user info\n const userInfo = await getUserInfo(config, tokens.access_token);\n\n // Calculate expiry timestamp\n const expiresAt = Math.floor(Date.now() / 1000) + tokens.expires_in;\n\n // Validate we have a refresh token (required for token refresh)\n if (!tokens.refresh_token) {\n throw new Error(\"OAuth server did not return a refresh token\");\n }\n\n // Save credentials (source is detected at runtime per-request, not stored here)\n const credentials: Credentials = {\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token,\n expiresAt,\n userId: userInfo.id,\n organizationId: userInfo.organizationId ?? \"\",\n email: userInfo.email,\n };\n\n saveCredentials(credentials);\n\n return credentials;\n}\n\n/**\n * Exchange authorization code for tokens\n */\nasync function exchangeCodeForTokens(\n config: OAuthConfig,\n code: string,\n codeVerifier: string\n): Promise<TokenResponse> {\n const tokenUrl = new URL(\"/api/auth/oauth2/token\", config.baseUrl);\n\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n client_id: CLIENT_ID,\n code,\n redirect_uri: REDIRECT_URI,\n code_verifier: codeVerifier,\n });\n\n const response = await fetch(tokenUrl.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: body.toString(),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Token exchange failed: ${response.status} ${errorText}`);\n }\n\n return response.json() as Promise<TokenResponse>;\n}\n\n/**\n * Refresh the access token using the refresh token\n */\nexport async function refreshAccessToken(config: OAuthConfig): Promise<Credentials | null> {\n const creds = getCredentials();\n if (!creds?.refreshToken) {\n return null;\n }\n\n const tokenUrl = new URL(\"/api/auth/oauth2/token\", config.baseUrl);\n\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: CLIENT_ID,\n refresh_token: creds.refreshToken,\n });\n\n const response = await fetch(tokenUrl.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: body.toString(),\n });\n\n if (!response.ok) {\n // Refresh failed - user needs to re-authenticate\n return null;\n }\n\n const tokens = (await response.json()) as TokenResponse;\n const expiresAt = Math.floor(Date.now() / 1000) + tokens.expires_in;\n\n const newCredentials: Credentials = {\n ...creds,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? creds.refreshToken,\n expiresAt,\n };\n\n saveCredentials(newCredentials);\n\n return newCredentials;\n}\n\n/**\n * Get user info from the OAuth server\n */\nasync function getUserInfo(config: OAuthConfig, accessToken: string): Promise<UserInfo> {\n const userInfoUrl = new URL(\"/api/auth/oauth2/userinfo\", config.baseUrl);\n\n const response = await fetch(userInfoUrl.toString(), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get user info: ${response.status}`);\n }\n\n const data = (await response.json()) as {\n sub?: string;\n id?: string;\n email?: string;\n name?: string;\n organizationId?: string;\n };\n\n const id = data.sub ?? data.id;\n const email = data.email;\n\n if (!id || !email) {\n throw new Error(\"Invalid user info response: missing id or email\");\n }\n\n return {\n id,\n email,\n name: data.name ?? email,\n organizationId: data.organizationId,\n };\n}\n\n/**\n * Ensure we have a valid access token, refreshing if necessary\n */\nexport async function ensureValidToken(config: OAuthConfig): Promise<string | null> {\n const creds = getCredentials();\n if (!creds) {\n return null;\n }\n\n const now = Date.now();\n const expiresAt = creds.expiresAt * 1000;\n const bufferMs = 5 * 60 * 1000; // 5 minutes\n\n // If token is still valid, return it\n if (now < expiresAt - bufferMs) {\n return creds.accessToken;\n }\n\n // Try to refresh\n const refreshed = await refreshAccessToken(config);\n return refreshed?.accessToken ?? null;\n}\n","import * as crypto from \"node:crypto\";\n\n/**\n * Generate a cryptographically random code verifier for PKCE\n * Must be between 43-128 characters, using unreserved characters\n */\nexport function generateCodeVerifier(): string {\n // Generate 32 random bytes and encode as base64url\n const buffer = crypto.randomBytes(32);\n return buffer\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n}\n\n/**\n * Generate the code challenge from a code verifier using S256 method\n */\nexport function generateCodeChallenge(verifier: string): string {\n const hash = crypto.createHash(\"sha256\").update(verifier).digest();\n return hash\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n}\n\n/**\n * Generate a random state parameter for CSRF protection\n */\nexport function generateState(): string {\n return crypto.randomBytes(16).toString(\"hex\");\n}\n","import * as http from \"node:http\";\nimport { URL } from \"node:url\";\n\nexport interface CallbackResult {\n code: string;\n state: string;\n}\n\nexport interface CallbackError {\n error: string;\n errorDescription?: string;\n}\n\nconst SUCCESS_HTML = `\n<!DOCTYPE html>\n<html>\n<head>\n <title>Authentication Successful</title>\n <style>\n * { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n padding: 2rem;\n background: #F5F5F0;\n color: #171717;\n }\n .card {\n width: 100%;\n max-width: 400px;\n background: white;\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06);\n padding: 2rem;\n text-align: center;\n }\n .logo {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n margin-bottom: 1.5rem;\n }\n .logo-icon {\n width: 16px;\n height: 16px;\n background: #EA580C;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .logo-icon-inner {\n width: 3px;\n height: 3px;\n background: white;\n animation: flash 1.2s ease-in-out infinite;\n }\n @keyframes flash {\n 0%, 100% { opacity: 0.9; }\n 50% { opacity: 0.2; }\n }\n .logo-text {\n font-size: 1.25rem;\n font-weight: 300;\n color: #171717;\n }\n h1 {\n margin: 0 0 0.5rem 0;\n font-size: 1.25rem;\n font-weight: 500;\n letter-spacing: -0.01em;\n color: #171717;\n }\n p {\n margin: 0;\n color: #737373;\n font-size: 0.875rem;\n font-weight: 400;\n }\n </style>\n</head>\n<body>\n <div class=\"card\">\n <div class=\"logo\">\n <div class=\"logo-icon\"><div class=\"logo-icon-inner\"></div></div>\n <span class=\"logo-text\">Program.</span>\n </div>\n <h1>Authentication Successful</h1>\n <p>You can close this window and return to the terminal.</p>\n </div>\n</body>\n</html>\n`;\n\nconst ERROR_HTML = (error: string, description?: string) => `\n<!DOCTYPE html>\n<html>\n<head>\n <title>Authentication Failed</title>\n <style>\n * { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n padding: 2rem;\n background: #F5F5F0;\n color: #171717;\n }\n .logo {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 2rem;\n }\n .logo-icon {\n width: 16px;\n height: 16px;\n background: #EA580C;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .logo-icon-inner {\n width: 3px;\n height: 3px;\n background: white;\n animation: flash 1.2s infinite;\n }\n @keyframes flash {\n 0% { opacity: 0.8; }\n 50% { opacity: 0.1; }\n 100% { opacity: 0.8; }\n }\n .logo-text {\n font-size: 1.25rem;\n font-weight: 300;\n color: #171717;\n }\n .card {\n width: 100%;\n max-width: 400px;\n background: white;\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06);\n padding: 2rem;\n text-align: center;\n }\n .icon {\n width: 48px;\n height: 48px;\n background: #dc2626;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 1.5rem;\n }\n .icon svg {\n width: 24px;\n height: 24px;\n }\n .icon svg path {\n fill: none;\n stroke: white;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n h1 {\n margin: 0 0 0.5rem 0;\n font-size: 1.25rem;\n font-weight: 300;\n letter-spacing: -0.01em;\n }\n p {\n margin: 0;\n color: #737373;\n font-size: 0.875rem;\n font-weight: 400;\n }\n .error-detail {\n margin-top: 1rem;\n padding: 0.75rem;\n background: #fef2f2;\n border-radius: 8px;\n color: #dc2626;\n font-size: 0.8125rem;\n }\n </style>\n</head>\n<body>\n <div class=\"logo\">\n <div class=\"logo-icon\"><div class=\"logo-icon-inner\"></div></div>\n <span class=\"logo-text\">Program.</span>\n </div>\n <div class=\"card\">\n <div class=\"icon\">\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </div>\n <h1>Authentication Failed</h1>\n <p>Unable to complete the authentication process.</p>\n <div class=\"error-detail\">${error}${description ? `: ${description}` : \"\"}</div>\n </div>\n</body>\n</html>\n`;\n\n/**\n * Start a local HTTP server to receive the OAuth callback\n * Returns a promise that resolves with the authorization code\n */\nexport function startCallbackServer(\n port: number,\n expectedState: string,\n timeoutMs = 120000\n): Promise<CallbackResult> {\n return new Promise((resolve, reject) => {\n const server = http.createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400);\n res.end(\"Bad request\");\n return;\n }\n\n const url = new URL(req.url, `http://localhost:${port}`);\n\n // Only handle /callback path\n if (url.pathname !== \"/callback\") {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const error = url.searchParams.get(\"error\");\n const errorDescription = url.searchParams.get(\"error_description\");\n\n // Handle error response from OAuth server\n if (error) {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(ERROR_HTML(error, errorDescription ?? undefined));\n\n server.close();\n reject(new Error(errorDescription ?? error));\n return;\n }\n\n // Validate state to prevent CSRF\n if (state !== expectedState) {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(ERROR_HTML(\"Invalid state\", \"State mismatch - possible CSRF attack\"));\n\n server.close();\n reject(new Error(\"State mismatch - possible CSRF attack\"));\n return;\n }\n\n // Validate code exists\n if (!code) {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(ERROR_HTML(\"Missing code\", \"No authorization code received\"));\n\n server.close();\n reject(new Error(\"No authorization code received\"));\n return;\n }\n\n // Success!\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(SUCCESS_HTML);\n\n server.close();\n resolve({ code, state });\n });\n\n // Handle server errors\n server.on(\"error\", (err) => {\n reject(new Error(`Failed to start callback server: ${err.message}`));\n });\n\n // Set timeout\n const timeout = setTimeout(() => {\n server.close();\n reject(new Error(\"Authentication timed out\"));\n }, timeoutMs);\n\n // Clear timeout when server closes\n server.on(\"close\", () => {\n clearTimeout(timeout);\n });\n\n // Start listening\n server.listen(port, \"127.0.0.1\", () => {\n // Server is ready\n });\n });\n}\n","import { getCredentials, ensureValidToken } from \"./auth/index.js\";\nimport type {OAuthConfig} from \"./auth/index.js\";\n\nexport interface ConvexConfig {\n convexUrl: string;\n oauthConfig: OAuthConfig;\n}\n\nexport interface ConvexResponse<T> {\n success: boolean;\n data?: T;\n error?: string;\n}\n\n/**\n * Create a Convex HTTP client for calling Convex functions via the CLI gateway\n */\nexport function createConvexClient(config: ConvexConfig) {\n const { convexUrl } = config;\n\n // The CLI gateway is on the .convex.site endpoint\n const gatewayUrl = convexUrl.replace(\".convex.cloud\", \".convex.site\");\n\n /**\n * Call a Convex query function via the CLI gateway\n */\n async function query<T>(\n functionPath: string,\n args: Record<string, unknown> = {}\n ): Promise<ConvexResponse<T>> {\n return callGateway<T>(functionPath, args);\n }\n\n /**\n * Call a Convex mutation function via the CLI gateway\n */\n async function mutation<T>(\n functionPath: string,\n args: Record<string, unknown> = {}\n ): Promise<ConvexResponse<T>> {\n return callGateway<T>(functionPath, args);\n }\n\n /**\n * Call a Convex action function via the CLI gateway\n */\n async function action<T>(\n functionPath: string,\n args: Record<string, unknown> = {}\n ): Promise<ConvexResponse<T>> {\n return callGateway<T>(functionPath, args);\n }\n\n /**\n * Call the CLI gateway with OAuth authentication\n */\n async function callGateway<T>(\n functionPath: string,\n args: Record<string, unknown>\n ): Promise<ConvexResponse<T>> {\n // Get valid access token\n const accessToken = await ensureValidToken(config.oauthConfig);\n if (!accessToken) {\n return {\n success: false,\n error: \"Not authenticated. Run 'program auth login' first.\",\n };\n }\n\n // Build the gateway URL\n const url = new URL(\"/cli\", gatewayUrl);\n\n try {\n const response = await fetch(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({\n fn: functionPath,\n params: args,\n }),\n });\n\n const result = (await response.json()) as {\n success: boolean;\n data?: T;\n error?: string;\n };\n\n if (!response.ok || !result.success) {\n return {\n success: false,\n error: result.error ?? `Gateway error: ${response.status}`,\n };\n }\n\n return { success: true, data: result.data };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n }\n\n /**\n * Get the current credentials (for checking auth status)\n */\n function getAuth() {\n return getCredentials();\n }\n\n return {\n query,\n mutation,\n action,\n getAuth,\n };\n}\n\nexport type ConvexClient = ReturnType<typeof createConvexClient>;\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatKeyValue, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport type GetOptions = OutputOptions;\n\ninterface ProjectWithComposition {\n _id: string;\n title: string;\n description?: string;\n createdAt: number;\n updatedAt: number;\n latestVersion: {\n _id: string;\n version: number;\n compositionId: string;\n createdAt: number;\n } | null;\n composition: {\n _id: string;\n title: string;\n description?: string;\n duration: number;\n fps: number;\n width: number;\n height: number;\n sceneCount: number;\n scenes: unknown[];\n } | null;\n}\n\nexport async function getCommand(projectId: string, options: GetOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching project...\").start();\n\n const client = createConvexClient(convexConfig);\n\n const result = await client.query<ProjectWithComposition>(\"projects.byId\", {\n id: projectId,\n });\n\n spinner?.stop();\n\n if (!result.success || !result.data) {\n outputError(result.error ?? \"Failed to get project\", options);\n process.exit(1);\n }\n\n const project = result.data;\n\n if (options.json) {\n outputSuccess(project, options);\n } else {\n console.log(chalk.bold(project.title || \"Untitled Project\"));\n if (project.description) {\n console.log(chalk.dim(project.description));\n }\n console.log();\n\n console.log(\n formatKeyValue([\n { key: \"ID\", value: project._id },\n { key: \"Created\", value: new Date(project.createdAt).toLocaleString() },\n { key: \"Updated\", value: new Date(project.updatedAt).toLocaleString() },\n ])\n );\n\n if (project.latestVersion) {\n console.log(chalk.bold(\"\\nVersion\"));\n console.log(\n formatKeyValue([\n { key: \"Version\", value: String(project.latestVersion.version) },\n { key: \"Composition ID\", value: project.latestVersion.compositionId },\n ])\n );\n } else {\n console.log(chalk.dim(\"\\nNo versions yet\"));\n }\n\n if (project.composition) {\n console.log(chalk.bold(\"\\nComposition\"));\n console.log(\n formatKeyValue([\n { key: \"Title\", value: project.composition.title },\n { key: \"Resolution\", value: `${project.composition.width}x${project.composition.height}` },\n { key: \"FPS\", value: String(project.composition.fps) },\n { key: \"Duration\", value: `${(project.composition.duration / 1000).toFixed(1)}s` },\n { key: \"Scenes\", value: String(project.composition.sceneCount) },\n ])\n );\n\n if (project.composition.sceneCount > 0 && Array.isArray(project.composition.scenes)) {\n console.log(chalk.bold(\"\\nScenes\"));\n for (const scene of project.composition.scenes as { id: string; type: string; duration: number }[]) {\n console.log(chalk.dim(` - ${scene.type} (${(scene.duration / 1000).toFixed(1)}s)`));\n }\n }\n } else {\n console.log(chalk.dim(\"\\nNo composition yet\"));\n }\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatTable, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport interface ListOptions extends OutputOptions {\n limit?: number;\n}\n\ninterface Project {\n _id: string;\n title: string;\n description?: string;\n createdAt: number;\n updatedAt: number;\n}\n\ninterface ListResult {\n items: Project[];\n nextCursor: string | null;\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching projects...\").start();\n\n const client = createConvexClient(convexConfig);\n\n const result = await client.query<ListResult>(\"projects.list\", {\n limit: options.limit,\n });\n\n spinner?.stop();\n\n if (!result.success || !result.data) {\n outputError(result.error ?? \"Failed to list projects\", options);\n process.exit(1);\n }\n\n const projects = result.data.items;\n\n if (options.json) {\n outputSuccess(projects, options);\n } else {\n if (projects.length === 0) {\n console.log(chalk.dim(\"No projects found. Create one with 'program project create'\"));\n return;\n }\n\n console.log(`Found ${chalk.cyan(projects.length)} project${projects.length === 1 ? \"\" : \"s\"}:\\n`);\n\n const rows = projects.map((p) => [\n p._id,\n p.title || chalk.dim(\"Untitled\"),\n formatDate(p.createdAt),\n ]);\n\n console.log(formatTable([\"ID\", \"Title\", \"Created\"], rows));\n }\n}\n\nfunction formatDate(timestamp: number): string {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return \"today\";\n } else if (diffDays === 1) {\n return \"yesterday\";\n } else if (diffDays < 7) {\n return `${diffDays} days ago`;\n } else {\n return date.toLocaleDateString();\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatTable, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport interface ListOptions extends OutputOptions {\n limit?: number;\n publicOnly?: boolean;\n}\n\ninterface Template {\n _id: string;\n name: string;\n description?: string;\n public: boolean;\n createdAt: number;\n updatedAt: number;\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching workflow templates...\").start();\n\n const client = createConvexClient(convexConfig);\n\n const result = await client.query<Template[]>(\"workflows.listTemplates\", {\n category: options.publicOnly ? \"public\" : undefined,\n });\n\n spinner?.stop();\n\n if (!result.success || !result.data) {\n outputError(result.error ?? \"Failed to list templates\", options);\n process.exit(1);\n }\n\n const templates = result.data;\n\n if (options.json) {\n outputSuccess(\n templates.map((t) => ({\n id: t._id,\n name: t.name,\n description: t.description,\n public: t.public,\n })),\n options\n );\n } else {\n if (templates.length === 0) {\n console.log(chalk.dim(\"No workflow templates found.\"));\n return;\n }\n\n console.log(`Found ${chalk.cyan(templates.length)} template${templates.length === 1 ? \"\" : \"s\"}:\\n`);\n\n const rows = templates.map((t) => [\n t._id,\n t.name,\n t.description?.substring(0, 40) ?? chalk.dim(\"No description\"),\n t.public ? chalk.green(\"public\") : chalk.dim(\"private\"),\n ]);\n\n console.log(formatTable([\"ID\", \"Name\", \"Description\", \"Visibility\"], rows));\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatSuccess, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport interface RunOptions extends OutputOptions {\n project?: string;\n input?: string;\n}\n\nexport async function runCommand(templateId: string, options: RunOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Starting workflow execution...\").start();\n\n // Parse input JSON if provided\n let input: Record<string, unknown> | undefined;\n if (options.input) {\n try {\n input = JSON.parse(options.input) as Record<string, unknown>;\n } catch {\n spinner?.stop();\n outputError(\"Invalid JSON in --input parameter\", options);\n process.exit(1);\n }\n }\n\n const client = createConvexClient(convexConfig);\n\n const result = await client.mutation<string>(\"workflows.run\", {\n templateId,\n projectId: options.project,\n input,\n });\n\n spinner?.stop();\n\n if (!result.success || !result.data) {\n outputError(result.error ?? \"Failed to start workflow\", options);\n process.exit(1);\n }\n\n const executionId = result.data;\n\n if (options.json) {\n outputSuccess({ executionId }, options);\n } else {\n console.log(formatSuccess(`Workflow started`));\n console.log(chalk.dim(` Execution ID: ${executionId}`));\n console.log(chalk.dim(` Check status with: program workflow status ${executionId}`));\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatKeyValue, formatSuccess, formatWarning, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport interface StatusOptions extends OutputOptions {\n watch?: boolean;\n interval?: number;\n}\n\ninterface ExecutionStatus {\n status: \"pending\" | \"running\" | \"success\" | \"error\" | \"cancelled\";\n output?: unknown;\n error?: string;\n completedAt?: number;\n nodeStatuses?: { nodeId: string; status: string }[];\n}\n\nexport async function statusCommand(executionId: string, options: StatusOptions): Promise<void> {\n const client = createConvexClient(convexConfig);\n const pollInterval = options.interval ?? 2000;\n\n if (options.watch) {\n await watchStatus(client, executionId, pollInterval, options);\n } else {\n await getStatusOnce(client, executionId, options);\n }\n}\n\nasync function getStatusOnce(\n client: ReturnType<typeof createConvexClient>,\n executionId: string,\n options: StatusOptions\n): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching execution status...\").start();\n\n const result = await client.query<ExecutionStatus>(\"workflows.status\", {\n executionId,\n });\n\n spinner?.stop();\n\n if (!result.success) {\n outputError(result.error ?? \"Failed to get status\", options);\n process.exit(1);\n }\n\n const status = result.data;\n\n if (!status) {\n outputError(\"Execution not found\", options);\n process.exit(1);\n }\n\n if (options.json) {\n outputSuccess(status, options);\n } else {\n printStatus(status);\n }\n}\n\nasync function watchStatus(\n client: ReturnType<typeof createConvexClient>,\n executionId: string,\n pollInterval: number,\n options: StatusOptions\n): Promise<void> {\n let lastStatus: string | null = null;\n\n const poll = async (): Promise<boolean> => {\n const result = await client.query<ExecutionStatus>(\"workflows.status\", {\n executionId,\n });\n\n if (!result.success) {\n outputError(result.error ?? \"Failed to get status\", options);\n return true; // Stop polling\n }\n\n const status = result.data;\n\n if (!status) {\n outputError(\"Execution not found\", options);\n return true;\n }\n\n // For JSON mode, output each status change\n if (options.json) {\n if (status.status !== lastStatus) {\n console.log(JSON.stringify(status));\n lastStatus = status.status;\n }\n } else {\n // For human mode, clear and reprint\n if (status.status !== lastStatus) {\n console.clear();\n console.log(chalk.dim(`Watching execution ${executionId}...\\n`));\n printStatus(status);\n lastStatus = status.status;\n }\n }\n\n // Stop polling if complete\n if ([\"success\", \"error\", \"cancelled\"].includes(status.status)) {\n return true;\n }\n\n return false;\n };\n\n // Initial poll\n let done = await poll();\n\n // Continue polling until complete\n while (!done) {\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n done = await poll();\n }\n}\n\nfunction printStatus(status: ExecutionStatus): void {\n const statusColor = getStatusColor(status.status);\n\n console.log(\n formatKeyValue([\n { key: \"Status\", value: statusColor(status.status) },\n ...(status.completedAt\n ? [{ key: \"Completed\", value: new Date(status.completedAt).toLocaleString() }]\n : []),\n ])\n );\n\n if (status.nodeStatuses && status.nodeStatuses.length > 0) {\n console.log(chalk.dim(\"\\nStep progress:\"));\n for (const node of status.nodeStatuses) {\n const nodeColor = getStatusColor(node.status);\n console.log(` ${nodeColor(getStatusIcon(node.status))} ${node.nodeId}`);\n }\n }\n\n if (status.error) {\n console.log(formatWarning(`\\nError: ${status.error}`));\n }\n\n if (status.status === \"success\" && status.output) {\n console.log(formatSuccess(\"\\nOutput:\"));\n console.log(JSON.stringify(status.output, null, 2));\n }\n}\n\nfunction getStatusColor(status: string): (text: string) => string {\n switch (status) {\n case \"success\":\n return chalk.green;\n case \"error\":\n return chalk.red;\n case \"cancelled\":\n return chalk.yellow;\n case \"running\":\n return chalk.blue;\n case \"pending\":\n default:\n return chalk.dim;\n }\n}\n\nfunction getStatusIcon(status: string): string {\n switch (status) {\n case \"success\":\n return \"✓\";\n case \"error\":\n return \"✕\";\n case \"running\":\n return \"●\";\n case \"pending\":\n default:\n return \"○\";\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { ensureValidToken } from \"../../lib/auth/index.js\";\nimport { oauthConfig, BASE_URL } from \"../../lib/config.js\";\nimport { outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\nimport { detectAgentSource } from \"../../lib/agent-detect.js\";\n\nexport interface ExecuteOptions extends OutputOptions {\n project: string;\n params?: string;\n}\n\nexport async function executeCommand(\n toolName: string,\n options: ExecuteOptions\n): Promise<void> {\n const spinner = options.json ? null : ora(`Executing ${toolName}...`).start();\n\n // Get valid access token\n const accessToken = await ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n outputError(\"Not authenticated. Run 'program auth login' first.\", options);\n process.exit(1);\n }\n\n // Parse params if provided\n let params: Record<string, unknown> = {};\n if (options.params) {\n try {\n params = JSON.parse(options.params) as Record<string, unknown>;\n } catch {\n spinner?.stop();\n outputError(\"Invalid JSON in --params\", options);\n process.exit(1);\n }\n }\n\n // Detect agent at runtime (not login time) for correct multi-agent support\n const source = detectAgentSource();\n\n try {\n const response = await fetch(`${BASE_URL}/api/cli/tool`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({\n projectId: options.project,\n tool: toolName,\n params,\n source,\n }),\n });\n\n const result = (await response.json()) as {\n success: boolean;\n data?: unknown;\n error?: string;\n compositionId?: string;\n };\n\n spinner?.stop();\n\n if (!response.ok || !result.success) {\n outputError(result.error ?? `Tool execution failed: ${response.status}`, options);\n process.exit(1);\n }\n\n if (options.json) {\n outputSuccess(result.data, options);\n } else {\n console.log(chalk.green(`✓ ${toolName} executed successfully`));\n if (result.compositionId) {\n console.log(chalk.dim(` Composition: ${result.compositionId}`));\n }\n console.log();\n console.log(JSON.stringify(result.data, null, 2));\n }\n } catch (error) {\n spinner?.stop();\n outputError(error instanceof Error ? error.message : \"Request failed\", options);\n process.exit(1);\n }\n}\n","/**\n * Runtime agent detection\n *\n * Detects which agent/IDE is running the CLI based on environment variables.\n * This is checked per-request, not at login time, so multiple agents can\n * use the same credentials simultaneously with correct attribution.\n */\n\n/**\n * Detect which agent is currently running this CLI command.\n * Returns undefined for unknown agents (will show as \"Agent via CLI\").\n */\nexport function detectAgentSource(): string | undefined {\n // Claude Code sets CLAUDECODE=1 (external env var from IDE, not project-owned)\n // eslint-disable-next-line turbo/no-undeclared-env-vars\n if (process.env.CLAUDECODE === \"1\") {\n return \"claude-code\";\n }\n\n // Future: Add detection for other agents when we know their env vars\n // OpenCode, Codex, Cursor, etc.\n\n // Unknown agent - return undefined to use default display\n return undefined;\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { BASE_URL } from \"../../lib/config.js\";\nimport { outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport type ListOptions = OutputOptions;\n\ninterface Tool {\n name: string;\n description: string;\n inputs: string[];\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching available tools...\").start();\n\n try {\n const response = await fetch(`${BASE_URL}/api/cli/tool`, {\n method: \"GET\",\n });\n\n const result = (await response.json()) as {\n success: boolean;\n tools?: Tool[];\n error?: string;\n };\n\n spinner?.stop();\n\n if (!response.ok || !result.success) {\n outputError(result.error ?? \"Failed to list tools\", options);\n process.exit(1);\n }\n\n const tools = result.tools ?? [];\n\n if (options.json) {\n outputSuccess(tools, options);\n } else {\n console.log(chalk.bold(`Available Tools (${tools.length}):\\n`));\n\n for (const tool of tools) {\n console.log(chalk.cyan(` ${tool.name}`));\n console.log(chalk.dim(` ${tool.description}`));\n if (tool.inputs.length > 0) {\n console.log(chalk.dim(` Inputs: ${tool.inputs.join(\", \")}`));\n }\n console.log();\n }\n\n console.log(chalk.dim(\"Usage: program tool exec <toolName> --project <id> --params '{...}'\"));\n }\n } catch (error) {\n spinner?.stop();\n outputError(error instanceof Error ? error.message : \"Request failed\", options);\n process.exit(1);\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { ensureValidToken } from \"../../lib/auth/index.js\";\nimport { oauthConfig, BASE_URL } from \"../../lib/config.js\";\nimport { outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\nimport { detectAgentSource } from \"../../lib/agent-detect.js\";\n\nexport interface SendMessageOptions extends OutputOptions {\n project: string;\n role?: \"user\" | \"assistant\";\n}\n\nexport async function sendCommand(\n text: string,\n options: SendMessageOptions\n): Promise<void> {\n const spinner = options.json ? null : ora(\"Sending message...\").start();\n\n // Get valid access token\n const accessToken = await ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n outputError(\"Not authenticated. Run 'program auth login' first.\", options);\n process.exit(1);\n }\n\n const role = options.role ?? \"assistant\";\n\n // Detect agent at runtime (not login time) for correct multi-agent support\n const source = detectAgentSource();\n\n try {\n const response = await fetch(`${BASE_URL}/api/cli/message`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({\n projectId: options.project,\n role,\n text,\n source,\n }),\n });\n\n const result = (await response.json()) as {\n success: boolean;\n messageId?: string;\n error?: string;\n };\n\n spinner?.stop();\n\n if (!response.ok || !result.success) {\n outputError(result.error ?? `Failed to send message: ${response.status}`, options);\n process.exit(1);\n }\n\n if (options.json) {\n outputSuccess({ messageId: result.messageId, role, text }, options);\n } else {\n console.log(chalk.green(`✓ Message sent as ${role}`));\n if (result.messageId) {\n console.log(chalk.dim(` Message ID: ${result.messageId}`));\n }\n }\n } catch (error) {\n spinner?.stop();\n outputError(error instanceof Error ? error.message : \"Request failed\", options);\n process.exit(1);\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { ensureValidToken } from \"../../lib/auth/index.js\";\nimport { oauthConfig, BASE_URL } from \"../../lib/config.js\";\nimport { outputError, outputSuccess } from \"../../lib/output.js\";\nimport type { OutputOptions } from \"../../lib/output.js\";\n\nexport interface ListMessageOptions extends OutputOptions {\n project: string;\n limit?: number;\n}\n\ninterface MessagePart {\n type: string;\n text?: string;\n toolName?: string;\n toolCallId?: string;\n state?: string;\n}\n\ninterface Message {\n id: string;\n role: \"user\" | \"assistant\";\n parts: MessagePart[];\n source?: string;\n createdAt: number;\n}\n\nexport async function listCommand(options: ListMessageOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching messages...\").start();\n\n // Get valid access token\n const accessToken = await ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n outputError(\n \"Not authenticated. Run 'program auth login' first.\",\n options\n );\n process.exit(1);\n }\n\n try {\n const url = new URL(`${BASE_URL}/api/cli/message`);\n url.searchParams.set(\"projectId\", options.project);\n if (options.limit) {\n url.searchParams.set(\"limit\", options.limit.toString());\n }\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n const result = (await response.json()) as {\n success: boolean;\n chatId?: string;\n messages?: Message[];\n error?: string;\n };\n\n spinner?.stop();\n\n if (!response.ok || !result.success) {\n outputError(\n result.error ?? `Failed to fetch messages: ${response.status}`,\n options\n );\n process.exit(1);\n }\n\n if (options.json) {\n outputSuccess(result, options);\n } else {\n const messages = result.messages ?? [];\n if (messages.length === 0) {\n console.log(chalk.dim(\"No messages in this chat yet.\"));\n return;\n }\n\n console.log(chalk.bold(`Chat Messages (${messages.length}):\\n`));\n\n for (const msg of messages) {\n // Format the role with source if available\n let roleLabel = msg.role === \"user\" ? \"You\" : \"Assistant\";\n if (msg.source) {\n if (msg.source === \"cli:claude-code\") {\n roleLabel = \"Claude via CLI\";\n } else if (msg.source.startsWith(\"cli:\")) {\n roleLabel = `${roleLabel} via CLI`;\n }\n }\n\n // Get text content from parts\n const textContent = msg.parts\n .filter((p): p is MessagePart & { text: string } => p.type === \"text\" && !!p.text)\n .map((p) => p.text)\n .join(\"\\n\");\n\n // Get tool calls\n const toolCalls = msg.parts.filter(\n (p) => p.type === \"tool-invocation\" || p.type === \"tool-call\"\n );\n\n // Format timestamp\n const time = new Date(msg.createdAt).toLocaleTimeString();\n\n // Print message\n const roleColor = msg.role === \"user\" ? chalk.blue : chalk.green;\n console.log(roleColor(`[${time}] ${roleLabel}:`));\n\n if (textContent) {\n // Indent and truncate long messages\n const truncated =\n textContent.length > 500\n ? textContent.substring(0, 500) + \"...\"\n : textContent;\n console.log(\n truncated\n .split(\"\\n\")\n .map((line) => ` ${line}`)\n .join(\"\\n\")\n );\n }\n\n if (toolCalls.length > 0) {\n console.log(\n chalk.dim(` [${toolCalls.length} tool call(s)]`)\n );\n }\n\n console.log();\n }\n }\n } catch (error) {\n spinner?.stop();\n outputError(\n error instanceof Error ? error.message : \"Request failed\",\n options\n );\n process.exit(1);\n }\n}\n","import { outputSuccess } from \"../lib/output.js\";\nimport type {OutputOptions} from \"../lib/output.js\";\n\nexport interface DocsOptions extends OutputOptions {\n schema?: boolean;\n}\n\n// Command schema for agents\nconst COMMAND_SCHEMA = {\n name: \"program\",\n version: \"0.1.0\",\n description: \"CLI for interacting with the Program video creation platform\",\n commands: {\n auth: {\n description: \"Authentication commands\",\n subcommands: {\n login: {\n description: \"Authenticate with the Program platform\",\n options: {\n \"--json\": \"Output as JSON\",\n },\n example: \"program auth login\",\n },\n logout: {\n description: \"Log out from the Program platform\",\n options: {\n \"--json\": \"Output as JSON\",\n },\n example: \"program auth logout\",\n },\n status: {\n description: \"Check authentication status\",\n options: {\n \"--json\": \"Output as JSON\",\n },\n example: \"program auth status --json\",\n },\n },\n },\n project: {\n description: \"Project management commands\",\n subcommands: {\n create: {\n description: \"Create a new project\",\n options: {\n \"--title <title>\": \"Project title\",\n \"--description <desc>\": \"Project description\",\n \"--json\": \"Output as JSON\",\n },\n example: 'program project create --title \"My Video\" --json',\n },\n list: {\n description: \"List projects\",\n options: {\n \"--limit <n>\": \"Maximum number of projects to return\",\n \"--json\": \"Output as JSON\",\n },\n example: \"program project list --json\",\n },\n },\n },\n workflow: {\n description: \"Workflow template commands\",\n subcommands: {\n list: {\n description: \"List available workflow templates\",\n options: {\n \"--limit <n>\": \"Maximum number of templates to return\",\n \"--public-only\": \"Only show public templates\",\n \"--json\": \"Output as JSON\",\n },\n example: \"program workflow list --json\",\n },\n run: {\n description: \"Execute a workflow template\",\n args: {\n templateId: \"ID of the template to run\",\n },\n options: {\n \"--project <id>\": \"Project ID to associate with execution\",\n \"--input <json>\": \"JSON input for the workflow\",\n \"--json\": \"Output as JSON\",\n },\n example: \"program workflow run tmpl_abc --project proj_123 --input '{\\\"files\\\":[\\\"src/main.ts\\\"]}' --json\",\n },\n status: {\n description: \"Check workflow execution status\",\n args: {\n executionId: \"ID of the execution to check\",\n },\n options: {\n \"--watch\": \"Continuously poll for status updates\",\n \"--interval <ms>\": \"Poll interval in milliseconds (default: 2000)\",\n \"--json\": \"Output as JSON\",\n },\n example: \"program workflow status exec_789 --watch --json\",\n },\n },\n },\n docs: {\n description: \"Display CLI documentation\",\n options: {\n \"--schema\": \"Output full command schema as JSON\",\n },\n example: \"program docs --schema\",\n },\n },\n globalOptions: {\n \"--help\": \"Display help information\",\n \"--version\": \"Display version number\",\n },\n notes: [\n \"Always use --json flag for parseable output when integrating with agents\",\n \"Workflow inputs should be valid JSON strings\",\n \"Run 'program auth login' first to authenticate\",\n ],\n};\n\nexport function docsCommand(options: DocsOptions): void {\n if (options.schema ?? options.json) {\n outputSuccess(COMMAND_SCHEMA, { json: true });\n } else {\n printHumanDocs();\n }\n}\n\nfunction printHumanDocs(): void {\n console.log(`\nProgram CLI v${COMMAND_SCHEMA.version}\n${COMMAND_SCHEMA.description}\n\nCOMMANDS:\n\n auth login Authenticate with the Program platform\n auth logout Log out from the Program platform\n auth status Check authentication status\n\n project create Create a new project\n project list List projects\n\n workflow list List available workflow templates\n workflow run <id> Execute a workflow template\n workflow status <id> Check workflow execution status\n\n docs Display this documentation\n docs --schema Output full command schema as JSON\n\nGLOBAL OPTIONS:\n\n --json Output as JSON (recommended for agents)\n --help Display help information\n --version Display version number\n\nEXAMPLES:\n\n # Authenticate\n program auth login\n\n # Create a project\n program project create --title \"My Video\" --json\n\n # Run a workflow\n program workflow run tmpl_abc --project proj_123 --json\n\n # Watch execution progress\n program workflow status exec_789 --watch --json\n\nFor agent integration, always use the --json flag.\n`);\n}\n"],"mappings":"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","names":["chalk","message","chalk","message","chalk","chalk","minutes","chalk","ora","URL","CLIENT_ID","CLIENT_ID","ora","chalk","chalk","ora","ora","project","chalk","chalk","ora","ora","chalk","chalk","ora","listCommand","ora","chalk","chalk","ora","ora","chalk","chalk","ora","statusCommand","ora","chalk","chalk","ora","ora","chalk","chalk","ora","listCommand","ora","chalk","tool","chalk","ora","ora","chalk","chalk","ora","listCommand","ora","chalk","listCommand","statusCommand"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/auth/login.ts","../src/lib/auth/credentials.ts","../src/lib/auth/device.ts","../src/lib/config.ts","../src/lib/output.ts","../src/commands/auth/logout.ts","../src/commands/auth/status.ts","../src/commands/project/create.ts","../src/lib/auth/oauth.ts","../src/lib/auth/pkce.ts","../src/lib/auth/callback-server.ts","../src/lib/convex.ts","../src/commands/project/get.ts","../src/commands/project/list.ts","../src/commands/workflow/list.ts","../src/commands/workflow/run.ts","../src/commands/workflow/status.ts","../src/commands/tool/execute.ts","../src/lib/agent-detect.ts","../src/commands/tool/list.ts","../src/commands/message/send.ts","../src/commands/message/list.ts","../src/commands/docs.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { loginCommand } from \"./commands/auth/login.js\";\nimport type { LoginOptions } from \"./commands/auth/login.js\";\nimport { logoutCommand } from \"./commands/auth/logout.js\";\nimport type { LogoutOptions } from \"./commands/auth/logout.js\";\nimport { statusCommand as authStatusCommand } from \"./commands/auth/status.js\";\nimport type { StatusOptions as AuthStatusOptions } from \"./commands/auth/status.js\";\nimport { createCommand as projectCreateCommand } from \"./commands/project/create.js\";\nimport type { CreateOptions } from \"./commands/project/create.js\";\nimport { getCommand as projectGetCommand } from \"./commands/project/get.js\";\nimport type { GetOptions } from \"./commands/project/get.js\";\nimport { listCommand as projectListCommand } from \"./commands/project/list.js\";\nimport type { ListOptions as ProjectListOptions } from \"./commands/project/list.js\";\nimport { listCommand as workflowListCommand } from \"./commands/workflow/list.js\";\nimport type { ListOptions as WorkflowListOptions } from \"./commands/workflow/list.js\";\nimport { runCommand as workflowRunCommand } from \"./commands/workflow/run.js\";\nimport type { RunOptions } from \"./commands/workflow/run.js\";\nimport { statusCommand as workflowStatusCommand } from \"./commands/workflow/status.js\";\nimport type { StatusOptions as WorkflowStatusOptions } from \"./commands/workflow/status.js\";\nimport { executeCommand as toolExecuteCommand } from \"./commands/tool/execute.js\";\nimport type { ExecuteOptions } from \"./commands/tool/execute.js\";\nimport { listCommand as toolListCommand } from \"./commands/tool/list.js\";\nimport type { ListOptions as ToolListOptions } from \"./commands/tool/list.js\";\nimport { sendCommand as messageSendCommand } from \"./commands/message/send.js\";\nimport type { SendMessageOptions } from \"./commands/message/send.js\";\nimport { listCommand as messageListCommand } from \"./commands/message/list.js\";\nimport type { ListMessageOptions } from \"./commands/message/list.js\";\nimport { docsCommand } from \"./commands/docs.js\";\nimport type { DocsOptions } from \"./commands/docs.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"program\")\n .description(\"CLI for the Program video creation platform\")\n .version(\"0.1.0\");\n\n// Auth commands\nconst auth = program.command(\"auth\").description(\"Authentication commands\");\n\nauth\n .command(\"login\")\n .description(\"Authenticate with the Program platform\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: LoginOptions) => {\n await loginCommand(options);\n });\n\nauth\n .command(\"logout\")\n .description(\"Log out from the Program platform\")\n .option(\"--json\", \"Output as JSON\")\n .action((options: LogoutOptions) => {\n logoutCommand(options);\n });\n\nauth\n .command(\"status\")\n .description(\"Check authentication status\")\n .option(\"--json\", \"Output as JSON\")\n .action((options: AuthStatusOptions) => {\n authStatusCommand(options);\n });\n\n// Project commands\nconst project = program.command(\"project\").description(\"Project management commands\");\n\nproject\n .command(\"create\")\n .description(\"Create a new project\")\n .option(\"--title <title>\", \"Project title\")\n .option(\"--description <description>\", \"Project description\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: CreateOptions) => {\n await projectCreateCommand(options);\n });\n\nproject\n .command(\"list\")\n .description(\"List projects\")\n .option(\"--limit <limit>\", \"Maximum number of projects to return\", parseInt)\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: ProjectListOptions) => {\n await projectListCommand(options);\n });\n\nproject\n .command(\"get <id>\")\n .description(\"Get project details including composition\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (id: string, options: GetOptions) => {\n await projectGetCommand(id, options);\n });\n\n// Workflow commands\nconst workflow = program.command(\"workflow\").description(\"Workflow template commands\");\n\nworkflow\n .command(\"list\")\n .description(\"List available workflow templates\")\n .option(\"--limit <limit>\", \"Maximum number of templates to return\", parseInt)\n .option(\"--public-only\", \"Only show public templates\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: WorkflowListOptions) => {\n await workflowListCommand(options);\n });\n\nworkflow\n .command(\"run <templateId>\")\n .description(\"Execute a workflow template\")\n .option(\"--project <projectId>\", \"Project ID to associate with execution\")\n .option(\"--input <json>\", \"JSON input for the workflow\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (templateId: string, options: RunOptions) => {\n await workflowRunCommand(templateId, options);\n });\n\nworkflow\n .command(\"status <executionId>\")\n .description(\"Check workflow execution status\")\n .option(\"--watch\", \"Continuously poll for status updates\")\n .option(\"--interval <ms>\", \"Poll interval in milliseconds\", parseInt)\n .option(\"--json\", \"Output as JSON\")\n .action(async (executionId: string, options: WorkflowStatusOptions) => {\n await workflowStatusCommand(executionId, options);\n });\n\n// Tool commands (direct agent tool access)\nconst tool = program.command(\"tool\").description(\"Execute agent tools directly\");\n\ntool\n .command(\"list\")\n .description(\"List available agent tools\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: ToolListOptions) => {\n await toolListCommand(options);\n });\n\ntool\n .command(\"exec <toolName>\")\n .description(\"Execute an agent tool\")\n .requiredOption(\"--project <projectId>\", \"Project ID to execute tool against\")\n .option(\"--params <json>\", \"JSON parameters for the tool\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (toolName: string, options: ExecuteOptions) => {\n await toolExecuteCommand(toolName, options);\n });\n\n// Message commands (send and list messages in project chat)\nconst message = program.command(\"message\").description(\"Manage messages in project chat\");\n\nmessage\n .command(\"list\")\n .description(\"List messages in the project chat\")\n .requiredOption(\"--project <projectId>\", \"Project ID to list messages from\")\n .option(\"--limit <limit>\", \"Maximum number of messages to return\", parseInt)\n .option(\"--json\", \"Output as JSON\")\n .action(async (options: ListMessageOptions) => {\n await messageListCommand(options);\n });\n\nmessage\n .command(\"send <text>\")\n .description(\n \"Log a text message to the project chat. NOTE: This only adds a message to the chat history - it does NOT trigger the AI agent. To perform actions, use 'tool exec' instead.\",\n )\n .requiredOption(\"--project <projectId>\", \"Project ID to send message to\")\n .option(\"--role <role>\", \"Message role: user or assistant (default: assistant)\")\n .option(\"--json\", \"Output as JSON\")\n .action(async (text: string, options: SendMessageOptions) => {\n await messageSendCommand(text, options);\n });\n\n// Docs command\nprogram\n .command(\"docs\")\n .description(\"Display CLI documentation and command schema\")\n .option(\"--schema\", \"Output full command schema as JSON\")\n .option(\"--json\", \"Output as JSON\")\n .action((options: DocsOptions) => {\n docsCommand(options);\n });\n\n// Parse arguments\nprogram.parse();\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { startDeviceAuth } from \"../../lib/auth/device.js\";\nimport { oauthConfig } from \"../../lib/config.js\";\nimport { formatSuccess, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type { OutputOptions } from \"../../lib/output.js\";\n\nexport type LoginOptions = OutputOptions;\n\n/**\n * Format user code with dash for readability (ABCD1234 -> ABCD-1234)\n */\nfunction formatUserCode(code: string): string {\n if (code.length === 8) {\n return `${code.slice(0, 4)}-${code.slice(4)}`;\n }\n return code;\n}\n\n/**\n * Device authorization flow - works everywhere including headless environments\n * User visits a URL on any device and enters the code shown in the terminal\n */\nexport async function loginCommand(options: LoginOptions): Promise<void> {\n const spinner = ora(\"Requesting device code...\").start();\n\n try {\n const deviceAuth = await startDeviceAuth(oauthConfig);\n spinner.stop();\n\n // Display the code and URL for the user\n console.log();\n console.log(chalk.bold(\" Sign in to Program\"));\n console.log();\n console.log(` Visit: ${chalk.cyan(deviceAuth.verificationUrl)}`);\n console.log();\n console.log(` Enter code: ${chalk.bold.yellow(formatUserCode(deviceAuth.userCode))}`);\n console.log();\n\n // If there's a complete URL with the code embedded, also show that\n if (deviceAuth.verificationUrlComplete) {\n console.log(chalk.dim(` Or open: ${deviceAuth.verificationUrlComplete}`));\n console.log();\n }\n\n const waitingSpinner = ora(\"Waiting for authorization...\").start();\n\n // Poll until the user completes auth\n const credentials = await deviceAuth.pollForCompletion();\n\n waitingSpinner.stop();\n\n if (options.json) {\n outputSuccess(\n {\n authenticated: true,\n email: credentials.email,\n userId: credentials.userId,\n organizationId: credentials.organizationId,\n },\n options\n );\n } else {\n console.log(formatSuccess(`Authenticated as ${chalk.cyan(credentials.email)}`));\n if (credentials.organizationId) {\n console.log(chalk.dim(` Organization: ${credentials.organizationId}`));\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Authentication failed\";\n outputError(message, options);\n process.exit(1);\n }\n}\n","import Conf from \"conf\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\n\nexport interface Credentials {\n accessToken: string;\n refreshToken: string;\n expiresAt: number;\n userId: string;\n organizationId: string;\n email: string;\n}\n\n// Use ~/.program/ for credentials storage\nconst CREDENTIALS_DIR = path.join(os.homedir(), \".program\");\nconst CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, \"credentials.json\");\n\n// Ensure directory exists with proper permissions\nfunction ensureCredentialsDir(): void {\n if (!fs.existsSync(CREDENTIALS_DIR)) {\n fs.mkdirSync(CREDENTIALS_DIR, { mode: 0o700, recursive: true });\n }\n}\n\n// Using conf for secure credential storage with automatic file permissions\nconst store = new Conf<{ credentials: Credentials | null }>({\n projectName: \"program-cli\",\n cwd: CREDENTIALS_DIR,\n configName: \"credentials\",\n fileExtension: \"json\",\n defaults: {\n credentials: null,\n },\n});\n\nexport function saveCredentials(credentials: Credentials): void {\n ensureCredentialsDir();\n store.set(\"credentials\", credentials);\n\n // Ensure file has restrictive permissions (owner read/write only)\n try {\n fs.chmodSync(CREDENTIALS_FILE, 0o600);\n } catch {\n // Ignore chmod errors on Windows\n }\n}\n\nexport function getCredentials(): Credentials | null {\n return store.get(\"credentials\");\n}\n\nexport function clearCredentials(): void {\n store.delete(\"credentials\");\n}\n\nexport function isAuthenticated(): boolean {\n const creds = getCredentials();\n if (!creds) return false;\n\n // Check if token is expired (with 5 minute buffer)\n const now = Date.now();\n const expiresAt = creds.expiresAt * 1000; // Convert to milliseconds\n const bufferMs = 5 * 60 * 1000; // 5 minutes\n\n return now < expiresAt - bufferMs;\n}\n\nexport function needsRefresh(): boolean {\n const creds = getCredentials();\n if (!creds) return false;\n\n // Needs refresh if within 5 minutes of expiry\n const now = Date.now();\n const expiresAt = creds.expiresAt * 1000;\n const bufferMs = 5 * 60 * 1000;\n\n return now >= expiresAt - bufferMs && now < expiresAt;\n}\n","import { saveCredentials, getCredentials } from \"./credentials.js\";\nimport type { Credentials } from \"./credentials.js\";\n\n// OAuth client ID - same as the main oauth.ts\nconst CLIENT_ID = \"program-cli\";\nconst SCOPES = [\"openid\", \"profile\", \"email\", \"offline_access\"];\n\nexport interface DeviceAuthConfig {\n baseUrl: string;\n}\n\ninterface DeviceCodeResponse {\n device_code: string;\n user_code: string;\n verification_uri: string;\n verification_uri_complete?: string;\n expires_in: number;\n interval: number;\n}\n\ninterface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n token_type?: string;\n scope?: string;\n}\n\ninterface TokenErrorResponse {\n error: string;\n error_description?: string;\n}\n\ninterface UserInfo {\n id: string;\n email: string;\n name: string;\n organizationId?: string;\n}\n\n/**\n * Request a device code from the server\n */\nexport async function requestDeviceCode(\n config: DeviceAuthConfig\n): Promise<DeviceCodeResponse> {\n const url = new URL(\"/api/auth/device/code\", config.baseUrl);\n\n const response = await fetch(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n client_id: CLIENT_ID,\n scope: SCOPES.join(\" \"),\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to get device code: ${response.status} ${errorText}`);\n }\n\n return response.json() as Promise<DeviceCodeResponse>;\n}\n\n/**\n * Poll for the token after user authorizes\n * Returns the token response or an error code\n */\nexport async function pollForToken(\n config: DeviceAuthConfig,\n deviceCode: string\n): Promise<TokenResponse | TokenErrorResponse> {\n const url = new URL(\"/api/auth/device/token\", config.baseUrl);\n\n const response = await fetch(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n device_code: deviceCode,\n client_id: CLIENT_ID,\n }),\n });\n\n // Device flow uses 400 status for pending/slow_down errors\n const data = (await response.json()) as TokenResponse | TokenErrorResponse;\n\n if (!response.ok) {\n // Check if it's an expected error (authorization_pending, slow_down)\n if (\"error\" in data) {\n return data;\n }\n throw new Error(`Token request failed: ${response.status}`);\n }\n\n return data as TokenResponse;\n}\n\n/**\n * Get user info from the BetterAuth session endpoint\n * Device authorization returns a BetterAuth token, not an OIDC token\n */\nasync function getUserInfo(\n config: DeviceAuthConfig,\n accessToken: string\n): Promise<UserInfo> {\n // Use the BetterAuth get-session endpoint with Bearer token\n const sessionUrl = new URL(\"/api/auth/get-session\", config.baseUrl);\n\n const response = await fetch(sessionUrl.toString(), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!response.ok) {\n // Try the token/session endpoint if get-session doesn't work\n const tokenUrl = new URL(\"/api/auth/token\", config.baseUrl);\n const tokenResponse = await fetch(tokenUrl.toString(), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!tokenResponse.ok) {\n throw new Error(`Failed to get user info: ${response.status}`);\n }\n\n const tokenData = (await tokenResponse.json()) as {\n user?: { id?: string; email?: string; name?: string };\n session?: { activeOrganizationId?: string };\n };\n\n if (!tokenData.user?.id || !tokenData.user.email) {\n throw new Error(\"Invalid token response: missing user info\");\n }\n\n return {\n id: tokenData.user.id,\n email: tokenData.user.email,\n name: tokenData.user.name ?? tokenData.user.email,\n organizationId: tokenData.session?.activeOrganizationId,\n };\n }\n\n const data = (await response.json()) as {\n user?: {\n id?: string;\n email?: string;\n name?: string;\n };\n session?: {\n activeOrganizationId?: string;\n };\n };\n\n if (!data.user?.id || !data.user.email) {\n throw new Error(\"Invalid session response: missing user info\");\n }\n\n return {\n id: data.user.id,\n email: data.user.email,\n name: data.user.name ?? data.user.email,\n organizationId: data.session?.activeOrganizationId,\n };\n}\n\n/**\n * Start the device authorization flow\n * Returns display info for the CLI to show the user\n */\nexport interface DeviceAuthDisplay {\n userCode: string;\n verificationUrl: string;\n verificationUrlComplete?: string;\n expiresIn: number;\n interval: number;\n pollForCompletion: () => Promise<Credentials>;\n}\n\nexport async function startDeviceAuth(\n config: DeviceAuthConfig\n): Promise<DeviceAuthDisplay> {\n const deviceCode = await requestDeviceCode(config);\n\n return {\n userCode: deviceCode.user_code,\n verificationUrl: deviceCode.verification_uri,\n verificationUrlComplete: deviceCode.verification_uri_complete,\n expiresIn: deviceCode.expires_in,\n interval: deviceCode.interval,\n pollForCompletion: async () => {\n return pollUntilComplete(config, deviceCode);\n },\n };\n}\n\n/**\n * Poll until the user completes authorization or the code expires\n */\nasync function pollUntilComplete(\n config: DeviceAuthConfig,\n deviceCode: DeviceCodeResponse\n): Promise<Credentials> {\n const startTime = Date.now();\n const expiresAt = startTime + deviceCode.expires_in * 1000;\n let interval = deviceCode.interval * 1000;\n\n while (Date.now() < expiresAt) {\n // Wait for the interval before polling\n await new Promise((resolve) => setTimeout(resolve, interval));\n\n const result = await pollForToken(config, deviceCode.device_code);\n\n // Check if it's an error response\n if (\"error\" in result) {\n switch (result.error) {\n case \"authorization_pending\":\n // User hasn't completed authorization yet, continue polling\n continue;\n\n case \"slow_down\":\n // Server asked us to slow down, increase interval\n interval += 5000;\n continue;\n\n case \"expired_token\":\n throw new Error(\"Device code expired. Please start a new login.\");\n\n case \"access_denied\":\n throw new Error(\"Access denied. You denied the authorization request.\");\n\n default:\n throw new Error(\n result.error_description ?? `Authorization failed: ${result.error}`\n );\n }\n }\n\n // Success! We got tokens\n const tokens = result;\n\n // Get user info\n const userInfo = await getUserInfo(config, tokens.access_token);\n\n // Calculate expiry timestamp (default to 1 hour if not provided)\n const expiresIn = tokens.expires_in ?? 3600;\n const expiresAtTimestamp = Math.floor(Date.now() / 1000) + expiresIn;\n\n // Save credentials (refresh token may not be present for device flow)\n const credentials: Credentials = {\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? \"\",\n expiresAt: expiresAtTimestamp,\n userId: userInfo.id,\n organizationId: userInfo.organizationId ?? \"\",\n email: userInfo.email,\n };\n\n saveCredentials(credentials);\n\n return credentials;\n }\n\n throw new Error(\"Device code expired. Please start a new login.\");\n}\n\n/**\n * Check if we have valid credentials\n */\nexport function hasValidCredentials(): boolean {\n const creds = getCredentials();\n if (!creds) return false;\n\n // Check if token is expired (with 5 min buffer)\n const now = Date.now();\n const expiresAt = creds.expiresAt * 1000;\n const bufferMs = 5 * 60 * 1000;\n\n return now < expiresAt - bufferMs;\n}\n","import type { OAuthConfig } from \"./auth/index.js\";\nimport type { ConvexConfig } from \"./convex.js\";\n\n// Environment-based configuration\n// These can be overridden via environment variables\n\nfunction getEnvOrDefault(key: string, defaultValue: string): string {\n return process.env[key] ?? defaultValue;\n}\n\n// Base URL for the web app (OAuth provider)\n// Set via BASE_URL environment variable\nexport const BASE_URL = getEnvOrDefault(\n \"BASE_URL\",\n \"https://program.video\"\n);\n\n// Convex deployment URL (production)\nexport const CONVEX_URL = \"https://keen-eel-920.convex.cloud\";\n\nexport const oauthConfig: OAuthConfig = {\n baseUrl: BASE_URL,\n};\n\nexport const convexConfig: ConvexConfig = {\n convexUrl: CONVEX_URL,\n oauthConfig,\n};\n","import chalk from \"chalk\";\n\nexport interface OutputOptions {\n json?: boolean;\n}\n\nexport interface SuccessResult<T> {\n success: true;\n data: T;\n}\n\nexport interface ErrorResult {\n success: false;\n error: string;\n}\n\nexport type Result<T> = SuccessResult<T> | ErrorResult;\n\n/**\n * Output a success result in the appropriate format\n */\nexport function outputSuccess<T>(data: T, options: OutputOptions = {}): void {\n if (options.json) {\n const result: SuccessResult<T> = { success: true, data };\n console.log(JSON.stringify(result, null, 2));\n } else {\n // For human-readable output, we'll handle this per-command\n // This is a fallback that just pretty-prints\n console.log(data);\n }\n}\n\n/**\n * Output an error result in the appropriate format\n */\nexport function outputError(error: string, options: OutputOptions = {}): void {\n if (options.json) {\n const result: ErrorResult = { success: false, error };\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.error(chalk.red(\"Error:\"), error);\n }\n}\n\n/**\n * Format a table for human-readable output\n */\nexport function formatTable(\n headers: string[],\n rows: string[][],\n options: { indent?: number } = {}\n): string {\n const indent = \" \".repeat(options.indent ?? 0);\n\n // Calculate column widths\n const widths = headers.map((h, i) => {\n const maxRow = Math.max(...rows.map((r) => (r[i] ?? \"\").length));\n return Math.max(h.length, maxRow);\n });\n\n // Format header\n const headerLine = headers\n .map((h, i) => chalk.bold(h.padEnd(widths[i] ?? 0)))\n .join(\" \");\n\n // Format separator\n const separator = widths.map((w) => \"-\".repeat(w)).join(\" \");\n\n // Format rows\n const formattedRows = rows.map((row) =>\n row.map((cell, i) => (cell || \"\").padEnd(widths[i] ?? 0)).join(\" \")\n );\n\n return [indent + headerLine, indent + separator, ...formattedRows.map((r) => indent + r)].join(\n \"\\n\"\n );\n}\n\n/**\n * Format a key-value list for human-readable output\n */\nexport function formatKeyValue(\n items: { key: string; value: string }[],\n options: { indent?: number } = {}\n): string {\n const indent = \" \".repeat(options.indent ?? 0);\n const maxKeyLength = Math.max(...items.map((item) => item.key.length));\n\n return items\n .map(\n (item) =>\n indent + chalk.dim(item.key.padEnd(maxKeyLength) + \":\") + \" \" + item.value\n )\n .join(\"\\n\");\n}\n\n/**\n * Format a success message\n */\nexport function formatSuccess(message: string): string {\n return chalk.green(\"✓\") + \" \" + message;\n}\n\n/**\n * Format a warning message\n */\nexport function formatWarning(message: string): string {\n return chalk.yellow(\"⚠\") + \" \" + message;\n}\n\n/**\n * Format an info message\n */\nexport function formatInfo(message: string): string {\n return chalk.blue(\"ℹ\") + \" \" + message;\n}\n","import { clearCredentials, getCredentials } from \"../../lib/auth/credentials.js\";\nimport { formatSuccess, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport type LogoutOptions = OutputOptions;\n\nexport function logoutCommand(options: LogoutOptions): void {\n const credentials = getCredentials();\n\n if (!credentials) {\n if (options.json) {\n outputSuccess({ loggedOut: true, wasAuthenticated: false }, options);\n } else {\n console.log(\"Not currently logged in.\");\n }\n return;\n }\n\n const email = credentials.email;\n clearCredentials();\n\n if (options.json) {\n outputSuccess({ loggedOut: true, wasAuthenticated: true, email }, options);\n } else {\n console.log(formatSuccess(`Logged out from ${email}`));\n }\n}\n","import chalk from \"chalk\";\nimport { getCredentials, isAuthenticated, needsRefresh } from \"../../lib/auth/credentials.js\";\nimport { formatKeyValue, formatSuccess, formatWarning, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport type StatusOptions = OutputOptions;\n\nexport function statusCommand(options: StatusOptions): void {\n const credentials = getCredentials();\n\n if (!credentials) {\n if (options.json) {\n outputSuccess({ authenticated: false }, options);\n } else {\n console.log(\"Not logged in. Run 'program auth login' to authenticate.\");\n }\n return;\n }\n\n const authenticated = isAuthenticated();\n const expiresAt = credentials.expiresAt;\n const now = Math.floor(Date.now() / 1000);\n const expiresIn = expiresAt - now;\n\n if (options.json) {\n outputSuccess(\n {\n authenticated,\n user: credentials.email,\n userId: credentials.userId,\n organizationId: credentials.organizationId,\n expiresAt,\n expiresIn,\n needsRefresh: needsRefresh(),\n },\n options\n );\n } else {\n if (!authenticated) {\n console.log(formatWarning(\"Token expired. Run 'program auth login' to re-authenticate.\"));\n return;\n }\n\n console.log(formatSuccess(\"Logged in\"));\n console.log();\n console.log(\n formatKeyValue([\n { key: \"Email\", value: credentials.email },\n { key: \"User ID\", value: credentials.userId },\n { key: \"Organization\", value: credentials.organizationId || chalk.dim(\"(none)\") },\n { key: \"Token expires\", value: formatExpiresIn(expiresIn) },\n ])\n );\n }\n}\n\nfunction formatExpiresIn(seconds: number): string {\n if (seconds <= 0) {\n return chalk.red(\"expired\");\n }\n\n if (seconds < 60) {\n return chalk.yellow(`in ${seconds} seconds`);\n }\n\n if (seconds < 3600) {\n const minutes = Math.floor(seconds / 60);\n return chalk.green(`in ${minutes} minute${minutes === 1 ? \"\" : \"s\"}`);\n }\n\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n return chalk.green(`in ${hours}h ${minutes}m`);\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatSuccess, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport interface CreateOptions extends OutputOptions {\n title?: string;\n description?: string;\n}\n\ninterface CreateResult {\n id: string;\n title: string;\n}\n\nexport async function createCommand(options: CreateOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Creating project...\").start();\n\n const client = createConvexClient(convexConfig);\n\n const result = await client.mutation<string>(\"projects.create\", {\n title: options.title,\n description: options.description,\n });\n\n spinner?.stop();\n\n if (!result.success || !result.data) {\n outputError(result.error ?? \"Failed to create project\", options);\n process.exit(1);\n }\n\n const projectData: CreateResult = {\n id: result.data,\n title: options.title ?? \"Untitled Project\",\n };\n\n if (options.json) {\n outputSuccess(projectData, options);\n } else {\n console.log(formatSuccess(`Created project ${chalk.cyan(projectData.title)}`));\n console.log(chalk.dim(` ID: ${projectData.id}`));\n }\n}\n","import open from \"open\";\nimport { generateCodeChallenge, generateCodeVerifier, generateState } from \"./pkce.js\";\nimport { startCallbackServer } from \"./callback-server.js\";\nimport { saveCredentials, getCredentials } from \"./credentials.js\";\nimport type {Credentials} from \"./credentials.js\";\n\n// OAuth configuration\nconst CALLBACK_PORT = 8976;\nconst REDIRECT_URI = `http://localhost:${CALLBACK_PORT}/callback`;\n// Use standard OAuth scopes - email is required to identify the user\nconst SCOPES = [\"openid\", \"profile\", \"email\", \"offline_access\"];\n\n// OAuth client ID - same for all agents\n// Agent source is detected at runtime per-request (see lib/agent-detect.ts)\nconst CLIENT_ID = \"program-cli\";\n\nexport interface OAuthConfig {\n baseUrl: string;\n}\n\nexport interface TokenResponse {\n access_token: string;\n refresh_token?: string;\n expires_in: number;\n token_type: string;\n scope?: string;\n}\n\nexport interface UserInfo {\n id: string;\n email: string;\n name: string;\n organizationId?: string;\n}\n\n/**\n * Start the OAuth login flow\n * Opens browser for authentication and waits for callback\n */\nexport async function login(config: OAuthConfig): Promise<Credentials> {\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n // Build authorization URL (use the page that handles the redirect properly)\n const authUrl = new URL(\"/oauth/authorize\", config.baseUrl);\n authUrl.searchParams.set(\"client_id\", CLIENT_ID);\n authUrl.searchParams.set(\"redirect_uri\", REDIRECT_URI);\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"scope\", SCOPES.join(\" \"));\n authUrl.searchParams.set(\"state\", state);\n authUrl.searchParams.set(\"code_challenge\", codeChallenge);\n authUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n\n // Start callback server before opening browser\n const callbackPromise = startCallbackServer(CALLBACK_PORT, state);\n\n // Open browser to authorization URL\n await open(authUrl.toString());\n\n // Wait for callback with authorization code\n const { code } = await callbackPromise;\n\n // Exchange code for tokens\n const tokens = await exchangeCodeForTokens(config, code, codeVerifier);\n\n // Get user info\n const userInfo = await getUserInfo(config, tokens.access_token);\n\n // Calculate expiry timestamp\n const expiresAt = Math.floor(Date.now() / 1000) + tokens.expires_in;\n\n // Validate we have a refresh token (required for token refresh)\n if (!tokens.refresh_token) {\n throw new Error(\"OAuth server did not return a refresh token\");\n }\n\n // Save credentials (source is detected at runtime per-request, not stored here)\n const credentials: Credentials = {\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token,\n expiresAt,\n userId: userInfo.id,\n organizationId: userInfo.organizationId ?? \"\",\n email: userInfo.email,\n };\n\n saveCredentials(credentials);\n\n return credentials;\n}\n\n/**\n * Exchange authorization code for tokens\n */\nasync function exchangeCodeForTokens(\n config: OAuthConfig,\n code: string,\n codeVerifier: string\n): Promise<TokenResponse> {\n const tokenUrl = new URL(\"/api/auth/oauth2/token\", config.baseUrl);\n\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n client_id: CLIENT_ID,\n code,\n redirect_uri: REDIRECT_URI,\n code_verifier: codeVerifier,\n });\n\n const response = await fetch(tokenUrl.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: body.toString(),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Token exchange failed: ${response.status} ${errorText}`);\n }\n\n return response.json() as Promise<TokenResponse>;\n}\n\n/**\n * Refresh the access token using the refresh token\n */\nexport async function refreshAccessToken(config: OAuthConfig): Promise<Credentials | null> {\n const creds = getCredentials();\n if (!creds?.refreshToken) {\n return null;\n }\n\n const tokenUrl = new URL(\"/api/auth/oauth2/token\", config.baseUrl);\n\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: CLIENT_ID,\n refresh_token: creds.refreshToken,\n });\n\n const response = await fetch(tokenUrl.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: body.toString(),\n });\n\n if (!response.ok) {\n // Refresh failed - user needs to re-authenticate\n return null;\n }\n\n const tokens = (await response.json()) as TokenResponse;\n const expiresAt = Math.floor(Date.now() / 1000) + tokens.expires_in;\n\n const newCredentials: Credentials = {\n ...creds,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? creds.refreshToken,\n expiresAt,\n };\n\n saveCredentials(newCredentials);\n\n return newCredentials;\n}\n\n/**\n * Get user info from the OAuth server\n */\nasync function getUserInfo(config: OAuthConfig, accessToken: string): Promise<UserInfo> {\n const userInfoUrl = new URL(\"/api/auth/oauth2/userinfo\", config.baseUrl);\n\n const response = await fetch(userInfoUrl.toString(), {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to get user info: ${response.status}`);\n }\n\n const data = (await response.json()) as {\n sub?: string;\n id?: string;\n email?: string;\n name?: string;\n organizationId?: string;\n };\n\n const id = data.sub ?? data.id;\n const email = data.email;\n\n if (!id || !email) {\n throw new Error(\"Invalid user info response: missing id or email\");\n }\n\n return {\n id,\n email,\n name: data.name ?? email,\n organizationId: data.organizationId,\n };\n}\n\n/**\n * Ensure we have a valid access token, refreshing if necessary\n */\nexport async function ensureValidToken(config: OAuthConfig): Promise<string | null> {\n const creds = getCredentials();\n if (!creds) {\n return null;\n }\n\n const now = Date.now();\n const expiresAt = creds.expiresAt * 1000;\n const bufferMs = 5 * 60 * 1000; // 5 minutes\n\n // If token is still valid, return it\n if (now < expiresAt - bufferMs) {\n return creds.accessToken;\n }\n\n // Try to refresh\n const refreshed = await refreshAccessToken(config);\n return refreshed?.accessToken ?? null;\n}\n","import * as crypto from \"node:crypto\";\n\n/**\n * Generate a cryptographically random code verifier for PKCE\n * Must be between 43-128 characters, using unreserved characters\n */\nexport function generateCodeVerifier(): string {\n // Generate 32 random bytes and encode as base64url\n const buffer = crypto.randomBytes(32);\n return buffer\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n}\n\n/**\n * Generate the code challenge from a code verifier using S256 method\n */\nexport function generateCodeChallenge(verifier: string): string {\n const hash = crypto.createHash(\"sha256\").update(verifier).digest();\n return hash\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n}\n\n/**\n * Generate a random state parameter for CSRF protection\n */\nexport function generateState(): string {\n return crypto.randomBytes(16).toString(\"hex\");\n}\n","import * as http from \"node:http\";\nimport { URL } from \"node:url\";\n\nexport interface CallbackResult {\n code: string;\n state: string;\n}\n\nexport interface CallbackError {\n error: string;\n errorDescription?: string;\n}\n\nconst SUCCESS_HTML = `\n<!DOCTYPE html>\n<html>\n<head>\n <title>Authentication Successful</title>\n <style>\n * { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n padding: 2rem;\n background: #F5F5F0;\n color: #171717;\n }\n .card {\n width: 100%;\n max-width: 400px;\n background: white;\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06);\n padding: 2rem;\n text-align: center;\n }\n .logo {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n margin-bottom: 1.5rem;\n }\n .logo-icon {\n width: 16px;\n height: 16px;\n background: #EA580C;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .logo-icon-inner {\n width: 3px;\n height: 3px;\n background: white;\n animation: flash 1.2s ease-in-out infinite;\n }\n @keyframes flash {\n 0%, 100% { opacity: 0.9; }\n 50% { opacity: 0.2; }\n }\n .logo-text {\n font-size: 1.25rem;\n font-weight: 300;\n color: #171717;\n }\n h1 {\n margin: 0 0 0.5rem 0;\n font-size: 1.25rem;\n font-weight: 500;\n letter-spacing: -0.01em;\n color: #171717;\n }\n p {\n margin: 0;\n color: #737373;\n font-size: 0.875rem;\n font-weight: 400;\n }\n </style>\n</head>\n<body>\n <div class=\"card\">\n <div class=\"logo\">\n <div class=\"logo-icon\"><div class=\"logo-icon-inner\"></div></div>\n <span class=\"logo-text\">Program.</span>\n </div>\n <h1>Authentication Successful</h1>\n <p>You can close this window and return to the terminal.</p>\n </div>\n</body>\n</html>\n`;\n\nconst ERROR_HTML = (error: string, description?: string) => `\n<!DOCTYPE html>\n<html>\n<head>\n <title>Authentication Failed</title>\n <style>\n * { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n padding: 2rem;\n background: #F5F5F0;\n color: #171717;\n }\n .logo {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 2rem;\n }\n .logo-icon {\n width: 16px;\n height: 16px;\n background: #EA580C;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .logo-icon-inner {\n width: 3px;\n height: 3px;\n background: white;\n animation: flash 1.2s infinite;\n }\n @keyframes flash {\n 0% { opacity: 0.8; }\n 50% { opacity: 0.1; }\n 100% { opacity: 0.8; }\n }\n .logo-text {\n font-size: 1.25rem;\n font-weight: 300;\n color: #171717;\n }\n .card {\n width: 100%;\n max-width: 400px;\n background: white;\n border-radius: 12px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06);\n padding: 2rem;\n text-align: center;\n }\n .icon {\n width: 48px;\n height: 48px;\n background: #dc2626;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 1.5rem;\n }\n .icon svg {\n width: 24px;\n height: 24px;\n }\n .icon svg path {\n fill: none;\n stroke: white;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n }\n h1 {\n margin: 0 0 0.5rem 0;\n font-size: 1.25rem;\n font-weight: 300;\n letter-spacing: -0.01em;\n }\n p {\n margin: 0;\n color: #737373;\n font-size: 0.875rem;\n font-weight: 400;\n }\n .error-detail {\n margin-top: 1rem;\n padding: 0.75rem;\n background: #fef2f2;\n border-radius: 8px;\n color: #dc2626;\n font-size: 0.8125rem;\n }\n </style>\n</head>\n<body>\n <div class=\"logo\">\n <div class=\"logo-icon\"><div class=\"logo-icon-inner\"></div></div>\n <span class=\"logo-text\">Program.</span>\n </div>\n <div class=\"card\">\n <div class=\"icon\">\n <svg viewBox=\"0 0 24 24\">\n <path d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </div>\n <h1>Authentication Failed</h1>\n <p>Unable to complete the authentication process.</p>\n <div class=\"error-detail\">${error}${description ? `: ${description}` : \"\"}</div>\n </div>\n</body>\n</html>\n`;\n\n/**\n * Start a local HTTP server to receive the OAuth callback\n * Returns a promise that resolves with the authorization code\n */\nexport function startCallbackServer(\n port: number,\n expectedState: string,\n timeoutMs = 120000\n): Promise<CallbackResult> {\n return new Promise((resolve, reject) => {\n const server = http.createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400);\n res.end(\"Bad request\");\n return;\n }\n\n const url = new URL(req.url, `http://localhost:${port}`);\n\n // Only handle /callback path\n if (url.pathname !== \"/callback\") {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const error = url.searchParams.get(\"error\");\n const errorDescription = url.searchParams.get(\"error_description\");\n\n // Handle error response from OAuth server\n if (error) {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(ERROR_HTML(error, errorDescription ?? undefined));\n\n server.close();\n reject(new Error(errorDescription ?? error));\n return;\n }\n\n // Validate state to prevent CSRF\n if (state !== expectedState) {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(ERROR_HTML(\"Invalid state\", \"State mismatch - possible CSRF attack\"));\n\n server.close();\n reject(new Error(\"State mismatch - possible CSRF attack\"));\n return;\n }\n\n // Validate code exists\n if (!code) {\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(ERROR_HTML(\"Missing code\", \"No authorization code received\"));\n\n server.close();\n reject(new Error(\"No authorization code received\"));\n return;\n }\n\n // Success!\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(SUCCESS_HTML);\n\n server.close();\n resolve({ code, state });\n });\n\n // Handle server errors\n server.on(\"error\", (err) => {\n reject(new Error(`Failed to start callback server: ${err.message}`));\n });\n\n // Set timeout\n const timeout = setTimeout(() => {\n server.close();\n reject(new Error(\"Authentication timed out\"));\n }, timeoutMs);\n\n // Clear timeout when server closes\n server.on(\"close\", () => {\n clearTimeout(timeout);\n });\n\n // Start listening\n server.listen(port, \"127.0.0.1\", () => {\n // Server is ready\n });\n });\n}\n","import { getCredentials, ensureValidToken } from \"./auth/index.js\";\nimport type {OAuthConfig} from \"./auth/index.js\";\n\nexport interface ConvexConfig {\n convexUrl: string;\n oauthConfig: OAuthConfig;\n}\n\nexport interface ConvexResponse<T> {\n success: boolean;\n data?: T;\n error?: string;\n}\n\n/**\n * Create a Convex HTTP client for calling Convex functions via the CLI gateway\n */\nexport function createConvexClient(config: ConvexConfig) {\n const { convexUrl } = config;\n\n // The CLI gateway is on the .convex.site endpoint\n const gatewayUrl = convexUrl.replace(\".convex.cloud\", \".convex.site\");\n\n /**\n * Call a Convex query function via the CLI gateway\n */\n async function query<T>(\n functionPath: string,\n args: Record<string, unknown> = {}\n ): Promise<ConvexResponse<T>> {\n return callGateway<T>(functionPath, args);\n }\n\n /**\n * Call a Convex mutation function via the CLI gateway\n */\n async function mutation<T>(\n functionPath: string,\n args: Record<string, unknown> = {}\n ): Promise<ConvexResponse<T>> {\n return callGateway<T>(functionPath, args);\n }\n\n /**\n * Call a Convex action function via the CLI gateway\n */\n async function action<T>(\n functionPath: string,\n args: Record<string, unknown> = {}\n ): Promise<ConvexResponse<T>> {\n return callGateway<T>(functionPath, args);\n }\n\n /**\n * Call the CLI gateway with OAuth authentication\n */\n async function callGateway<T>(\n functionPath: string,\n args: Record<string, unknown>\n ): Promise<ConvexResponse<T>> {\n // Get valid access token\n const accessToken = await ensureValidToken(config.oauthConfig);\n if (!accessToken) {\n return {\n success: false,\n error: \"Not authenticated. Run 'program auth login' first.\",\n };\n }\n\n // Build the gateway URL\n const url = new URL(\"/cli\", gatewayUrl);\n\n try {\n const response = await fetch(url.toString(), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({\n fn: functionPath,\n params: args,\n }),\n });\n\n const result = (await response.json()) as {\n success: boolean;\n data?: T;\n error?: string;\n };\n\n if (!response.ok || !result.success) {\n return {\n success: false,\n error: result.error ?? `Gateway error: ${response.status}`,\n };\n }\n\n return { success: true, data: result.data };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n }\n\n /**\n * Get the current credentials (for checking auth status)\n */\n function getAuth() {\n return getCredentials();\n }\n\n return {\n query,\n mutation,\n action,\n getAuth,\n };\n}\n\nexport type ConvexClient = ReturnType<typeof createConvexClient>;\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatKeyValue, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport type GetOptions = OutputOptions;\n\ninterface ProjectWithComposition {\n _id: string;\n title: string;\n description?: string;\n createdAt: number;\n updatedAt: number;\n latestVersion: {\n _id: string;\n version: number;\n compositionId: string;\n createdAt: number;\n } | null;\n composition: {\n _id: string;\n title: string;\n description?: string;\n duration: number;\n fps: number;\n width: number;\n height: number;\n sceneCount: number;\n scenes: unknown[];\n } | null;\n}\n\nexport async function getCommand(projectId: string, options: GetOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching project...\").start();\n\n const client = createConvexClient(convexConfig);\n\n const result = await client.query<ProjectWithComposition>(\"projects.byId\", {\n id: projectId,\n });\n\n spinner?.stop();\n\n if (!result.success || !result.data) {\n outputError(result.error ?? \"Failed to get project\", options);\n process.exit(1);\n }\n\n const project = result.data;\n\n if (options.json) {\n outputSuccess(project, options);\n } else {\n console.log(chalk.bold(project.title || \"Untitled Project\"));\n if (project.description) {\n console.log(chalk.dim(project.description));\n }\n console.log();\n\n console.log(\n formatKeyValue([\n { key: \"ID\", value: project._id },\n { key: \"Created\", value: new Date(project.createdAt).toLocaleString() },\n { key: \"Updated\", value: new Date(project.updatedAt).toLocaleString() },\n ])\n );\n\n if (project.latestVersion) {\n console.log(chalk.bold(\"\\nVersion\"));\n console.log(\n formatKeyValue([\n { key: \"Version\", value: String(project.latestVersion.version) },\n { key: \"Composition ID\", value: project.latestVersion.compositionId },\n ])\n );\n } else {\n console.log(chalk.dim(\"\\nNo versions yet\"));\n }\n\n if (project.composition) {\n console.log(chalk.bold(\"\\nComposition\"));\n console.log(\n formatKeyValue([\n { key: \"Title\", value: project.composition.title },\n { key: \"Resolution\", value: `${project.composition.width}x${project.composition.height}` },\n { key: \"FPS\", value: String(project.composition.fps) },\n { key: \"Duration\", value: `${(project.composition.duration / 1000).toFixed(1)}s` },\n { key: \"Scenes\", value: String(project.composition.sceneCount) },\n ])\n );\n\n if (project.composition.sceneCount > 0 && Array.isArray(project.composition.scenes)) {\n console.log(chalk.bold(\"\\nScenes\"));\n for (const scene of project.composition.scenes as { id: string; type: string; duration: number }[]) {\n console.log(chalk.dim(` - ${scene.type} (${(scene.duration / 1000).toFixed(1)}s)`));\n }\n }\n } else {\n console.log(chalk.dim(\"\\nNo composition yet\"));\n }\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatTable, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport interface ListOptions extends OutputOptions {\n limit?: number;\n}\n\ninterface Project {\n _id: string;\n title: string;\n description?: string;\n createdAt: number;\n updatedAt: number;\n}\n\ninterface ListResult {\n items: Project[];\n nextCursor: string | null;\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching projects...\").start();\n\n const client = createConvexClient(convexConfig);\n\n const result = await client.query<ListResult>(\"projects.list\", {\n limit: options.limit,\n });\n\n spinner?.stop();\n\n if (!result.success || !result.data) {\n outputError(result.error ?? \"Failed to list projects\", options);\n process.exit(1);\n }\n\n const projects = result.data.items;\n\n if (options.json) {\n outputSuccess(projects, options);\n } else {\n if (projects.length === 0) {\n console.log(chalk.dim(\"No projects found. Create one with 'program project create'\"));\n return;\n }\n\n console.log(`Found ${chalk.cyan(projects.length)} project${projects.length === 1 ? \"\" : \"s\"}:\\n`);\n\n const rows = projects.map((p) => [\n p._id,\n p.title || chalk.dim(\"Untitled\"),\n formatDate(p.createdAt),\n ]);\n\n console.log(formatTable([\"ID\", \"Title\", \"Created\"], rows));\n }\n}\n\nfunction formatDate(timestamp: number): string {\n const date = new Date(timestamp);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n\n if (diffDays === 0) {\n return \"today\";\n } else if (diffDays === 1) {\n return \"yesterday\";\n } else if (diffDays < 7) {\n return `${diffDays} days ago`;\n } else {\n return date.toLocaleDateString();\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatTable, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport interface ListOptions extends OutputOptions {\n limit?: number;\n publicOnly?: boolean;\n}\n\ninterface Template {\n _id: string;\n name: string;\n description?: string;\n public: boolean;\n createdAt: number;\n updatedAt: number;\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching workflow templates...\").start();\n\n const client = createConvexClient(convexConfig);\n\n const result = await client.query<Template[]>(\"workflows.listTemplates\", {\n category: options.publicOnly ? \"public\" : undefined,\n });\n\n spinner?.stop();\n\n if (!result.success || !result.data) {\n outputError(result.error ?? \"Failed to list templates\", options);\n process.exit(1);\n }\n\n const templates = result.data;\n\n if (options.json) {\n outputSuccess(\n templates.map((t) => ({\n id: t._id,\n name: t.name,\n description: t.description,\n public: t.public,\n })),\n options\n );\n } else {\n if (templates.length === 0) {\n console.log(chalk.dim(\"No workflow templates found.\"));\n return;\n }\n\n console.log(`Found ${chalk.cyan(templates.length)} template${templates.length === 1 ? \"\" : \"s\"}:\\n`);\n\n const rows = templates.map((t) => [\n t._id,\n t.name,\n t.description?.substring(0, 40) ?? chalk.dim(\"No description\"),\n t.public ? chalk.green(\"public\") : chalk.dim(\"private\"),\n ]);\n\n console.log(formatTable([\"ID\", \"Name\", \"Description\", \"Visibility\"], rows));\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatSuccess, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport interface RunOptions extends OutputOptions {\n project?: string;\n input?: string;\n}\n\nexport async function runCommand(templateId: string, options: RunOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Starting workflow execution...\").start();\n\n // Parse input JSON if provided\n let input: Record<string, unknown> | undefined;\n if (options.input) {\n try {\n input = JSON.parse(options.input) as Record<string, unknown>;\n } catch {\n spinner?.stop();\n outputError(\"Invalid JSON in --input parameter\", options);\n process.exit(1);\n }\n }\n\n const client = createConvexClient(convexConfig);\n\n const result = await client.mutation<string>(\"workflows.run\", {\n templateId,\n projectId: options.project,\n input,\n });\n\n spinner?.stop();\n\n if (!result.success || !result.data) {\n outputError(result.error ?? \"Failed to start workflow\", options);\n process.exit(1);\n }\n\n const executionId = result.data;\n\n if (options.json) {\n outputSuccess({ executionId }, options);\n } else {\n console.log(formatSuccess(`Workflow started`));\n console.log(chalk.dim(` Execution ID: ${executionId}`));\n console.log(chalk.dim(` Check status with: program workflow status ${executionId}`));\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { createConvexClient } from \"../../lib/convex.js\";\nimport { convexConfig } from \"../../lib/config.js\";\nimport { formatKeyValue, formatSuccess, formatWarning, outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport interface StatusOptions extends OutputOptions {\n watch?: boolean;\n interval?: number;\n}\n\ninterface ExecutionStatus {\n status: \"pending\" | \"running\" | \"success\" | \"error\" | \"cancelled\";\n output?: unknown;\n error?: string;\n completedAt?: number;\n nodeStatuses?: { nodeId: string; status: string }[];\n}\n\nexport async function statusCommand(executionId: string, options: StatusOptions): Promise<void> {\n const client = createConvexClient(convexConfig);\n const pollInterval = options.interval ?? 2000;\n\n if (options.watch) {\n await watchStatus(client, executionId, pollInterval, options);\n } else {\n await getStatusOnce(client, executionId, options);\n }\n}\n\nasync function getStatusOnce(\n client: ReturnType<typeof createConvexClient>,\n executionId: string,\n options: StatusOptions\n): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching execution status...\").start();\n\n const result = await client.query<ExecutionStatus>(\"workflows.status\", {\n executionId,\n });\n\n spinner?.stop();\n\n if (!result.success) {\n outputError(result.error ?? \"Failed to get status\", options);\n process.exit(1);\n }\n\n const status = result.data;\n\n if (!status) {\n outputError(\"Execution not found\", options);\n process.exit(1);\n }\n\n if (options.json) {\n outputSuccess(status, options);\n } else {\n printStatus(status);\n }\n}\n\nasync function watchStatus(\n client: ReturnType<typeof createConvexClient>,\n executionId: string,\n pollInterval: number,\n options: StatusOptions\n): Promise<void> {\n let lastStatus: string | null = null;\n\n const poll = async (): Promise<boolean> => {\n const result = await client.query<ExecutionStatus>(\"workflows.status\", {\n executionId,\n });\n\n if (!result.success) {\n outputError(result.error ?? \"Failed to get status\", options);\n return true; // Stop polling\n }\n\n const status = result.data;\n\n if (!status) {\n outputError(\"Execution not found\", options);\n return true;\n }\n\n // For JSON mode, output each status change\n if (options.json) {\n if (status.status !== lastStatus) {\n console.log(JSON.stringify(status));\n lastStatus = status.status;\n }\n } else {\n // For human mode, clear and reprint\n if (status.status !== lastStatus) {\n console.clear();\n console.log(chalk.dim(`Watching execution ${executionId}...\\n`));\n printStatus(status);\n lastStatus = status.status;\n }\n }\n\n // Stop polling if complete\n if ([\"success\", \"error\", \"cancelled\"].includes(status.status)) {\n return true;\n }\n\n return false;\n };\n\n // Initial poll\n let done = await poll();\n\n // Continue polling until complete\n while (!done) {\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n done = await poll();\n }\n}\n\nfunction printStatus(status: ExecutionStatus): void {\n const statusColor = getStatusColor(status.status);\n\n console.log(\n formatKeyValue([\n { key: \"Status\", value: statusColor(status.status) },\n ...(status.completedAt\n ? [{ key: \"Completed\", value: new Date(status.completedAt).toLocaleString() }]\n : []),\n ])\n );\n\n if (status.nodeStatuses && status.nodeStatuses.length > 0) {\n console.log(chalk.dim(\"\\nStep progress:\"));\n for (const node of status.nodeStatuses) {\n const nodeColor = getStatusColor(node.status);\n console.log(` ${nodeColor(getStatusIcon(node.status))} ${node.nodeId}`);\n }\n }\n\n if (status.error) {\n console.log(formatWarning(`\\nError: ${status.error}`));\n }\n\n if (status.status === \"success\" && status.output) {\n console.log(formatSuccess(\"\\nOutput:\"));\n console.log(JSON.stringify(status.output, null, 2));\n }\n}\n\nfunction getStatusColor(status: string): (text: string) => string {\n switch (status) {\n case \"success\":\n return chalk.green;\n case \"error\":\n return chalk.red;\n case \"cancelled\":\n return chalk.yellow;\n case \"running\":\n return chalk.blue;\n case \"pending\":\n default:\n return chalk.dim;\n }\n}\n\nfunction getStatusIcon(status: string): string {\n switch (status) {\n case \"success\":\n return \"✓\";\n case \"error\":\n return \"✕\";\n case \"running\":\n return \"●\";\n case \"pending\":\n default:\n return \"○\";\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { ensureValidToken } from \"../../lib/auth/index.js\";\nimport { oauthConfig, BASE_URL } from \"../../lib/config.js\";\nimport { outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\nimport { detectAgentSource } from \"../../lib/agent-detect.js\";\n\nexport interface ExecuteOptions extends OutputOptions {\n project: string;\n params?: string;\n}\n\nexport async function executeCommand(\n toolName: string,\n options: ExecuteOptions\n): Promise<void> {\n const spinner = options.json ? null : ora(`Executing ${toolName}...`).start();\n\n // Get valid access token\n const accessToken = await ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n outputError(\"Not authenticated. Run 'program auth login' first.\", options);\n process.exit(1);\n }\n\n // Parse params if provided\n let params: Record<string, unknown> = {};\n if (options.params) {\n try {\n params = JSON.parse(options.params) as Record<string, unknown>;\n } catch {\n spinner?.stop();\n outputError(\"Invalid JSON in --params\", options);\n process.exit(1);\n }\n }\n\n // Detect agent at runtime (not login time) for correct multi-agent support\n const source = detectAgentSource();\n\n try {\n const response = await fetch(`${BASE_URL}/api/cli/tool`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({\n projectId: options.project,\n tool: toolName,\n params,\n source,\n }),\n });\n\n const result = (await response.json()) as {\n success: boolean;\n data?: unknown;\n error?: string;\n compositionId?: string;\n };\n\n spinner?.stop();\n\n if (!response.ok || !result.success) {\n outputError(result.error ?? `Tool execution failed: ${response.status}`, options);\n process.exit(1);\n }\n\n if (options.json) {\n outputSuccess(result.data, options);\n } else {\n console.log(chalk.green(`✓ ${toolName} executed successfully`));\n if (result.compositionId) {\n console.log(chalk.dim(` Composition: ${result.compositionId}`));\n }\n console.log();\n console.log(JSON.stringify(result.data, null, 2));\n }\n } catch (error) {\n spinner?.stop();\n outputError(error instanceof Error ? error.message : \"Request failed\", options);\n process.exit(1);\n }\n}\n","/**\n * Runtime agent detection\n *\n * Detects which agent/IDE is running the CLI based on environment variables.\n * This is checked per-request, not at login time, so multiple agents can\n * use the same credentials simultaneously with correct attribution.\n */\n\n/**\n * Detect which agent is currently running this CLI command.\n * Returns undefined for unknown agents (will show as \"Agent via CLI\").\n */\nexport function detectAgentSource(): string | undefined {\n // Claude Code sets CLAUDECODE=1 (external env var from IDE, not project-owned)\n // eslint-disable-next-line turbo/no-undeclared-env-vars\n if (process.env.CLAUDECODE === \"1\") {\n return \"claude-code\";\n }\n\n // Future: Add detection for other agents when we know their env vars\n // OpenCode, Codex, Cursor, etc.\n\n // Unknown agent - return undefined to use default display\n return undefined;\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { BASE_URL } from \"../../lib/config.js\";\nimport { outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\n\nexport type ListOptions = OutputOptions;\n\ninterface Tool {\n name: string;\n description: string;\n inputs: string[];\n}\n\nexport async function listCommand(options: ListOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching available tools...\").start();\n\n try {\n const response = await fetch(`${BASE_URL}/api/cli/tool`, {\n method: \"GET\",\n });\n\n const result = (await response.json()) as {\n success: boolean;\n tools?: Tool[];\n error?: string;\n };\n\n spinner?.stop();\n\n if (!response.ok || !result.success) {\n outputError(result.error ?? \"Failed to list tools\", options);\n process.exit(1);\n }\n\n const tools = result.tools ?? [];\n\n if (options.json) {\n outputSuccess(tools, options);\n } else {\n console.log(chalk.bold(`Available Tools (${tools.length}):\\n`));\n\n for (const tool of tools) {\n console.log(chalk.cyan(` ${tool.name}`));\n console.log(chalk.dim(` ${tool.description}`));\n if (tool.inputs.length > 0) {\n console.log(chalk.dim(` Inputs: ${tool.inputs.join(\", \")}`));\n }\n console.log();\n }\n\n console.log(chalk.dim(\"Usage: program tool exec <toolName> --project <id> --params '{...}'\"));\n }\n } catch (error) {\n spinner?.stop();\n outputError(error instanceof Error ? error.message : \"Request failed\", options);\n process.exit(1);\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { ensureValidToken } from \"../../lib/auth/index.js\";\nimport { oauthConfig, BASE_URL } from \"../../lib/config.js\";\nimport { outputError, outputSuccess } from \"../../lib/output.js\";\nimport type {OutputOptions} from \"../../lib/output.js\";\nimport { detectAgentSource } from \"../../lib/agent-detect.js\";\n\nexport interface SendMessageOptions extends OutputOptions {\n project: string;\n role?: \"user\" | \"assistant\";\n}\n\nexport async function sendCommand(\n text: string,\n options: SendMessageOptions\n): Promise<void> {\n const spinner = options.json ? null : ora(\"Sending message...\").start();\n\n // Get valid access token\n const accessToken = await ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n outputError(\"Not authenticated. Run 'program auth login' first.\", options);\n process.exit(1);\n }\n\n const role = options.role ?? \"assistant\";\n\n // Detect agent at runtime (not login time) for correct multi-agent support\n const source = detectAgentSource();\n\n try {\n const response = await fetch(`${BASE_URL}/api/cli/message`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({\n projectId: options.project,\n role,\n text,\n source,\n }),\n });\n\n const result = (await response.json()) as {\n success: boolean;\n messageId?: string;\n error?: string;\n };\n\n spinner?.stop();\n\n if (!response.ok || !result.success) {\n outputError(result.error ?? `Failed to send message: ${response.status}`, options);\n process.exit(1);\n }\n\n if (options.json) {\n outputSuccess({ messageId: result.messageId, role, text }, options);\n } else {\n console.log(chalk.green(`✓ Message sent as ${role}`));\n if (result.messageId) {\n console.log(chalk.dim(` Message ID: ${result.messageId}`));\n }\n }\n } catch (error) {\n spinner?.stop();\n outputError(error instanceof Error ? error.message : \"Request failed\", options);\n process.exit(1);\n }\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { ensureValidToken } from \"../../lib/auth/index.js\";\nimport { oauthConfig, BASE_URL } from \"../../lib/config.js\";\nimport { outputError, outputSuccess } from \"../../lib/output.js\";\nimport type { OutputOptions } from \"../../lib/output.js\";\n\nexport interface ListMessageOptions extends OutputOptions {\n project: string;\n limit?: number;\n}\n\ninterface MessagePart {\n type: string;\n text?: string;\n toolName?: string;\n toolCallId?: string;\n state?: string;\n}\n\ninterface Message {\n id: string;\n role: \"user\" | \"assistant\";\n parts: MessagePart[];\n source?: string;\n createdAt: number;\n}\n\nexport async function listCommand(options: ListMessageOptions): Promise<void> {\n const spinner = options.json ? null : ora(\"Fetching messages...\").start();\n\n // Get valid access token\n const accessToken = await ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n outputError(\n \"Not authenticated. Run 'program auth login' first.\",\n options\n );\n process.exit(1);\n }\n\n try {\n const url = new URL(`${BASE_URL}/api/cli/message`);\n url.searchParams.set(\"projectId\", options.project);\n if (options.limit) {\n url.searchParams.set(\"limit\", options.limit.toString());\n }\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n const result = (await response.json()) as {\n success: boolean;\n chatId?: string;\n messages?: Message[];\n error?: string;\n };\n\n spinner?.stop();\n\n if (!response.ok || !result.success) {\n outputError(\n result.error ?? `Failed to fetch messages: ${response.status}`,\n options\n );\n process.exit(1);\n }\n\n if (options.json) {\n outputSuccess(result, options);\n } else {\n const messages = result.messages ?? [];\n if (messages.length === 0) {\n console.log(chalk.dim(\"No messages in this chat yet.\"));\n return;\n }\n\n console.log(chalk.bold(`Chat Messages (${messages.length}):\\n`));\n\n for (const msg of messages) {\n // Format the role with source if available\n let roleLabel = msg.role === \"user\" ? \"You\" : \"Assistant\";\n if (msg.source) {\n if (msg.source === \"cli:claude-code\") {\n roleLabel = \"Claude via CLI\";\n } else if (msg.source.startsWith(\"cli:\")) {\n roleLabel = `${roleLabel} via CLI`;\n }\n }\n\n // Get text content from parts\n const textContent = msg.parts\n .filter((p): p is MessagePart & { text: string } => p.type === \"text\" && !!p.text)\n .map((p) => p.text)\n .join(\"\\n\");\n\n // Get tool calls\n const toolCalls = msg.parts.filter(\n (p) => p.type === \"tool-invocation\" || p.type === \"tool-call\"\n );\n\n // Format timestamp\n const time = new Date(msg.createdAt).toLocaleTimeString();\n\n // Print message\n const roleColor = msg.role === \"user\" ? chalk.blue : chalk.green;\n console.log(roleColor(`[${time}] ${roleLabel}:`));\n\n if (textContent) {\n // Indent and truncate long messages\n const truncated =\n textContent.length > 500\n ? textContent.substring(0, 500) + \"...\"\n : textContent;\n console.log(\n truncated\n .split(\"\\n\")\n .map((line) => ` ${line}`)\n .join(\"\\n\")\n );\n }\n\n if (toolCalls.length > 0) {\n console.log(\n chalk.dim(` [${toolCalls.length} tool call(s)]`)\n );\n }\n\n console.log();\n }\n }\n } catch (error) {\n spinner?.stop();\n outputError(\n error instanceof Error ? error.message : \"Request failed\",\n options\n );\n process.exit(1);\n }\n}\n","import { outputSuccess } from \"../lib/output.js\";\nimport type {OutputOptions} from \"../lib/output.js\";\n\nexport interface DocsOptions extends OutputOptions {\n schema?: boolean;\n}\n\n// Command schema for agents\nconst COMMAND_SCHEMA = {\n name: \"program\",\n version: \"0.1.0\",\n description: \"CLI for interacting with the Program video creation platform\",\n commands: {\n auth: {\n description: \"Authentication commands\",\n subcommands: {\n login: {\n description: \"Authenticate with the Program platform\",\n options: {\n \"--json\": \"Output as JSON\",\n },\n example: \"program auth login\",\n },\n logout: {\n description: \"Log out from the Program platform\",\n options: {\n \"--json\": \"Output as JSON\",\n },\n example: \"program auth logout\",\n },\n status: {\n description: \"Check authentication status\",\n options: {\n \"--json\": \"Output as JSON\",\n },\n example: \"program auth status --json\",\n },\n },\n },\n project: {\n description: \"Project management commands\",\n subcommands: {\n create: {\n description: \"Create a new project\",\n options: {\n \"--title <title>\": \"Project title\",\n \"--description <desc>\": \"Project description\",\n \"--json\": \"Output as JSON\",\n },\n example: 'program project create --title \"My Video\" --json',\n },\n list: {\n description: \"List projects\",\n options: {\n \"--limit <n>\": \"Maximum number of projects to return\",\n \"--json\": \"Output as JSON\",\n },\n example: \"program project list --json\",\n },\n },\n },\n workflow: {\n description: \"Workflow template commands\",\n subcommands: {\n list: {\n description: \"List available workflow templates\",\n options: {\n \"--limit <n>\": \"Maximum number of templates to return\",\n \"--public-only\": \"Only show public templates\",\n \"--json\": \"Output as JSON\",\n },\n example: \"program workflow list --json\",\n },\n run: {\n description: \"Execute a workflow template\",\n args: {\n templateId: \"ID of the template to run\",\n },\n options: {\n \"--project <id>\": \"Project ID to associate with execution\",\n \"--input <json>\": \"JSON input for the workflow\",\n \"--json\": \"Output as JSON\",\n },\n example: \"program workflow run tmpl_abc --project proj_123 --input '{\\\"files\\\":[\\\"src/main.ts\\\"]}' --json\",\n },\n status: {\n description: \"Check workflow execution status\",\n args: {\n executionId: \"ID of the execution to check\",\n },\n options: {\n \"--watch\": \"Continuously poll for status updates\",\n \"--interval <ms>\": \"Poll interval in milliseconds (default: 2000)\",\n \"--json\": \"Output as JSON\",\n },\n example: \"program workflow status exec_789 --watch --json\",\n },\n },\n },\n docs: {\n description: \"Display CLI documentation\",\n options: {\n \"--schema\": \"Output full command schema as JSON\",\n },\n example: \"program docs --schema\",\n },\n },\n globalOptions: {\n \"--help\": \"Display help information\",\n \"--version\": \"Display version number\",\n },\n notes: [\n \"Always use --json flag for parseable output when integrating with agents\",\n \"Workflow inputs should be valid JSON strings\",\n \"Run 'program auth login' first to authenticate\",\n ],\n};\n\nexport function docsCommand(options: DocsOptions): void {\n if (options.schema ?? options.json) {\n outputSuccess(COMMAND_SCHEMA, { json: true });\n } else {\n printHumanDocs();\n }\n}\n\nfunction printHumanDocs(): void {\n console.log(`\nProgram CLI v${COMMAND_SCHEMA.version}\n${COMMAND_SCHEMA.description}\n\nCOMMANDS:\n\n auth login Authenticate with the Program platform\n auth logout Log out from the Program platform\n auth status Check authentication status\n\n project create Create a new project\n project list List projects\n\n workflow list List available workflow templates\n workflow run <id> Execute a workflow template\n workflow status <id> Check workflow execution status\n\n docs Display this documentation\n docs --schema Output full command schema as JSON\n\nGLOBAL OPTIONS:\n\n --json Output as JSON (recommended for agents)\n --help Display help information\n --version Display version number\n\nEXAMPLES:\n\n # Authenticate\n program auth login\n\n # Create a project\n program project create --title \"My Video\" --json\n\n # Run a workflow\n program workflow run tmpl_abc --project proj_123 --json\n\n # Watch execution progress\n program workflow status exec_789 --watch --json\n\nFor agent integration, always use the --json flag.\n`);\n}\n"],"mappings":"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","names":["chalk","message","chalk","message","chalk","chalk","minutes","chalk","ora","URL","CLIENT_ID","CLIENT_ID","ora","chalk","chalk","ora","ora","project","chalk","chalk","ora","ora","chalk","chalk","ora","listCommand","ora","chalk","chalk","ora","ora","chalk","chalk","ora","statusCommand","ora","chalk","chalk","ora","ora","chalk","chalk","ora","listCommand","ora","chalk","tool","chalk","ora","ora","chalk","chalk","ora","listCommand","ora","chalk","listCommand","statusCommand"]}
|