@program-video/cli 0.1.4 → 0.1.5
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/AGENTS.md +12 -5
- package/dist/index.js +14 -64
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -17,19 +17,26 @@ npx @program-video/cli tool exec addScene --project <projectId> --params '{"titl
|
|
|
17
17
|
|
|
18
18
|
## Authentication
|
|
19
19
|
|
|
20
|
-
**Always
|
|
20
|
+
**Always check auth status first, then authenticate if needed.**
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npx @program-video/cli auth
|
|
23
|
+
npx @program-video/cli auth status --json
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
If not authenticated, run login and **relay the code to the user**:
|
|
27
27
|
|
|
28
|
-
Check auth status:
|
|
29
28
|
```bash
|
|
30
|
-
npx @program-video/cli auth
|
|
29
|
+
npx @program-video/cli auth login
|
|
31
30
|
```
|
|
32
31
|
|
|
32
|
+
The command outputs a URL and code. **You MUST tell the user both:**
|
|
33
|
+
- The URL to visit (e.g., `https://program.video/device`)
|
|
34
|
+
- The code to enter (e.g., `ABCD-1234`)
|
|
35
|
+
|
|
36
|
+
Example: "Please visit https://program.video/device and enter code **ABCD-1234** to authorize."
|
|
37
|
+
|
|
38
|
+
Wait for the command to complete - it confirms when authenticated. Credentials are stored in `~/.program/credentials.json`.
|
|
39
|
+
|
|
33
40
|
## Commands
|
|
34
41
|
|
|
35
42
|
### Projects
|
package/dist/index.js
CHANGED
|
@@ -198,13 +198,7 @@ async function pollUntilComplete(config, deviceCode) {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
// src/lib/config.ts
|
|
201
|
-
|
|
202
|
-
return process.env[key] ?? defaultValue;
|
|
203
|
-
}
|
|
204
|
-
var BASE_URL = getEnvOrDefault(
|
|
205
|
-
"BASE_URL",
|
|
206
|
-
"https://program.video"
|
|
207
|
-
);
|
|
201
|
+
var BASE_URL = "https://program.video";
|
|
208
202
|
var CONVEX_URL = "https://keen-eel-920.convex.cloud";
|
|
209
203
|
var oauthConfig = {
|
|
210
204
|
baseUrl: BASE_URL
|
|
@@ -275,16 +269,15 @@ async function loginCommand(options) {
|
|
|
275
269
|
const deviceAuth = await startDeviceAuth(oauthConfig);
|
|
276
270
|
spinner?.stop();
|
|
277
271
|
spinner?.clear();
|
|
278
|
-
|
|
279
|
-
void open(authUrl).catch(() => {
|
|
272
|
+
void open(deviceAuth.verificationUrl).catch(() => {
|
|
280
273
|
});
|
|
281
274
|
console.log();
|
|
282
275
|
console.log(chalk2.bold(" Sign in to Program"));
|
|
283
276
|
console.log();
|
|
284
|
-
console.log(`
|
|
285
|
-
console.log(`
|
|
277
|
+
console.log(` URL: ${chalk2.cyan(deviceAuth.verificationUrl)}`);
|
|
278
|
+
console.log(` Code: ${chalk2.bold.yellow(formatUserCode(deviceAuth.userCode))}`);
|
|
286
279
|
console.log();
|
|
287
|
-
console.log(
|
|
280
|
+
console.log(chalk2.dim(" Enter the code above in your browser to authorize."));
|
|
288
281
|
console.log();
|
|
289
282
|
const waitingSpinner = showSpinner ? ora("Waiting for authorization...").start() : null;
|
|
290
283
|
const credentials = await deviceAuth.pollForCompletion();
|
|
@@ -400,52 +393,7 @@ import chalk4 from "chalk";
|
|
|
400
393
|
import ora2 from "ora";
|
|
401
394
|
|
|
402
395
|
// src/lib/auth/oauth.ts
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
// src/lib/auth/pkce.ts
|
|
406
|
-
import * as crypto from "crypto";
|
|
407
|
-
|
|
408
|
-
// src/lib/auth/callback-server.ts
|
|
409
|
-
import * as http from "http";
|
|
410
|
-
import { URL as URL2 } from "url";
|
|
411
|
-
|
|
412
|
-
// src/lib/auth/oauth.ts
|
|
413
|
-
var CALLBACK_PORT = 8976;
|
|
414
|
-
var REDIRECT_URI = `http://localhost:${CALLBACK_PORT}/callback`;
|
|
415
|
-
var CLIENT_ID2 = "program-cli";
|
|
416
|
-
async function refreshAccessToken(config) {
|
|
417
|
-
const creds = getCredentials();
|
|
418
|
-
if (!creds?.refreshToken) {
|
|
419
|
-
return null;
|
|
420
|
-
}
|
|
421
|
-
const tokenUrl = new URL("/api/auth/oauth2/token", config.baseUrl);
|
|
422
|
-
const body = new URLSearchParams({
|
|
423
|
-
grant_type: "refresh_token",
|
|
424
|
-
client_id: CLIENT_ID2,
|
|
425
|
-
refresh_token: creds.refreshToken
|
|
426
|
-
});
|
|
427
|
-
const response = await fetch(tokenUrl.toString(), {
|
|
428
|
-
method: "POST",
|
|
429
|
-
headers: {
|
|
430
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
431
|
-
},
|
|
432
|
-
body: body.toString()
|
|
433
|
-
});
|
|
434
|
-
if (!response.ok) {
|
|
435
|
-
return null;
|
|
436
|
-
}
|
|
437
|
-
const tokens = await response.json();
|
|
438
|
-
const expiresAt = Math.floor(Date.now() / 1e3) + tokens.expires_in;
|
|
439
|
-
const newCredentials = {
|
|
440
|
-
...creds,
|
|
441
|
-
accessToken: tokens.access_token,
|
|
442
|
-
refreshToken: tokens.refresh_token ?? creds.refreshToken,
|
|
443
|
-
expiresAt
|
|
444
|
-
};
|
|
445
|
-
saveCredentials(newCredentials);
|
|
446
|
-
return newCredentials;
|
|
447
|
-
}
|
|
448
|
-
async function ensureValidToken(config) {
|
|
396
|
+
function ensureValidToken(_config) {
|
|
449
397
|
const creds = getCredentials();
|
|
450
398
|
if (!creds) {
|
|
451
399
|
return null;
|
|
@@ -456,8 +404,7 @@ async function ensureValidToken(config) {
|
|
|
456
404
|
if (now < expiresAt - bufferMs) {
|
|
457
405
|
return creds.accessToken;
|
|
458
406
|
}
|
|
459
|
-
|
|
460
|
-
return refreshed?.accessToken ?? null;
|
|
407
|
+
return null;
|
|
461
408
|
}
|
|
462
409
|
|
|
463
410
|
// src/lib/convex.ts
|
|
@@ -474,7 +421,7 @@ function createConvexClient(config) {
|
|
|
474
421
|
return callGateway(functionPath, args);
|
|
475
422
|
}
|
|
476
423
|
async function callGateway(functionPath, args) {
|
|
477
|
-
const accessToken =
|
|
424
|
+
const accessToken = ensureValidToken(config.oauthConfig);
|
|
478
425
|
if (!accessToken) {
|
|
479
426
|
return {
|
|
480
427
|
success: false,
|
|
@@ -883,6 +830,9 @@ function detectAgentSource() {
|
|
|
883
830
|
if (process.env.CLAUDECODE === "1") {
|
|
884
831
|
return "claude-code";
|
|
885
832
|
}
|
|
833
|
+
if (process.env.OPENCODE === "1") {
|
|
834
|
+
return "opencode";
|
|
835
|
+
}
|
|
886
836
|
return void 0;
|
|
887
837
|
}
|
|
888
838
|
|
|
@@ -890,7 +840,7 @@ function detectAgentSource() {
|
|
|
890
840
|
async function executeCommand(toolName, options) {
|
|
891
841
|
const showSpinner = !options.json && process.stdout.isTTY;
|
|
892
842
|
const spinner = showSpinner ? ora8(`Executing ${toolName}...`).start() : null;
|
|
893
|
-
const accessToken =
|
|
843
|
+
const accessToken = ensureValidToken(oauthConfig);
|
|
894
844
|
if (!accessToken) {
|
|
895
845
|
spinner?.stop();
|
|
896
846
|
spinner?.clear();
|
|
@@ -995,7 +945,7 @@ import ora10 from "ora";
|
|
|
995
945
|
async function sendCommand(text, options) {
|
|
996
946
|
const showSpinner = !options.json && process.stdout.isTTY;
|
|
997
947
|
const spinner = showSpinner ? ora10("Sending message...").start() : null;
|
|
998
|
-
const accessToken =
|
|
948
|
+
const accessToken = ensureValidToken(oauthConfig);
|
|
999
949
|
if (!accessToken) {
|
|
1000
950
|
spinner?.stop();
|
|
1001
951
|
spinner?.clear();
|
|
@@ -1047,7 +997,7 @@ import ora11 from "ora";
|
|
|
1047
997
|
async function listCommand4(options) {
|
|
1048
998
|
const showSpinner = !options.json && process.stdout.isTTY;
|
|
1049
999
|
const spinner = showSpinner ? ora11("Fetching messages...").start() : null;
|
|
1050
|
-
const accessToken =
|
|
1000
|
+
const accessToken = ensureValidToken(oauthConfig);
|
|
1051
1001
|
if (!accessToken) {
|
|
1052
1002
|
spinner?.stop();
|
|
1053
1003
|
spinner?.clear();
|
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 open from \"open\";\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 showSpinner = process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Requesting device code...\").start() : null;\n\n try {\n const deviceAuth = await startDeviceAuth(oauthConfig);\n spinner?.stop();\n spinner?.clear();\n\n // Try to open the browser automatically (fire and forget, errors handled silently)\n const authUrl = deviceAuth.verificationUrlComplete ?? deviceAuth.verificationUrl;\n void open(authUrl).catch(() => {\n // Silently ignore - URL is displayed below for manual access\n });\n\n // Display the code and URL for the user (always show for headless/cloud environments)\n console.log();\n console.log(chalk.bold(\" Sign in to Program\"));\n console.log();\n console.log(` Your browser should open automatically.`);\n console.log(` If not, visit: ${chalk.cyan(deviceAuth.verificationUrl)}`);\n console.log();\n console.log(` Enter code: ${chalk.bold.yellow(formatUserCode(deviceAuth.userCode))}`);\n console.log();\n\n const waitingSpinner = showSpinner ? ora(\"Waiting for authorization...\").start() : null;\n\n // Poll until the user completes auth\n const credentials = await deviceAuth.pollForCompletion();\n\n waitingSpinner?.stop();\n waitingSpinner?.clear();\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 // Only show spinner in TTY environments (not through npx/pipes)\n const showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Creating project...\").start() : null;\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching project...\").start() : null;\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 spinner?.clear();\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 // Only show spinner in TTY environments (not through npx/pipes)\n const showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching projects...\").start() : null;\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching workflow templates...\").start() : null;\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Starting workflow execution...\").start() : null;\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 spinner?.clear();\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching execution status...\").start() : null;\n\n const result = await client.query<ExecutionStatus>(\"workflows.status\", {\n executionId,\n });\n\n spinner?.stop();\n spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(`Executing ${toolName}...`).start() : null;\n\n // Get valid access token\n const accessToken = await ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n spinner?.clear();\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 spinner?.clear();\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 spinner?.clear();\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching available tools...\").start() : null;\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 spinner?.clear();\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Sending message...\").start() : null;\n\n // Get valid access token\n const accessToken = await ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n spinner?.clear();\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 spinner?.clear();\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching messages...\").start() : null;\n\n // Get valid access token\n const accessToken = await ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n spinner?.clear();\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 spinner?.clear();\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 spinner?.clear();\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","open","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/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 open from \"open\";\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 showSpinner = process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Requesting device code...\").start() : null;\n\n try {\n const deviceAuth = await startDeviceAuth(oauthConfig);\n spinner?.stop();\n spinner?.clear();\n\n // Try to open the browser automatically (use base URL, not the one with code embedded)\n // User must manually enter the code for security\n void open(deviceAuth.verificationUrl).catch(() => {\n // Silently ignore - URL is displayed below for manual access\n });\n\n // Always display the code and URL (essential for agents/headless environments)\n console.log();\n console.log(chalk.bold(\" Sign in to Program\"));\n console.log();\n console.log(` URL: ${chalk.cyan(deviceAuth.verificationUrl)}`);\n console.log(` Code: ${chalk.bold.yellow(formatUserCode(deviceAuth.userCode))}`);\n console.log();\n console.log(chalk.dim(\" Enter the code above in your browser to authorize.\"));\n console.log();\n\n const waitingSpinner = showSpinner ? ora(\"Waiting for authorization...\").start() : null;\n\n // Poll until the user completes auth\n const credentials = await deviceAuth.pollForCompletion();\n\n waitingSpinner?.stop();\n waitingSpinner?.clear();\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// Production URLs - hardcoded to prevent credential theft via env var manipulation\nexport const BASE_URL = \"https://program.video\";\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 // Only show spinner in TTY environments (not through npx/pipes)\n const showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Creating project...\").start() : null;\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 spinner?.clear();\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 { getCredentials } from \"./credentials.js\";\n\nexport interface OAuthConfig {\n baseUrl: string;\n}\n\n/**\n * Ensure we have a valid access token.\n * For device auth, we don't refresh - user must re-authenticate if expired.\n */\nexport function ensureValidToken(_config: OAuthConfig): 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 // Token expired - user needs to re-authenticate\n return null;\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 = 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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching project...\").start() : null;\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 spinner?.clear();\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 // Only show spinner in TTY environments (not through npx/pipes)\n const showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching projects...\").start() : null;\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching workflow templates...\").start() : null;\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Starting workflow execution...\").start() : null;\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 spinner?.clear();\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching execution status...\").start() : null;\n\n const result = await client.query<ExecutionStatus>(\"workflows.status\", {\n executionId,\n });\n\n spinner?.stop();\n spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(`Executing ${toolName}...`).start() : null;\n\n // Get valid access token\n const accessToken = ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n spinner?.clear();\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 spinner?.clear();\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 spinner?.clear();\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 spinner?.clear();\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 if (process.env.CLAUDECODE === \"1\") {\n return \"claude-code\";\n }\n\n if (process.env.OPENCODE === \"1\") {\n return \"opencode\";\n }\n\n // OpenClaw and other agents will fall back to \"Agent via CLI\" until\n // they implement detection env vars\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching available tools...\").start() : null;\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 spinner?.clear();\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Sending message...\").start() : null;\n\n // Get valid access token\n const accessToken = ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n spinner?.clear();\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 spinner?.clear();\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 spinner?.clear();\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 showSpinner = !options.json && process.stdout.isTTY;\n const spinner = showSpinner ? ora(\"Fetching messages...\").start() : null;\n\n // Get valid access token\n const accessToken = ensureValidToken(oauthConfig);\n if (!accessToken) {\n spinner?.stop();\n spinner?.clear();\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 spinner?.clear();\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 spinner?.clear();\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","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"]}
|