olakai-cli 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +211 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/login.ts","../src/lib/config.ts","../src/lib/auth.ts","../src/lib/api.ts","../src/commands/logout.ts","../src/commands/whoami.ts","../src/commands/agents.ts","../src/commands/workflows.ts","../src/commands/kpis.ts","../src/commands/custom-data.ts","../src/commands/activity.ts","../src/commands/monitor.ts","../src/commands/monitor-transcript.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { createRequire } from \"module\";\nimport { Command } from \"commander\";\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { whoamiCommand } from \"./commands/whoami.js\";\nimport { registerAgentsCommand } from \"./commands/agents.js\";\nimport { registerWorkflowsCommand } from \"./commands/workflows.js\";\nimport { registerKpisCommand } from \"./commands/kpis.js\";\nimport { registerCustomDataCommand } from \"./commands/custom-data.js\";\nimport { registerActivityCommand } from \"./commands/activity.js\";\nimport { registerMonitorCommand } from \"./commands/monitor.js\";\nimport {\n setEnvironment,\n isValidEnvironment,\n getValidEnvironments,\n type Environment,\n} from \"./lib/config.js\";\n\nconst require = createRequire(import.meta.url);\nconst packageJson = require(\"../package.json\") as { version: string };\n\nconst program = new Command();\n\nprogram\n .name(\"olakai\")\n .description(\"Olakai CLI tool\")\n .version(packageJson.version)\n .option(\n \"-e, --env <environment>\",\n `Environment to use (${getValidEnvironments().join(\", \")})`,\n \"production\",\n )\n .hook(\"preAction\", (thisCommand) => {\n const options = thisCommand.opts();\n if (options.env) {\n if (!isValidEnvironment(options.env)) {\n console.error(\n `Invalid environment: ${options.env}. Valid options: ${getValidEnvironments().join(\", \")}`,\n );\n process.exit(1);\n }\n setEnvironment(options.env as Environment);\n }\n });\n\nprogram\n .command(\"login\")\n .description(\"Log in to Olakai using browser authentication\")\n .action(loginCommand);\n\nprogram\n .command(\"logout\")\n .description(\"Log out from Olakai\")\n .action(logoutCommand);\n\nprogram\n .command(\"whoami\")\n .description(\"Show current logged-in user\")\n .action(whoamiCommand);\n\n// Register subcommands for config management\nregisterAgentsCommand(program);\nregisterWorkflowsCommand(program);\nregisterKpisCommand(program);\nregisterCustomDataCommand(program);\n\n// Register subcommands for activity inspection\nregisterActivityCommand(program);\n\n// Register subcommands for local agent monitoring\nregisterMonitorCommand(program);\n\nprogram.parse();\n","import open from \"open\";\nimport { requestDeviceCode, pollForToken, getCurrentUser } from \"../lib/api.js\";\nimport { saveToken, isTokenValid } from \"../lib/auth.js\";\nimport { getEnvironment } from \"../lib/config.js\";\n\nconst POLL_INTERVAL_MS = 5000; // 5 seconds\n\n/**\n * Login command handler\n */\nexport async function loginCommand(): Promise<void> {\n // Check if already logged in\n if (isTokenValid()) {\n try {\n const user = await getCurrentUser();\n console.log(`Already logged in as ${user.email}`);\n console.log(\"Run 'olakai logout' to log out first.\");\n return;\n } catch {\n // Token is invalid, continue with login\n }\n }\n\n console.log(`Logging in to Olakai (${getEnvironment()})...\\n`);\n\n try {\n // Request device code\n const deviceCode = await requestDeviceCode();\n\n // Display instructions\n console.log(\"To complete login, visit:\");\n console.log(`\\n ${deviceCode.verification_uri_complete}\\n`);\n console.log(`Or go to ${deviceCode.verification_uri} and enter code:`);\n console.log(`\\n ${deviceCode.user_code}\\n`);\n\n // Try to open browser\n console.log(\"Opening browser...\");\n try {\n await open(deviceCode.verification_uri_complete);\n } catch {\n console.log(\"(Could not open browser automatically)\");\n }\n\n console.log(\"\\nWaiting for authorization...\");\n\n // Poll for token\n const expiresAt = Date.now() + deviceCode.expires_in * 1000;\n\n while (Date.now() < expiresAt) {\n await sleep(POLL_INTERVAL_MS);\n\n try {\n const tokenResponse = await pollForToken(deviceCode.device_code);\n\n if (tokenResponse) {\n // Save token\n saveToken(tokenResponse.access_token, tokenResponse.expires_in);\n\n // Get user info\n const user = await getCurrentUser();\n\n console.log(`\\nLogged in as ${user.email}`);\n console.log(`Account: ${user.accountId}`);\n console.log(`Role: ${user.role}`);\n return;\n }\n\n // Still pending, show spinner\n process.stdout.write(\".\");\n } catch (error) {\n if (error instanceof Error) {\n console.error(`\\nLogin failed: ${error.message}`);\n } else {\n console.error(\"\\nLogin failed: Unknown error\");\n }\n process.exit(1);\n }\n }\n\n console.error(\"\\nLogin timed out. Please try again.\");\n process.exit(1);\n } catch (error) {\n if (error instanceof Error) {\n console.error(`Login failed: ${error.message}`);\n } else {\n console.error(\"Login failed: Unknown error\");\n }\n process.exit(1);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","export type Environment = \"production\" | \"staging\" | \"local\";\n\nconst HOSTS: Record<Environment, string> = {\n production: \"https://app.olakai.ai\",\n staging: \"https://staging.app.olakai.ai\",\n local: \"http://localhost:3000\",\n};\n\n// CLI client identifier\nexport const CLIENT_ID = \"olakai-cli\";\n\nlet currentEnvironment: Environment = \"production\";\n\n/**\n * Set the current environment\n */\nexport function setEnvironment(env: Environment): void {\n currentEnvironment = env;\n}\n\n/**\n * Get the current environment from:\n * 1. Environment variable OLAKAI_ENV\n * 2. Programmatically set value\n * 3. Default to \"production\"\n */\nexport function getEnvironment(): Environment {\n const envVar = process.env.OLAKAI_ENV as Environment | undefined;\n if (envVar && isValidEnvironment(envVar)) {\n return envVar;\n }\n return currentEnvironment;\n}\n\n/**\n * Get the API base URL for the current environment\n */\nexport function getBaseUrl(): string {\n return HOSTS[getEnvironment()];\n}\n\n/**\n * Check if a string is a valid environment\n */\nexport function isValidEnvironment(env: string): env is Environment {\n return env === \"production\" || env === \"staging\" || env === \"local\";\n}\n\n/**\n * Get list of valid environments for CLI help\n */\nexport function getValidEnvironments(): Environment[] {\n return [\"production\", \"staging\", \"local\"];\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { type Environment, getEnvironment } from \"./config.js\";\n\ninterface StoredCredentials {\n token: string;\n expiresAt: number; // Unix timestamp in seconds\n environment: Environment;\n}\n\n/**\n * Get the credentials file path\n */\nfunction getCredentialsPath(): string {\n const configDir = path.join(os.homedir(), \".config\", \"olakai\");\n return path.join(configDir, \"credentials.json\");\n}\n\n/**\n * Ensure the config directory exists\n */\nfunction ensureConfigDir(): void {\n const configDir = path.dirname(getCredentialsPath());\n if (!fs.existsSync(configDir)) {\n fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });\n }\n}\n\n/**\n * Save an access token to disk\n */\nexport function saveToken(token: string, expiresIn: number): void {\n ensureConfigDir();\n\n const credentials: StoredCredentials = {\n token,\n expiresAt: Math.floor(Date.now() / 1000) + expiresIn,\n environment: getEnvironment(),\n };\n\n const credentialsPath = getCredentialsPath();\n fs.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {\n mode: 0o600, // Read/write for owner only\n });\n}\n\n/**\n * Load the stored token\n */\nexport function loadToken(): StoredCredentials | null {\n const credentialsPath = getCredentialsPath();\n\n if (!fs.existsSync(credentialsPath)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(credentialsPath, \"utf-8\");\n const credentials = JSON.parse(content) as StoredCredentials;\n return credentials;\n } catch {\n return null;\n }\n}\n\n/**\n * Clear stored credentials\n */\nexport function clearToken(): void {\n const credentialsPath = getCredentialsPath();\n\n if (fs.existsSync(credentialsPath)) {\n fs.unlinkSync(credentialsPath);\n }\n}\n\n/**\n * Check if the stored token is valid (exists and not expired)\n */\nexport function isTokenValid(): boolean {\n const credentials = loadToken();\n\n if (!credentials) {\n return false;\n }\n\n // Check if expired (with 60 second buffer)\n const now = Math.floor(Date.now() / 1000);\n if (credentials.expiresAt <= now + 60) {\n return false;\n }\n\n // Check if environment matches\n if (credentials.environment !== getEnvironment()) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Get the current valid token or null\n */\nexport function getValidToken(): string | null {\n if (!isTokenValid()) {\n return null;\n }\n\n const credentials = loadToken();\n return credentials?.token ?? null;\n}\n","import { getBaseUrl, CLIENT_ID } from \"./config.js\";\nimport { getValidToken } from \"./auth.js\";\n\nexport interface 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\nexport interface TokenResponse {\n access_token: string;\n token_type: string;\n expires_in: number;\n}\n\nexport interface TokenErrorResponse {\n error: \"authorization_pending\" | \"expired_token\" | \"access_denied\";\n error_description?: string;\n}\n\nexport interface UserMeResponse {\n id: string;\n email: string;\n firstName: string;\n lastName: string;\n role: string;\n accountId: string;\n}\n\n// Config API Types\nexport interface AgentApiKey {\n id: string;\n key?: string; // Only present on creation\n keyMasked: string;\n isActive: boolean;\n createdAt?: string;\n}\n\nexport type DefaultAggregationMethod =\n | \"SUM\"\n | \"AVERAGE\"\n | \"COUNT\"\n | \"MIN\"\n | \"MAX\"\n | \"LATEST\";\n\nexport type KpiScope = \"PROMPT_REQUEST\" | \"CHAT\" | \"DOCUMENT\";\n\nexport interface KpiDefinition {\n id: string;\n name: string;\n description: string | null;\n type: \"PREDEFINED\" | \"USER_DEFINED\";\n category: string | null;\n agentId: string | null;\n scope: KpiScope;\n calculatorId: string;\n calculatorParams: Record<string, unknown> | null;\n unit: string | null;\n defaultAggregationMethod: DefaultAggregationMethod;\n isActive: boolean;\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport interface CreateKpiPayload {\n name: string;\n description?: string;\n type?: \"PREDEFINED\" | \"USER_DEFINED\";\n category?: string;\n agentId?: string;\n scope: KpiScope;\n calculatorId: string;\n calculatorParams?: Record<string, unknown>;\n unit?: string;\n defaultAggregationMethod?: DefaultAggregationMethod;\n}\n\nexport interface UpdateKpiPayload {\n name?: string;\n description?: string | null;\n type?: \"PREDEFINED\" | \"USER_DEFINED\";\n category?: string | null;\n agentId?: string | null;\n scope?: KpiScope;\n calculatorId?: string;\n calculatorParams?: Record<string, unknown>;\n unit?: string | null;\n defaultAggregationMethod?: DefaultAggregationMethod;\n isActive?: boolean;\n}\n\nexport interface ContextVariable {\n name: string;\n description: string;\n type: \"string\" | \"number\" | \"boolean\";\n sampleValue?: string | number | boolean;\n source: \"shared\" | \"custom\";\n}\n\nexport interface FormulaValidationResult {\n valid: boolean;\n error?: string;\n type?: string | null;\n charIndex?: number;\n parsedFormula?: unknown;\n}\n\nexport interface Agent {\n id: string;\n name: string;\n description: string;\n role: \"WORKER\" | \"COORDINATOR\";\n source: \"SDK\" | \"AUTOMATION_PROVIDER\";\n workflowId: string | null;\n category: string | null;\n apiKey: AgentApiKey | null;\n kpiDefinitions?: KpiDefinition[];\n workflow?: Workflow | null;\n}\n\nexport interface Workflow {\n id: string;\n name: string;\n description: string | null;\n isActive: boolean;\n agentCount: number;\n agents?: Agent[];\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport interface CreateAgentPayload {\n name: string;\n description?: string;\n role?: \"WORKER\" | \"COORDINATOR\";\n workflowId?: string;\n createApiKey?: boolean;\n category?: string;\n source?: string;\n}\n\nexport interface UpdateAgentPayload {\n name?: string;\n description?: string;\n role?: \"WORKER\" | \"COORDINATOR\";\n workflowId?: string | null;\n category?: string | null;\n}\n\nexport interface CreateWorkflowPayload {\n name: string;\n description?: string;\n}\n\nexport interface UpdateWorkflowPayload {\n name?: string;\n description?: string | null;\n isActive?: boolean;\n}\n\n/**\n * Request a device code to start the login flow\n */\nexport async function requestDeviceCode(): Promise<DeviceCodeResponse> {\n const response = await fetch(`${getBaseUrl()}/api/auth/device/code`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ client_id: CLIENT_ID }),\n });\n\n if (!response.ok) {\n const error = (await response.json()) as { error_description?: string; error?: string };\n throw new Error(error.error_description || error.error || \"Failed to request device code\");\n }\n\n return (await response.json()) as DeviceCodeResponse;\n}\n\n/**\n * Poll for token exchange\n * Returns the token response if approved, or throws an error\n */\nexport async function pollForToken(\n deviceCode: string,\n): Promise<TokenResponse | null> {\n const response = await fetch(`${getBaseUrl()}/api/auth/device/token`, {\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 const data = (await response.json()) as TokenResponse | TokenErrorResponse;\n\n if (!response.ok) {\n if (\"error\" in data && data.error === \"authorization_pending\") {\n return null; // Still waiting for user\n }\n const errorMsg = \"error_description\" in data ? data.error_description : (\"error\" in data ? data.error : \"Token exchange failed\");\n throw new Error(errorMsg || \"Token exchange failed\");\n }\n\n return data as TokenResponse;\n}\n\n/**\n * Get current user info\n */\nexport async function getCurrentUser(): Promise<UserMeResponse> {\n const token = getValidToken();\n\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/user/me`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n throw new Error(\"Failed to get user info\");\n }\n\n return (await response.json()) as UserMeResponse;\n}\n\n// ============================================\n// Config API - Agents\n// ============================================\n\n/**\n * List agents for the current account\n */\nexport async function listAgents(options?: {\n includeKpis?: boolean;\n}): Promise<Agent[]> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (options?.includeKpis) {\n params.set(\"includeKpis\", \"true\");\n }\n\n const url = `${getBaseUrl()}/api/config/agents${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list agents\");\n }\n\n const data = (await response.json()) as { agents: Agent[] };\n return data.agents;\n}\n\n/**\n * Get a single agent by ID\n */\nexport async function getAgent(id: string): Promise<Agent> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/agents/${id}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Agent not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get agent\");\n }\n\n return (await response.json()) as Agent;\n}\n\n/**\n * Create a new agent\n */\nexport async function createAgent(payload: CreateAgentPayload): Promise<Agent> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/agents`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 409) {\n throw new Error(\"An agent with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to create agent\");\n }\n\n return (await response.json()) as Agent;\n}\n\n/**\n * Update an agent\n */\nexport async function updateAgent(\n id: string,\n payload: UpdateAgentPayload,\n): Promise<Agent> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/agents/${id}`, {\n method: \"PUT\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Agent not found\");\n }\n if (response.status === 409) {\n throw new Error(\"An agent with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to update agent\");\n }\n\n return (await response.json()) as Agent;\n}\n\n/**\n * Delete an agent\n */\nexport async function deleteAgent(id: string): Promise<void> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/agents/${id}`, {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Agent not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to delete agent\");\n }\n}\n\n// ============================================\n// Config API - Workflows\n// ============================================\n\n/**\n * List workflows for the current account\n */\nexport async function listWorkflows(options?: {\n includeAgents?: boolean;\n includeInactive?: boolean;\n}): Promise<Workflow[]> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (options?.includeAgents) {\n params.set(\"includeAgents\", \"true\");\n }\n if (options?.includeInactive) {\n params.set(\"includeInactive\", \"true\");\n }\n\n const url = `${getBaseUrl()}/api/config/workflows${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list workflows\");\n }\n\n const data = (await response.json()) as { workflows: Workflow[] };\n return data.workflows;\n}\n\n/**\n * Get a single workflow by ID\n */\nexport async function getWorkflow(id: string): Promise<Workflow> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/workflows/${id}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Workflow not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get workflow\");\n }\n\n return (await response.json()) as Workflow;\n}\n\n/**\n * Create a new workflow\n */\nexport async function createWorkflow(\n payload: CreateWorkflowPayload,\n): Promise<Workflow> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/workflows`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 409) {\n throw new Error(\"A workflow with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to create workflow\");\n }\n\n return (await response.json()) as Workflow;\n}\n\n/**\n * Update a workflow\n */\nexport async function updateWorkflow(\n id: string,\n payload: UpdateWorkflowPayload,\n): Promise<Workflow> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/workflows/${id}`, {\n method: \"PUT\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Workflow not found\");\n }\n if (response.status === 409) {\n throw new Error(\"A workflow with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to update workflow\");\n }\n\n return (await response.json()) as Workflow;\n}\n\n/**\n * Delete a workflow\n */\nexport async function deleteWorkflow(id: string): Promise<void> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/workflows/${id}`, {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Workflow not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to delete workflow\");\n }\n}\n\n// ============================================\n// Config API - KPIs\n// ============================================\n\n/**\n * List KPI definitions for the current account\n */\nexport async function listKpis(options?: {\n agentId?: string;\n includeInactive?: boolean;\n}): Promise<KpiDefinition[]> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (options?.agentId) {\n params.set(\"agentId\", options.agentId);\n }\n if (options?.includeInactive) {\n params.set(\"includeInactive\", \"true\");\n }\n\n const url = `${getBaseUrl()}/api/config/kpis${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list KPIs\");\n }\n\n const data = (await response.json()) as { kpiDefinitions: KpiDefinition[] };\n return data.kpiDefinitions;\n}\n\n/**\n * Get a single KPI definition by ID\n */\nexport async function getKpi(id: string): Promise<KpiDefinition> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/kpis/${id}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"KPI definition not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get KPI\");\n }\n\n return (await response.json()) as KpiDefinition;\n}\n\n/**\n * Create a new KPI definition\n */\nexport async function createKpi(payload: CreateKpiPayload): Promise<KpiDefinition> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/kpis`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 409) {\n throw new Error(\"A KPI definition with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to create KPI\");\n }\n\n return (await response.json()) as KpiDefinition;\n}\n\n/**\n * Update a KPI definition\n */\nexport async function updateKpi(\n id: string,\n payload: UpdateKpiPayload,\n): Promise<KpiDefinition> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/kpis/${id}`, {\n method: \"PUT\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"KPI definition not found\");\n }\n if (response.status === 409) {\n throw new Error(\"A KPI definition with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to update KPI\");\n }\n\n return (await response.json()) as KpiDefinition;\n}\n\n/**\n * Delete a KPI definition\n */\nexport async function deleteKpi(id: string): Promise<void> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/kpis/${id}`, {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"KPI definition not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to delete KPI\");\n }\n}\n\n/**\n * Get available context variables for KPI formulas\n */\nexport async function getKpiContextVariables(\n agentId?: string,\n scope?: KpiScope,\n): Promise<ContextVariable[]> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (agentId) {\n params.set(\"agentId\", agentId);\n }\n if (scope) {\n params.set(\"scope\", scope);\n }\n\n const url = `${getBaseUrl()}/api/config/kpis/context-variables${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get context variables\");\n }\n\n const data = (await response.json()) as { contextVariables: ContextVariable[] };\n return data.contextVariables;\n}\n\n/**\n * Validate a KPI formula expression\n */\nexport async function validateKpiFormula(\n formula: string,\n agentId?: string,\n scope?: KpiScope,\n): Promise<FormulaValidationResult> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const body: Record<string, string | undefined> = { formula, agentId };\n if (scope) {\n body.scope = scope;\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/kpis/validate`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to validate formula\");\n }\n\n return (await response.json()) as FormulaValidationResult;\n}\n\n// ============================================\n// Activity API - Prompt Inspection\n// ============================================\n\nexport interface ActivityPrompt {\n id: string;\n createdAt: string;\n agentId: string | null;\n agentName?: string | null;\n workflowId: string | null;\n workflowName?: string | null;\n taskExecutionId?: string | null;\n app: string;\n modelType: string | null;\n modelId: string | null;\n tokens: number;\n requestTime: number;\n isHighRisk: boolean;\n blocked: boolean;\n decorationStatus: string;\n sensitivity: string[];\n prompt?: string;\n response?: string;\n analytics?: {\n task: string | null;\n subtask: string | null;\n timesaved_minutes: number | null;\n riskassessment_dangerousity: number | null;\n };\n kpiData?: Record<string, unknown>;\n}\n\nexport interface ActivityListResponse {\n prompts: ActivityPrompt[];\n total: number;\n limit: number;\n offset: number;\n hasMore: boolean;\n}\n\nexport interface ActivityListOptions {\n agentId?: string;\n workflowId?: string;\n since?: string;\n until?: string;\n limit?: number;\n offset?: number;\n includeContent?: boolean;\n includeAnalytics?: boolean;\n}\n\nexport interface CoreKpiValue {\n name: string;\n value: number;\n measurement: \"count\" | \"ratio\" | \"sum\";\n unitPrefix?: string;\n unitSuffix?: string;\n}\n\nexport interface AggregatedKpi {\n kpiDefinitionId: string;\n name: string;\n value: number | null;\n aggregationMethod: string;\n unit: string | null;\n dataPointCount: number;\n}\n\nexport interface PeriodKpiData {\n periodStart: string;\n periodEnd: string;\n coreKpis: CoreKpiValue[];\n}\n\nexport interface KpiAtom {\n promptRequestId: string;\n createdAt: string;\n kpis: Record<string, unknown>;\n}\n\nexport interface ActivityKpisResponse {\n coreKpis: CoreKpiValue[];\n kpis: AggregatedKpi[];\n periodData?: PeriodKpiData[];\n atoms?: KpiAtom[];\n}\n\nexport interface ActivityKpisOptions {\n agentId?: string;\n workflowId?: string;\n since?: string;\n until?: string;\n period?: \"hourly\" | \"daily\" | \"weekly\";\n includeAtoms?: boolean;\n}\n\n/**\n * List activity prompts with filters\n */\nexport async function listActivity(\n options: ActivityListOptions = {}\n): Promise<ActivityListResponse> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (options.agentId) params.set(\"agentId\", options.agentId);\n if (options.workflowId) params.set(\"workflowId\", options.workflowId);\n if (options.since) params.set(\"since\", options.since);\n if (options.until) params.set(\"until\", options.until);\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options.offset !== undefined) params.set(\"offset\", String(options.offset));\n if (options.includeContent) params.set(\"includeContent\", \"true\");\n if (options.includeAnalytics) params.set(\"includeAnalytics\", \"true\");\n\n const url = `${getBaseUrl()}/api/activity/prompts${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list activity\");\n }\n\n return (await response.json()) as ActivityListResponse;\n}\n\n/**\n * Get a single activity prompt by ID\n */\nexport async function getActivity(\n id: string,\n includeContent?: boolean\n): Promise<ActivityPrompt> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (includeContent) params.set(\"includeContent\", \"true\");\n\n const url = `${getBaseUrl()}/api/activity/prompts/${id}${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Prompt request not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get activity\");\n }\n\n return (await response.json()) as ActivityPrompt;\n}\n\n/**\n * Get aggregated KPI values for an agent or workflow\n */\nexport async function getActivityKpis(\n options: ActivityKpisOptions\n): Promise<ActivityKpisResponse> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n if (!options.agentId && !options.workflowId) {\n throw new Error(\"Either agentId or workflowId is required\");\n }\n\n const params = new URLSearchParams();\n if (options.agentId) params.set(\"agentId\", options.agentId);\n if (options.workflowId) params.set(\"workflowId\", options.workflowId);\n if (options.since) params.set(\"since\", options.since);\n if (options.until) params.set(\"until\", options.until);\n if (options.period) params.set(\"period\", options.period);\n if (options.includeAtoms) params.set(\"includeAtoms\", \"true\");\n\n const url = `${getBaseUrl()}/api/activity/kpis${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get activity KPIs\");\n }\n\n return (await response.json()) as ActivityKpisResponse;\n}\n\n// ============================================\n// Activity API - Session Diagnostics\n// ============================================\n\nexport interface SessionDiagnostic {\n id: string;\n createdAt: string;\n agentId: string | null;\n decorationStatus: string;\n decorationDate: string | null;\n decorationCandidate: boolean;\n decorationError: string | null;\n decorationErrorStreak: number;\n decoratorVersion: string | null;\n hasKpiData: boolean;\n}\n\nexport interface SessionsListResponse {\n sessions: SessionDiagnostic[];\n summary: {\n sessionCount: number;\n byStatus: Record<string, number>;\n };\n total: number;\n limit: number;\n offset: number;\n hasMore: boolean;\n}\n\nexport interface SessionsListOptions {\n agentId: string;\n since?: string;\n until?: string;\n limit?: number;\n offset?: number;\n}\n\n/**\n * List session diagnostics for an agent\n */\nexport async function listSessions(\n options: SessionsListOptions,\n): Promise<SessionsListResponse> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n params.set(\"agentId\", options.agentId);\n if (options.since) params.set(\"since\", options.since);\n if (options.until) params.set(\"until\", options.until);\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options.offset !== undefined) params.set(\"offset\", String(options.offset));\n\n const url = `${getBaseUrl()}/api/activity/sessions?${params}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list sessions\");\n }\n\n return (await response.json()) as SessionsListResponse;\n}\n\n// Custom Data Config Types\nexport type CustomDataType = \"STRING\" | \"NUMBER\" | \"BOOLEAN\";\n\nexport interface CustomDataConfig {\n id: string;\n accountId: string;\n agentId: string | null; // NULL means legacy account-level config\n name: string;\n description: string | null;\n type: CustomDataType;\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport interface CreateCustomDataPayload {\n agentId: string; // Required for new configs\n name: string;\n description?: string | null;\n type: CustomDataType;\n}\n\nexport interface UpdateCustomDataPayload {\n name?: string;\n description?: string | null;\n type?: CustomDataType;\n // Note: agentId is not updatable after creation\n}\n\n/**\n * List custom data configurations\n * @param agentId - Optional agent ID to filter by. If provided, returns agent-specific configs\n * merged with legacy account-level configs. If omitted, returns all account configs.\n */\nexport async function listCustomDataConfigs(agentId?: string): Promise<CustomDataConfig[]> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (agentId) {\n params.set(\"agentId\", agentId);\n }\n\n const url = `${getBaseUrl()}/api/config/custom-data${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list custom data configurations\");\n }\n\n const data = (await response.json()) as { customDataConfigs: CustomDataConfig[] };\n return data.customDataConfigs;\n}\n\n/**\n * Get a single custom data configuration\n */\nexport async function getCustomDataConfig(id: string): Promise<CustomDataConfig> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const url = `${getBaseUrl()}/api/config/custom-data/${encodeURIComponent(id)}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Custom data configuration not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get custom data configuration\");\n }\n\n return (await response.json()) as CustomDataConfig;\n}\n\n/**\n * Create a new custom data configuration\n */\nexport async function createCustomDataConfig(\n payload: CreateCustomDataPayload\n): Promise<CustomDataConfig> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const url = `${getBaseUrl()}/api/config/custom-data`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 409) {\n throw new Error(\"A custom data configuration with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to create custom data configuration\");\n }\n\n return (await response.json()) as CustomDataConfig;\n}\n\n/**\n * Update a custom data configuration\n */\nexport async function updateCustomDataConfig(\n id: string,\n payload: UpdateCustomDataPayload\n): Promise<CustomDataConfig> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const url = `${getBaseUrl()}/api/config/custom-data/${encodeURIComponent(id)}`;\n const response = await fetch(url, {\n method: \"PUT\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Custom data configuration not found\");\n }\n if (response.status === 409) {\n throw new Error(\"A custom data configuration with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to update custom data configuration\");\n }\n\n return (await response.json()) as CustomDataConfig;\n}\n\n/**\n * Delete a custom data configuration\n */\nexport async function deleteCustomDataConfig(id: string): Promise<void> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const url = `${getBaseUrl()}/api/config/custom-data/${encodeURIComponent(id)}`;\n const response = await fetch(url, {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Custom data configuration not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to delete custom data configuration\");\n }\n}\n","import { clearToken, isTokenValid } from \"../lib/auth.js\";\n\n/**\n * Logout command handler\n */\nexport function logoutCommand(): void {\n if (!isTokenValid()) {\n console.log(\"Not currently logged in.\");\n return;\n }\n\n clearToken();\n console.log(\"Logged out successfully.\");\n}\n","import { getCurrentUser } from \"../lib/api.js\";\nimport { isTokenValid } from \"../lib/auth.js\";\nimport { getEnvironment } from \"../lib/config.js\";\n\n/**\n * Whoami command handler\n */\nexport async function whoamiCommand(): Promise<void> {\n if (!isTokenValid()) {\n console.log(\"Not logged in. Run 'olakai login' to authenticate.\");\n process.exit(1);\n }\n\n try {\n const user = await getCurrentUser();\n\n console.log(`Email: ${user.email}`);\n console.log(`Name: ${user.firstName} ${user.lastName}`);\n console.log(`Role: ${user.role}`);\n console.log(`Account ID: ${user.accountId}`);\n console.log(`Environment: ${getEnvironment()}`);\n } catch (error) {\n if (error instanceof Error) {\n console.error(`Error: ${error.message}`);\n } else {\n console.error(\"Failed to get user info\");\n }\n process.exit(1);\n }\n}\n","import { Command } from \"commander\";\nimport {\n listAgents,\n getAgent,\n createAgent,\n updateAgent,\n deleteAgent,\n type Agent,\n} from \"../lib/api.js\";\n\nfunction formatAgentTable(agents: Agent[]): void {\n if (agents.length === 0) {\n console.log(\"No agents found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"ID\", \"NAME\", \"ROLE\", \"WORKFLOW\", \"API KEY\"];\n const rows = agents.map((agent) => [\n agent.id.slice(0, 12) + \"...\",\n agent.name.slice(0, 30),\n agent.role,\n agent.workflowId ? agent.workflowId.slice(0, 12) + \"...\" : \"-\",\n agent.apiKey ? (agent.apiKey.isActive ? \"Active\" : \"Inactive\") : \"None\",\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n}\n\nfunction formatAgentDetail(agent: Agent): void {\n console.log(`ID: ${agent.id}`);\n console.log(`Name: ${agent.name}`);\n console.log(`Description: ${agent.description || \"-\"}`);\n console.log(`Role: ${agent.role}`);\n console.log(`Source: ${agent.source}`);\n console.log(`Category: ${agent.category || \"-\"}`);\n console.log(`Workflow ID: ${agent.workflowId || \"-\"}`);\n\n if (agent.workflow) {\n console.log(`Workflow: ${agent.workflow.name}`);\n }\n\n console.log(\"\");\n console.log(\"API Key:\");\n if (agent.apiKey) {\n console.log(` ID: ${agent.apiKey.id}`);\n if (agent.apiKey.key) {\n console.log(` Key: ${agent.apiKey.key}`);\n } else {\n console.log(` Key: ${agent.apiKey.keyMasked}`);\n }\n console.log(` Status: ${agent.apiKey.isActive ? \"Active\" : \"Inactive\"}`);\n } else {\n console.log(\" None\");\n }\n\n if (agent.kpiDefinitions && agent.kpiDefinitions.length > 0) {\n console.log(\"\");\n console.log(\"KPI Definitions:\");\n for (const kpi of agent.kpiDefinitions) {\n console.log(` - ${kpi.name} (${kpi.type})`);\n }\n }\n}\n\nasync function listCommand(options: {\n json?: boolean;\n includeKpis?: boolean;\n}): Promise<void> {\n try {\n const agents = await listAgents({ includeKpis: options.includeKpis });\n\n if (options.json) {\n console.log(JSON.stringify(agents, null, 2));\n } else {\n formatAgentTable(agents);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function getCommand(id: string, options: { json?: boolean }): Promise<void> {\n try {\n const agent = await getAgent(id);\n\n if (options.json) {\n console.log(JSON.stringify(agent, null, 2));\n } else {\n formatAgentDetail(agent);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function createCommand(options: {\n name: string;\n description?: string;\n role?: string;\n workflow?: string;\n withApiKey?: boolean;\n category?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.name) {\n console.error(\"Error: --name is required\");\n process.exit(1);\n }\n\n const agent = await createAgent({\n name: options.name,\n description: options.description || \"\",\n role: (options.role as \"WORKER\" | \"COORDINATOR\") || \"WORKER\",\n workflowId: options.workflow,\n createApiKey: options.withApiKey || false,\n category: options.category,\n });\n\n if (options.json) {\n console.log(JSON.stringify(agent, null, 2));\n } else {\n console.log(\"Agent created successfully!\");\n console.log(\"\");\n formatAgentDetail(agent);\n\n if (agent.apiKey?.key) {\n console.log(\"\");\n console.log(\n \"IMPORTANT: Save your API key now. It will not be shown again.\"\n );\n }\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function updateCommand(\n id: string,\n options: {\n name?: string;\n description?: string;\n role?: string;\n workflow?: string;\n category?: string;\n json?: boolean;\n }\n): Promise<void> {\n try {\n const payload: {\n name?: string;\n description?: string;\n role?: \"WORKER\" | \"COORDINATOR\";\n workflowId?: string | null;\n category?: string | null;\n } = {};\n\n if (options.name !== undefined) payload.name = options.name;\n if (options.description !== undefined)\n payload.description = options.description;\n if (options.role !== undefined)\n payload.role = options.role as \"WORKER\" | \"COORDINATOR\";\n if (options.workflow !== undefined) payload.workflowId = options.workflow;\n if (options.category !== undefined) payload.category = options.category;\n\n if (Object.keys(payload).length === 0) {\n console.error(\"Error: At least one field to update is required\");\n process.exit(1);\n }\n\n const agent = await updateAgent(id, payload);\n\n if (options.json) {\n console.log(JSON.stringify(agent, null, 2));\n } else {\n console.log(\"Agent updated successfully!\");\n console.log(\"\");\n formatAgentDetail(agent);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function deleteCommand(\n id: string,\n options: { force?: boolean }\n): Promise<void> {\n try {\n if (!options.force) {\n // In a real CLI, we'd use readline for confirmation\n // For now, require --force flag\n console.log(\"Are you sure you want to delete this agent?\");\n console.log(\"Use --force to confirm deletion.\");\n process.exit(1);\n }\n\n await deleteAgent(id);\n console.log(\"Agent deleted successfully.\");\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nexport function registerAgentsCommand(program: Command): void {\n const agents = program\n .command(\"agents\")\n .description(\"Manage agents\");\n\n agents\n .command(\"list\")\n .description(\"List all agents\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--include-kpis\", \"Include KPI definitions\")\n .action(listCommand);\n\n agents\n .command(\"get <id>\")\n .description(\"Get agent details\")\n .option(\"--json\", \"Output as JSON\")\n .action(getCommand);\n\n agents\n .command(\"create\")\n .description(\"Create a new agent\")\n .requiredOption(\"--name <name>\", \"Agent name\")\n .option(\"--description <description>\", \"Agent description\")\n .option(\"--role <role>\", \"Agent role (WORKER or COORDINATOR)\", \"WORKER\")\n .option(\"--workflow <id>\", \"Workflow ID to assign\")\n .option(\"--with-api-key\", \"Create an API key for this agent\")\n .option(\"--category <category>\", \"Agent category\")\n .option(\"--json\", \"Output as JSON\")\n .action(createCommand);\n\n agents\n .command(\"update <id>\")\n .description(\"Update an agent\")\n .option(\"--name <name>\", \"Agent name\")\n .option(\"--description <description>\", \"Agent description\")\n .option(\"--role <role>\", \"Agent role (WORKER or COORDINATOR)\")\n .option(\"--workflow <id>\", \"Workflow ID to assign\")\n .option(\"--category <category>\", \"Agent category\")\n .option(\"--json\", \"Output as JSON\")\n .action(updateCommand);\n\n agents\n .command(\"delete <id>\")\n .description(\"Delete an agent\")\n .option(\"--force\", \"Skip confirmation\")\n .action(deleteCommand);\n}\n","import { Command } from \"commander\";\nimport {\n listWorkflows,\n getWorkflow,\n createWorkflow,\n updateWorkflow,\n deleteWorkflow,\n type Workflow,\n} from \"../lib/api.js\";\n\nfunction formatWorkflowTable(workflows: Workflow[]): void {\n if (workflows.length === 0) {\n console.log(\"No workflows found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"ID\", \"NAME\", \"AGENTS\", \"STATUS\"];\n const rows = workflows.map((wf) => [\n wf.id.slice(0, 12) + \"...\",\n wf.name.slice(0, 30),\n wf.agentCount.toString(),\n wf.isActive ? \"Active\" : \"Inactive\",\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n}\n\nfunction formatWorkflowDetail(workflow: Workflow): void {\n console.log(`ID: ${workflow.id}`);\n console.log(`Name: ${workflow.name}`);\n console.log(`Description: ${workflow.description || \"-\"}`);\n console.log(`Status: ${workflow.isActive ? \"Active\" : \"Inactive\"}`);\n console.log(`Agents: ${workflow.agentCount}`);\n if (workflow.createdAt) {\n console.log(`Created: ${new Date(workflow.createdAt).toISOString()}`);\n }\n if (workflow.updatedAt) {\n console.log(`Updated: ${new Date(workflow.updatedAt).toISOString()}`);\n }\n\n if (workflow.agents && workflow.agents.length > 0) {\n console.log(\"\");\n console.log(\"Agents:\");\n for (const agent of workflow.agents) {\n const apiKeyStatus = agent.apiKey\n ? agent.apiKey.isActive\n ? \"API Key: Active\"\n : \"API Key: Inactive\"\n : \"No API Key\";\n console.log(` - ${agent.name} (${agent.role}) - ${apiKeyStatus}`);\n }\n }\n}\n\nasync function listCommand(options: {\n json?: boolean;\n includeAgents?: boolean;\n includeInactive?: boolean;\n}): Promise<void> {\n try {\n const workflows = await listWorkflows({\n includeAgents: options.includeAgents,\n includeInactive: options.includeInactive,\n });\n\n if (options.json) {\n console.log(JSON.stringify(workflows, null, 2));\n } else {\n formatWorkflowTable(workflows);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function getCommand(id: string, options: { json?: boolean }): Promise<void> {\n try {\n const workflow = await getWorkflow(id);\n\n if (options.json) {\n console.log(JSON.stringify(workflow, null, 2));\n } else {\n formatWorkflowDetail(workflow);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function createCommand(options: {\n name: string;\n description?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.name) {\n console.error(\"Error: --name is required\");\n process.exit(1);\n }\n\n const workflow = await createWorkflow({\n name: options.name,\n description: options.description,\n });\n\n if (options.json) {\n console.log(JSON.stringify(workflow, null, 2));\n } else {\n console.log(\"Workflow created successfully!\");\n console.log(\"\");\n formatWorkflowDetail(workflow);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function updateCommand(\n id: string,\n options: {\n name?: string;\n description?: string;\n active?: boolean;\n inactive?: boolean;\n json?: boolean;\n }\n): Promise<void> {\n try {\n const payload: {\n name?: string;\n description?: string | null;\n isActive?: boolean;\n } = {};\n\n if (options.name !== undefined) payload.name = options.name;\n if (options.description !== undefined)\n payload.description = options.description;\n if (options.active) payload.isActive = true;\n if (options.inactive) payload.isActive = false;\n\n if (Object.keys(payload).length === 0) {\n console.error(\"Error: At least one field to update is required\");\n process.exit(1);\n }\n\n const workflow = await updateWorkflow(id, payload);\n\n if (options.json) {\n console.log(JSON.stringify(workflow, null, 2));\n } else {\n console.log(\"Workflow updated successfully!\");\n console.log(\"\");\n formatWorkflowDetail(workflow);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function deleteCommand(\n id: string,\n options: { force?: boolean }\n): Promise<void> {\n try {\n if (!options.force) {\n // In a real CLI, we'd use readline for confirmation\n // For now, require --force flag\n console.log(\"Are you sure you want to delete this workflow?\");\n console.log(\"Use --force to confirm deletion.\");\n process.exit(1);\n }\n\n await deleteWorkflow(id);\n console.log(\"Workflow deleted successfully.\");\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nexport function registerWorkflowsCommand(program: Command): void {\n const workflows = program\n .command(\"workflows\")\n .description(\"Manage workflows\");\n\n workflows\n .command(\"list\")\n .description(\"List all workflows\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--include-agents\", \"Include agent details\")\n .option(\"--include-inactive\", \"Include inactive workflows\")\n .action(listCommand);\n\n workflows\n .command(\"get <id>\")\n .description(\"Get workflow details\")\n .option(\"--json\", \"Output as JSON\")\n .action(getCommand);\n\n workflows\n .command(\"create\")\n .description(\"Create a new workflow\")\n .requiredOption(\"--name <name>\", \"Workflow name\")\n .option(\"--description <description>\", \"Workflow description\")\n .option(\"--json\", \"Output as JSON\")\n .action(createCommand);\n\n workflows\n .command(\"update <id>\")\n .description(\"Update a workflow\")\n .option(\"--name <name>\", \"Workflow name\")\n .option(\"--description <description>\", \"Workflow description\")\n .option(\"--active\", \"Set workflow as active\")\n .option(\"--inactive\", \"Set workflow as inactive\")\n .option(\"--json\", \"Output as JSON\")\n .action(updateCommand);\n\n workflows\n .command(\"delete <id>\")\n .description(\"Delete a workflow\")\n .option(\"--force\", \"Skip confirmation\")\n .action(deleteCommand);\n}\n","import { Command } from \"commander\";\nimport {\n listKpis,\n getKpi,\n createKpi,\n updateKpi,\n deleteKpi,\n getKpiContextVariables,\n validateKpiFormula,\n type KpiDefinition,\n type KpiScope,\n type ContextVariable,\n type CreateKpiPayload,\n type DefaultAggregationMethod,\n} from \"../lib/api.js\";\n\nconst AGGREGATION_METHODS: DefaultAggregationMethod[] = [\n \"SUM\",\n \"AVERAGE\",\n \"COUNT\",\n \"MIN\",\n \"MAX\",\n \"LATEST\",\n];\n\nconst CALCULATOR_IDS = [\"formula\", \"classifier\", \"llm-data\"];\n\nconst KPI_SCOPES: KpiScope[] = [\"PROMPT_REQUEST\", \"CHAT\", \"DOCUMENT\"];\n\n// Classifier template definitions — mirrors CLASSIFIER_TEMPLATES from\n// localnode-app/packages/config/classifier-templates.ts\ntype OutputClassOption = { label: string; value: number };\n\ntype ClassifierTemplate = {\n id: string;\n name: string;\n description: string;\n promptTemplate: string;\n defaultUnit: string;\n defaultOutputClasses: OutputClassOption[];\n};\n\nconst CLASSIFIER_TEMPLATES: ClassifierTemplate[] = [\n {\n id: \"sentiment_scorer\",\n name: \"Sentiment Scorer\",\n description:\n \"Scores the overall emotional tone and user satisfaction of a conversation\",\n defaultUnit: \"score\",\n promptTemplate: `Analyze the overall sentiment of the following AI assistant conversation. Consider the user's tone, satisfaction level, and emotional state throughout the interaction.\n\nConversation:\n{{Complete exchange}}\n\nRate the sentiment using exactly one of these numeric scores:\n{{outputClassDescriptions}}\n\nRespond with only the numeric score.`,\n defaultOutputClasses: [\n { label: \"Very Negative\", value: 1 },\n { label: \"Negative\", value: 2 },\n { label: \"Neutral\", value: 3 },\n { label: \"Positive\", value: 4 },\n { label: \"Very Positive\", value: 5 },\n ],\n },\n {\n id: \"time_saved_estimator\",\n name: \"Time Saved Estimator\",\n description:\n \"Estimates how much time the AI interaction saved compared to manual effort\",\n defaultUnit: \"minutes\",\n promptTemplate: `Estimate how much time this AI assistant interaction saved the user compared to completing the task manually without AI assistance. Consider the complexity of the request, the completeness of the response, and typical human effort for similar tasks.\n\nConversation:\n{{Complete exchange}}\n\nClassify the estimated time saved using exactly one of these values (in minutes):\n{{outputClassDescriptions}}\n\nRespond with only the numeric value.`,\n defaultOutputClasses: [\n { label: \"No time saved\", value: 0 },\n { label: \"A few minutes\", value: 3 },\n { label: \"Moderate time\", value: 10 },\n { label: \"Significant time\", value: 30 },\n { label: \"Major time savings\", value: 60 },\n ],\n },\n];\n\nfunction resolveOutputClassDescriptions(classes: OutputClassOption[]): string {\n return classes.map((c) => `${c.value} = ${c.label}`).join(\"\\n\");\n}\n\nfunction resolveTemplatePrompt(\n template: ClassifierTemplate,\n classes: OutputClassOption[],\n): string {\n return template.promptTemplate.replace(\n \"{{outputClassDescriptions}}\",\n resolveOutputClassDescriptions(classes),\n );\n}\n\nfunction formatKpiTable(kpis: KpiDefinition[]): void {\n if (kpis.length === 0) {\n console.log(\"No KPI definitions found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"ID\", \"NAME\", \"SCOPE\", \"CALCULATOR\", \"AGGREGATION\", \"STATUS\"];\n const rows = kpis.map((kpi) => [\n kpi.id.slice(0, 12) + \"...\",\n kpi.name.slice(0, 25),\n kpi.scope || \"PROMPT_REQUEST\",\n kpi.calculatorId,\n kpi.defaultAggregationMethod,\n kpi.isActive ? \"Active\" : \"Inactive\",\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n}\n\nfunction formatKpiDetail(kpi: KpiDefinition): void {\n console.log(`ID: ${kpi.id}`);\n console.log(`Name: ${kpi.name}`);\n console.log(`Description: ${kpi.description || \"-\"}`);\n console.log(`Type: ${kpi.type}`);\n console.log(`Category: ${kpi.category || \"-\"}`);\n console.log(`Agent ID: ${kpi.agentId || \"-\"}`);\n console.log(`Scope: ${kpi.scope || \"PROMPT_REQUEST\"}`);\n console.log(`Calculator: ${kpi.calculatorId}`);\n console.log(`Aggregation: ${kpi.defaultAggregationMethod}`);\n console.log(`Unit: ${kpi.unit || \"-\"}`);\n console.log(`Status: ${kpi.isActive ? \"Active\" : \"Inactive\"}`);\n\n if (kpi.calculatorParams) {\n console.log(\"\");\n console.log(\"Calculator Parameters:\");\n console.log(JSON.stringify(kpi.calculatorParams, null, 2));\n }\n\n if (kpi.createdAt) {\n console.log(\"\");\n console.log(`Created: ${new Date(kpi.createdAt).toISOString()}`);\n }\n if (kpi.updatedAt) {\n console.log(`Updated: ${new Date(kpi.updatedAt).toISOString()}`);\n }\n}\n\nfunction formatContextVariablesTable(variables: ContextVariable[]): void {\n if (variables.length === 0) {\n console.log(\"No context variables found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"NAME\", \"TYPE\", \"SOURCE\", \"DESCRIPTION\"];\n const rows = variables.map((v) => [\n v.name,\n v.type,\n v.source,\n v.description.slice(0, 50),\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n}\n\nasync function listCommand(options: {\n json?: boolean;\n agentId?: string;\n includeInactive?: boolean;\n}): Promise<void> {\n try {\n const kpis = await listKpis({\n agentId: options.agentId,\n includeInactive: options.includeInactive,\n });\n\n if (options.json) {\n console.log(JSON.stringify(kpis, null, 2));\n } else {\n formatKpiTable(kpis);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function getCommand(\n id: string,\n options: { json?: boolean }\n): Promise<void> {\n try {\n const kpi = await getKpi(id);\n\n if (options.json) {\n console.log(JSON.stringify(kpi, null, 2));\n } else {\n formatKpiDetail(kpi);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function createCommand(options: {\n name: string;\n calculatorId: string;\n scope: string;\n description?: string;\n type?: string;\n category?: string;\n agentId?: string;\n formula?: string;\n templateId?: string;\n outputClasses?: string;\n outputLabels?: string;\n samplingFactor?: string;\n unit?: string;\n aggregation?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.name) {\n console.error(\"Error: --name is required\");\n process.exit(1);\n }\n\n if (!options.calculatorId) {\n console.error(\"Error: --calculator-id is required\");\n console.error(`Valid values: ${CALCULATOR_IDS.join(\", \")}`);\n process.exit(1);\n }\n\n if (!CALCULATOR_IDS.includes(options.calculatorId)) {\n console.error(`Error: Invalid calculator ID \"${options.calculatorId}\"`);\n console.error(`Valid values: ${CALCULATOR_IDS.join(\", \")}`);\n process.exit(1);\n }\n\n // Validate scope\n const upperScope = options.scope.toUpperCase() as KpiScope;\n if (!KPI_SCOPES.includes(upperScope)) {\n console.error(`Error: Invalid scope \"${options.scope}\"`);\n console.error(`Valid values: ${KPI_SCOPES.join(\", \")}`);\n process.exit(1);\n }\n\n // Build calculator params\n let calculatorParams: Record<string, unknown> | undefined;\n let resolvedUnit = options.unit;\n\n if (options.calculatorId === \"formula\") {\n if (!options.formula) {\n console.error(\n \"Error: --formula is required when calculator-id is 'formula'\"\n );\n process.exit(1);\n }\n // Validate and parse the formula using the API\n const validation = await validateKpiFormula(options.formula, options.agentId, upperScope);\n if (!validation.valid) {\n console.error(`Error: Invalid formula: ${validation.error}`);\n process.exit(1);\n }\n // Use the parsed formula AST, not the raw string\n calculatorParams = { formula: validation.parsedFormula };\n } else if (options.calculatorId === \"classifier\") {\n if (!options.templateId) {\n console.error(\n \"Error: Classifier KPIs require --template-id. Run `olakai kpis templates` to see available templates.\"\n );\n process.exit(1);\n }\n\n const templateIds = CLASSIFIER_TEMPLATES.map((t) => t.id);\n const template = CLASSIFIER_TEMPLATES.find(\n (t) => t.id === options.templateId,\n );\n if (!template) {\n console.error(\n `Error: Unknown template \"${options.templateId}\". Valid templates: ${templateIds.join(\", \")}`\n );\n process.exit(1);\n }\n\n // Resolve output classes — use overrides if provided, else template defaults\n let outputClasses = template.defaultOutputClasses;\n if (options.outputClasses || options.outputLabels) {\n const rawValues = options.outputClasses\n ? options.outputClasses.split(\",\").map((v) => v.trim())\n : template.defaultOutputClasses.map((c) => String(c.value));\n const rawLabels = options.outputLabels\n ? options.outputLabels.split(\",\").map((l) => l.trim())\n : template.defaultOutputClasses.map((c) => c.label);\n\n if (rawValues.length !== rawLabels.length) {\n console.error(\n `Error: --output-classes (${rawValues.length} values) and --output-labels (${rawLabels.length} labels) must have the same count.`\n );\n process.exit(1);\n }\n\n outputClasses = rawValues.map((v, i) => ({\n label: rawLabels[i],\n value: Number(v),\n }));\n }\n\n // Resolve prompt with output class descriptions\n const promptTemplate = resolveTemplatePrompt(template, outputClasses);\n\n calculatorParams = {\n promptTemplate,\n outputClasses: outputClasses.map((c) => c.value),\n outputClassLabels: outputClasses.map((c) => c.label),\n classifierTemplateId: template.id,\n };\n\n // Parse sampling factor if provided\n if (options.samplingFactor !== undefined) {\n const factor = Number(options.samplingFactor);\n if (isNaN(factor) || factor < 0 || factor > 1) {\n console.error(\"Error: --sampling-factor must be a number between 0 and 1.\");\n process.exit(1);\n }\n calculatorParams.samplingFactor = factor;\n }\n\n // Use template default unit unless explicitly overridden\n if (!resolvedUnit) {\n resolvedUnit = template.defaultUnit;\n }\n }\n\n // Validate aggregation method\n let aggregation: DefaultAggregationMethod | undefined;\n if (options.aggregation) {\n const upperAggregation =\n options.aggregation.toUpperCase() as DefaultAggregationMethod;\n if (!AGGREGATION_METHODS.includes(upperAggregation)) {\n console.error(`Error: Invalid aggregation method \"${options.aggregation}\"`);\n console.error(`Valid values: ${AGGREGATION_METHODS.join(\", \")}`);\n process.exit(1);\n }\n aggregation = upperAggregation;\n }\n\n const payload: CreateKpiPayload = {\n name: options.name,\n calculatorId: options.calculatorId,\n scope: upperScope,\n description: options.description,\n type:\n options.type === \"PREDEFINED\" ? \"PREDEFINED\" : \"USER_DEFINED\",\n category: options.category,\n agentId: options.agentId,\n calculatorParams,\n unit: resolvedUnit,\n defaultAggregationMethod: aggregation,\n };\n\n const kpi = await createKpi(payload);\n\n if (options.json) {\n console.log(JSON.stringify(kpi, null, 2));\n } else {\n console.log(\"KPI definition created successfully!\");\n console.log(\"\");\n formatKpiDetail(kpi);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function updateCommand(\n id: string,\n options: {\n name?: string;\n description?: string;\n category?: string;\n agentId?: string;\n scope?: string;\n calculatorId?: string;\n formula?: string;\n unit?: string;\n aggregation?: string;\n active?: boolean;\n inactive?: boolean;\n json?: boolean;\n }\n): Promise<void> {\n try {\n const payload: Record<string, unknown> = {};\n\n if (options.name !== undefined) payload.name = options.name;\n if (options.description !== undefined)\n payload.description = options.description;\n if (options.category !== undefined) payload.category = options.category;\n if (options.agentId !== undefined) payload.agentId = options.agentId;\n if (options.calculatorId !== undefined)\n payload.calculatorId = options.calculatorId;\n if (options.unit !== undefined) payload.unit = options.unit;\n if (options.active) payload.isActive = true;\n if (options.inactive) payload.isActive = false;\n\n // Validate and set scope\n let validatedScope: KpiScope | undefined;\n if (options.scope !== undefined) {\n const upperScope = options.scope.toUpperCase() as KpiScope;\n if (!KPI_SCOPES.includes(upperScope)) {\n console.error(`Error: Invalid scope \"${options.scope}\"`);\n console.error(`Valid values: ${KPI_SCOPES.join(\", \")}`);\n process.exit(1);\n }\n payload.scope = upperScope;\n validatedScope = upperScope;\n }\n\n // Handle formula update - validate and parse before storing\n if (options.formula !== undefined) {\n const validation = await validateKpiFormula(options.formula, options.agentId, validatedScope);\n if (!validation.valid) {\n console.error(`Error: Invalid formula: ${validation.error}`);\n process.exit(1);\n }\n // Use the parsed formula AST, not the raw string\n payload.calculatorParams = { formula: validation.parsedFormula };\n }\n\n // Validate and set aggregation method\n if (options.aggregation) {\n const upperAggregation =\n options.aggregation.toUpperCase() as DefaultAggregationMethod;\n if (!AGGREGATION_METHODS.includes(upperAggregation)) {\n console.error(`Error: Invalid aggregation method \"${options.aggregation}\"`);\n console.error(`Valid values: ${AGGREGATION_METHODS.join(\", \")}`);\n process.exit(1);\n }\n payload.defaultAggregationMethod = upperAggregation;\n }\n\n if (Object.keys(payload).length === 0) {\n console.error(\"Error: At least one field to update is required\");\n process.exit(1);\n }\n\n const kpi = await updateKpi(id, payload);\n\n if (options.json) {\n console.log(JSON.stringify(kpi, null, 2));\n } else {\n console.log(\"KPI definition updated successfully!\");\n console.log(\"\");\n formatKpiDetail(kpi);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function deleteCommand(\n id: string,\n options: { force?: boolean }\n): Promise<void> {\n try {\n if (!options.force) {\n console.log(\"Are you sure you want to delete this KPI definition?\");\n console.log(\"Use --force to confirm deletion.\");\n process.exit(1);\n }\n\n await deleteKpi(id);\n console.log(\"KPI definition deleted successfully.\");\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function contextVariablesCommand(options: {\n json?: boolean;\n agentId?: string;\n scope?: string;\n}): Promise<void> {\n try {\n // Validate scope if provided\n let validatedScope: KpiScope | undefined;\n if (options.scope) {\n const upperScope = options.scope.toUpperCase() as KpiScope;\n if (!KPI_SCOPES.includes(upperScope)) {\n console.error(`Error: Invalid scope \"${options.scope}\"`);\n console.error(`Valid values: ${KPI_SCOPES.join(\", \")}`);\n process.exit(1);\n }\n validatedScope = upperScope;\n }\n\n const variables = await getKpiContextVariables(options.agentId, validatedScope);\n\n if (options.json) {\n console.log(JSON.stringify(variables, null, 2));\n } else {\n console.log(\"Available context variables for KPI formulas:\");\n console.log(\"\");\n formatContextVariablesTable(variables);\n console.log(\"\");\n console.log(\n \"Use these variable names in your formula expressions, e.g.:\"\n );\n console.log(' IF(PII detected, 1, 0)');\n console.log(' Documents count * 10');\n console.log(' IF(CODE detected AND SECRET detected, \"high-risk\", \"normal\")');\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function validateCommand(options: {\n formula: string;\n agentId?: string;\n scope?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.formula) {\n console.error(\"Error: --formula is required\");\n process.exit(1);\n }\n\n // Validate scope if provided\n let validatedScope: KpiScope | undefined;\n if (options.scope) {\n const upperScope = options.scope.toUpperCase() as KpiScope;\n if (!KPI_SCOPES.includes(upperScope)) {\n console.error(`Error: Invalid scope \"${options.scope}\"`);\n console.error(`Valid values: ${KPI_SCOPES.join(\", \")}`);\n process.exit(1);\n }\n validatedScope = upperScope;\n }\n\n const result = await validateKpiFormula(options.formula, options.agentId, validatedScope);\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n if (result.valid) {\n console.log(\"Formula is valid!\");\n console.log(`Result type: ${result.type || \"unknown\"}`);\n } else {\n console.error(\"Formula is invalid:\");\n console.error(` ${result.error}`);\n if (result.charIndex !== undefined) {\n console.error(` Position: character ${result.charIndex}`);\n }\n process.exit(1);\n }\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nfunction templatesCommand(options: { json?: boolean }): void {\n if (options.json) {\n console.log(\n JSON.stringify(\n CLASSIFIER_TEMPLATES.map((t) => ({\n id: t.id,\n name: t.name,\n description: t.description,\n defaultUnit: t.defaultUnit,\n outputClasses: t.defaultOutputClasses,\n })),\n null,\n 2,\n ),\n );\n } else {\n console.log(\"Available Classifier Templates:\");\n console.log(\"\");\n for (const t of CLASSIFIER_TEMPLATES) {\n console.log(` ${t.id.padEnd(24)} ${t.description}`);\n const classRange = t.defaultOutputClasses;\n console.log(\n `${\"\".padEnd(26)}Classes: ${classRange.map((c) => `${c.value} (${c.label})`).join(\", \")}`,\n );\n console.log(\n `${\"\".padEnd(26)}Default unit: ${t.defaultUnit}`,\n );\n console.log(\"\");\n }\n console.log(\"Usage:\");\n console.log(\n ' olakai kpis create --name \"User Satisfaction\" --calculator-id classifier --template-id sentiment_scorer --scope CHAT',\n );\n }\n}\n\nexport function registerKpisCommand(program: Command): void {\n const kpis = program\n .command(\"kpis\")\n .description(\"Manage KPI definitions\");\n\n kpis\n .command(\"list\")\n .description(\"List all KPI definitions\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--agent-id <id>\", \"Filter by agent ID\")\n .option(\"--include-inactive\", \"Include inactive KPI definitions\")\n .action(listCommand);\n\n kpis\n .command(\"get <id>\")\n .description(\"Get KPI definition details\")\n .option(\"--json\", \"Output as JSON\")\n .action(getCommand);\n\n kpis\n .command(\"create\")\n .description(\"Create a new KPI definition\")\n .requiredOption(\"--name <name>\", \"KPI name\")\n .requiredOption(\n \"--calculator-id <id>\",\n \"Calculator type: formula, classifier, or llm-data\"\n )\n .requiredOption(\n \"--scope <scope>\",\n \"KPI scope: PROMPT_REQUEST, CHAT, or DOCUMENT\"\n )\n .option(\"--description <description>\", \"KPI description\")\n .option(\"--type <type>\", \"KPI type: PREDEFINED or USER_DEFINED (default)\")\n .option(\"--category <category>\", \"KPI category for grouping\")\n .option(\"--agent-id <id>\", \"Associate KPI with a specific agent\")\n .option(\"--formula <formula>\", \"Formula expression (required for formula calculator)\")\n .option(\"--template-id <id>\", \"Classifier template: sentiment_scorer, time_saved_estimator\")\n .option(\"--output-classes <values>\", \"Override output class values (comma-separated numbers)\")\n .option(\"--output-labels <labels>\", \"Override output class labels (comma-separated)\")\n .option(\"--sampling-factor <factor>\", \"Fraction of events to classify, 0-1 (cost control)\")\n .option(\"--unit <unit>\", 'Display unit (e.g., \"ms\", \"%\", \"count\")')\n .option(\n \"--aggregation <method>\",\n \"Default aggregation: SUM, AVERAGE, COUNT, MIN, MAX, LATEST (default)\"\n )\n .option(\"--json\", \"Output as JSON\")\n .action(createCommand);\n\n kpis\n .command(\"templates\")\n .description(\"List available classifier templates\")\n .option(\"--json\", \"Output as JSON\")\n .action(templatesCommand);\n\n kpis\n .command(\"update <id>\")\n .description(\"Update a KPI definition\")\n .option(\"--name <name>\", \"KPI name\")\n .option(\"--description <description>\", \"KPI description\")\n .option(\"--category <category>\", \"KPI category\")\n .option(\"--agent-id <id>\", \"Associate with agent\")\n .option(\"--scope <scope>\", \"KPI scope: PROMPT_REQUEST, CHAT, or DOCUMENT\")\n .option(\"--calculator-id <id>\", \"Calculator type\")\n .option(\"--formula <formula>\", \"Formula expression\")\n .option(\"--unit <unit>\", \"Display unit\")\n .option(\"--aggregation <method>\", \"Default aggregation method\")\n .option(\"--active\", \"Set KPI as active\")\n .option(\"--inactive\", \"Set KPI as inactive\")\n .option(\"--json\", \"Output as JSON\")\n .action(updateCommand);\n\n kpis\n .command(\"delete <id>\")\n .description(\"Delete a KPI definition\")\n .option(\"--force\", \"Skip confirmation\")\n .action(deleteCommand);\n\n kpis\n .command(\"context-variables\")\n .description(\"List available context variables for formulas\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--agent-id <id>\", \"Include agent-specific variables\")\n .option(\"--scope <scope>\", \"Filter variables by scope: PROMPT_REQUEST, CHAT, or DOCUMENT\")\n .action(contextVariablesCommand);\n\n kpis\n .command(\"validate\")\n .description(\"Validate a KPI formula expression\")\n .requiredOption(\"--formula <formula>\", \"Formula expression to validate\")\n .option(\"--agent-id <id>\", \"Include agent-specific context\")\n .option(\"--scope <scope>\", \"Validate against scope: PROMPT_REQUEST, CHAT, or DOCUMENT\")\n .option(\"--json\", \"Output as JSON\")\n .action(validateCommand);\n}\n","import { Command } from \"commander\";\nimport {\n listCustomDataConfigs,\n getCustomDataConfig,\n createCustomDataConfig,\n updateCustomDataConfig,\n deleteCustomDataConfig,\n type CustomDataConfig,\n type CustomDataType,\n} from \"../lib/api.js\";\n\nconst DATA_TYPES: CustomDataType[] = [\"STRING\", \"NUMBER\", \"BOOLEAN\"];\n\nfunction formatTable(configs: CustomDataConfig[]): void {\n if (configs.length === 0) {\n console.log(\"No custom data configurations found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"ID\", \"NAME\", \"TYPE\", \"AGENT ID\", \"DESCRIPTION\"];\n const rows = configs.map((config) => [\n config.id.slice(0, 12) + \"...\",\n config.name.slice(0, 25),\n config.type,\n config.agentId ? config.agentId.slice(0, 12) + \"...\" : \"(account-level)\",\n (config.description || \"-\").slice(0, 30),\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n}\n\nfunction formatDetail(config: CustomDataConfig): void {\n console.log(`ID: ${config.id}`);\n console.log(`Name: ${config.name}`);\n console.log(`Type: ${config.type}`);\n console.log(`Agent ID: ${config.agentId || \"(account-level / legacy)\"}`);\n console.log(`Description: ${config.description || \"-\"}`);\n if (config.createdAt) {\n console.log(`Created: ${new Date(config.createdAt).toISOString()}`);\n }\n if (config.updatedAt) {\n console.log(`Updated: ${new Date(config.updatedAt).toISOString()}`);\n }\n}\n\nasync function listCommand(options: { agentId?: string; json?: boolean }): Promise<void> {\n try {\n const configs = await listCustomDataConfigs(options.agentId);\n\n if (options.json) {\n console.log(JSON.stringify(configs, null, 2));\n } else {\n formatTable(configs);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function getCommand(\n id: string,\n options: { json?: boolean }\n): Promise<void> {\n try {\n const config = await getCustomDataConfig(id);\n\n if (options.json) {\n console.log(JSON.stringify(config, null, 2));\n } else {\n formatDetail(config);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function createCommand(options: {\n agentId: string;\n name: string;\n type: string;\n description?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.agentId) {\n console.error(\"Error: --agent-id is required\");\n console.error(\"Custom data configurations must be associated with an agent.\");\n process.exit(1);\n }\n\n if (!options.name) {\n console.error(\"Error: --name is required\");\n process.exit(1);\n }\n\n if (!options.type) {\n console.error(\"Error: --type is required\");\n console.error(`Valid values: ${DATA_TYPES.join(\", \")}`);\n process.exit(1);\n }\n\n const upperType = options.type.toUpperCase() as CustomDataType;\n if (!DATA_TYPES.includes(upperType)) {\n console.error(`Error: Invalid type \"${options.type}\"`);\n console.error(`Valid values: ${DATA_TYPES.join(\", \")}`);\n process.exit(1);\n }\n\n const config = await createCustomDataConfig({\n agentId: options.agentId,\n name: options.name,\n type: upperType,\n description: options.description ?? null,\n });\n\n if (options.json) {\n console.log(JSON.stringify(config, null, 2));\n } else {\n console.log(\"Custom data configuration created successfully!\");\n console.log(\"\");\n formatDetail(config);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function updateCommand(\n id: string,\n options: {\n name?: string;\n type?: string;\n description?: string;\n json?: boolean;\n }\n): Promise<void> {\n try {\n const payload: {\n name?: string;\n type?: CustomDataType;\n description?: string | null;\n } = {};\n\n if (options.name !== undefined) payload.name = options.name;\n if (options.description !== undefined)\n payload.description = options.description || null;\n\n if (options.type !== undefined) {\n const upperType = options.type.toUpperCase() as CustomDataType;\n if (!DATA_TYPES.includes(upperType)) {\n console.error(`Error: Invalid type \"${options.type}\"`);\n console.error(`Valid values: ${DATA_TYPES.join(\", \")}`);\n process.exit(1);\n }\n payload.type = upperType;\n }\n\n if (Object.keys(payload).length === 0) {\n console.error(\"Error: At least one field to update is required\");\n process.exit(1);\n }\n\n const config = await updateCustomDataConfig(id, payload);\n\n if (options.json) {\n console.log(JSON.stringify(config, null, 2));\n } else {\n console.log(\"Custom data configuration updated successfully!\");\n console.log(\"\");\n formatDetail(config);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function deleteCommand(\n id: string,\n options: { force?: boolean }\n): Promise<void> {\n try {\n if (!options.force) {\n console.log(\n \"Are you sure you want to delete this custom data configuration?\"\n );\n console.log(\"Use --force to confirm deletion.\");\n process.exit(1);\n }\n\n await deleteCustomDataConfig(id);\n console.log(\"Custom data configuration deleted successfully.\");\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nexport function registerCustomDataCommand(program: Command): void {\n const customData = program\n .command(\"custom-data\")\n .description(\"Manage custom data configurations for KPI formulas\");\n\n customData\n .command(\"list\")\n .description(\"List custom data configurations\")\n .option(\"--agent-id <agentId>\", \"Filter by agent ID (omit to list all account configs)\")\n .option(\"--json\", \"Output as JSON\")\n .action(listCommand);\n\n customData\n .command(\"get <id>\")\n .description(\"Get custom data configuration details\")\n .option(\"--json\", \"Output as JSON\")\n .action(getCommand);\n\n customData\n .command(\"create\")\n .description(\"Create a new custom data configuration for an agent\")\n .requiredOption(\"--agent-id <agentId>\", \"Agent ID (required)\")\n .requiredOption(\"--name <name>\", \"Configuration name (used in KPI formulas)\")\n .requiredOption(\n \"--type <type>\",\n \"Data type: STRING, NUMBER, or BOOLEAN\"\n )\n .option(\"--description <description>\", \"Configuration description\")\n .option(\"--json\", \"Output as JSON\")\n .action(createCommand);\n\n customData\n .command(\"update <id>\")\n .description(\"Update a custom data configuration\")\n .option(\"--name <name>\", \"Configuration name\")\n .option(\"--type <type>\", \"Data type: STRING, NUMBER, or BOOLEAN\")\n .option(\"--description <description>\", \"Configuration description\")\n .option(\"--json\", \"Output as JSON\")\n .action(updateCommand);\n\n customData\n .command(\"delete <id>\")\n .description(\"Delete a custom data configuration\")\n .option(\"--force\", \"Skip confirmation\")\n .action(deleteCommand);\n}\n","import { Command } from \"commander\";\nimport {\n listActivity,\n getActivity,\n getActivityKpis,\n listSessions,\n type ActivityPrompt,\n type ActivityListResponse,\n type ActivityKpisResponse,\n type CoreKpiValue,\n type SessionsListResponse,\n} from \"../lib/api.js\";\n\nfunction formatActivityTable(data: ActivityListResponse): void {\n if (data.prompts.length === 0) {\n console.log(\"No activity found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"ID\", \"AGENT\", \"APP\", \"MODEL\", \"TOKENS\", \"TIME(ms)\", \"RISK\", \"STATUS\"];\n const rows = data.prompts.map((prompt) => [\n prompt.id.slice(0, 12) + \"...\",\n prompt.agentName || (prompt.agentId ? prompt.agentId.slice(0, 12) + \"...\" : \"-\"),\n prompt.app.slice(0, 12),\n prompt.modelId?.slice(0, 15) || \"-\",\n String(prompt.tokens),\n String(prompt.requestTime),\n prompt.isHighRisk ? \"Yes\" : \"No\",\n prompt.decorationStatus.slice(0, 10),\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n\n // Print pagination info\n console.log(\"\");\n console.log(`Showing ${data.prompts.length} of ${data.total} results (offset: ${data.offset})`);\n if (data.hasMore) {\n console.log(`Use --offset ${data.offset + data.limit} to see more results`);\n }\n}\n\nfunction formatActivityDetail(prompt: ActivityPrompt): void {\n console.log(`ID: ${prompt.id}`);\n console.log(`Created: ${prompt.createdAt}`);\n console.log(`Agent: ${prompt.agentName || \"-\"} (${prompt.agentId || \"-\"})`);\n console.log(`Workflow: ${prompt.workflowName || \"-\"} (${prompt.workflowId || \"-\"})`);\n if (prompt.taskExecutionId) {\n console.log(`Task Exec ID: ${prompt.taskExecutionId}`);\n }\n console.log(`App: ${prompt.app}`);\n console.log(`Model: ${prompt.modelId || \"-\"} (${prompt.modelType || \"-\"})`);\n console.log(`Tokens: ${prompt.tokens}`);\n console.log(`Request Time: ${prompt.requestTime}ms`);\n console.log(`High Risk: ${prompt.isHighRisk ? \"Yes\" : \"No\"}`);\n console.log(`Blocked: ${prompt.blocked ? \"Yes\" : \"No\"}`);\n console.log(`Status: ${prompt.decorationStatus}`);\n\n if (prompt.sensitivity && prompt.sensitivity.length > 0) {\n console.log(`Sensitivity: ${prompt.sensitivity.join(\", \")}`);\n }\n\n if (prompt.analytics) {\n console.log(\"\");\n console.log(\"Analytics:\");\n console.log(` Task: ${prompt.analytics.task || \"-\"}`);\n console.log(` Subtask: ${prompt.analytics.subtask || \"-\"}`);\n console.log(` Time Saved: ${prompt.analytics.timesaved_minutes ?? \"-\"} minutes`);\n console.log(` Risk Score: ${prompt.analytics.riskassessment_dangerousity ?? \"-\"}`);\n }\n\n if (prompt.kpiData && Object.keys(prompt.kpiData).length > 0) {\n console.log(\"\");\n console.log(\"KPIs:\");\n for (const [key, value] of Object.entries(prompt.kpiData)) {\n console.log(` ${key}: ${value}`);\n }\n }\n\n if (prompt.prompt !== undefined) {\n console.log(\"\");\n console.log(\"Prompt:\");\n console.log(\"---\");\n console.log(prompt.prompt.slice(0, 1000) + (prompt.prompt.length > 1000 ? \"...\" : \"\"));\n console.log(\"---\");\n }\n\n if (prompt.response !== undefined) {\n console.log(\"\");\n console.log(\"Response:\");\n console.log(\"---\");\n console.log(prompt.response.slice(0, 1000) + (prompt.response.length > 1000 ? \"...\" : \"\"));\n console.log(\"---\");\n }\n}\n\nfunction formatCoreKpi(kpi: CoreKpiValue): string {\n const prefix = kpi.unitPrefix || \"\";\n const suffix = kpi.unitSuffix || \"\";\n return `${prefix}${kpi.value}${suffix}`;\n}\n\nfunction formatKpisResponse(data: ActivityKpisResponse): void {\n // Core KPIs\n console.log(\"Core KPIs:\");\n for (const kpi of data.coreKpis) {\n console.log(` ${kpi.name.padEnd(25)} ${formatCoreKpi(kpi)}`);\n }\n\n // Custom KPIs\n if (data.kpis.length > 0) {\n console.log(\"\");\n console.log(\"Custom KPIs:\");\n const headers = [\"NAME\", \"VALUE\", \"UNIT\", \"AGGREGATION\", \"DATA POINTS\"];\n const rows = data.kpis.map((kpi) => [\n kpi.name.slice(0, 25),\n kpi.value !== null ? String(kpi.value) : \"-\",\n kpi.unit || \"-\",\n kpi.aggregationMethod,\n String(kpi.dataPointCount),\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n console.log(\" \" + headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(\" \" + widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n for (const row of rows) {\n console.log(\" \" + row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n }\n\n // Period data\n if (data.periodData && data.periodData.length > 0) {\n console.log(\"\");\n console.log(\"Period Breakdown:\");\n for (const period of data.periodData) {\n console.log(` ${period.periodStart} - ${period.periodEnd}`);\n for (const kpi of period.coreKpis) {\n console.log(` ${kpi.name}: ${formatCoreKpi(kpi)}`);\n }\n }\n }\n\n // Atoms summary\n if (data.atoms && data.atoms.length > 0) {\n console.log(\"\");\n console.log(`Per-Prompt KPI Atoms: ${data.atoms.length} records`);\n console.log(\" (Use --json for full atom data)\");\n }\n}\n\nasync function listCommand(options: {\n agentId?: string;\n workflowId?: string;\n since?: string;\n until?: string;\n limit?: string;\n offset?: string;\n includeContent?: boolean;\n includeAnalytics?: boolean;\n json?: boolean;\n}): Promise<void> {\n try {\n const data = await listActivity({\n agentId: options.agentId,\n workflowId: options.workflowId,\n since: options.since,\n until: options.until,\n limit: options.limit ? parseInt(options.limit, 10) : undefined,\n offset: options.offset ? parseInt(options.offset, 10) : undefined,\n includeContent: options.includeContent,\n includeAnalytics: options.includeAnalytics,\n });\n\n if (options.json) {\n console.log(JSON.stringify(data, null, 2));\n } else {\n formatActivityTable(data);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function getCommand(\n id: string,\n options: { includeContent?: boolean; json?: boolean }\n): Promise<void> {\n try {\n const prompt = await getActivity(id, options.includeContent);\n\n if (options.json) {\n console.log(JSON.stringify(prompt, null, 2));\n } else {\n formatActivityDetail(prompt);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function kpisCommand(options: {\n agentId?: string;\n workflowId?: string;\n since?: string;\n until?: string;\n period?: string;\n includeAtoms?: boolean;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.agentId && !options.workflowId) {\n console.error(\"Error: Either --agent-id or --workflow-id is required\");\n process.exit(1);\n }\n\n const data = await getActivityKpis({\n agentId: options.agentId,\n workflowId: options.workflowId,\n since: options.since,\n until: options.until,\n period: options.period as \"hourly\" | \"daily\" | \"weekly\" | undefined,\n includeAtoms: options.includeAtoms,\n });\n\n if (options.json) {\n console.log(JSON.stringify(data, null, 2));\n } else {\n formatKpisResponse(data);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nfunction formatSessionsTable(data: SessionsListResponse): void {\n // Summary\n console.log(\"Session Decoration Status\");\n console.log(\"\");\n console.log(\"Summary:\");\n console.log(` Total Sessions: ${data.summary.sessionCount}`);\n\n const statuses = [\"DECORATED\", \"NEW\", \"DECORATION_FAILED\", \"DECORATION_OUTDATED\", \"SKIPPED\"];\n for (const status of statuses) {\n const count = data.summary.byStatus[status] || 0;\n const pct = data.summary.sessionCount > 0 ? ((count / data.summary.sessionCount) * 100).toFixed(1) : \"0.0\";\n const label = status.charAt(0) + status.slice(1).toLowerCase().replace(/_/g, \" \");\n console.log(` ${label.padEnd(17)} ${String(count).padStart(4)} (${pct}%)`);\n }\n\n if (data.sessions.length === 0) {\n console.log(\"\");\n console.log(\"No sessions found.\");\n return;\n }\n\n console.log(\"\");\n\n // Table\n const headers = [\"ID\", \"STATUS\", \"DATE\", \"CANDIDATE\", \"ERRORS\", \"KPI DATA\", \"VERSION\"];\n const rows = data.sessions.map((s) => [\n s.id.slice(0, 15) + \"...\",\n s.decorationStatus,\n s.decorationDate || \"-\",\n s.decorationCandidate ? \"Yes\" : \"No\",\n String(s.decorationErrorStreak),\n s.hasKpiData ? \"Yes\" : \"No\",\n s.decoratorVersion || \"-\",\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n\n console.log(\"\");\n console.log(`Showing ${data.sessions.length} of ${data.total} results (offset: ${data.offset})`);\n if (data.hasMore) {\n console.log(`Use --offset ${data.offset + data.limit} to see more results`);\n }\n}\n\nasync function sessionsCommand(options: {\n agentId: string;\n since?: string;\n until?: string;\n limit?: string;\n offset?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n const data = await listSessions({\n agentId: options.agentId,\n since: options.since,\n until: options.until,\n limit: options.limit ? parseInt(options.limit, 10) : undefined,\n offset: options.offset ? parseInt(options.offset, 10) : undefined,\n });\n\n if (options.json) {\n console.log(JSON.stringify(data, null, 2));\n } else {\n formatSessionsTable(data);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nexport function registerActivityCommand(program: Command): void {\n const activity = program\n .command(\"activity\")\n .description(\"Inspect AI activity and prompts\");\n\n activity\n .command(\"list\")\n .description(\"List prompt requests with filters\")\n .option(\"--agent-id <id>\", \"Filter by agent ID\")\n .option(\"--workflow-id <id>\", \"Filter by workflow ID\")\n .option(\"--since <date>\", \"Start date (ISO format)\")\n .option(\"--until <date>\", \"End date (ISO format)\")\n .option(\"--limit <n>\", \"Results per page\", \"20\")\n .option(\"--offset <n>\", \"Skip first N results\", \"0\")\n .option(\"--include-content\", \"Include prompt/response content\")\n .option(\"--include-analytics\", \"Include advanced analytics\")\n .option(\"--json\", \"Output as JSON\")\n .action(listCommand);\n\n activity\n .command(\"get <id>\")\n .description(\"Get prompt request details\")\n .option(\"--include-content\", \"Include prompt/response content\")\n .option(\"--json\", \"Output as JSON\")\n .action(getCommand);\n\n activity\n .command(\"kpis\")\n .description(\"Get aggregated KPI values\")\n .option(\"--agent-id <id>\", \"Agent ID\")\n .option(\"--workflow-id <id>\", \"Workflow ID\")\n .option(\"--since <date>\", \"Period start (ISO format)\")\n .option(\"--until <date>\", \"Period end (ISO format)\")\n .option(\"--period <type>\", \"Aggregation period (hourly, daily, weekly)\")\n .option(\"--include-atoms\", \"Include per-prompt KPI data\")\n .option(\"--json\", \"Output as JSON\")\n .action(kpisCommand);\n\n activity\n .command(\"sessions\")\n .description(\"Inspect chat/session decoration status for troubleshooting\")\n .requiredOption(\"--agent-id <id>\", \"Agent ID (required)\")\n .option(\"--since <date>\", \"Start date (ISO format)\")\n .option(\"--until <date>\", \"End date (ISO format)\")\n .option(\"--limit <n>\", \"Results per page\", \"20\")\n .option(\"--offset <n>\", \"Skip first N results\", \"0\")\n .option(\"--json\", \"Output as JSON\")\n .action(sessionsCommand);\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as readline from \"node:readline\";\nimport { Command } from \"commander\";\nimport {\n listAgents,\n createAgent,\n getAgent,\n type Agent,\n} from \"../lib/api.js\";\nimport { getValidToken } from \"../lib/auth.js\";\nimport { getBaseUrl } from \"../lib/config.js\";\nimport {\n parseTranscript,\n type ExtractedTranscriptData,\n} from \"./monitor-transcript.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface MonitorConfig {\n agentId: string;\n apiKey: string;\n agentName: string;\n source: string;\n createdAt: string;\n monitoringEndpoint: string;\n}\n\ninterface ClaudeSettings {\n hooks?: Record<string, HookMatcherEntry[]>;\n [key: string]: unknown;\n}\n\nexport interface HookMatcherEntry {\n matcher: string;\n hooks: HookCommand[];\n}\n\nexport interface HookCommand {\n type: string;\n command: string;\n}\n\n/**\n * Claude Code hook event payloads.\n *\n * The Stop / SubagentStop hooks send ONLY the fields below — the\n * conversation data (prompt, response, tokens, model, etc.) is NOT in\n * the hook JSON. To get that data we must read the transcript file at\n * `transcript_path`.\n *\n * The exact field that carries the subagent name is not formally\n * documented, so we accept several candidates (`agent_name`,\n * `agent_type`, `subagent_type`) and fall back to the `tool_input`\n * shape that the Agent tool_use block uses.\n */\nexport interface ClaudeHookEvent {\n session_id?: string;\n transcript_path?: string;\n hook_event_name?: string; // \"Stop\" | \"SubagentStop\"\n stop_hook_active?: boolean;\n cwd?: string;\n agent_name?: string;\n agent_type?: string;\n subagent_type?: string;\n tool_input?: {\n subagent_type?: string;\n description?: string;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst CLAUDE_DIR = \".claude\";\nconst SETTINGS_FILE = \"settings.json\";\nconst MONITOR_CONFIG_FILE = \"olakai-monitor.json\";\n\nconst OLAKAI_HOOK_MARKER = \"olakai monitor hook\";\n\nconst HOOK_DEFINITIONS: Record<string, HookMatcherEntry[]> = {\n Stop: [\n {\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: \"olakai monitor hook stop\",\n },\n ],\n },\n ],\n SubagentStop: [\n {\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: \"olakai monitor hook subagent-stop\",\n },\n ],\n },\n ],\n};\n\n/**\n * Produce the `hooks` block for a Claude Code settings.json by layering\n * the Olakai defaults on top of an existing hooks block.\n *\n * Rules:\n * - For each event in HOOK_DEFINITIONS: if the existing block already\n * has an Olakai-marker entry for that event, keep the existing\n * entries verbatim (user-customized command strings such as\n * `OLAKAI_MONITOR_DEBUG=1 olakai monitor hook stop` survive).\n * - If it doesn't, append the default Olakai entries, preserving any\n * non-Olakai entries already configured on that event.\n * - Events we don't manage (`PreToolUse`, `UserPromptSubmit`, ...)\n * pass through untouched.\n *\n * Exported for unit tests.\n */\nexport function mergeHooksSettings(\n existing: Record<string, HookMatcherEntry[]> | undefined,\n definitions: Record<string, HookMatcherEntry[]> = HOOK_DEFINITIONS,\n): Record<string, HookMatcherEntry[]> {\n const merged: Record<string, HookMatcherEntry[]> = {\n ...(existing ?? {}),\n };\n\n for (const [event, defaultEntries] of Object.entries(definitions)) {\n const existingEntries = merged[event] ?? [];\n const hasOlakaiHook = existingEntries.some((e) =>\n e.hooks.some((h) => h.command.includes(OLAKAI_HOOK_MARKER)),\n );\n\n if (hasOlakaiHook) {\n merged[event] = existingEntries;\n } else {\n merged[event] = [...existingEntries, ...defaultEntries];\n }\n }\n\n return merged;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Find the project root by walking up from cwd looking for .claude/ directory.\n * Falls back to cwd if none found.\n */\nfunction findProjectRoot(startDir?: string): string {\n let dir = startDir ?? process.cwd();\n while (true) {\n if (fs.existsSync(path.join(dir, CLAUDE_DIR))) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break; // reached filesystem root\n dir = parent;\n }\n // Fall back to cwd (init will create .claude/)\n return startDir ?? process.cwd();\n}\n\nfunction getClaudeDir(projectRoot: string): string {\n return path.join(projectRoot, CLAUDE_DIR);\n}\n\nfunction getSettingsPath(projectRoot: string): string {\n return path.join(getClaudeDir(projectRoot), SETTINGS_FILE);\n}\n\nfunction getMonitorConfigPath(projectRoot: string): string {\n return path.join(getClaudeDir(projectRoot), MONITOR_CONFIG_FILE);\n}\n\nfunction readJsonFile<T>(filePath: string): T | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const content = fs.readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nfunction writeJsonFile(filePath: string, data: unknown): void {\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + \"\\n\", \"utf-8\");\n}\n\nfunction loadMonitorConfig(projectRoot?: string): MonitorConfig | null {\n const root = projectRoot ?? findProjectRoot();\n return readJsonFile<MonitorConfig>(getMonitorConfigPath(root));\n}\n\n/**\n * Read stdin with a timeout. Returns empty string if stdin has no data\n * or times out.\n */\nfunction readStdin(timeoutMs: number = 3000): Promise<string> {\n return new Promise((resolve) => {\n // If stdin is a TTY (no piped data), return immediately\n if (process.stdin.isTTY) {\n resolve(\"\");\n return;\n }\n\n let data = \"\";\n const timer = setTimeout(() => {\n process.stdin.removeAllListeners();\n process.stdin.destroy();\n resolve(data);\n }, timeoutMs);\n\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk: string) => {\n data += chunk;\n });\n process.stdin.on(\"end\", () => {\n clearTimeout(timer);\n resolve(data);\n });\n process.stdin.on(\"error\", () => {\n clearTimeout(timer);\n resolve(data);\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// Subcommands\n// ---------------------------------------------------------------------------\n\n/**\n * olakai monitor init\n *\n * Interactive setup: create/select agent, write hooks, save config.\n */\nasync function initCommand(): Promise<void> {\n // 1. Check authentication\n const token = getValidToken();\n if (!token) {\n console.error(\"Not logged in. Run 'olakai login' first.\");\n process.exit(1);\n }\n\n console.log(\"Setting up Claude Code monitoring for this workspace...\\n\");\n\n const projectRoot = process.cwd();\n const dirName = path.basename(projectRoot);\n\n // 2. Create or select an agent\n let agent: Agent;\n const choice = await prompt(\n \"Create a new agent or use an existing one? (new/existing) [new]: \",\n );\n\n if (choice.toLowerCase() === \"existing\" || choice.toLowerCase() === \"e\") {\n // List agents and let user pick\n const agents = await listAgents();\n if (agents.length === 0) {\n console.log(\"No agents found. Creating a new one instead.\\n\");\n agent = await createNewAgent(dirName);\n } else {\n console.log(\"\\nAvailable agents:\");\n for (let i = 0; i < agents.length; i++) {\n console.log(` ${i + 1}. ${agents[i].name} (${agents[i].id.slice(0, 12)}...)`);\n }\n\n const selection = await prompt(`\\nSelect agent (1-${agents.length}): `);\n const idx = parseInt(selection, 10) - 1;\n\n if (isNaN(idx) || idx < 0 || idx >= agents.length) {\n console.error(\"Invalid selection.\");\n process.exit(1);\n }\n\n // Fetch full agent detail (may include API key info)\n agent = await getAgent(agents[idx].id);\n\n // If agent doesn't have an active API key, we need to create one.\n // The CLI create endpoint generates one with --with-api-key but there's\n // no standalone \"create API key\" endpoint exposed in the CLI API module.\n // So we warn and ask user to use an agent that already has one, or create new.\n if (!agent.apiKey?.key && !agent.apiKey?.isActive) {\n console.log(\n \"\\nThis agent has no active API key. Please create a new agent instead,\",\n );\n console.log(\"or generate an API key via the Olakai dashboard.\\n\");\n const createNew = await prompt(\"Create a new agent? (y/n) [y]: \");\n if (createNew.toLowerCase() !== \"n\") {\n agent = await createNewAgent(dirName);\n } else {\n process.exit(1);\n }\n }\n }\n } else {\n agent = await createNewAgent(dirName);\n }\n\n // Resolve the API key. For newly created agents, agent.apiKey.key is populated.\n // For existing agents, the key is masked — we can't get the plaintext back.\n // In that case, prompt for it.\n let apiKey = agent.apiKey?.key;\n if (!apiKey) {\n console.log(\n \"\\nThe API key for this agent is not available (it is only shown once at creation).\",\n );\n apiKey = await prompt(\"Paste the API key for this agent: \");\n if (!apiKey) {\n console.error(\"API key is required for monitoring.\");\n process.exit(1);\n }\n }\n\n // 3. Write Claude Code hooks\n const claudeDir = getClaudeDir(projectRoot);\n if (!fs.existsSync(claudeDir)) {\n fs.mkdirSync(claudeDir, { recursive: true });\n }\n\n const settingsPath = getSettingsPath(projectRoot);\n const existingSettings = readJsonFile<ClaudeSettings>(settingsPath) ?? {};\n\n const mergedHooks = mergeHooksSettings(existingSettings.hooks);\n\n const updatedSettings: ClaudeSettings = {\n ...existingSettings,\n hooks: mergedHooks,\n };\n\n writeJsonFile(settingsPath, updatedSettings);\n\n // 4. Save monitor config\n const monitoringEndpoint = `${getBaseUrl()}/api/monitoring/prompt`;\n const monitorConfig: MonitorConfig = {\n agentId: agent.id,\n apiKey,\n agentName: agent.name,\n source: \"claude-code\",\n createdAt: new Date().toISOString(),\n monitoringEndpoint,\n };\n\n const monitorConfigPath = getMonitorConfigPath(projectRoot);\n writeJsonFile(monitorConfigPath, monitorConfig);\n // Restrict permissions — file contains a plaintext API key\n fs.chmodSync(monitorConfigPath, 0o600);\n\n // 5. Success message\n console.log(\"\");\n console.log(`\\u2713 Agent \"${agent.name}\" configured (ID: ${agent.id})`);\n if (agent.apiKey?.key) {\n console.log(\"\\u2713 API key generated\");\n }\n console.log(`\\u2713 Claude Code hooks configured in ${CLAUDE_DIR}/${SETTINGS_FILE}`);\n console.log(`\\u2713 Monitor config saved to ${CLAUDE_DIR}/${MONITOR_CONFIG_FILE}`);\n console.log(\"\");\n console.log(\n \"Monitoring is now active. Claude Code will report activity to Olakai\",\n );\n console.log(\n `on each turn. View activity at: ${getBaseUrl()}/dashboard`,\n );\n console.log(\"\");\n console.log(\n `\\u26A0 Ensure ${CLAUDE_DIR}/${MONITOR_CONFIG_FILE} is in your .gitignore (it contains your API key)`,\n );\n console.log(\"\");\n console.log(\"To check status: olakai monitor status\");\n console.log(\"To disable: olakai monitor disable\");\n}\n\nasync function createNewAgent(defaultName: string): Promise<Agent> {\n const nameInput = await prompt(\n `Agent name [${defaultName}]: `,\n );\n const agentName = nameInput || defaultName;\n\n const agent = await createAgent({\n name: agentName,\n description: `Claude Code local agent for ${agentName}`,\n role: \"WORKER\",\n createApiKey: true,\n category: \"CODING\",\n source: \"CLAUDE_CODE\",\n });\n\n return agent;\n}\n\n/**\n * Debug logger. Only writes when OLAKAI_MONITOR_DEBUG=1.\n * Errors are swallowed — debug logging must never break the hook.\n */\nfunction debugLog(label: string, data: unknown): void {\n if (process.env.OLAKAI_MONITOR_DEBUG !== \"1\") return;\n try {\n const logPath = `/tmp/olakai-monitor-debug-${process.pid}.log`;\n const line = `[${new Date().toISOString()}] ${label}: ${\n typeof data === \"string\" ? data : JSON.stringify(data, null, 2)\n }\\n`;\n fs.appendFileSync(logPath, line, \"utf-8\");\n } catch {\n // Ignore debug-log failures\n }\n}\n\n/**\n * Load a transcript JSONL from disk and extract the data we want to\n * report. Any failure (missing file, malformed JSON, unexpected shape)\n * is swallowed and we return a best-effort partial result. Parsing\n * itself lives in `monitor-transcript.ts` so it can be unit-tested.\n */\nfunction extractFromTranscript(\n transcriptPath: string | undefined,\n): ExtractedTranscriptData {\n const empty: ExtractedTranscriptData = {\n prompt: \"\",\n response: \"\",\n tokens: 0,\n inputTokens: 0,\n outputTokens: 0,\n modelName: null,\n numTurns: 0,\n };\n\n if (!transcriptPath) return empty;\n\n let raw: string;\n try {\n raw = fs.readFileSync(transcriptPath, \"utf-8\");\n } catch (err) {\n debugLog(\"transcript-read-failed\", {\n transcriptPath,\n error: (err as Error).message,\n });\n return empty;\n }\n\n return parseTranscript(raw);\n}\n\n/**\n * Best-effort extraction of the subagent name from a SubagentStop hook\n * payload. Claude Code's payload shape for this hook isn't fully\n * documented, so we probe several candidate fields in order of\n * likelihood and fall back to undefined when nothing is found.\n */\nfunction extractSubagentName(event: ClaudeHookEvent): string | undefined {\n const candidates = [\n event.agent_name,\n event.subagent_type,\n event.agent_type,\n event.tool_input?.subagent_type,\n ];\n for (const value of candidates) {\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n }\n return undefined;\n}\n\n/**\n * olakai monitor hook <event>\n *\n * Fire-and-forget handler called by Claude Code hooks.\n * Reads event JSON from stdin, POSTs to monitoring endpoint.\n * MUST NOT produce stderr output or exit non-zero.\n */\nasync function hookCommand(event: string): Promise<void> {\n try {\n const config = loadMonitorConfig();\n if (!config) {\n // No config found — monitoring not set up. Silent exit.\n return;\n }\n\n // Read event data from stdin\n const stdinData = await readStdin(3000);\n debugLog(\"stdin-raw\", stdinData);\n\n let eventData: ClaudeHookEvent = {};\n if (stdinData) {\n try {\n eventData = JSON.parse(stdinData) as ClaudeHookEvent;\n } catch {\n // Malformed JSON from stdin — skip silently\n debugLog(\"stdin-parse-failed\", stdinData);\n return;\n }\n }\n\n debugLog(\"event-parsed\", { event, eventData });\n\n // Build monitoring payload based on event type\n const payload = buildPayload(event, eventData, config);\n if (!payload) {\n // Nothing meaningful to report\n return;\n }\n\n debugLog(\"payload-built\", payload);\n\n // POST to monitoring endpoint with a 5-second timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5000);\n\n try {\n const res = await fetch(config.monitoringEndpoint, {\n method: \"POST\",\n headers: {\n \"x-api-key\": config.apiKey,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify([payload]),\n signal: controller.signal,\n });\n debugLog(\"response-status\", {\n status: res.status,\n ok: res.ok,\n });\n } finally {\n clearTimeout(timeoutId);\n }\n } catch (err) {\n // Silently swallow ALL errors. Hook failures must not break Claude Code.\n debugLog(\"hook-exception\", (err as Error).message);\n }\n}\n\n/**\n * Build a MonitorPayload from the Claude Code hook event data.\n *\n * For Stop / SubagentStop events, the hook JSON contains only\n * session_id + transcript_path — the actual conversation data is\n * extracted from the transcript JSONL file.\n *\n * Exported for unit tests.\n */\nexport function buildPayload(\n event: string,\n eventData: ClaudeHookEvent,\n config: MonitorConfig,\n): Record<string, unknown> | null {\n const sessionId = eventData.session_id ?? `claude-code-${Date.now()}`;\n\n switch (event) {\n case \"stop\":\n case \"subagent-stop\": {\n const extracted = extractFromTranscript(eventData.transcript_path);\n const isSubagent = event === \"subagent-stop\";\n\n const customData: Record<string, unknown> = {\n hookEvent:\n eventData.hook_event_name ??\n (isSubagent ? \"SubagentStop\" : \"Stop\"),\n sessionId,\n transcriptPath: eventData.transcript_path ?? \"\",\n cwd: eventData.cwd ?? \"\",\n stopHookActive: eventData.stop_hook_active ?? false,\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n numTurns: extracted.numTurns,\n };\n\n if (typeof extracted.latencyMs === \"number\") {\n customData.latencyMs = extracted.latencyMs;\n }\n\n if (isSubagent) {\n const subagent = extractSubagentName(eventData);\n if (subagent) {\n customData.subagent = subagent;\n }\n } else if (extracted.skill) {\n // Skill detection only applies to main-agent Stop events. The\n // subagent's first \"user\" message is the spawning prompt, not a\n // human slash-command.\n customData.skill = extracted.skill;\n }\n\n return {\n prompt: extracted.prompt,\n response: extracted.response,\n chatId: sessionId,\n // Top-level source so the backend ExternalPromptRequestSchema\n // picks it up (matches regex ^[a-z0-9_-]+$).\n source: config.source,\n modelName: extracted.modelName ?? undefined,\n tokens: extracted.tokens,\n customData,\n };\n }\n\n default:\n return null;\n }\n}\n\n/**\n * olakai monitor status\n *\n * Show current monitoring configuration and recent activity.\n */\nasync function statusCommand(options: { json?: boolean }): Promise<void> {\n const projectRoot = findProjectRoot();\n const config = loadMonitorConfig(projectRoot);\n\n if (!config) {\n console.log(\"Monitoring is not configured for this workspace.\");\n console.log(\"Run 'olakai monitor init' to set up monitoring.\");\n process.exit(1);\n }\n\n // Check if hooks are still present in settings.json\n const settings = readJsonFile<ClaudeSettings>(getSettingsPath(projectRoot));\n const hooksPresent = settings?.hooks\n ? Object.values(settings.hooks).some((entries) =>\n entries.some((e) =>\n e.hooks.some((h) => h.command.includes(OLAKAI_HOOK_MARKER)),\n ),\n )\n : false;\n\n if (options.json) {\n console.log(\n JSON.stringify(\n {\n ...config,\n apiKey: config.apiKey.slice(0, 12) + \"...\",\n hooksConfigured: hooksPresent,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log(\"Olakai Monitor Status\");\n console.log(\"=====================\");\n console.log(`Agent: ${config.agentName}`);\n console.log(`Agent ID: ${config.agentId}`);\n console.log(`API Key: ${config.apiKey.slice(0, 12)}...`);\n console.log(`Endpoint: ${config.monitoringEndpoint}`);\n console.log(`Source: ${config.source}`);\n console.log(`Configured: ${config.createdAt}`);\n console.log(`Hooks: ${hooksPresent ? \"Active\" : \"Missing (run 'olakai monitor init' to restore)\"}`);\n\n // Try to show recent activity\n try {\n const token = getValidToken();\n if (token) {\n const params = new URLSearchParams({\n agentId: config.agentId,\n limit: \"5\",\n });\n const response = await fetch(\n `${getBaseUrl()}/api/activity/prompts?${params}`,\n {\n headers: { Authorization: `Bearer ${token}` },\n },\n );\n if (response.ok) {\n const data = (await response.json()) as {\n prompts: Array<{ id: string; createdAt: string }>;\n };\n if (data.prompts && data.prompts.length > 0) {\n console.log(\"\");\n console.log(\"Recent Activity:\");\n for (const p of data.prompts) {\n console.log(` ${p.createdAt} ${p.id.slice(0, 12)}...`);\n }\n } else {\n console.log(\"\");\n console.log(\"No activity recorded yet.\");\n }\n }\n }\n } catch {\n // Activity check is optional — don't fail\n }\n}\n\n/**\n * olakai monitor disable\n *\n * Remove Olakai hooks from settings.json and optionally remove config.\n */\nasync function disableCommand(options: {\n keepConfig?: boolean;\n}): Promise<void> {\n const projectRoot = findProjectRoot();\n\n // 1. Remove hooks from settings.json\n const settingsPath = getSettingsPath(projectRoot);\n const settings = readJsonFile<ClaudeSettings>(settingsPath);\n\n if (settings?.hooks) {\n const cleanedHooks: Record<string, HookMatcherEntry[]> = {};\n\n for (const [event, entries] of Object.entries(settings.hooks)) {\n const filtered = entries.filter(\n (e) =>\n !e.hooks.some((h) => h.command.includes(OLAKAI_HOOK_MARKER)),\n );\n if (filtered.length > 0) {\n cleanedHooks[event] = filtered;\n }\n }\n\n if (Object.keys(cleanedHooks).length > 0) {\n settings.hooks = cleanedHooks;\n } else {\n delete settings.hooks;\n }\n\n writeJsonFile(settingsPath, settings);\n console.log(`\\u2713 Olakai hooks removed from ${CLAUDE_DIR}/${SETTINGS_FILE}`);\n } else {\n console.log(\"No hooks found in settings.json.\");\n }\n\n // 2. Remove or keep monitor config\n if (!options.keepConfig) {\n const configPath = getMonitorConfigPath(projectRoot);\n if (fs.existsSync(configPath)) {\n fs.unlinkSync(configPath);\n console.log(`\\u2713 Monitor config removed (${CLAUDE_DIR}/${MONITOR_CONFIG_FILE})`);\n }\n } else {\n console.log(\n `Monitor config retained at ${CLAUDE_DIR}/${MONITOR_CONFIG_FILE}`,\n );\n }\n\n console.log(\"\");\n console.log(\"Monitoring disabled. Run 'olakai monitor init' to re-enable.\");\n}\n\n// ---------------------------------------------------------------------------\n// Command registration\n// ---------------------------------------------------------------------------\n\nexport function registerMonitorCommand(program: Command): void {\n const monitor = program\n .command(\"monitor\")\n .description(\"Monitor Claude Code sessions with Olakai\");\n\n monitor\n .command(\"init\")\n .description(\n \"Set up Olakai monitoring for this Claude Code workspace\",\n )\n .action(initCommand);\n\n monitor\n .command(\"hook <event>\")\n .description(\"Hook handler called by Claude Code (internal use)\")\n .action(hookCommand);\n\n monitor\n .command(\"status\")\n .description(\"Show monitoring status for this workspace\")\n .option(\"--json\", \"Output as JSON\")\n .action(statusCommand);\n\n monitor\n .command(\"disable\")\n .description(\"Remove Olakai monitoring from this workspace\")\n .option(\n \"--keep-config\",\n \"Keep the monitor config file (only remove hooks)\",\n )\n .action(disableCommand);\n}\n","/**\n * Transcript parsing for Claude Code Stop-hook monitoring.\n *\n * The Stop hook passes only a `transcript_path` pointing at a JSONL file.\n * This module is the single place we extract the per-turn data we report\n * to Olakai (prompt, response, tokens, model, latency, skill invocation).\n *\n * The code here is intentionally pure and exports named helpers so it can\n * be unit-tested without touching the filesystem or HTTP layer.\n */\n\n/**\n * Shape of a single line in a Claude Code transcript JSONL file.\n * Each line is a standalone JSON object. We only care about `user` and\n * `assistant` entries; other types (`system`, `file-history-snapshot`,\n * `progress`, compaction markers, ...) are ignored.\n */\nexport interface TranscriptLine {\n type?: string;\n subtype?: string;\n isMeta?: boolean;\n isSidechain?: boolean;\n timestamp?: string;\n message?: {\n role?: string;\n model?: string;\n content?: string | TranscriptContentBlock[];\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n };\n}\n\nexport interface TranscriptContentBlock {\n type?: string;\n text?: string;\n}\n\nexport interface ExtractedTranscriptData {\n prompt: string;\n response: string;\n tokens: number;\n inputTokens: number;\n outputTokens: number;\n modelName: string | null;\n numTurns: number;\n /**\n * Latency in milliseconds between the current turn's user message and\n * its final assistant response. Undefined when latency could not be\n * computed (first turn, missing timestamps, no user predecessor).\n */\n latencyMs?: number;\n /**\n * Leading slash-command captured from the current turn's user message\n * (e.g. `\"olakai-create-agent\"` for `/olakai-create-agent do X`).\n * Undefined when the user message did not start with a slash-command.\n */\n skill?: string;\n}\n\n/**\n * Match a slash-command at the start of a message. Leading whitespace is\n * trimmed before matching. The captured group is the skill name.\n *\n * Examples (match):\n * \"/foo\" -> \"foo\"\n * \"/foo-bar\" -> \"foo-bar\"\n * \"/foo some args\" -> \"foo\"\n *\n * Examples (no match):\n * \"Not a skill: /path/file\" — slash is not at the start\n * \"/path/file\" — second segment, name contains a slash\n * \"\" — empty\n */\nconst SKILL_REGEX = /^\\/([\\w-]+)(?:\\s|$)/;\n\nexport function detectSkill(userMessage: string | undefined): string | undefined {\n if (typeof userMessage !== \"string\") return undefined;\n const trimmed = userMessage.trimStart();\n if (!trimmed) return undefined;\n const match = SKILL_REGEX.exec(trimmed);\n if (!match) return undefined;\n return match[1];\n}\n\n/**\n * Extract plain text from a transcript message's `content` field.\n * Content may be a string or an array of content blocks.\n * Only `text` blocks contribute — `thinking`, `tool_use`, `tool_result`,\n * and `image` blocks are ignored.\n */\nexport function extractTextContent(\n content: string | TranscriptContentBlock[] | undefined,\n): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n const parts: string[] = [];\n for (const block of content) {\n if (block?.type === \"text\" && typeof block.text === \"string\") {\n parts.push(block.text);\n }\n }\n return parts.join(\"\\n\").trim();\n}\n\n/**\n * Heuristic: is this a \"meta\" user message that should not be treated\n * as a real prompt? These include slash-command invocations and local\n * command caveats injected by Claude Code itself. Note that these are\n * separate `type: \"system\"` entries — regular `type: \"user\"` entries\n * carrying a typed slash-command still come through here and are NOT\n * skipped.\n */\nexport function isMetaUserMessage(line: TranscriptLine, text: string): boolean {\n if (line.isMeta === true) return true;\n if (!text) return true;\n return (\n text.includes(\"<command-name>\") ||\n text.includes(\"<local-command-caveat>\") ||\n text.includes(\"<command-message>\")\n );\n}\n\n/**\n * Parse an ISO 8601 timestamp to epoch milliseconds.\n * Returns NaN for invalid/undefined input.\n */\nfunction parseTimestamp(ts: string | undefined): number {\n if (typeof ts !== \"string\" || !ts) return NaN;\n return Date.parse(ts);\n}\n\n/**\n * Compaction markers interleaved in the transcript that should be\n * skipped when computing per-turn latency. The exact subtype strings\n * come from Claude Code's own PreCompact / PostCompact hook events\n * (recorded as `type: \"system\"` entries in the transcript).\n */\nfunction isCompactionEntry(line: TranscriptLine): boolean {\n if (line.type !== \"system\") return false;\n const subtype = line.subtype ?? \"\";\n return (\n subtype === \"compact_boundary\" ||\n subtype === \"pre_compact\" ||\n subtype === \"post_compact\" ||\n /compact/i.test(subtype)\n );\n}\n\n/**\n * Parse the transcript JSONL contents and extract the data we want to\n * report: last user prompt, last assistant response, usage totals for\n * the most recent assistant turn, model name, number of assistant\n * turns, latency for the most recent turn, and slash-command (skill)\n * detected on the current turn's user message.\n *\n * `raw` is the full UTF-8 contents of the transcript file. This entry\n * point is pure — no filesystem I/O — so it's trivial to unit test.\n */\nexport function parseTranscript(raw: string): ExtractedTranscriptData {\n const empty: ExtractedTranscriptData = {\n prompt: \"\",\n response: \"\",\n tokens: 0,\n inputTokens: 0,\n outputTokens: 0,\n modelName: null,\n numTurns: 0,\n };\n\n if (!raw) return empty;\n\n const lines = raw.split(\"\\n\");\n let lastUserText = \"\";\n let lastUserTimestamp: number = NaN;\n let lastAssistantText = \"\";\n let lastAssistantTimestamp: number = NaN;\n let lastAssistantModel: string | null = null;\n let lastAssistantInputTokens = 0;\n let lastAssistantOutputTokens = 0;\n let numTurns = 0;\n // Tracks whether we have seen a new user message since the last\n // assistant-latency update. Ensures latency is always measured\n // relative to the user that preceded the final assistant in the\n // current turn — not across turns.\n let currentTurnUserTimestamp: number = NaN;\n\n for (const rawLine of lines) {\n if (!rawLine) continue;\n let parsed: TranscriptLine;\n try {\n parsed = JSON.parse(rawLine) as TranscriptLine;\n } catch {\n continue; // skip malformed lines\n }\n\n // Skip compaction markers so they don't break the user->assistant\n // pairing used for latency.\n if (isCompactionEntry(parsed)) continue;\n\n // Skip sidechain (subagent) entries — we want the top-level session\n // conversation. If a transcript only has sidechain entries, the\n // loop below will leave us with empty strings.\n if (parsed.isSidechain === true) continue;\n\n if (parsed.type === \"user\" && parsed.message) {\n const text = extractTextContent(parsed.message.content);\n if (isMetaUserMessage(parsed, text)) continue;\n lastUserText = text;\n lastUserTimestamp = parseTimestamp(parsed.timestamp);\n currentTurnUserTimestamp = lastUserTimestamp;\n } else if (parsed.type === \"assistant\" && parsed.message) {\n const text = extractTextContent(parsed.message.content);\n // Count every assistant entry (each represents one model response\n // turn, even if it contains only a tool_use or thinking block).\n numTurns += 1;\n if (text) lastAssistantText = text;\n if (typeof parsed.message.model === \"string\") {\n lastAssistantModel = parsed.message.model;\n }\n const usage = parsed.message.usage;\n if (usage) {\n // Overwrite with the most recent turn's usage. Include cache\n // tokens in the input total so total token count reflects real\n // billable input.\n const input =\n (usage.input_tokens ?? 0) +\n (usage.cache_creation_input_tokens ?? 0) +\n (usage.cache_read_input_tokens ?? 0);\n const output = usage.output_tokens ?? 0;\n lastAssistantInputTokens = input;\n lastAssistantOutputTokens = output;\n }\n const ts = parseTimestamp(parsed.timestamp);\n if (!Number.isNaN(ts)) {\n lastAssistantTimestamp = ts;\n }\n }\n }\n\n const result: ExtractedTranscriptData = {\n prompt: lastUserText,\n response: lastAssistantText,\n tokens: lastAssistantInputTokens + lastAssistantOutputTokens,\n inputTokens: lastAssistantInputTokens,\n outputTokens: lastAssistantOutputTokens,\n modelName: lastAssistantModel,\n numTurns,\n };\n\n if (\n !Number.isNaN(currentTurnUserTimestamp) &&\n !Number.isNaN(lastAssistantTimestamp) &&\n lastAssistantTimestamp >= currentTurnUserTimestamp\n ) {\n result.latencyMs = Math.round(\n lastAssistantTimestamp - currentTurnUserTimestamp,\n );\n }\n\n const skill = detectSkill(lastUserText);\n if (skill) {\n result.skill = skill;\n }\n\n return result;\n}\n"],"mappings":"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","names":["program","listCommand","getCommand","createCommand","updateCommand","deleteCommand","program","listCommand","getCommand","createCommand","updateCommand","deleteCommand","program","listCommand","getCommand","createCommand","updateCommand","deleteCommand","program","prompt","listCommand","getCommand","program","fs","path","program","require"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/login.ts","../src/lib/config.ts","../src/lib/auth.ts","../src/lib/api.ts","../src/commands/logout.ts","../src/commands/whoami.ts","../src/commands/agents.ts","../src/commands/workflows.ts","../src/commands/kpis.ts","../src/commands/custom-data.ts","../src/commands/activity.ts","../src/commands/monitor.ts","../src/commands/monitor-transcript.ts","../src/commands/monitor-state.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { createRequire } from \"module\";\nimport { Command } from \"commander\";\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { whoamiCommand } from \"./commands/whoami.js\";\nimport { registerAgentsCommand } from \"./commands/agents.js\";\nimport { registerWorkflowsCommand } from \"./commands/workflows.js\";\nimport { registerKpisCommand } from \"./commands/kpis.js\";\nimport { registerCustomDataCommand } from \"./commands/custom-data.js\";\nimport { registerActivityCommand } from \"./commands/activity.js\";\nimport { registerMonitorCommand } from \"./commands/monitor.js\";\nimport {\n setEnvironment,\n isValidEnvironment,\n getValidEnvironments,\n type Environment,\n} from \"./lib/config.js\";\n\nconst require = createRequire(import.meta.url);\nconst packageJson = require(\"../package.json\") as { version: string };\n\nconst program = new Command();\n\nprogram\n .name(\"olakai\")\n .description(\"Olakai CLI tool\")\n .version(packageJson.version)\n .option(\n \"-e, --env <environment>\",\n `Environment to use (${getValidEnvironments().join(\", \")})`,\n \"production\",\n )\n .hook(\"preAction\", (thisCommand) => {\n const options = thisCommand.opts();\n if (options.env) {\n if (!isValidEnvironment(options.env)) {\n console.error(\n `Invalid environment: ${options.env}. Valid options: ${getValidEnvironments().join(\", \")}`,\n );\n process.exit(1);\n }\n setEnvironment(options.env as Environment);\n }\n });\n\nprogram\n .command(\"login\")\n .description(\"Log in to Olakai using browser authentication\")\n .action(loginCommand);\n\nprogram\n .command(\"logout\")\n .description(\"Log out from Olakai\")\n .action(logoutCommand);\n\nprogram\n .command(\"whoami\")\n .description(\"Show current logged-in user\")\n .action(whoamiCommand);\n\n// Register subcommands for config management\nregisterAgentsCommand(program);\nregisterWorkflowsCommand(program);\nregisterKpisCommand(program);\nregisterCustomDataCommand(program);\n\n// Register subcommands for activity inspection\nregisterActivityCommand(program);\n\n// Register subcommands for local agent monitoring\nregisterMonitorCommand(program);\n\nprogram.parse();\n","import open from \"open\";\nimport { requestDeviceCode, pollForToken, getCurrentUser } from \"../lib/api.js\";\nimport { saveToken, isTokenValid } from \"../lib/auth.js\";\nimport { getEnvironment } from \"../lib/config.js\";\n\nconst POLL_INTERVAL_MS = 5000; // 5 seconds\n\n/**\n * Login command handler\n */\nexport async function loginCommand(): Promise<void> {\n // Check if already logged in\n if (isTokenValid()) {\n try {\n const user = await getCurrentUser();\n console.log(`Already logged in as ${user.email}`);\n console.log(\"Run 'olakai logout' to log out first.\");\n return;\n } catch {\n // Token is invalid, continue with login\n }\n }\n\n console.log(`Logging in to Olakai (${getEnvironment()})...\\n`);\n\n try {\n // Request device code\n const deviceCode = await requestDeviceCode();\n\n // Display instructions\n console.log(\"To complete login, visit:\");\n console.log(`\\n ${deviceCode.verification_uri_complete}\\n`);\n console.log(`Or go to ${deviceCode.verification_uri} and enter code:`);\n console.log(`\\n ${deviceCode.user_code}\\n`);\n\n // Try to open browser\n console.log(\"Opening browser...\");\n try {\n await open(deviceCode.verification_uri_complete);\n } catch {\n console.log(\"(Could not open browser automatically)\");\n }\n\n console.log(\"\\nWaiting for authorization...\");\n\n // Poll for token\n const expiresAt = Date.now() + deviceCode.expires_in * 1000;\n\n while (Date.now() < expiresAt) {\n await sleep(POLL_INTERVAL_MS);\n\n try {\n const tokenResponse = await pollForToken(deviceCode.device_code);\n\n if (tokenResponse) {\n // Save token\n saveToken(tokenResponse.access_token, tokenResponse.expires_in);\n\n // Get user info\n const user = await getCurrentUser();\n\n console.log(`\\nLogged in as ${user.email}`);\n console.log(`Account: ${user.accountId}`);\n console.log(`Role: ${user.role}`);\n return;\n }\n\n // Still pending, show spinner\n process.stdout.write(\".\");\n } catch (error) {\n if (error instanceof Error) {\n console.error(`\\nLogin failed: ${error.message}`);\n } else {\n console.error(\"\\nLogin failed: Unknown error\");\n }\n process.exit(1);\n }\n }\n\n console.error(\"\\nLogin timed out. Please try again.\");\n process.exit(1);\n } catch (error) {\n if (error instanceof Error) {\n console.error(`Login failed: ${error.message}`);\n } else {\n console.error(\"Login failed: Unknown error\");\n }\n process.exit(1);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","export type Environment = \"production\" | \"staging\" | \"local\";\n\nconst HOSTS: Record<Environment, string> = {\n production: \"https://app.olakai.ai\",\n staging: \"https://staging.app.olakai.ai\",\n local: \"http://localhost:3000\",\n};\n\n// CLI client identifier\nexport const CLIENT_ID = \"olakai-cli\";\n\nlet currentEnvironment: Environment = \"production\";\n\n/**\n * Set the current environment\n */\nexport function setEnvironment(env: Environment): void {\n currentEnvironment = env;\n}\n\n/**\n * Get the current environment from:\n * 1. Environment variable OLAKAI_ENV\n * 2. Programmatically set value\n * 3. Default to \"production\"\n */\nexport function getEnvironment(): Environment {\n const envVar = process.env.OLAKAI_ENV as Environment | undefined;\n if (envVar && isValidEnvironment(envVar)) {\n return envVar;\n }\n return currentEnvironment;\n}\n\n/**\n * Get the API base URL for the current environment\n */\nexport function getBaseUrl(): string {\n return HOSTS[getEnvironment()];\n}\n\n/**\n * Check if a string is a valid environment\n */\nexport function isValidEnvironment(env: string): env is Environment {\n return env === \"production\" || env === \"staging\" || env === \"local\";\n}\n\n/**\n * Get list of valid environments for CLI help\n */\nexport function getValidEnvironments(): Environment[] {\n return [\"production\", \"staging\", \"local\"];\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { type Environment, getEnvironment } from \"./config.js\";\n\ninterface StoredCredentials {\n token: string;\n expiresAt: number; // Unix timestamp in seconds\n environment: Environment;\n}\n\n/**\n * Get the credentials file path\n */\nfunction getCredentialsPath(): string {\n const configDir = path.join(os.homedir(), \".config\", \"olakai\");\n return path.join(configDir, \"credentials.json\");\n}\n\n/**\n * Ensure the config directory exists\n */\nfunction ensureConfigDir(): void {\n const configDir = path.dirname(getCredentialsPath());\n if (!fs.existsSync(configDir)) {\n fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });\n }\n}\n\n/**\n * Save an access token to disk\n */\nexport function saveToken(token: string, expiresIn: number): void {\n ensureConfigDir();\n\n const credentials: StoredCredentials = {\n token,\n expiresAt: Math.floor(Date.now() / 1000) + expiresIn,\n environment: getEnvironment(),\n };\n\n const credentialsPath = getCredentialsPath();\n fs.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {\n mode: 0o600, // Read/write for owner only\n });\n}\n\n/**\n * Load the stored token\n */\nexport function loadToken(): StoredCredentials | null {\n const credentialsPath = getCredentialsPath();\n\n if (!fs.existsSync(credentialsPath)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(credentialsPath, \"utf-8\");\n const credentials = JSON.parse(content) as StoredCredentials;\n return credentials;\n } catch {\n return null;\n }\n}\n\n/**\n * Clear stored credentials\n */\nexport function clearToken(): void {\n const credentialsPath = getCredentialsPath();\n\n if (fs.existsSync(credentialsPath)) {\n fs.unlinkSync(credentialsPath);\n }\n}\n\n/**\n * Check if the stored token is valid (exists and not expired)\n */\nexport function isTokenValid(): boolean {\n const credentials = loadToken();\n\n if (!credentials) {\n return false;\n }\n\n // Check if expired (with 60 second buffer)\n const now = Math.floor(Date.now() / 1000);\n if (credentials.expiresAt <= now + 60) {\n return false;\n }\n\n // Check if environment matches\n if (credentials.environment !== getEnvironment()) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Get the current valid token or null\n */\nexport function getValidToken(): string | null {\n if (!isTokenValid()) {\n return null;\n }\n\n const credentials = loadToken();\n return credentials?.token ?? null;\n}\n","import { getBaseUrl, CLIENT_ID } from \"./config.js\";\nimport { getValidToken } from \"./auth.js\";\n\nexport interface 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\nexport interface TokenResponse {\n access_token: string;\n token_type: string;\n expires_in: number;\n}\n\nexport interface TokenErrorResponse {\n error: \"authorization_pending\" | \"expired_token\" | \"access_denied\";\n error_description?: string;\n}\n\nexport interface UserMeResponse {\n id: string;\n email: string;\n firstName: string;\n lastName: string;\n role: string;\n accountId: string;\n}\n\n// Config API Types\nexport interface AgentApiKey {\n id: string;\n key?: string; // Only present on creation\n keyMasked: string;\n isActive: boolean;\n createdAt?: string;\n}\n\nexport type DefaultAggregationMethod =\n | \"SUM\"\n | \"AVERAGE\"\n | \"COUNT\"\n | \"MIN\"\n | \"MAX\"\n | \"LATEST\";\n\nexport type KpiScope = \"PROMPT_REQUEST\" | \"CHAT\" | \"DOCUMENT\";\n\nexport interface KpiDefinition {\n id: string;\n name: string;\n description: string | null;\n type: \"PREDEFINED\" | \"USER_DEFINED\";\n category: string | null;\n agentId: string | null;\n scope: KpiScope;\n calculatorId: string;\n calculatorParams: Record<string, unknown> | null;\n unit: string | null;\n defaultAggregationMethod: DefaultAggregationMethod;\n isActive: boolean;\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport interface CreateKpiPayload {\n name: string;\n description?: string;\n type?: \"PREDEFINED\" | \"USER_DEFINED\";\n category?: string;\n agentId?: string;\n scope: KpiScope;\n calculatorId: string;\n calculatorParams?: Record<string, unknown>;\n unit?: string;\n defaultAggregationMethod?: DefaultAggregationMethod;\n}\n\nexport interface UpdateKpiPayload {\n name?: string;\n description?: string | null;\n type?: \"PREDEFINED\" | \"USER_DEFINED\";\n category?: string | null;\n agentId?: string | null;\n scope?: KpiScope;\n calculatorId?: string;\n calculatorParams?: Record<string, unknown>;\n unit?: string | null;\n defaultAggregationMethod?: DefaultAggregationMethod;\n isActive?: boolean;\n}\n\nexport interface ContextVariable {\n name: string;\n description: string;\n type: \"string\" | \"number\" | \"boolean\";\n sampleValue?: string | number | boolean;\n source: \"shared\" | \"custom\";\n}\n\nexport interface FormulaValidationResult {\n valid: boolean;\n error?: string;\n type?: string | null;\n charIndex?: number;\n parsedFormula?: unknown;\n}\n\nexport interface Agent {\n id: string;\n name: string;\n description: string;\n role: \"WORKER\" | \"COORDINATOR\";\n source: \"SDK\" | \"AUTOMATION_PROVIDER\";\n workflowId: string | null;\n category: string | null;\n apiKey: AgentApiKey | null;\n kpiDefinitions?: KpiDefinition[];\n workflow?: Workflow | null;\n}\n\nexport interface Workflow {\n id: string;\n name: string;\n description: string | null;\n isActive: boolean;\n agentCount: number;\n agents?: Agent[];\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport interface CreateAgentPayload {\n name: string;\n description?: string;\n role?: \"WORKER\" | \"COORDINATOR\";\n workflowId?: string;\n createApiKey?: boolean;\n category?: string;\n source?: string;\n}\n\nexport interface UpdateAgentPayload {\n name?: string;\n description?: string;\n role?: \"WORKER\" | \"COORDINATOR\";\n workflowId?: string | null;\n category?: string | null;\n}\n\nexport interface CreateWorkflowPayload {\n name: string;\n description?: string;\n}\n\nexport interface UpdateWorkflowPayload {\n name?: string;\n description?: string | null;\n isActive?: boolean;\n}\n\n/**\n * Request a device code to start the login flow\n */\nexport async function requestDeviceCode(): Promise<DeviceCodeResponse> {\n const response = await fetch(`${getBaseUrl()}/api/auth/device/code`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ client_id: CLIENT_ID }),\n });\n\n if (!response.ok) {\n const error = (await response.json()) as { error_description?: string; error?: string };\n throw new Error(error.error_description || error.error || \"Failed to request device code\");\n }\n\n return (await response.json()) as DeviceCodeResponse;\n}\n\n/**\n * Poll for token exchange\n * Returns the token response if approved, or throws an error\n */\nexport async function pollForToken(\n deviceCode: string,\n): Promise<TokenResponse | null> {\n const response = await fetch(`${getBaseUrl()}/api/auth/device/token`, {\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 const data = (await response.json()) as TokenResponse | TokenErrorResponse;\n\n if (!response.ok) {\n if (\"error\" in data && data.error === \"authorization_pending\") {\n return null; // Still waiting for user\n }\n const errorMsg = \"error_description\" in data ? data.error_description : (\"error\" in data ? data.error : \"Token exchange failed\");\n throw new Error(errorMsg || \"Token exchange failed\");\n }\n\n return data as TokenResponse;\n}\n\n/**\n * Get current user info\n */\nexport async function getCurrentUser(): Promise<UserMeResponse> {\n const token = getValidToken();\n\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/user/me`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n throw new Error(\"Failed to get user info\");\n }\n\n return (await response.json()) as UserMeResponse;\n}\n\n// ============================================\n// Config API - Agents\n// ============================================\n\n/**\n * List agents for the current account\n */\nexport async function listAgents(options?: {\n includeKpis?: boolean;\n}): Promise<Agent[]> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (options?.includeKpis) {\n params.set(\"includeKpis\", \"true\");\n }\n\n const url = `${getBaseUrl()}/api/config/agents${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list agents\");\n }\n\n const data = (await response.json()) as { agents: Agent[] };\n return data.agents;\n}\n\n/**\n * Get a single agent by ID\n */\nexport async function getAgent(id: string): Promise<Agent> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/agents/${id}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Agent not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get agent\");\n }\n\n return (await response.json()) as Agent;\n}\n\n/**\n * Create a new agent\n */\nexport async function createAgent(payload: CreateAgentPayload): Promise<Agent> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/agents`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 409) {\n throw new Error(\"An agent with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to create agent\");\n }\n\n return (await response.json()) as Agent;\n}\n\n/**\n * Update an agent\n */\nexport async function updateAgent(\n id: string,\n payload: UpdateAgentPayload,\n): Promise<Agent> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/agents/${id}`, {\n method: \"PUT\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Agent not found\");\n }\n if (response.status === 409) {\n throw new Error(\"An agent with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to update agent\");\n }\n\n return (await response.json()) as Agent;\n}\n\n/**\n * Delete an agent\n */\nexport async function deleteAgent(id: string): Promise<void> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/agents/${id}`, {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Agent not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to delete agent\");\n }\n}\n\n// ============================================\n// Config API - Workflows\n// ============================================\n\n/**\n * List workflows for the current account\n */\nexport async function listWorkflows(options?: {\n includeAgents?: boolean;\n includeInactive?: boolean;\n}): Promise<Workflow[]> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (options?.includeAgents) {\n params.set(\"includeAgents\", \"true\");\n }\n if (options?.includeInactive) {\n params.set(\"includeInactive\", \"true\");\n }\n\n const url = `${getBaseUrl()}/api/config/workflows${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list workflows\");\n }\n\n const data = (await response.json()) as { workflows: Workflow[] };\n return data.workflows;\n}\n\n/**\n * Get a single workflow by ID\n */\nexport async function getWorkflow(id: string): Promise<Workflow> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/workflows/${id}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Workflow not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get workflow\");\n }\n\n return (await response.json()) as Workflow;\n}\n\n/**\n * Create a new workflow\n */\nexport async function createWorkflow(\n payload: CreateWorkflowPayload,\n): Promise<Workflow> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/workflows`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 409) {\n throw new Error(\"A workflow with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to create workflow\");\n }\n\n return (await response.json()) as Workflow;\n}\n\n/**\n * Update a workflow\n */\nexport async function updateWorkflow(\n id: string,\n payload: UpdateWorkflowPayload,\n): Promise<Workflow> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/workflows/${id}`, {\n method: \"PUT\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Workflow not found\");\n }\n if (response.status === 409) {\n throw new Error(\"A workflow with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to update workflow\");\n }\n\n return (await response.json()) as Workflow;\n}\n\n/**\n * Delete a workflow\n */\nexport async function deleteWorkflow(id: string): Promise<void> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/workflows/${id}`, {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Workflow not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to delete workflow\");\n }\n}\n\n// ============================================\n// Config API - KPIs\n// ============================================\n\n/**\n * List KPI definitions for the current account\n */\nexport async function listKpis(options?: {\n agentId?: string;\n includeInactive?: boolean;\n}): Promise<KpiDefinition[]> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (options?.agentId) {\n params.set(\"agentId\", options.agentId);\n }\n if (options?.includeInactive) {\n params.set(\"includeInactive\", \"true\");\n }\n\n const url = `${getBaseUrl()}/api/config/kpis${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list KPIs\");\n }\n\n const data = (await response.json()) as { kpiDefinitions: KpiDefinition[] };\n return data.kpiDefinitions;\n}\n\n/**\n * Get a single KPI definition by ID\n */\nexport async function getKpi(id: string): Promise<KpiDefinition> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/kpis/${id}`, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"KPI definition not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get KPI\");\n }\n\n return (await response.json()) as KpiDefinition;\n}\n\n/**\n * Create a new KPI definition\n */\nexport async function createKpi(payload: CreateKpiPayload): Promise<KpiDefinition> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/kpis`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 409) {\n throw new Error(\"A KPI definition with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to create KPI\");\n }\n\n return (await response.json()) as KpiDefinition;\n}\n\n/**\n * Update a KPI definition\n */\nexport async function updateKpi(\n id: string,\n payload: UpdateKpiPayload,\n): Promise<KpiDefinition> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/kpis/${id}`, {\n method: \"PUT\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"KPI definition not found\");\n }\n if (response.status === 409) {\n throw new Error(\"A KPI definition with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to update KPI\");\n }\n\n return (await response.json()) as KpiDefinition;\n}\n\n/**\n * Delete a KPI definition\n */\nexport async function deleteKpi(id: string): Promise<void> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/kpis/${id}`, {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"KPI definition not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to delete KPI\");\n }\n}\n\n/**\n * Get available context variables for KPI formulas\n */\nexport async function getKpiContextVariables(\n agentId?: string,\n scope?: KpiScope,\n): Promise<ContextVariable[]> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (agentId) {\n params.set(\"agentId\", agentId);\n }\n if (scope) {\n params.set(\"scope\", scope);\n }\n\n const url = `${getBaseUrl()}/api/config/kpis/context-variables${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get context variables\");\n }\n\n const data = (await response.json()) as { contextVariables: ContextVariable[] };\n return data.contextVariables;\n}\n\n/**\n * Validate a KPI formula expression\n */\nexport async function validateKpiFormula(\n formula: string,\n agentId?: string,\n scope?: KpiScope,\n): Promise<FormulaValidationResult> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const body: Record<string, string | undefined> = { formula, agentId };\n if (scope) {\n body.scope = scope;\n }\n\n const response = await fetch(`${getBaseUrl()}/api/config/kpis/validate`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to validate formula\");\n }\n\n return (await response.json()) as FormulaValidationResult;\n}\n\n// ============================================\n// Activity API - Prompt Inspection\n// ============================================\n\nexport interface ActivityPrompt {\n id: string;\n createdAt: string;\n agentId: string | null;\n agentName?: string | null;\n workflowId: string | null;\n workflowName?: string | null;\n taskExecutionId?: string | null;\n app: string;\n modelType: string | null;\n modelId: string | null;\n tokens: number;\n requestTime: number;\n isHighRisk: boolean;\n blocked: boolean;\n decorationStatus: string;\n sensitivity: string[];\n prompt?: string;\n response?: string;\n analytics?: {\n task: string | null;\n subtask: string | null;\n timesaved_minutes: number | null;\n riskassessment_dangerousity: number | null;\n };\n kpiData?: Record<string, unknown>;\n}\n\nexport interface ActivityListResponse {\n prompts: ActivityPrompt[];\n total: number;\n limit: number;\n offset: number;\n hasMore: boolean;\n}\n\nexport interface ActivityListOptions {\n agentId?: string;\n workflowId?: string;\n since?: string;\n until?: string;\n limit?: number;\n offset?: number;\n includeContent?: boolean;\n includeAnalytics?: boolean;\n}\n\nexport interface CoreKpiValue {\n name: string;\n value: number;\n measurement: \"count\" | \"ratio\" | \"sum\";\n unitPrefix?: string;\n unitSuffix?: string;\n}\n\nexport interface AggregatedKpi {\n kpiDefinitionId: string;\n name: string;\n value: number | null;\n aggregationMethod: string;\n unit: string | null;\n dataPointCount: number;\n}\n\nexport interface PeriodKpiData {\n periodStart: string;\n periodEnd: string;\n coreKpis: CoreKpiValue[];\n}\n\nexport interface KpiAtom {\n promptRequestId: string;\n createdAt: string;\n kpis: Record<string, unknown>;\n}\n\nexport interface ActivityKpisResponse {\n coreKpis: CoreKpiValue[];\n kpis: AggregatedKpi[];\n periodData?: PeriodKpiData[];\n atoms?: KpiAtom[];\n}\n\nexport interface ActivityKpisOptions {\n agentId?: string;\n workflowId?: string;\n since?: string;\n until?: string;\n period?: \"hourly\" | \"daily\" | \"weekly\";\n includeAtoms?: boolean;\n}\n\n/**\n * List activity prompts with filters\n */\nexport async function listActivity(\n options: ActivityListOptions = {}\n): Promise<ActivityListResponse> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (options.agentId) params.set(\"agentId\", options.agentId);\n if (options.workflowId) params.set(\"workflowId\", options.workflowId);\n if (options.since) params.set(\"since\", options.since);\n if (options.until) params.set(\"until\", options.until);\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options.offset !== undefined) params.set(\"offset\", String(options.offset));\n if (options.includeContent) params.set(\"includeContent\", \"true\");\n if (options.includeAnalytics) params.set(\"includeAnalytics\", \"true\");\n\n const url = `${getBaseUrl()}/api/activity/prompts${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list activity\");\n }\n\n return (await response.json()) as ActivityListResponse;\n}\n\n/**\n * Get a single activity prompt by ID\n */\nexport async function getActivity(\n id: string,\n includeContent?: boolean\n): Promise<ActivityPrompt> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (includeContent) params.set(\"includeContent\", \"true\");\n\n const url = `${getBaseUrl()}/api/activity/prompts/${id}${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Prompt request not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get activity\");\n }\n\n return (await response.json()) as ActivityPrompt;\n}\n\n/**\n * Get aggregated KPI values for an agent or workflow\n */\nexport async function getActivityKpis(\n options: ActivityKpisOptions\n): Promise<ActivityKpisResponse> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n if (!options.agentId && !options.workflowId) {\n throw new Error(\"Either agentId or workflowId is required\");\n }\n\n const params = new URLSearchParams();\n if (options.agentId) params.set(\"agentId\", options.agentId);\n if (options.workflowId) params.set(\"workflowId\", options.workflowId);\n if (options.since) params.set(\"since\", options.since);\n if (options.until) params.set(\"until\", options.until);\n if (options.period) params.set(\"period\", options.period);\n if (options.includeAtoms) params.set(\"includeAtoms\", \"true\");\n\n const url = `${getBaseUrl()}/api/activity/kpis${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get activity KPIs\");\n }\n\n return (await response.json()) as ActivityKpisResponse;\n}\n\n// ============================================\n// Activity API - Session Diagnostics\n// ============================================\n\nexport interface SessionDiagnostic {\n id: string;\n createdAt: string;\n agentId: string | null;\n decorationStatus: string;\n decorationDate: string | null;\n decorationCandidate: boolean;\n decorationError: string | null;\n decorationErrorStreak: number;\n decoratorVersion: string | null;\n hasKpiData: boolean;\n}\n\nexport interface SessionsListResponse {\n sessions: SessionDiagnostic[];\n summary: {\n sessionCount: number;\n byStatus: Record<string, number>;\n };\n total: number;\n limit: number;\n offset: number;\n hasMore: boolean;\n}\n\nexport interface SessionsListOptions {\n agentId: string;\n since?: string;\n until?: string;\n limit?: number;\n offset?: number;\n}\n\n/**\n * List session diagnostics for an agent\n */\nexport async function listSessions(\n options: SessionsListOptions,\n): Promise<SessionsListResponse> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n params.set(\"agentId\", options.agentId);\n if (options.since) params.set(\"since\", options.since);\n if (options.until) params.set(\"until\", options.until);\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\n if (options.offset !== undefined) params.set(\"offset\", String(options.offset));\n\n const url = `${getBaseUrl()}/api/activity/sessions?${params}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list sessions\");\n }\n\n return (await response.json()) as SessionsListResponse;\n}\n\n// Custom Data Config Types\nexport type CustomDataType = \"STRING\" | \"NUMBER\" | \"BOOLEAN\";\n\nexport interface CustomDataConfig {\n id: string;\n accountId: string;\n agentId: string | null; // NULL means legacy account-level config\n name: string;\n description: string | null;\n type: CustomDataType;\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport interface CreateCustomDataPayload {\n agentId: string; // Required for new configs\n name: string;\n description?: string | null;\n type: CustomDataType;\n}\n\nexport interface UpdateCustomDataPayload {\n name?: string;\n description?: string | null;\n type?: CustomDataType;\n // Note: agentId is not updatable after creation\n}\n\n/**\n * List custom data configurations\n * @param agentId - Optional agent ID to filter by. If provided, returns agent-specific configs\n * merged with legacy account-level configs. If omitted, returns all account configs.\n */\nexport async function listCustomDataConfigs(agentId?: string): Promise<CustomDataConfig[]> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const params = new URLSearchParams();\n if (agentId) {\n params.set(\"agentId\", agentId);\n }\n\n const url = `${getBaseUrl()}/api/config/custom-data${params.toString() ? `?${params}` : \"\"}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to list custom data configurations\");\n }\n\n const data = (await response.json()) as { customDataConfigs: CustomDataConfig[] };\n return data.customDataConfigs;\n}\n\n/**\n * Get a single custom data configuration\n */\nexport async function getCustomDataConfig(id: string): Promise<CustomDataConfig> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const url = `${getBaseUrl()}/api/config/custom-data/${encodeURIComponent(id)}`;\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Custom data configuration not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to get custom data configuration\");\n }\n\n return (await response.json()) as CustomDataConfig;\n}\n\n/**\n * Create a new custom data configuration\n */\nexport async function createCustomDataConfig(\n payload: CreateCustomDataPayload\n): Promise<CustomDataConfig> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const url = `${getBaseUrl()}/api/config/custom-data`;\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 409) {\n throw new Error(\"A custom data configuration with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to create custom data configuration\");\n }\n\n return (await response.json()) as CustomDataConfig;\n}\n\n/**\n * Update a custom data configuration\n */\nexport async function updateCustomDataConfig(\n id: string,\n payload: UpdateCustomDataPayload\n): Promise<CustomDataConfig> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const url = `${getBaseUrl()}/api/config/custom-data/${encodeURIComponent(id)}`;\n const response = await fetch(url, {\n method: \"PUT\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Custom data configuration not found\");\n }\n if (response.status === 409) {\n throw new Error(\"A custom data configuration with this name already exists\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to update custom data configuration\");\n }\n\n return (await response.json()) as CustomDataConfig;\n}\n\n/**\n * Delete a custom data configuration\n */\nexport async function deleteCustomDataConfig(id: string): Promise<void> {\n const token = getValidToken();\n if (!token) {\n throw new Error(\"Not logged in. Run 'olakai login' first.\");\n }\n\n const url = `${getBaseUrl()}/api/config/custom-data/${encodeURIComponent(id)}`;\n const response = await fetch(url, {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${token}`,\n },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error(\"Session expired. Run 'olakai login' to authenticate again.\");\n }\n if (response.status === 404) {\n throw new Error(\"Custom data configuration not found\");\n }\n const error = (await response.json()) as { error?: string };\n throw new Error(error.error || \"Failed to delete custom data configuration\");\n }\n}\n","import { clearToken, isTokenValid } from \"../lib/auth.js\";\n\n/**\n * Logout command handler\n */\nexport function logoutCommand(): void {\n if (!isTokenValid()) {\n console.log(\"Not currently logged in.\");\n return;\n }\n\n clearToken();\n console.log(\"Logged out successfully.\");\n}\n","import { getCurrentUser } from \"../lib/api.js\";\nimport { isTokenValid } from \"../lib/auth.js\";\nimport { getEnvironment } from \"../lib/config.js\";\n\n/**\n * Whoami command handler\n */\nexport async function whoamiCommand(): Promise<void> {\n if (!isTokenValid()) {\n console.log(\"Not logged in. Run 'olakai login' to authenticate.\");\n process.exit(1);\n }\n\n try {\n const user = await getCurrentUser();\n\n console.log(`Email: ${user.email}`);\n console.log(`Name: ${user.firstName} ${user.lastName}`);\n console.log(`Role: ${user.role}`);\n console.log(`Account ID: ${user.accountId}`);\n console.log(`Environment: ${getEnvironment()}`);\n } catch (error) {\n if (error instanceof Error) {\n console.error(`Error: ${error.message}`);\n } else {\n console.error(\"Failed to get user info\");\n }\n process.exit(1);\n }\n}\n","import { Command } from \"commander\";\nimport {\n listAgents,\n getAgent,\n createAgent,\n updateAgent,\n deleteAgent,\n type Agent,\n} from \"../lib/api.js\";\n\nfunction formatAgentTable(agents: Agent[]): void {\n if (agents.length === 0) {\n console.log(\"No agents found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"ID\", \"NAME\", \"ROLE\", \"WORKFLOW\", \"API KEY\"];\n const rows = agents.map((agent) => [\n agent.id.slice(0, 12) + \"...\",\n agent.name.slice(0, 30),\n agent.role,\n agent.workflowId ? agent.workflowId.slice(0, 12) + \"...\" : \"-\",\n agent.apiKey ? (agent.apiKey.isActive ? \"Active\" : \"Inactive\") : \"None\",\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n}\n\nfunction formatAgentDetail(agent: Agent): void {\n console.log(`ID: ${agent.id}`);\n console.log(`Name: ${agent.name}`);\n console.log(`Description: ${agent.description || \"-\"}`);\n console.log(`Role: ${agent.role}`);\n console.log(`Source: ${agent.source}`);\n console.log(`Category: ${agent.category || \"-\"}`);\n console.log(`Workflow ID: ${agent.workflowId || \"-\"}`);\n\n if (agent.workflow) {\n console.log(`Workflow: ${agent.workflow.name}`);\n }\n\n console.log(\"\");\n console.log(\"API Key:\");\n if (agent.apiKey) {\n console.log(` ID: ${agent.apiKey.id}`);\n if (agent.apiKey.key) {\n console.log(` Key: ${agent.apiKey.key}`);\n } else {\n console.log(` Key: ${agent.apiKey.keyMasked}`);\n }\n console.log(` Status: ${agent.apiKey.isActive ? \"Active\" : \"Inactive\"}`);\n } else {\n console.log(\" None\");\n }\n\n if (agent.kpiDefinitions && agent.kpiDefinitions.length > 0) {\n console.log(\"\");\n console.log(\"KPI Definitions:\");\n for (const kpi of agent.kpiDefinitions) {\n console.log(` - ${kpi.name} (${kpi.type})`);\n }\n }\n}\n\nasync function listCommand(options: {\n json?: boolean;\n includeKpis?: boolean;\n}): Promise<void> {\n try {\n const agents = await listAgents({ includeKpis: options.includeKpis });\n\n if (options.json) {\n console.log(JSON.stringify(agents, null, 2));\n } else {\n formatAgentTable(agents);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function getCommand(id: string, options: { json?: boolean }): Promise<void> {\n try {\n const agent = await getAgent(id);\n\n if (options.json) {\n console.log(JSON.stringify(agent, null, 2));\n } else {\n formatAgentDetail(agent);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function createCommand(options: {\n name: string;\n description?: string;\n role?: string;\n workflow?: string;\n withApiKey?: boolean;\n category?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.name) {\n console.error(\"Error: --name is required\");\n process.exit(1);\n }\n\n const agent = await createAgent({\n name: options.name,\n description: options.description || \"\",\n role: (options.role as \"WORKER\" | \"COORDINATOR\") || \"WORKER\",\n workflowId: options.workflow,\n createApiKey: options.withApiKey || false,\n category: options.category,\n });\n\n if (options.json) {\n console.log(JSON.stringify(agent, null, 2));\n } else {\n console.log(\"Agent created successfully!\");\n console.log(\"\");\n formatAgentDetail(agent);\n\n if (agent.apiKey?.key) {\n console.log(\"\");\n console.log(\n \"IMPORTANT: Save your API key now. It will not be shown again.\"\n );\n }\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function updateCommand(\n id: string,\n options: {\n name?: string;\n description?: string;\n role?: string;\n workflow?: string;\n category?: string;\n json?: boolean;\n }\n): Promise<void> {\n try {\n const payload: {\n name?: string;\n description?: string;\n role?: \"WORKER\" | \"COORDINATOR\";\n workflowId?: string | null;\n category?: string | null;\n } = {};\n\n if (options.name !== undefined) payload.name = options.name;\n if (options.description !== undefined)\n payload.description = options.description;\n if (options.role !== undefined)\n payload.role = options.role as \"WORKER\" | \"COORDINATOR\";\n if (options.workflow !== undefined) payload.workflowId = options.workflow;\n if (options.category !== undefined) payload.category = options.category;\n\n if (Object.keys(payload).length === 0) {\n console.error(\"Error: At least one field to update is required\");\n process.exit(1);\n }\n\n const agent = await updateAgent(id, payload);\n\n if (options.json) {\n console.log(JSON.stringify(agent, null, 2));\n } else {\n console.log(\"Agent updated successfully!\");\n console.log(\"\");\n formatAgentDetail(agent);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function deleteCommand(\n id: string,\n options: { force?: boolean }\n): Promise<void> {\n try {\n if (!options.force) {\n // In a real CLI, we'd use readline for confirmation\n // For now, require --force flag\n console.log(\"Are you sure you want to delete this agent?\");\n console.log(\"Use --force to confirm deletion.\");\n process.exit(1);\n }\n\n await deleteAgent(id);\n console.log(\"Agent deleted successfully.\");\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nexport function registerAgentsCommand(program: Command): void {\n const agents = program\n .command(\"agents\")\n .description(\"Manage agents\");\n\n agents\n .command(\"list\")\n .description(\"List all agents\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--include-kpis\", \"Include KPI definitions\")\n .action(listCommand);\n\n agents\n .command(\"get <id>\")\n .description(\"Get agent details\")\n .option(\"--json\", \"Output as JSON\")\n .action(getCommand);\n\n agents\n .command(\"create\")\n .description(\"Create a new agent\")\n .requiredOption(\"--name <name>\", \"Agent name\")\n .option(\"--description <description>\", \"Agent description\")\n .option(\"--role <role>\", \"Agent role (WORKER or COORDINATOR)\", \"WORKER\")\n .option(\"--workflow <id>\", \"Workflow ID to assign\")\n .option(\"--with-api-key\", \"Create an API key for this agent\")\n .option(\"--category <category>\", \"Agent category\")\n .option(\"--json\", \"Output as JSON\")\n .action(createCommand);\n\n agents\n .command(\"update <id>\")\n .description(\"Update an agent\")\n .option(\"--name <name>\", \"Agent name\")\n .option(\"--description <description>\", \"Agent description\")\n .option(\"--role <role>\", \"Agent role (WORKER or COORDINATOR)\")\n .option(\"--workflow <id>\", \"Workflow ID to assign\")\n .option(\"--category <category>\", \"Agent category\")\n .option(\"--json\", \"Output as JSON\")\n .action(updateCommand);\n\n agents\n .command(\"delete <id>\")\n .description(\"Delete an agent\")\n .option(\"--force\", \"Skip confirmation\")\n .action(deleteCommand);\n}\n","import { Command } from \"commander\";\nimport {\n listWorkflows,\n getWorkflow,\n createWorkflow,\n updateWorkflow,\n deleteWorkflow,\n type Workflow,\n} from \"../lib/api.js\";\n\nfunction formatWorkflowTable(workflows: Workflow[]): void {\n if (workflows.length === 0) {\n console.log(\"No workflows found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"ID\", \"NAME\", \"AGENTS\", \"STATUS\"];\n const rows = workflows.map((wf) => [\n wf.id.slice(0, 12) + \"...\",\n wf.name.slice(0, 30),\n wf.agentCount.toString(),\n wf.isActive ? \"Active\" : \"Inactive\",\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n}\n\nfunction formatWorkflowDetail(workflow: Workflow): void {\n console.log(`ID: ${workflow.id}`);\n console.log(`Name: ${workflow.name}`);\n console.log(`Description: ${workflow.description || \"-\"}`);\n console.log(`Status: ${workflow.isActive ? \"Active\" : \"Inactive\"}`);\n console.log(`Agents: ${workflow.agentCount}`);\n if (workflow.createdAt) {\n console.log(`Created: ${new Date(workflow.createdAt).toISOString()}`);\n }\n if (workflow.updatedAt) {\n console.log(`Updated: ${new Date(workflow.updatedAt).toISOString()}`);\n }\n\n if (workflow.agents && workflow.agents.length > 0) {\n console.log(\"\");\n console.log(\"Agents:\");\n for (const agent of workflow.agents) {\n const apiKeyStatus = agent.apiKey\n ? agent.apiKey.isActive\n ? \"API Key: Active\"\n : \"API Key: Inactive\"\n : \"No API Key\";\n console.log(` - ${agent.name} (${agent.role}) - ${apiKeyStatus}`);\n }\n }\n}\n\nasync function listCommand(options: {\n json?: boolean;\n includeAgents?: boolean;\n includeInactive?: boolean;\n}): Promise<void> {\n try {\n const workflows = await listWorkflows({\n includeAgents: options.includeAgents,\n includeInactive: options.includeInactive,\n });\n\n if (options.json) {\n console.log(JSON.stringify(workflows, null, 2));\n } else {\n formatWorkflowTable(workflows);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function getCommand(id: string, options: { json?: boolean }): Promise<void> {\n try {\n const workflow = await getWorkflow(id);\n\n if (options.json) {\n console.log(JSON.stringify(workflow, null, 2));\n } else {\n formatWorkflowDetail(workflow);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function createCommand(options: {\n name: string;\n description?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.name) {\n console.error(\"Error: --name is required\");\n process.exit(1);\n }\n\n const workflow = await createWorkflow({\n name: options.name,\n description: options.description,\n });\n\n if (options.json) {\n console.log(JSON.stringify(workflow, null, 2));\n } else {\n console.log(\"Workflow created successfully!\");\n console.log(\"\");\n formatWorkflowDetail(workflow);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function updateCommand(\n id: string,\n options: {\n name?: string;\n description?: string;\n active?: boolean;\n inactive?: boolean;\n json?: boolean;\n }\n): Promise<void> {\n try {\n const payload: {\n name?: string;\n description?: string | null;\n isActive?: boolean;\n } = {};\n\n if (options.name !== undefined) payload.name = options.name;\n if (options.description !== undefined)\n payload.description = options.description;\n if (options.active) payload.isActive = true;\n if (options.inactive) payload.isActive = false;\n\n if (Object.keys(payload).length === 0) {\n console.error(\"Error: At least one field to update is required\");\n process.exit(1);\n }\n\n const workflow = await updateWorkflow(id, payload);\n\n if (options.json) {\n console.log(JSON.stringify(workflow, null, 2));\n } else {\n console.log(\"Workflow updated successfully!\");\n console.log(\"\");\n formatWorkflowDetail(workflow);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function deleteCommand(\n id: string,\n options: { force?: boolean }\n): Promise<void> {\n try {\n if (!options.force) {\n // In a real CLI, we'd use readline for confirmation\n // For now, require --force flag\n console.log(\"Are you sure you want to delete this workflow?\");\n console.log(\"Use --force to confirm deletion.\");\n process.exit(1);\n }\n\n await deleteWorkflow(id);\n console.log(\"Workflow deleted successfully.\");\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nexport function registerWorkflowsCommand(program: Command): void {\n const workflows = program\n .command(\"workflows\")\n .description(\"Manage workflows\");\n\n workflows\n .command(\"list\")\n .description(\"List all workflows\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--include-agents\", \"Include agent details\")\n .option(\"--include-inactive\", \"Include inactive workflows\")\n .action(listCommand);\n\n workflows\n .command(\"get <id>\")\n .description(\"Get workflow details\")\n .option(\"--json\", \"Output as JSON\")\n .action(getCommand);\n\n workflows\n .command(\"create\")\n .description(\"Create a new workflow\")\n .requiredOption(\"--name <name>\", \"Workflow name\")\n .option(\"--description <description>\", \"Workflow description\")\n .option(\"--json\", \"Output as JSON\")\n .action(createCommand);\n\n workflows\n .command(\"update <id>\")\n .description(\"Update a workflow\")\n .option(\"--name <name>\", \"Workflow name\")\n .option(\"--description <description>\", \"Workflow description\")\n .option(\"--active\", \"Set workflow as active\")\n .option(\"--inactive\", \"Set workflow as inactive\")\n .option(\"--json\", \"Output as JSON\")\n .action(updateCommand);\n\n workflows\n .command(\"delete <id>\")\n .description(\"Delete a workflow\")\n .option(\"--force\", \"Skip confirmation\")\n .action(deleteCommand);\n}\n","import { Command } from \"commander\";\nimport {\n listKpis,\n getKpi,\n createKpi,\n updateKpi,\n deleteKpi,\n getKpiContextVariables,\n validateKpiFormula,\n type KpiDefinition,\n type KpiScope,\n type ContextVariable,\n type CreateKpiPayload,\n type DefaultAggregationMethod,\n} from \"../lib/api.js\";\n\nconst AGGREGATION_METHODS: DefaultAggregationMethod[] = [\n \"SUM\",\n \"AVERAGE\",\n \"COUNT\",\n \"MIN\",\n \"MAX\",\n \"LATEST\",\n];\n\nconst CALCULATOR_IDS = [\"formula\", \"classifier\", \"llm-data\"];\n\nconst KPI_SCOPES: KpiScope[] = [\"PROMPT_REQUEST\", \"CHAT\", \"DOCUMENT\"];\n\n// Classifier template definitions — mirrors CLASSIFIER_TEMPLATES from\n// localnode-app/packages/config/classifier-templates.ts\ntype OutputClassOption = { label: string; value: number };\n\ntype ClassifierTemplate = {\n id: string;\n name: string;\n description: string;\n promptTemplate: string;\n defaultUnit: string;\n defaultOutputClasses: OutputClassOption[];\n};\n\nconst CLASSIFIER_TEMPLATES: ClassifierTemplate[] = [\n {\n id: \"sentiment_scorer\",\n name: \"Sentiment Scorer\",\n description:\n \"Scores the overall emotional tone and user satisfaction of a conversation\",\n defaultUnit: \"score\",\n promptTemplate: `Analyze the overall sentiment of the following AI assistant conversation. Consider the user's tone, satisfaction level, and emotional state throughout the interaction.\n\nConversation:\n{{Complete exchange}}\n\nRate the sentiment using exactly one of these numeric scores:\n{{outputClassDescriptions}}\n\nRespond with only the numeric score.`,\n defaultOutputClasses: [\n { label: \"Very Negative\", value: 1 },\n { label: \"Negative\", value: 2 },\n { label: \"Neutral\", value: 3 },\n { label: \"Positive\", value: 4 },\n { label: \"Very Positive\", value: 5 },\n ],\n },\n {\n id: \"time_saved_estimator\",\n name: \"Time Saved Estimator\",\n description:\n \"Estimates how much time the AI interaction saved compared to manual effort\",\n defaultUnit: \"minutes\",\n promptTemplate: `Estimate how much time this AI assistant interaction saved the user compared to completing the task manually without AI assistance. Consider the complexity of the request, the completeness of the response, and typical human effort for similar tasks.\n\nConversation:\n{{Complete exchange}}\n\nClassify the estimated time saved using exactly one of these values (in minutes):\n{{outputClassDescriptions}}\n\nRespond with only the numeric value.`,\n defaultOutputClasses: [\n { label: \"No time saved\", value: 0 },\n { label: \"A few minutes\", value: 3 },\n { label: \"Moderate time\", value: 10 },\n { label: \"Significant time\", value: 30 },\n { label: \"Major time savings\", value: 60 },\n ],\n },\n];\n\nfunction resolveOutputClassDescriptions(classes: OutputClassOption[]): string {\n return classes.map((c) => `${c.value} = ${c.label}`).join(\"\\n\");\n}\n\nfunction resolveTemplatePrompt(\n template: ClassifierTemplate,\n classes: OutputClassOption[],\n): string {\n return template.promptTemplate.replace(\n \"{{outputClassDescriptions}}\",\n resolveOutputClassDescriptions(classes),\n );\n}\n\nfunction formatKpiTable(kpis: KpiDefinition[]): void {\n if (kpis.length === 0) {\n console.log(\"No KPI definitions found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"ID\", \"NAME\", \"SCOPE\", \"CALCULATOR\", \"AGGREGATION\", \"STATUS\"];\n const rows = kpis.map((kpi) => [\n kpi.id.slice(0, 12) + \"...\",\n kpi.name.slice(0, 25),\n kpi.scope || \"PROMPT_REQUEST\",\n kpi.calculatorId,\n kpi.defaultAggregationMethod,\n kpi.isActive ? \"Active\" : \"Inactive\",\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n}\n\nfunction formatKpiDetail(kpi: KpiDefinition): void {\n console.log(`ID: ${kpi.id}`);\n console.log(`Name: ${kpi.name}`);\n console.log(`Description: ${kpi.description || \"-\"}`);\n console.log(`Type: ${kpi.type}`);\n console.log(`Category: ${kpi.category || \"-\"}`);\n console.log(`Agent ID: ${kpi.agentId || \"-\"}`);\n console.log(`Scope: ${kpi.scope || \"PROMPT_REQUEST\"}`);\n console.log(`Calculator: ${kpi.calculatorId}`);\n console.log(`Aggregation: ${kpi.defaultAggregationMethod}`);\n console.log(`Unit: ${kpi.unit || \"-\"}`);\n console.log(`Status: ${kpi.isActive ? \"Active\" : \"Inactive\"}`);\n\n if (kpi.calculatorParams) {\n console.log(\"\");\n console.log(\"Calculator Parameters:\");\n console.log(JSON.stringify(kpi.calculatorParams, null, 2));\n }\n\n if (kpi.createdAt) {\n console.log(\"\");\n console.log(`Created: ${new Date(kpi.createdAt).toISOString()}`);\n }\n if (kpi.updatedAt) {\n console.log(`Updated: ${new Date(kpi.updatedAt).toISOString()}`);\n }\n}\n\nfunction formatContextVariablesTable(variables: ContextVariable[]): void {\n if (variables.length === 0) {\n console.log(\"No context variables found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"NAME\", \"TYPE\", \"SOURCE\", \"DESCRIPTION\"];\n const rows = variables.map((v) => [\n v.name,\n v.type,\n v.source,\n v.description.slice(0, 50),\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n}\n\nasync function listCommand(options: {\n json?: boolean;\n agentId?: string;\n includeInactive?: boolean;\n}): Promise<void> {\n try {\n const kpis = await listKpis({\n agentId: options.agentId,\n includeInactive: options.includeInactive,\n });\n\n if (options.json) {\n console.log(JSON.stringify(kpis, null, 2));\n } else {\n formatKpiTable(kpis);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function getCommand(\n id: string,\n options: { json?: boolean }\n): Promise<void> {\n try {\n const kpi = await getKpi(id);\n\n if (options.json) {\n console.log(JSON.stringify(kpi, null, 2));\n } else {\n formatKpiDetail(kpi);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function createCommand(options: {\n name: string;\n calculatorId: string;\n scope: string;\n description?: string;\n type?: string;\n category?: string;\n agentId?: string;\n formula?: string;\n templateId?: string;\n outputClasses?: string;\n outputLabels?: string;\n samplingFactor?: string;\n unit?: string;\n aggregation?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.name) {\n console.error(\"Error: --name is required\");\n process.exit(1);\n }\n\n if (!options.calculatorId) {\n console.error(\"Error: --calculator-id is required\");\n console.error(`Valid values: ${CALCULATOR_IDS.join(\", \")}`);\n process.exit(1);\n }\n\n if (!CALCULATOR_IDS.includes(options.calculatorId)) {\n console.error(`Error: Invalid calculator ID \"${options.calculatorId}\"`);\n console.error(`Valid values: ${CALCULATOR_IDS.join(\", \")}`);\n process.exit(1);\n }\n\n // Validate scope\n const upperScope = options.scope.toUpperCase() as KpiScope;\n if (!KPI_SCOPES.includes(upperScope)) {\n console.error(`Error: Invalid scope \"${options.scope}\"`);\n console.error(`Valid values: ${KPI_SCOPES.join(\", \")}`);\n process.exit(1);\n }\n\n // Build calculator params\n let calculatorParams: Record<string, unknown> | undefined;\n let resolvedUnit = options.unit;\n\n if (options.calculatorId === \"formula\") {\n if (!options.formula) {\n console.error(\n \"Error: --formula is required when calculator-id is 'formula'\"\n );\n process.exit(1);\n }\n // Validate and parse the formula using the API\n const validation = await validateKpiFormula(options.formula, options.agentId, upperScope);\n if (!validation.valid) {\n console.error(`Error: Invalid formula: ${validation.error}`);\n process.exit(1);\n }\n // Use the parsed formula AST, not the raw string\n calculatorParams = { formula: validation.parsedFormula };\n } else if (options.calculatorId === \"classifier\") {\n if (!options.templateId) {\n console.error(\n \"Error: Classifier KPIs require --template-id. Run `olakai kpis templates` to see available templates.\"\n );\n process.exit(1);\n }\n\n const templateIds = CLASSIFIER_TEMPLATES.map((t) => t.id);\n const template = CLASSIFIER_TEMPLATES.find(\n (t) => t.id === options.templateId,\n );\n if (!template) {\n console.error(\n `Error: Unknown template \"${options.templateId}\". Valid templates: ${templateIds.join(\", \")}`\n );\n process.exit(1);\n }\n\n // Resolve output classes — use overrides if provided, else template defaults\n let outputClasses = template.defaultOutputClasses;\n if (options.outputClasses || options.outputLabels) {\n const rawValues = options.outputClasses\n ? options.outputClasses.split(\",\").map((v) => v.trim())\n : template.defaultOutputClasses.map((c) => String(c.value));\n const rawLabels = options.outputLabels\n ? options.outputLabels.split(\",\").map((l) => l.trim())\n : template.defaultOutputClasses.map((c) => c.label);\n\n if (rawValues.length !== rawLabels.length) {\n console.error(\n `Error: --output-classes (${rawValues.length} values) and --output-labels (${rawLabels.length} labels) must have the same count.`\n );\n process.exit(1);\n }\n\n outputClasses = rawValues.map((v, i) => ({\n label: rawLabels[i],\n value: Number(v),\n }));\n }\n\n // Resolve prompt with output class descriptions\n const promptTemplate = resolveTemplatePrompt(template, outputClasses);\n\n calculatorParams = {\n promptTemplate,\n outputClasses: outputClasses.map((c) => c.value),\n outputClassLabels: outputClasses.map((c) => c.label),\n classifierTemplateId: template.id,\n };\n\n // Parse sampling factor if provided\n if (options.samplingFactor !== undefined) {\n const factor = Number(options.samplingFactor);\n if (isNaN(factor) || factor < 0 || factor > 1) {\n console.error(\"Error: --sampling-factor must be a number between 0 and 1.\");\n process.exit(1);\n }\n calculatorParams.samplingFactor = factor;\n }\n\n // Use template default unit unless explicitly overridden\n if (!resolvedUnit) {\n resolvedUnit = template.defaultUnit;\n }\n }\n\n // Validate aggregation method\n let aggregation: DefaultAggregationMethod | undefined;\n if (options.aggregation) {\n const upperAggregation =\n options.aggregation.toUpperCase() as DefaultAggregationMethod;\n if (!AGGREGATION_METHODS.includes(upperAggregation)) {\n console.error(`Error: Invalid aggregation method \"${options.aggregation}\"`);\n console.error(`Valid values: ${AGGREGATION_METHODS.join(\", \")}`);\n process.exit(1);\n }\n aggregation = upperAggregation;\n }\n\n const payload: CreateKpiPayload = {\n name: options.name,\n calculatorId: options.calculatorId,\n scope: upperScope,\n description: options.description,\n type:\n options.type === \"PREDEFINED\" ? \"PREDEFINED\" : \"USER_DEFINED\",\n category: options.category,\n agentId: options.agentId,\n calculatorParams,\n unit: resolvedUnit,\n defaultAggregationMethod: aggregation,\n };\n\n const kpi = await createKpi(payload);\n\n if (options.json) {\n console.log(JSON.stringify(kpi, null, 2));\n } else {\n console.log(\"KPI definition created successfully!\");\n console.log(\"\");\n formatKpiDetail(kpi);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function updateCommand(\n id: string,\n options: {\n name?: string;\n description?: string;\n category?: string;\n agentId?: string;\n scope?: string;\n calculatorId?: string;\n formula?: string;\n unit?: string;\n aggregation?: string;\n active?: boolean;\n inactive?: boolean;\n json?: boolean;\n }\n): Promise<void> {\n try {\n const payload: Record<string, unknown> = {};\n\n if (options.name !== undefined) payload.name = options.name;\n if (options.description !== undefined)\n payload.description = options.description;\n if (options.category !== undefined) payload.category = options.category;\n if (options.agentId !== undefined) payload.agentId = options.agentId;\n if (options.calculatorId !== undefined)\n payload.calculatorId = options.calculatorId;\n if (options.unit !== undefined) payload.unit = options.unit;\n if (options.active) payload.isActive = true;\n if (options.inactive) payload.isActive = false;\n\n // Validate and set scope\n let validatedScope: KpiScope | undefined;\n if (options.scope !== undefined) {\n const upperScope = options.scope.toUpperCase() as KpiScope;\n if (!KPI_SCOPES.includes(upperScope)) {\n console.error(`Error: Invalid scope \"${options.scope}\"`);\n console.error(`Valid values: ${KPI_SCOPES.join(\", \")}`);\n process.exit(1);\n }\n payload.scope = upperScope;\n validatedScope = upperScope;\n }\n\n // Handle formula update - validate and parse before storing\n if (options.formula !== undefined) {\n const validation = await validateKpiFormula(options.formula, options.agentId, validatedScope);\n if (!validation.valid) {\n console.error(`Error: Invalid formula: ${validation.error}`);\n process.exit(1);\n }\n // Use the parsed formula AST, not the raw string\n payload.calculatorParams = { formula: validation.parsedFormula };\n }\n\n // Validate and set aggregation method\n if (options.aggregation) {\n const upperAggregation =\n options.aggregation.toUpperCase() as DefaultAggregationMethod;\n if (!AGGREGATION_METHODS.includes(upperAggregation)) {\n console.error(`Error: Invalid aggregation method \"${options.aggregation}\"`);\n console.error(`Valid values: ${AGGREGATION_METHODS.join(\", \")}`);\n process.exit(1);\n }\n payload.defaultAggregationMethod = upperAggregation;\n }\n\n if (Object.keys(payload).length === 0) {\n console.error(\"Error: At least one field to update is required\");\n process.exit(1);\n }\n\n const kpi = await updateKpi(id, payload);\n\n if (options.json) {\n console.log(JSON.stringify(kpi, null, 2));\n } else {\n console.log(\"KPI definition updated successfully!\");\n console.log(\"\");\n formatKpiDetail(kpi);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function deleteCommand(\n id: string,\n options: { force?: boolean }\n): Promise<void> {\n try {\n if (!options.force) {\n console.log(\"Are you sure you want to delete this KPI definition?\");\n console.log(\"Use --force to confirm deletion.\");\n process.exit(1);\n }\n\n await deleteKpi(id);\n console.log(\"KPI definition deleted successfully.\");\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function contextVariablesCommand(options: {\n json?: boolean;\n agentId?: string;\n scope?: string;\n}): Promise<void> {\n try {\n // Validate scope if provided\n let validatedScope: KpiScope | undefined;\n if (options.scope) {\n const upperScope = options.scope.toUpperCase() as KpiScope;\n if (!KPI_SCOPES.includes(upperScope)) {\n console.error(`Error: Invalid scope \"${options.scope}\"`);\n console.error(`Valid values: ${KPI_SCOPES.join(\", \")}`);\n process.exit(1);\n }\n validatedScope = upperScope;\n }\n\n const variables = await getKpiContextVariables(options.agentId, validatedScope);\n\n if (options.json) {\n console.log(JSON.stringify(variables, null, 2));\n } else {\n console.log(\"Available context variables for KPI formulas:\");\n console.log(\"\");\n formatContextVariablesTable(variables);\n console.log(\"\");\n console.log(\n \"Use these variable names in your formula expressions, e.g.:\"\n );\n console.log(' IF(PII detected, 1, 0)');\n console.log(' Documents count * 10');\n console.log(' IF(CODE detected AND SECRET detected, \"high-risk\", \"normal\")');\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function validateCommand(options: {\n formula: string;\n agentId?: string;\n scope?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.formula) {\n console.error(\"Error: --formula is required\");\n process.exit(1);\n }\n\n // Validate scope if provided\n let validatedScope: KpiScope | undefined;\n if (options.scope) {\n const upperScope = options.scope.toUpperCase() as KpiScope;\n if (!KPI_SCOPES.includes(upperScope)) {\n console.error(`Error: Invalid scope \"${options.scope}\"`);\n console.error(`Valid values: ${KPI_SCOPES.join(\", \")}`);\n process.exit(1);\n }\n validatedScope = upperScope;\n }\n\n const result = await validateKpiFormula(options.formula, options.agentId, validatedScope);\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n if (result.valid) {\n console.log(\"Formula is valid!\");\n console.log(`Result type: ${result.type || \"unknown\"}`);\n } else {\n console.error(\"Formula is invalid:\");\n console.error(` ${result.error}`);\n if (result.charIndex !== undefined) {\n console.error(` Position: character ${result.charIndex}`);\n }\n process.exit(1);\n }\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nfunction templatesCommand(options: { json?: boolean }): void {\n if (options.json) {\n console.log(\n JSON.stringify(\n CLASSIFIER_TEMPLATES.map((t) => ({\n id: t.id,\n name: t.name,\n description: t.description,\n defaultUnit: t.defaultUnit,\n outputClasses: t.defaultOutputClasses,\n })),\n null,\n 2,\n ),\n );\n } else {\n console.log(\"Available Classifier Templates:\");\n console.log(\"\");\n for (const t of CLASSIFIER_TEMPLATES) {\n console.log(` ${t.id.padEnd(24)} ${t.description}`);\n const classRange = t.defaultOutputClasses;\n console.log(\n `${\"\".padEnd(26)}Classes: ${classRange.map((c) => `${c.value} (${c.label})`).join(\", \")}`,\n );\n console.log(\n `${\"\".padEnd(26)}Default unit: ${t.defaultUnit}`,\n );\n console.log(\"\");\n }\n console.log(\"Usage:\");\n console.log(\n ' olakai kpis create --name \"User Satisfaction\" --calculator-id classifier --template-id sentiment_scorer --scope CHAT',\n );\n }\n}\n\nexport function registerKpisCommand(program: Command): void {\n const kpis = program\n .command(\"kpis\")\n .description(\"Manage KPI definitions\");\n\n kpis\n .command(\"list\")\n .description(\"List all KPI definitions\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--agent-id <id>\", \"Filter by agent ID\")\n .option(\"--include-inactive\", \"Include inactive KPI definitions\")\n .action(listCommand);\n\n kpis\n .command(\"get <id>\")\n .description(\"Get KPI definition details\")\n .option(\"--json\", \"Output as JSON\")\n .action(getCommand);\n\n kpis\n .command(\"create\")\n .description(\"Create a new KPI definition\")\n .requiredOption(\"--name <name>\", \"KPI name\")\n .requiredOption(\n \"--calculator-id <id>\",\n \"Calculator type: formula, classifier, or llm-data\"\n )\n .requiredOption(\n \"--scope <scope>\",\n \"KPI scope: PROMPT_REQUEST, CHAT, or DOCUMENT\"\n )\n .option(\"--description <description>\", \"KPI description\")\n .option(\"--type <type>\", \"KPI type: PREDEFINED or USER_DEFINED (default)\")\n .option(\"--category <category>\", \"KPI category for grouping\")\n .option(\"--agent-id <id>\", \"Associate KPI with a specific agent\")\n .option(\"--formula <formula>\", \"Formula expression (required for formula calculator)\")\n .option(\"--template-id <id>\", \"Classifier template: sentiment_scorer, time_saved_estimator\")\n .option(\"--output-classes <values>\", \"Override output class values (comma-separated numbers)\")\n .option(\"--output-labels <labels>\", \"Override output class labels (comma-separated)\")\n .option(\"--sampling-factor <factor>\", \"Fraction of events to classify, 0-1 (cost control)\")\n .option(\"--unit <unit>\", 'Display unit (e.g., \"ms\", \"%\", \"count\")')\n .option(\n \"--aggregation <method>\",\n \"Default aggregation: SUM, AVERAGE, COUNT, MIN, MAX, LATEST (default)\"\n )\n .option(\"--json\", \"Output as JSON\")\n .action(createCommand);\n\n kpis\n .command(\"templates\")\n .description(\"List available classifier templates\")\n .option(\"--json\", \"Output as JSON\")\n .action(templatesCommand);\n\n kpis\n .command(\"update <id>\")\n .description(\"Update a KPI definition\")\n .option(\"--name <name>\", \"KPI name\")\n .option(\"--description <description>\", \"KPI description\")\n .option(\"--category <category>\", \"KPI category\")\n .option(\"--agent-id <id>\", \"Associate with agent\")\n .option(\"--scope <scope>\", \"KPI scope: PROMPT_REQUEST, CHAT, or DOCUMENT\")\n .option(\"--calculator-id <id>\", \"Calculator type\")\n .option(\"--formula <formula>\", \"Formula expression\")\n .option(\"--unit <unit>\", \"Display unit\")\n .option(\"--aggregation <method>\", \"Default aggregation method\")\n .option(\"--active\", \"Set KPI as active\")\n .option(\"--inactive\", \"Set KPI as inactive\")\n .option(\"--json\", \"Output as JSON\")\n .action(updateCommand);\n\n kpis\n .command(\"delete <id>\")\n .description(\"Delete a KPI definition\")\n .option(\"--force\", \"Skip confirmation\")\n .action(deleteCommand);\n\n kpis\n .command(\"context-variables\")\n .description(\"List available context variables for formulas\")\n .option(\"--json\", \"Output as JSON\")\n .option(\"--agent-id <id>\", \"Include agent-specific variables\")\n .option(\"--scope <scope>\", \"Filter variables by scope: PROMPT_REQUEST, CHAT, or DOCUMENT\")\n .action(contextVariablesCommand);\n\n kpis\n .command(\"validate\")\n .description(\"Validate a KPI formula expression\")\n .requiredOption(\"--formula <formula>\", \"Formula expression to validate\")\n .option(\"--agent-id <id>\", \"Include agent-specific context\")\n .option(\"--scope <scope>\", \"Validate against scope: PROMPT_REQUEST, CHAT, or DOCUMENT\")\n .option(\"--json\", \"Output as JSON\")\n .action(validateCommand);\n}\n","import { Command } from \"commander\";\nimport {\n listCustomDataConfigs,\n getCustomDataConfig,\n createCustomDataConfig,\n updateCustomDataConfig,\n deleteCustomDataConfig,\n type CustomDataConfig,\n type CustomDataType,\n} from \"../lib/api.js\";\n\nconst DATA_TYPES: CustomDataType[] = [\"STRING\", \"NUMBER\", \"BOOLEAN\"];\n\nfunction formatTable(configs: CustomDataConfig[]): void {\n if (configs.length === 0) {\n console.log(\"No custom data configurations found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"ID\", \"NAME\", \"TYPE\", \"AGENT ID\", \"DESCRIPTION\"];\n const rows = configs.map((config) => [\n config.id.slice(0, 12) + \"...\",\n config.name.slice(0, 25),\n config.type,\n config.agentId ? config.agentId.slice(0, 12) + \"...\" : \"(account-level)\",\n (config.description || \"-\").slice(0, 30),\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n}\n\nfunction formatDetail(config: CustomDataConfig): void {\n console.log(`ID: ${config.id}`);\n console.log(`Name: ${config.name}`);\n console.log(`Type: ${config.type}`);\n console.log(`Agent ID: ${config.agentId || \"(account-level / legacy)\"}`);\n console.log(`Description: ${config.description || \"-\"}`);\n if (config.createdAt) {\n console.log(`Created: ${new Date(config.createdAt).toISOString()}`);\n }\n if (config.updatedAt) {\n console.log(`Updated: ${new Date(config.updatedAt).toISOString()}`);\n }\n}\n\nasync function listCommand(options: { agentId?: string; json?: boolean }): Promise<void> {\n try {\n const configs = await listCustomDataConfigs(options.agentId);\n\n if (options.json) {\n console.log(JSON.stringify(configs, null, 2));\n } else {\n formatTable(configs);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function getCommand(\n id: string,\n options: { json?: boolean }\n): Promise<void> {\n try {\n const config = await getCustomDataConfig(id);\n\n if (options.json) {\n console.log(JSON.stringify(config, null, 2));\n } else {\n formatDetail(config);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function createCommand(options: {\n agentId: string;\n name: string;\n type: string;\n description?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.agentId) {\n console.error(\"Error: --agent-id is required\");\n console.error(\"Custom data configurations must be associated with an agent.\");\n process.exit(1);\n }\n\n if (!options.name) {\n console.error(\"Error: --name is required\");\n process.exit(1);\n }\n\n if (!options.type) {\n console.error(\"Error: --type is required\");\n console.error(`Valid values: ${DATA_TYPES.join(\", \")}`);\n process.exit(1);\n }\n\n const upperType = options.type.toUpperCase() as CustomDataType;\n if (!DATA_TYPES.includes(upperType)) {\n console.error(`Error: Invalid type \"${options.type}\"`);\n console.error(`Valid values: ${DATA_TYPES.join(\", \")}`);\n process.exit(1);\n }\n\n const config = await createCustomDataConfig({\n agentId: options.agentId,\n name: options.name,\n type: upperType,\n description: options.description ?? null,\n });\n\n if (options.json) {\n console.log(JSON.stringify(config, null, 2));\n } else {\n console.log(\"Custom data configuration created successfully!\");\n console.log(\"\");\n formatDetail(config);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function updateCommand(\n id: string,\n options: {\n name?: string;\n type?: string;\n description?: string;\n json?: boolean;\n }\n): Promise<void> {\n try {\n const payload: {\n name?: string;\n type?: CustomDataType;\n description?: string | null;\n } = {};\n\n if (options.name !== undefined) payload.name = options.name;\n if (options.description !== undefined)\n payload.description = options.description || null;\n\n if (options.type !== undefined) {\n const upperType = options.type.toUpperCase() as CustomDataType;\n if (!DATA_TYPES.includes(upperType)) {\n console.error(`Error: Invalid type \"${options.type}\"`);\n console.error(`Valid values: ${DATA_TYPES.join(\", \")}`);\n process.exit(1);\n }\n payload.type = upperType;\n }\n\n if (Object.keys(payload).length === 0) {\n console.error(\"Error: At least one field to update is required\");\n process.exit(1);\n }\n\n const config = await updateCustomDataConfig(id, payload);\n\n if (options.json) {\n console.log(JSON.stringify(config, null, 2));\n } else {\n console.log(\"Custom data configuration updated successfully!\");\n console.log(\"\");\n formatDetail(config);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function deleteCommand(\n id: string,\n options: { force?: boolean }\n): Promise<void> {\n try {\n if (!options.force) {\n console.log(\n \"Are you sure you want to delete this custom data configuration?\"\n );\n console.log(\"Use --force to confirm deletion.\");\n process.exit(1);\n }\n\n await deleteCustomDataConfig(id);\n console.log(\"Custom data configuration deleted successfully.\");\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nexport function registerCustomDataCommand(program: Command): void {\n const customData = program\n .command(\"custom-data\")\n .description(\"Manage custom data configurations for KPI formulas\");\n\n customData\n .command(\"list\")\n .description(\"List custom data configurations\")\n .option(\"--agent-id <agentId>\", \"Filter by agent ID (omit to list all account configs)\")\n .option(\"--json\", \"Output as JSON\")\n .action(listCommand);\n\n customData\n .command(\"get <id>\")\n .description(\"Get custom data configuration details\")\n .option(\"--json\", \"Output as JSON\")\n .action(getCommand);\n\n customData\n .command(\"create\")\n .description(\"Create a new custom data configuration for an agent\")\n .requiredOption(\"--agent-id <agentId>\", \"Agent ID (required)\")\n .requiredOption(\"--name <name>\", \"Configuration name (used in KPI formulas)\")\n .requiredOption(\n \"--type <type>\",\n \"Data type: STRING, NUMBER, or BOOLEAN\"\n )\n .option(\"--description <description>\", \"Configuration description\")\n .option(\"--json\", \"Output as JSON\")\n .action(createCommand);\n\n customData\n .command(\"update <id>\")\n .description(\"Update a custom data configuration\")\n .option(\"--name <name>\", \"Configuration name\")\n .option(\"--type <type>\", \"Data type: STRING, NUMBER, or BOOLEAN\")\n .option(\"--description <description>\", \"Configuration description\")\n .option(\"--json\", \"Output as JSON\")\n .action(updateCommand);\n\n customData\n .command(\"delete <id>\")\n .description(\"Delete a custom data configuration\")\n .option(\"--force\", \"Skip confirmation\")\n .action(deleteCommand);\n}\n","import { Command } from \"commander\";\nimport {\n listActivity,\n getActivity,\n getActivityKpis,\n listSessions,\n type ActivityPrompt,\n type ActivityListResponse,\n type ActivityKpisResponse,\n type CoreKpiValue,\n type SessionsListResponse,\n} from \"../lib/api.js\";\n\nfunction formatActivityTable(data: ActivityListResponse): void {\n if (data.prompts.length === 0) {\n console.log(\"No activity found.\");\n return;\n }\n\n // Calculate column widths\n const headers = [\"ID\", \"AGENT\", \"APP\", \"MODEL\", \"TOKENS\", \"TIME(ms)\", \"RISK\", \"STATUS\"];\n const rows = data.prompts.map((prompt) => [\n prompt.id.slice(0, 12) + \"...\",\n prompt.agentName || (prompt.agentId ? prompt.agentId.slice(0, 12) + \"...\" : \"-\"),\n prompt.app.slice(0, 12),\n prompt.modelId?.slice(0, 15) || \"-\",\n String(prompt.tokens),\n String(prompt.requestTime),\n prompt.isHighRisk ? \"Yes\" : \"No\",\n prompt.decorationStatus.slice(0, 10),\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n // Print header\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n // Print rows\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n\n // Print pagination info\n console.log(\"\");\n console.log(`Showing ${data.prompts.length} of ${data.total} results (offset: ${data.offset})`);\n if (data.hasMore) {\n console.log(`Use --offset ${data.offset + data.limit} to see more results`);\n }\n}\n\nfunction formatActivityDetail(prompt: ActivityPrompt): void {\n console.log(`ID: ${prompt.id}`);\n console.log(`Created: ${prompt.createdAt}`);\n console.log(`Agent: ${prompt.agentName || \"-\"} (${prompt.agentId || \"-\"})`);\n console.log(`Workflow: ${prompt.workflowName || \"-\"} (${prompt.workflowId || \"-\"})`);\n if (prompt.taskExecutionId) {\n console.log(`Task Exec ID: ${prompt.taskExecutionId}`);\n }\n console.log(`App: ${prompt.app}`);\n console.log(`Model: ${prompt.modelId || \"-\"} (${prompt.modelType || \"-\"})`);\n console.log(`Tokens: ${prompt.tokens}`);\n console.log(`Request Time: ${prompt.requestTime}ms`);\n console.log(`High Risk: ${prompt.isHighRisk ? \"Yes\" : \"No\"}`);\n console.log(`Blocked: ${prompt.blocked ? \"Yes\" : \"No\"}`);\n console.log(`Status: ${prompt.decorationStatus}`);\n\n if (prompt.sensitivity && prompt.sensitivity.length > 0) {\n console.log(`Sensitivity: ${prompt.sensitivity.join(\", \")}`);\n }\n\n if (prompt.analytics) {\n console.log(\"\");\n console.log(\"Analytics:\");\n console.log(` Task: ${prompt.analytics.task || \"-\"}`);\n console.log(` Subtask: ${prompt.analytics.subtask || \"-\"}`);\n console.log(` Time Saved: ${prompt.analytics.timesaved_minutes ?? \"-\"} minutes`);\n console.log(` Risk Score: ${prompt.analytics.riskassessment_dangerousity ?? \"-\"}`);\n }\n\n if (prompt.kpiData && Object.keys(prompt.kpiData).length > 0) {\n console.log(\"\");\n console.log(\"KPIs:\");\n for (const [key, value] of Object.entries(prompt.kpiData)) {\n console.log(` ${key}: ${value}`);\n }\n }\n\n if (prompt.prompt !== undefined) {\n console.log(\"\");\n console.log(\"Prompt:\");\n console.log(\"---\");\n console.log(prompt.prompt.slice(0, 1000) + (prompt.prompt.length > 1000 ? \"...\" : \"\"));\n console.log(\"---\");\n }\n\n if (prompt.response !== undefined) {\n console.log(\"\");\n console.log(\"Response:\");\n console.log(\"---\");\n console.log(prompt.response.slice(0, 1000) + (prompt.response.length > 1000 ? \"...\" : \"\"));\n console.log(\"---\");\n }\n}\n\nfunction formatCoreKpi(kpi: CoreKpiValue): string {\n const prefix = kpi.unitPrefix || \"\";\n const suffix = kpi.unitSuffix || \"\";\n return `${prefix}${kpi.value}${suffix}`;\n}\n\nfunction formatKpisResponse(data: ActivityKpisResponse): void {\n // Core KPIs\n console.log(\"Core KPIs:\");\n for (const kpi of data.coreKpis) {\n console.log(` ${kpi.name.padEnd(25)} ${formatCoreKpi(kpi)}`);\n }\n\n // Custom KPIs\n if (data.kpis.length > 0) {\n console.log(\"\");\n console.log(\"Custom KPIs:\");\n const headers = [\"NAME\", \"VALUE\", \"UNIT\", \"AGGREGATION\", \"DATA POINTS\"];\n const rows = data.kpis.map((kpi) => [\n kpi.name.slice(0, 25),\n kpi.value !== null ? String(kpi.value) : \"-\",\n kpi.unit || \"-\",\n kpi.aggregationMethod,\n String(kpi.dataPointCount),\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n console.log(\" \" + headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(\" \" + widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n for (const row of rows) {\n console.log(\" \" + row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n }\n\n // Period data\n if (data.periodData && data.periodData.length > 0) {\n console.log(\"\");\n console.log(\"Period Breakdown:\");\n for (const period of data.periodData) {\n console.log(` ${period.periodStart} - ${period.periodEnd}`);\n for (const kpi of period.coreKpis) {\n console.log(` ${kpi.name}: ${formatCoreKpi(kpi)}`);\n }\n }\n }\n\n // Atoms summary\n if (data.atoms && data.atoms.length > 0) {\n console.log(\"\");\n console.log(`Per-Prompt KPI Atoms: ${data.atoms.length} records`);\n console.log(\" (Use --json for full atom data)\");\n }\n}\n\nasync function listCommand(options: {\n agentId?: string;\n workflowId?: string;\n since?: string;\n until?: string;\n limit?: string;\n offset?: string;\n includeContent?: boolean;\n includeAnalytics?: boolean;\n json?: boolean;\n}): Promise<void> {\n try {\n const data = await listActivity({\n agentId: options.agentId,\n workflowId: options.workflowId,\n since: options.since,\n until: options.until,\n limit: options.limit ? parseInt(options.limit, 10) : undefined,\n offset: options.offset ? parseInt(options.offset, 10) : undefined,\n includeContent: options.includeContent,\n includeAnalytics: options.includeAnalytics,\n });\n\n if (options.json) {\n console.log(JSON.stringify(data, null, 2));\n } else {\n formatActivityTable(data);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function getCommand(\n id: string,\n options: { includeContent?: boolean; json?: boolean }\n): Promise<void> {\n try {\n const prompt = await getActivity(id, options.includeContent);\n\n if (options.json) {\n console.log(JSON.stringify(prompt, null, 2));\n } else {\n formatActivityDetail(prompt);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nasync function kpisCommand(options: {\n agentId?: string;\n workflowId?: string;\n since?: string;\n until?: string;\n period?: string;\n includeAtoms?: boolean;\n json?: boolean;\n}): Promise<void> {\n try {\n if (!options.agentId && !options.workflowId) {\n console.error(\"Error: Either --agent-id or --workflow-id is required\");\n process.exit(1);\n }\n\n const data = await getActivityKpis({\n agentId: options.agentId,\n workflowId: options.workflowId,\n since: options.since,\n until: options.until,\n period: options.period as \"hourly\" | \"daily\" | \"weekly\" | undefined,\n includeAtoms: options.includeAtoms,\n });\n\n if (options.json) {\n console.log(JSON.stringify(data, null, 2));\n } else {\n formatKpisResponse(data);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nfunction formatSessionsTable(data: SessionsListResponse): void {\n // Summary\n console.log(\"Session Decoration Status\");\n console.log(\"\");\n console.log(\"Summary:\");\n console.log(` Total Sessions: ${data.summary.sessionCount}`);\n\n const statuses = [\"DECORATED\", \"NEW\", \"DECORATION_FAILED\", \"DECORATION_OUTDATED\", \"SKIPPED\"];\n for (const status of statuses) {\n const count = data.summary.byStatus[status] || 0;\n const pct = data.summary.sessionCount > 0 ? ((count / data.summary.sessionCount) * 100).toFixed(1) : \"0.0\";\n const label = status.charAt(0) + status.slice(1).toLowerCase().replace(/_/g, \" \");\n console.log(` ${label.padEnd(17)} ${String(count).padStart(4)} (${pct}%)`);\n }\n\n if (data.sessions.length === 0) {\n console.log(\"\");\n console.log(\"No sessions found.\");\n return;\n }\n\n console.log(\"\");\n\n // Table\n const headers = [\"ID\", \"STATUS\", \"DATE\", \"CANDIDATE\", \"ERRORS\", \"KPI DATA\", \"VERSION\"];\n const rows = data.sessions.map((s) => [\n s.id.slice(0, 15) + \"...\",\n s.decorationStatus,\n s.decorationDate || \"-\",\n s.decorationCandidate ? \"Yes\" : \"No\",\n String(s.decorationErrorStreak),\n s.hasKpiData ? \"Yes\" : \"No\",\n s.decoratorVersion || \"-\",\n ]);\n\n const widths = headers.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n console.log(headers.map((h, i) => h.padEnd(widths[i])).join(\" \"));\n console.log(widths.map((w) => \"-\".repeat(w)).join(\" \"));\n\n for (const row of rows) {\n console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(\" \"));\n }\n\n console.log(\"\");\n console.log(`Showing ${data.sessions.length} of ${data.total} results (offset: ${data.offset})`);\n if (data.hasMore) {\n console.log(`Use --offset ${data.offset + data.limit} to see more results`);\n }\n}\n\nasync function sessionsCommand(options: {\n agentId: string;\n since?: string;\n until?: string;\n limit?: string;\n offset?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n const data = await listSessions({\n agentId: options.agentId,\n since: options.since,\n until: options.until,\n limit: options.limit ? parseInt(options.limit, 10) : undefined,\n offset: options.offset ? parseInt(options.offset, 10) : undefined,\n });\n\n if (options.json) {\n console.log(JSON.stringify(data, null, 2));\n } else {\n formatSessionsTable(data);\n }\n } catch (error) {\n console.error(\n `Error: ${error instanceof Error ? error.message : \"Unknown error\"}`\n );\n process.exit(1);\n }\n}\n\nexport function registerActivityCommand(program: Command): void {\n const activity = program\n .command(\"activity\")\n .description(\"Inspect AI activity and prompts\");\n\n activity\n .command(\"list\")\n .description(\"List prompt requests with filters\")\n .option(\"--agent-id <id>\", \"Filter by agent ID\")\n .option(\"--workflow-id <id>\", \"Filter by workflow ID\")\n .option(\"--since <date>\", \"Start date (ISO format)\")\n .option(\"--until <date>\", \"End date (ISO format)\")\n .option(\"--limit <n>\", \"Results per page\", \"20\")\n .option(\"--offset <n>\", \"Skip first N results\", \"0\")\n .option(\"--include-content\", \"Include prompt/response content\")\n .option(\"--include-analytics\", \"Include advanced analytics\")\n .option(\"--json\", \"Output as JSON\")\n .action(listCommand);\n\n activity\n .command(\"get <id>\")\n .description(\"Get prompt request details\")\n .option(\"--include-content\", \"Include prompt/response content\")\n .option(\"--json\", \"Output as JSON\")\n .action(getCommand);\n\n activity\n .command(\"kpis\")\n .description(\"Get aggregated KPI values\")\n .option(\"--agent-id <id>\", \"Agent ID\")\n .option(\"--workflow-id <id>\", \"Workflow ID\")\n .option(\"--since <date>\", \"Period start (ISO format)\")\n .option(\"--until <date>\", \"Period end (ISO format)\")\n .option(\"--period <type>\", \"Aggregation period (hourly, daily, weekly)\")\n .option(\"--include-atoms\", \"Include per-prompt KPI data\")\n .option(\"--json\", \"Output as JSON\")\n .action(kpisCommand);\n\n activity\n .command(\"sessions\")\n .description(\"Inspect chat/session decoration status for troubleshooting\")\n .requiredOption(\"--agent-id <id>\", \"Agent ID (required)\")\n .option(\"--since <date>\", \"Start date (ISO format)\")\n .option(\"--until <date>\", \"End date (ISO format)\")\n .option(\"--limit <n>\", \"Results per page\", \"20\")\n .option(\"--offset <n>\", \"Skip first N results\", \"0\")\n .option(\"--json\", \"Output as JSON\")\n .action(sessionsCommand);\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as readline from \"node:readline\";\nimport { Command } from \"commander\";\nimport {\n listAgents,\n createAgent,\n getAgent,\n type Agent,\n} from \"../lib/api.js\";\nimport { getValidToken } from \"../lib/auth.js\";\nimport { getBaseUrl } from \"../lib/config.js\";\nimport {\n parseTranscript,\n type ExtractedTranscriptData,\n} from \"./monitor-transcript.js\";\nimport {\n loadSessionState,\n saveSessionState,\n setDebugLogger,\n shouldReportTurn,\n} from \"./monitor-state.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface MonitorConfig {\n agentId: string;\n apiKey: string;\n agentName: string;\n source: string;\n createdAt: string;\n monitoringEndpoint: string;\n}\n\ninterface ClaudeSettings {\n hooks?: Record<string, HookMatcherEntry[]>;\n [key: string]: unknown;\n}\n\nexport interface HookMatcherEntry {\n matcher: string;\n hooks: HookCommand[];\n}\n\nexport interface HookCommand {\n type: string;\n command: string;\n}\n\n/**\n * Claude Code hook event payloads.\n *\n * The Stop / SubagentStop hooks send ONLY the fields below — the\n * conversation data (prompt, response, tokens, model, etc.) is NOT in\n * the hook JSON. To get that data we must read the transcript file at\n * `transcript_path`.\n *\n * The exact field that carries the subagent name is not formally\n * documented, so we accept several candidates (`agent_name`,\n * `agent_type`, `subagent_type`) and fall back to the `tool_input`\n * shape that the Agent tool_use block uses.\n */\nexport interface ClaudeHookEvent {\n session_id?: string;\n transcript_path?: string;\n hook_event_name?: string; // \"Stop\" | \"SubagentStop\"\n stop_hook_active?: boolean;\n cwd?: string;\n agent_name?: string;\n agent_type?: string;\n subagent_type?: string;\n tool_input?: {\n subagent_type?: string;\n description?: string;\n };\n /**\n * Claude Code's up-to-date final text block for the current turn,\n * taken from its in-memory state at hook-fire time. Preferred over\n * transcript-file parsing for the response because the on-disk\n * JSONL can lag the in-memory state when the hook fires mid-flush.\n * Undefined on older Claude Code versions or non-Stop hooks.\n */\n last_assistant_message?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst CLAUDE_DIR = \".claude\";\nconst SETTINGS_FILE = \"settings.json\";\nconst MONITOR_CONFIG_FILE = \"olakai-monitor.json\";\n\nconst OLAKAI_HOOK_MARKER = \"olakai monitor hook\";\n\nconst HOOK_DEFINITIONS: Record<string, HookMatcherEntry[]> = {\n Stop: [\n {\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: \"olakai monitor hook stop\",\n },\n ],\n },\n ],\n SubagentStop: [\n {\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: \"olakai monitor hook subagent-stop\",\n },\n ],\n },\n ],\n};\n\n/**\n * Produce the `hooks` block for a Claude Code settings.json by layering\n * the Olakai defaults on top of an existing hooks block.\n *\n * Rules:\n * - For each event in HOOK_DEFINITIONS: if the existing block already\n * has an Olakai-marker entry for that event, keep the existing\n * entries verbatim (user-customized command strings such as\n * `OLAKAI_MONITOR_DEBUG=1 olakai monitor hook stop` survive).\n * - If it doesn't, append the default Olakai entries, preserving any\n * non-Olakai entries already configured on that event.\n * - Events we don't manage (`PreToolUse`, `UserPromptSubmit`, ...)\n * pass through untouched.\n *\n * Exported for unit tests.\n */\nexport function mergeHooksSettings(\n existing: Record<string, HookMatcherEntry[]> | undefined,\n definitions: Record<string, HookMatcherEntry[]> = HOOK_DEFINITIONS,\n): Record<string, HookMatcherEntry[]> {\n const merged: Record<string, HookMatcherEntry[]> = {\n ...(existing ?? {}),\n };\n\n for (const [event, defaultEntries] of Object.entries(definitions)) {\n const existingEntries = merged[event] ?? [];\n const hasOlakaiHook = existingEntries.some((e) =>\n e.hooks.some((h) => h.command.includes(OLAKAI_HOOK_MARKER)),\n );\n\n if (hasOlakaiHook) {\n merged[event] = existingEntries;\n } else {\n merged[event] = [...existingEntries, ...defaultEntries];\n }\n }\n\n return merged;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Find the project root by walking up from cwd looking for a `.claude/`\n * directory. Used by `olakai monitor init` and related write-side paths\n * that need to know where to CREATE config. Stops at the first `.claude/`\n * it finds (regardless of whether the config file exists).\n *\n * Falls back to cwd if none found.\n */\nexport function findProjectRoot(startDir?: string): string {\n let dir = startDir ?? process.cwd();\n while (true) {\n if (fs.existsSync(path.join(dir, CLAUDE_DIR))) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break; // reached filesystem root\n dir = parent;\n }\n // Fall back to cwd (init will create .claude/)\n return startDir ?? process.cwd();\n}\n\n/**\n * Find the nearest ancestor directory that contains\n * `.claude/olakai-monitor.json`. Used by the hook path specifically —\n * we need the directory where the config FILE lives, not just any\n * `.claude/` directory.\n *\n * Why this matters (refinement of INV-002): a subrepo like\n * `/workspace/olakai-cli` can have its own `.claude/` (worktrees,\n * settings.local.json, etc.) without an `olakai-monitor.json`. The\n * parent workspace `/workspace` has both `.claude/` AND\n * `olakai-monitor.json`. `findProjectRoot` stops at the subrepo's\n * `.claude/`, so the hook would read from the wrong directory and\n * silent-exit. This walker keeps going until it finds the actual\n * config file or hits filesystem root.\n *\n * Returns null when no configured project is found in the ancestry,\n * so callers can emit a diagnostic and silent-exit cleanly.\n */\nexport function findConfiguredProjectRoot(startDir?: string): string | null {\n let dir = startDir ?? process.cwd();\n while (true) {\n if (\n fs.existsSync(path.join(dir, CLAUDE_DIR, MONITOR_CONFIG_FILE))\n ) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break; // reached filesystem root\n dir = parent;\n }\n return null;\n}\n\n/**\n * Resolve the configured-project directory from a Claude Code hook\n * payload, falling back to `fallbackCwd` when the payload doesn't\n * carry a usable `cwd` field. Returns null when no configured project\n * is found in the ancestry, letting the hook silent-exit cleanly.\n *\n * Background (INV-002): Claude Code sometimes invokes Stop /\n * SubagentStop hooks from a CWD that isn't under the workspace (e.g.\n * `/tmp`, `$HOME`) — or reports a subrepo CWD (e.g.\n * `/workspace/olakai-cli`) that has its own `.claude/` without the\n * monitor config. Either case used to make the hook silent-exit.\n *\n * We seed the ancestor walk with `payload.cwd` when present (reflects\n * the workspace Claude Code thinks it's in), and look for the actual\n * `.claude/olakai-monitor.json` file — not just any `.claude/`\n * directory — so stray `.claude/` dirs in subrepos don't trap the\n * search short of the real configured workspace.\n *\n * Exported as a pure function so unit tests can exercise it without\n * mocking `process.cwd()`.\n */\nexport function resolveProjectRootFromPayload(\n eventData: ClaudeHookEvent,\n fallbackCwd: string,\n): string | null {\n const payloadCwd =\n typeof eventData.cwd === \"string\" && eventData.cwd.trim()\n ? eventData.cwd\n : fallbackCwd;\n return findConfiguredProjectRoot(payloadCwd);\n}\n\nfunction getClaudeDir(projectRoot: string): string {\n return path.join(projectRoot, CLAUDE_DIR);\n}\n\nfunction getSettingsPath(projectRoot: string): string {\n return path.join(getClaudeDir(projectRoot), SETTINGS_FILE);\n}\n\nfunction getMonitorConfigPath(projectRoot: string): string {\n return path.join(getClaudeDir(projectRoot), MONITOR_CONFIG_FILE);\n}\n\nfunction readJsonFile<T>(filePath: string): T | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const content = fs.readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nfunction writeJsonFile(filePath: string, data: unknown): void {\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + \"\\n\", \"utf-8\");\n}\n\nfunction loadMonitorConfig(projectRoot?: string): MonitorConfig | null {\n const root = projectRoot ?? findProjectRoot();\n return readJsonFile<MonitorConfig>(getMonitorConfigPath(root));\n}\n\n/**\n * Read stdin with a timeout. Returns empty string if stdin has no data\n * or times out.\n */\nfunction readStdin(timeoutMs: number = 3000): Promise<string> {\n return new Promise((resolve) => {\n // If stdin is a TTY (no piped data), return immediately\n if (process.stdin.isTTY) {\n resolve(\"\");\n return;\n }\n\n let data = \"\";\n const timer = setTimeout(() => {\n process.stdin.removeAllListeners();\n process.stdin.destroy();\n resolve(data);\n }, timeoutMs);\n\n process.stdin.setEncoding(\"utf-8\");\n process.stdin.on(\"data\", (chunk: string) => {\n data += chunk;\n });\n process.stdin.on(\"end\", () => {\n clearTimeout(timer);\n resolve(data);\n });\n process.stdin.on(\"error\", () => {\n clearTimeout(timer);\n resolve(data);\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// Subcommands\n// ---------------------------------------------------------------------------\n\n/**\n * olakai monitor init\n *\n * Interactive setup: create/select agent, write hooks, save config.\n */\nasync function initCommand(): Promise<void> {\n // 1. Check authentication\n const token = getValidToken();\n if (!token) {\n console.error(\"Not logged in. Run 'olakai login' first.\");\n process.exit(1);\n }\n\n console.log(\"Setting up Claude Code monitoring for this workspace...\\n\");\n\n const projectRoot = process.cwd();\n const dirName = path.basename(projectRoot);\n\n // 2. Create or select an agent\n let agent: Agent;\n const choice = await prompt(\n \"Create a new agent or use an existing one? (new/existing) [new]: \",\n );\n\n if (choice.toLowerCase() === \"existing\" || choice.toLowerCase() === \"e\") {\n // List agents and let user pick\n const agents = await listAgents();\n if (agents.length === 0) {\n console.log(\"No agents found. Creating a new one instead.\\n\");\n agent = await createNewAgent(dirName);\n } else {\n console.log(\"\\nAvailable agents:\");\n for (let i = 0; i < agents.length; i++) {\n console.log(` ${i + 1}. ${agents[i].name} (${agents[i].id.slice(0, 12)}...)`);\n }\n\n const selection = await prompt(`\\nSelect agent (1-${agents.length}): `);\n const idx = parseInt(selection, 10) - 1;\n\n if (isNaN(idx) || idx < 0 || idx >= agents.length) {\n console.error(\"Invalid selection.\");\n process.exit(1);\n }\n\n // Fetch full agent detail (may include API key info)\n agent = await getAgent(agents[idx].id);\n\n // If agent doesn't have an active API key, we need to create one.\n // The CLI create endpoint generates one with --with-api-key but there's\n // no standalone \"create API key\" endpoint exposed in the CLI API module.\n // So we warn and ask user to use an agent that already has one, or create new.\n if (!agent.apiKey?.key && !agent.apiKey?.isActive) {\n console.log(\n \"\\nThis agent has no active API key. Please create a new agent instead,\",\n );\n console.log(\"or generate an API key via the Olakai dashboard.\\n\");\n const createNew = await prompt(\"Create a new agent? (y/n) [y]: \");\n if (createNew.toLowerCase() !== \"n\") {\n agent = await createNewAgent(dirName);\n } else {\n process.exit(1);\n }\n }\n }\n } else {\n agent = await createNewAgent(dirName);\n }\n\n // Resolve the API key. For newly created agents, agent.apiKey.key is populated.\n // For existing agents, the key is masked — we can't get the plaintext back.\n // In that case, prompt for it.\n let apiKey = agent.apiKey?.key;\n if (!apiKey) {\n console.log(\n \"\\nThe API key for this agent is not available (it is only shown once at creation).\",\n );\n apiKey = await prompt(\"Paste the API key for this agent: \");\n if (!apiKey) {\n console.error(\"API key is required for monitoring.\");\n process.exit(1);\n }\n }\n\n // 3. Write Claude Code hooks\n const claudeDir = getClaudeDir(projectRoot);\n if (!fs.existsSync(claudeDir)) {\n fs.mkdirSync(claudeDir, { recursive: true });\n }\n\n const settingsPath = getSettingsPath(projectRoot);\n const existingSettings = readJsonFile<ClaudeSettings>(settingsPath) ?? {};\n\n const mergedHooks = mergeHooksSettings(existingSettings.hooks);\n\n const updatedSettings: ClaudeSettings = {\n ...existingSettings,\n hooks: mergedHooks,\n };\n\n writeJsonFile(settingsPath, updatedSettings);\n\n // 4. Save monitor config\n const monitoringEndpoint = `${getBaseUrl()}/api/monitoring/prompt`;\n const monitorConfig: MonitorConfig = {\n agentId: agent.id,\n apiKey,\n agentName: agent.name,\n source: \"claude-code\",\n createdAt: new Date().toISOString(),\n monitoringEndpoint,\n };\n\n const monitorConfigPath = getMonitorConfigPath(projectRoot);\n writeJsonFile(monitorConfigPath, monitorConfig);\n // Restrict permissions — file contains a plaintext API key\n fs.chmodSync(monitorConfigPath, 0o600);\n\n // 5. Success message\n console.log(\"\");\n console.log(`\\u2713 Agent \"${agent.name}\" configured (ID: ${agent.id})`);\n if (agent.apiKey?.key) {\n console.log(\"\\u2713 API key generated\");\n }\n console.log(`\\u2713 Claude Code hooks configured in ${CLAUDE_DIR}/${SETTINGS_FILE}`);\n console.log(`\\u2713 Monitor config saved to ${CLAUDE_DIR}/${MONITOR_CONFIG_FILE}`);\n console.log(\"\");\n console.log(\n \"Monitoring is now active. Claude Code will report activity to Olakai\",\n );\n console.log(\n `on each turn. View activity at: ${getBaseUrl()}/dashboard`,\n );\n console.log(\"\");\n console.log(\n `\\u26A0 Ensure ${CLAUDE_DIR}/${MONITOR_CONFIG_FILE} is in your .gitignore (it contains your API key)`,\n );\n console.log(\"\");\n console.log(\"To check status: olakai monitor status\");\n console.log(\"To disable: olakai monitor disable\");\n}\n\nasync function createNewAgent(defaultName: string): Promise<Agent> {\n const nameInput = await prompt(\n `Agent name [${defaultName}]: `,\n );\n const agentName = nameInput || defaultName;\n\n const agent = await createAgent({\n name: agentName,\n description: `Claude Code local agent for ${agentName}`,\n role: \"WORKER\",\n createApiKey: true,\n category: \"CODING\",\n source: \"CLAUDE_CODE\",\n });\n\n return agent;\n}\n\n/**\n * Debug logger. Only writes when OLAKAI_MONITOR_DEBUG=1.\n * Errors are swallowed — debug logging must never break the hook.\n */\nfunction debugLog(label: string, data: unknown): void {\n if (process.env.OLAKAI_MONITOR_DEBUG !== \"1\") return;\n try {\n const logPath = `/tmp/olakai-monitor-debug-${process.pid}.log`;\n const line = `[${new Date().toISOString()}] ${label}: ${\n typeof data === \"string\" ? data : JSON.stringify(data, null, 2)\n }\\n`;\n fs.appendFileSync(logPath, line, \"utf-8\");\n } catch {\n // Ignore debug-log failures\n }\n}\n\n/**\n * Load a transcript JSONL from disk and extract the data we want to\n * report. Any failure (missing file, malformed JSON, unexpected shape)\n * is swallowed and we return a best-effort partial result. Parsing\n * itself lives in `monitor-transcript.ts` so it can be unit-tested.\n */\nfunction extractFromTranscript(\n transcriptPath: string | undefined,\n): ExtractedTranscriptData {\n const empty: ExtractedTranscriptData = {\n prompt: \"\",\n response: \"\",\n tokens: 0,\n inputTokens: 0,\n outputTokens: 0,\n modelName: null,\n numTurns: 0,\n toolCallCount: 0,\n filesEditedCount: 0,\n bashCommandCount: 0,\n };\n\n if (!transcriptPath) return empty;\n\n let raw: string;\n try {\n raw = fs.readFileSync(transcriptPath, \"utf-8\");\n } catch (err) {\n debugLog(\"transcript-read-failed\", {\n transcriptPath,\n error: (err as Error).message,\n });\n return empty;\n }\n\n return parseTranscript(raw);\n}\n\n/**\n * Best-effort extraction of the subagent name from a SubagentStop hook\n * payload. Claude Code's payload shape for this hook isn't fully\n * documented, so we probe several candidate fields in order of\n * likelihood and fall back to undefined when nothing is found.\n */\nfunction extractSubagentName(event: ClaudeHookEvent): string | undefined {\n const candidates = [\n event.agent_name,\n event.subagent_type,\n event.agent_type,\n event.tool_input?.subagent_type,\n ];\n for (const value of candidates) {\n if (typeof value === \"string\" && value.trim()) {\n return value.trim();\n }\n }\n return undefined;\n}\n\n/**\n * olakai monitor hook <event>\n *\n * Fire-and-forget handler called by Claude Code hooks.\n * Reads event JSON from stdin, POSTs to monitoring endpoint.\n * MUST NOT produce stderr output or exit non-zero.\n *\n * IMPORTANT ordering (INV-002): we read stdin BEFORE looking up the\n * monitor config. Claude Code sometimes invokes the hook with\n * `process.cwd()` set to an unrelated directory (e.g. `/tmp`), but it\n * always passes the workspace root in the hook payload's `cwd` field.\n * Using `payload.cwd` as the seed for `findProjectRoot` keeps the hook\n * working regardless of how Claude Code spawned it.\n */\nasync function hookCommand(event: string): Promise<void> {\n // Route monitor-state debug logs through our existing debugLog so all\n // breadcrumbs land in the same /tmp file under OLAKAI_MONITOR_DEBUG=1.\n setDebugLogger(debugLog);\n\n try {\n // 1. Read stdin first.\n const stdinData = await readStdin(3000);\n debugLog(\"stdin-raw\", stdinData);\n\n // 2. Parse payload. On failure, keep eventData as an empty object so\n // we still try a project-root lookup from process.cwd() as a\n // fallback instead of silently exiting.\n let eventData: ClaudeHookEvent = {};\n if (stdinData) {\n try {\n eventData = JSON.parse(stdinData) as ClaudeHookEvent;\n } catch {\n debugLog(\"stdin-parse-failed\", stdinData);\n // Deliberately fall through — empty eventData + process.cwd()\n // still gives us a reasonable chance of locating a config.\n }\n }\n\n debugLog(\"event-parsed\", { event, eventData });\n\n // 3. Resolve project root using payload.cwd (with process.cwd() as\n // a fallback), walking ancestors until we find a `.claude/\n // olakai-monitor.json`. Returns null when no configured workspace\n // is in the ancestry.\n const projectRoot = resolveProjectRootFromPayload(\n eventData,\n process.cwd(),\n );\n if (!projectRoot) {\n // No configured workspace in the ancestry of payload.cwd or\n // process.cwd(). Emit a breadcrumb so future \"why didn't my\n // hook fire?\" investigations are one grep away.\n debugLog(\"config-not-found\", {\n startDir:\n typeof eventData.cwd === \"string\" && eventData.cwd.trim()\n ? eventData.cwd\n : process.cwd(),\n });\n return;\n }\n const config = loadMonitorConfig(projectRoot);\n if (!config) {\n // Edge case: the monitor config file existed when findConfigured-\n // ProjectRoot checked, but became unreadable/malformed by the\n // time we tried to load it. Treat the same as no config.\n debugLog(\"config-load-failed\", { projectRoot });\n return;\n }\n\n // 4. Build monitoring payload from the transcript.\n const payload = buildPayload(event, eventData, config);\n if (!payload) {\n // Nothing meaningful to report\n return;\n }\n\n debugLog(\"payload-built\", payload);\n\n // 5. Per-session turn dedup (INV-004).\n //\n // When Claude Code fires Stop twice for a single user turn, the CLI\n // sees the same `userTurnTimestamp` on both firings — parseTranscript\n // always emits the latest user+assistant pair. Skip the POST when\n // the timestamp matches what we last reported for this session.\n const sessionId =\n (typeof eventData.session_id === \"string\" && eventData.session_id) ||\n undefined;\n\n // Re-extract so we can key dedup state on the same value that\n // drove the payload. This re-reads the transcript — cheap (<10ms\n // on the transcripts we observe in production) and avoids\n // threading `ExtractedTranscriptData` out of `buildPayload`.\n const extracted = extractFromTranscript(eventData.transcript_path);\n const userTurnTimestamp = extracted.userTurnTimestamp;\n\n if (sessionId) {\n const existingState = loadSessionState(sessionId);\n if (!shouldReportTurn(existingState, userTurnTimestamp)) {\n debugLog(\"turn-dedup-skip\", {\n sessionId,\n userTurnTimestamp,\n });\n return;\n }\n }\n\n // 6. POST to monitoring endpoint with a 5-second timeout.\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5000);\n\n try {\n const res = await fetch(config.monitoringEndpoint, {\n method: \"POST\",\n headers: {\n \"x-api-key\": config.apiKey,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify([payload]),\n signal: controller.signal,\n });\n debugLog(\"response-status\", {\n status: res.status,\n ok: res.ok,\n });\n } finally {\n clearTimeout(timeoutId);\n }\n\n // 7. Always save state after attempting the POST, even on failure.\n // Rationale: a dropped event is recoverable from the transcript\n // (or by operator action), but a retry storm during an Olakai\n // outage is not. We'd rather drop one event than send the same\n // duplicate ten times from a client that keeps retrying.\n if (sessionId && userTurnTimestamp) {\n saveSessionState(sessionId, {\n lastUserTimestamp: userTurnTimestamp,\n lastReportedAt: new Date().toISOString(),\n numTurnsAtLastReport: extracted.numTurns,\n });\n debugLog(\"state-saved\", {\n sessionId,\n userTurnTimestamp,\n numTurns: extracted.numTurns,\n });\n }\n } catch (err) {\n // Silently swallow ALL errors. Hook failures must not break Claude Code.\n debugLog(\"hook-exception\", (err as Error).message);\n }\n}\n\n/**\n * Build a MonitorPayload from the Claude Code hook event data.\n *\n * For Stop / SubagentStop events, the hook JSON contains only\n * session_id + transcript_path — the actual conversation data is\n * extracted from the transcript JSONL file.\n *\n * Exported for unit tests.\n */\nexport function buildPayload(\n event: string,\n eventData: ClaudeHookEvent,\n config: MonitorConfig,\n): Record<string, unknown> | null {\n const sessionId = eventData.session_id ?? `claude-code-${Date.now()}`;\n\n switch (event) {\n case \"stop\":\n case \"subagent-stop\": {\n const extracted = extractFromTranscript(eventData.transcript_path);\n const isSubagent = event === \"subagent-stop\";\n\n const customData: Record<string, unknown> = {\n hookEvent:\n eventData.hook_event_name ??\n (isSubagent ? \"SubagentStop\" : \"Stop\"),\n sessionId,\n transcriptPath: eventData.transcript_path ?? \"\",\n cwd: eventData.cwd ?? \"\",\n stopHookActive: eventData.stop_hook_active ?? false,\n inputTokens: extracted.inputTokens,\n outputTokens: extracted.outputTokens,\n numTurns: extracted.numTurns,\n // Per-turn work signals for the Claude Code classifier (D-027).\n // Always emitted as JSON numbers — the backend classifier and\n // future KPI formulas must see numeric 0, not missing keys or\n // strings. File paths and bash command strings are deliberately\n // NOT emitted; only the cardinality is privacy-safe to ship.\n toolCallCount: extracted.toolCallCount,\n filesEditedCount: extracted.filesEditedCount,\n bashCommandCount: extracted.bashCommandCount,\n };\n\n if (typeof extracted.latencyMs === \"number\") {\n customData.latencyMs = extracted.latencyMs;\n }\n\n if (isSubagent) {\n const subagent = extractSubagentName(eventData);\n if (subagent) {\n customData.subagent = subagent;\n }\n } else if (extracted.skill) {\n // Skill detection only applies to main-agent Stop events. The\n // subagent's first \"user\" message is the spawning prompt, not a\n // human slash-command.\n customData.skill = extracted.skill;\n }\n\n // Prefer the hook payload's last_assistant_message — Claude Code\n // ships it from in-memory state at hook-fire time, so it reflects\n // the final text block of the turn even when the transcript\n // JSONL hasn't been flushed to disk yet. Fall back to the\n // transcript parse when the payload field is missing or empty\n // (older Claude Code versions, or some edge hook payloads).\n const payloadAssistant = eventData.last_assistant_message;\n const response =\n typeof payloadAssistant === \"string\" && payloadAssistant.trim()\n ? payloadAssistant\n : extracted.response;\n\n return {\n prompt: extracted.prompt,\n response,\n chatId: sessionId,\n // Top-level source so the backend ExternalPromptRequestSchema\n // picks it up (matches regex ^[a-z0-9_-]+$).\n source: config.source,\n modelName: extracted.modelName ?? undefined,\n tokens: extracted.tokens,\n customData,\n };\n }\n\n default:\n return null;\n }\n}\n\n/**\n * olakai monitor status\n *\n * Show current monitoring configuration and recent activity.\n */\nasync function statusCommand(options: { json?: boolean }): Promise<void> {\n const projectRoot = findProjectRoot();\n const config = loadMonitorConfig(projectRoot);\n\n if (!config) {\n console.log(\"Monitoring is not configured for this workspace.\");\n console.log(\"Run 'olakai monitor init' to set up monitoring.\");\n process.exit(1);\n }\n\n // Check if hooks are still present in settings.json\n const settings = readJsonFile<ClaudeSettings>(getSettingsPath(projectRoot));\n const hooksPresent = settings?.hooks\n ? Object.values(settings.hooks).some((entries) =>\n entries.some((e) =>\n e.hooks.some((h) => h.command.includes(OLAKAI_HOOK_MARKER)),\n ),\n )\n : false;\n\n if (options.json) {\n console.log(\n JSON.stringify(\n {\n ...config,\n apiKey: config.apiKey.slice(0, 12) + \"...\",\n hooksConfigured: hooksPresent,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log(\"Olakai Monitor Status\");\n console.log(\"=====================\");\n console.log(`Agent: ${config.agentName}`);\n console.log(`Agent ID: ${config.agentId}`);\n console.log(`API Key: ${config.apiKey.slice(0, 12)}...`);\n console.log(`Endpoint: ${config.monitoringEndpoint}`);\n console.log(`Source: ${config.source}`);\n console.log(`Configured: ${config.createdAt}`);\n console.log(`Hooks: ${hooksPresent ? \"Active\" : \"Missing (run 'olakai monitor init' to restore)\"}`);\n\n // Try to show recent activity\n try {\n const token = getValidToken();\n if (token) {\n const params = new URLSearchParams({\n agentId: config.agentId,\n limit: \"5\",\n });\n const response = await fetch(\n `${getBaseUrl()}/api/activity/prompts?${params}`,\n {\n headers: { Authorization: `Bearer ${token}` },\n },\n );\n if (response.ok) {\n const data = (await response.json()) as {\n prompts: Array<{ id: string; createdAt: string }>;\n };\n if (data.prompts && data.prompts.length > 0) {\n console.log(\"\");\n console.log(\"Recent Activity:\");\n for (const p of data.prompts) {\n console.log(` ${p.createdAt} ${p.id.slice(0, 12)}...`);\n }\n } else {\n console.log(\"\");\n console.log(\"No activity recorded yet.\");\n }\n }\n }\n } catch {\n // Activity check is optional — don't fail\n }\n}\n\n/**\n * olakai monitor disable\n *\n * Remove Olakai hooks from settings.json and optionally remove config.\n */\nasync function disableCommand(options: {\n keepConfig?: boolean;\n}): Promise<void> {\n const projectRoot = findProjectRoot();\n\n // 1. Remove hooks from settings.json\n const settingsPath = getSettingsPath(projectRoot);\n const settings = readJsonFile<ClaudeSettings>(settingsPath);\n\n if (settings?.hooks) {\n const cleanedHooks: Record<string, HookMatcherEntry[]> = {};\n\n for (const [event, entries] of Object.entries(settings.hooks)) {\n const filtered = entries.filter(\n (e) =>\n !e.hooks.some((h) => h.command.includes(OLAKAI_HOOK_MARKER)),\n );\n if (filtered.length > 0) {\n cleanedHooks[event] = filtered;\n }\n }\n\n if (Object.keys(cleanedHooks).length > 0) {\n settings.hooks = cleanedHooks;\n } else {\n delete settings.hooks;\n }\n\n writeJsonFile(settingsPath, settings);\n console.log(`\\u2713 Olakai hooks removed from ${CLAUDE_DIR}/${SETTINGS_FILE}`);\n } else {\n console.log(\"No hooks found in settings.json.\");\n }\n\n // 2. Remove or keep monitor config\n if (!options.keepConfig) {\n const configPath = getMonitorConfigPath(projectRoot);\n if (fs.existsSync(configPath)) {\n fs.unlinkSync(configPath);\n console.log(`\\u2713 Monitor config removed (${CLAUDE_DIR}/${MONITOR_CONFIG_FILE})`);\n }\n } else {\n console.log(\n `Monitor config retained at ${CLAUDE_DIR}/${MONITOR_CONFIG_FILE}`,\n );\n }\n\n console.log(\"\");\n console.log(\"Monitoring disabled. Run 'olakai monitor init' to re-enable.\");\n}\n\n// ---------------------------------------------------------------------------\n// Command registration\n// ---------------------------------------------------------------------------\n\nexport function registerMonitorCommand(program: Command): void {\n const monitor = program\n .command(\"monitor\")\n .description(\"Monitor Claude Code sessions with Olakai\");\n\n monitor\n .command(\"init\")\n .description(\n \"Set up Olakai monitoring for this Claude Code workspace\",\n )\n .action(initCommand);\n\n monitor\n .command(\"hook <event>\")\n .description(\"Hook handler called by Claude Code (internal use)\")\n .action(hookCommand);\n\n monitor\n .command(\"status\")\n .description(\"Show monitoring status for this workspace\")\n .option(\"--json\", \"Output as JSON\")\n .action(statusCommand);\n\n monitor\n .command(\"disable\")\n .description(\"Remove Olakai monitoring from this workspace\")\n .option(\n \"--keep-config\",\n \"Keep the monitor config file (only remove hooks)\",\n )\n .action(disableCommand);\n}\n","/**\n * Transcript parsing for Claude Code Stop-hook monitoring.\n *\n * The Stop hook passes only a `transcript_path` pointing at a JSONL file.\n * This module is the single place we extract the per-turn data we report\n * to Olakai (prompt, response, tokens, model, latency, skill invocation).\n *\n * The code here is intentionally pure and exports named helpers so it can\n * be unit-tested without touching the filesystem or HTTP layer.\n */\n\n/**\n * Shape of a single line in a Claude Code transcript JSONL file.\n * Each line is a standalone JSON object. We only care about `user` and\n * `assistant` entries; other types (`system`, `file-history-snapshot`,\n * `progress`, compaction markers, ...) are ignored.\n */\nexport interface TranscriptLine {\n type?: string;\n subtype?: string;\n isMeta?: boolean;\n isSidechain?: boolean;\n timestamp?: string;\n message?: {\n role?: string;\n model?: string;\n content?: string | TranscriptContentBlock[];\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n };\n}\n\nexport interface TranscriptContentBlock {\n type?: string;\n text?: string;\n /**\n * For `tool_use` blocks. Name of the tool the assistant invoked\n * (e.g. `\"Edit\"`, `\"Write\"`, `\"MultiEdit\"`, `\"Bash\"`).\n */\n name?: string;\n /**\n * For `tool_use` blocks. Tool-specific input object. We read\n * `input.file_path` for `Edit`/`Write`/`MultiEdit` to count\n * distinct edited files. Typed as `unknown` because each tool\n * uses a different shape and we only probe `file_path` defensively.\n */\n input?: unknown;\n}\n\nexport interface ExtractedTranscriptData {\n prompt: string;\n response: string;\n tokens: number;\n inputTokens: number;\n outputTokens: number;\n modelName: string | null;\n numTurns: number;\n /**\n * Latency in milliseconds between the current turn's user message and\n * its final assistant response. Undefined when latency could not be\n * computed (first turn, missing timestamps, no user predecessor).\n */\n latencyMs?: number;\n /**\n * Leading slash-command captured from the current turn's user message\n * (e.g. `\"olakai-create-agent\"` for `/olakai-create-agent do X`).\n * Undefined when the user message did not start with a slash-command.\n */\n skill?: string;\n /**\n * ISO 8601 timestamp of the current turn's user message (the last\n * non-meta, non-sidechain user entry in the transcript). Used by the\n * hook layer to dedup duplicate Stop firings for the same user turn.\n * Undefined when no usable user entry is present or the timestamp\n * is missing/unparseable.\n */\n userTurnTimestamp?: string;\n /**\n * Count of `tool_use` content blocks in the current turn's assistant\n * messages. Used as a signal for the Claude Code work classifier\n * (D-027). Always an integer; `0` when the turn contained no tool\n * calls (explicit zero beats missing key). Per-turn, not per-session —\n * the chat decorator aggregates across turns server-side.\n */\n toolCallCount: number;\n /**\n * Count of distinct `file_path` values across `Edit`, `Write`, and\n * `MultiEdit` `tool_use` blocks in the current turn. Counted as the\n * size of a `Set<string>` so duplicate paths within the same turn\n * collapse to one. File paths themselves are NOT emitted — only the\n * cardinality is privacy-safe to report.\n */\n filesEditedCount: number;\n /**\n * Count of `tool_use` blocks with `name === \"Bash\"` in the current\n * turn. Bash command strings are NOT emitted — only the count.\n */\n bashCommandCount: number;\n}\n\n/**\n * Tool names whose invocations we count toward `filesEditedCount`.\n * Kept as a typed constant so both the per-block switch and any\n * future backend-side mirror can reference the same list.\n */\nconst FILE_EDITING_TOOL_NAMES = new Set<string>([\n \"Edit\",\n \"Write\",\n \"MultiEdit\",\n]);\n\n/**\n * Tool-name marker for Bash invocations. Hoisted to a constant so we\n * don't sprinkle the string literal through the parser.\n */\nconst BASH_TOOL_NAME = \"Bash\";\n\n/**\n * Match a slash-command at the start of a message. Leading whitespace is\n * trimmed before matching. The captured group is the skill name.\n *\n * Examples (match):\n * \"/foo\" -> \"foo\"\n * \"/foo-bar\" -> \"foo-bar\"\n * \"/foo some args\" -> \"foo\"\n *\n * Examples (no match):\n * \"Not a skill: /path/file\" — slash is not at the start\n * \"/path/file\" — second segment, name contains a slash\n * \"\" — empty\n */\nconst SKILL_REGEX = /^\\/([\\w-]+)(?:\\s|$)/;\n\nexport function detectSkill(userMessage: string | undefined): string | undefined {\n if (typeof userMessage !== \"string\") return undefined;\n const trimmed = userMessage.trimStart();\n if (!trimmed) return undefined;\n const match = SKILL_REGEX.exec(trimmed);\n if (!match) return undefined;\n return match[1];\n}\n\n/**\n * Extract plain text from a transcript message's `content` field.\n * Content may be a string or an array of content blocks.\n * Only `text` blocks contribute — `thinking`, `tool_use`, `tool_result`,\n * and `image` blocks are ignored.\n */\nexport function extractTextContent(\n content: string | TranscriptContentBlock[] | undefined,\n): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n const parts: string[] = [];\n for (const block of content) {\n if (block?.type === \"text\" && typeof block.text === \"string\") {\n parts.push(block.text);\n }\n }\n return parts.join(\"\\n\").trim();\n}\n\n/**\n * Heuristic: is this a \"meta\" user message that should not be treated\n * as a real prompt? These include slash-command invocations and local\n * command caveats injected by Claude Code itself. Note that these are\n * separate `type: \"system\"` entries — regular `type: \"user\"` entries\n * carrying a typed slash-command still come through here and are NOT\n * skipped.\n */\nexport function isMetaUserMessage(line: TranscriptLine, text: string): boolean {\n if (line.isMeta === true) return true;\n if (!text) return true;\n return (\n text.includes(\"<command-name>\") ||\n text.includes(\"<local-command-caveat>\") ||\n text.includes(\"<command-message>\")\n );\n}\n\n/**\n * Parse an ISO 8601 timestamp to epoch milliseconds.\n * Returns NaN for invalid/undefined input.\n */\nfunction parseTimestamp(ts: string | undefined): number {\n if (typeof ts !== \"string\" || !ts) return NaN;\n return Date.parse(ts);\n}\n\n/**\n * Compaction markers interleaved in the transcript that should be\n * skipped when computing per-turn latency. The exact subtype strings\n * come from Claude Code's own PreCompact / PostCompact hook events\n * (recorded as `type: \"system\"` entries in the transcript).\n */\nfunction isCompactionEntry(line: TranscriptLine): boolean {\n if (line.type !== \"system\") return false;\n const subtype = line.subtype ?? \"\";\n return (\n subtype === \"compact_boundary\" ||\n subtype === \"pre_compact\" ||\n subtype === \"post_compact\" ||\n /compact/i.test(subtype)\n );\n}\n\n/**\n * Parse the transcript JSONL contents and extract the data we want to\n * report: last user prompt, last assistant response, usage totals for\n * the most recent assistant turn, model name, number of assistant\n * turns, latency for the most recent turn, and slash-command (skill)\n * detected on the current turn's user message.\n *\n * `raw` is the full UTF-8 contents of the transcript file. This entry\n * point is pure — no filesystem I/O — so it's trivial to unit test.\n */\nexport function parseTranscript(raw: string): ExtractedTranscriptData {\n const empty: ExtractedTranscriptData = {\n prompt: \"\",\n response: \"\",\n tokens: 0,\n inputTokens: 0,\n outputTokens: 0,\n modelName: null,\n numTurns: 0,\n toolCallCount: 0,\n filesEditedCount: 0,\n bashCommandCount: 0,\n };\n\n if (!raw) return empty;\n\n const lines = raw.split(\"\\n\");\n let lastUserText = \"\";\n let lastUserTimestamp: number = NaN;\n // Original ISO string of the current turn's user message, preserved so\n // the hook layer can use it as a per-session dedup key across\n // duplicate Stop firings. Kept separate from the numeric timestamp\n // because round-tripping Date.parse back through new Date().toISOString()\n // drops sub-ms precision and normalizes timezone formatting.\n let lastUserTimestampRaw: string | undefined;\n let lastAssistantText = \"\";\n let lastAssistantTimestamp: number = NaN;\n let lastAssistantModel: string | null = null;\n let lastAssistantInputTokens = 0;\n let lastAssistantOutputTokens = 0;\n let numTurns = 0;\n // Tracks whether we have seen a new user message since the last\n // assistant-latency update. Ensures latency is always measured\n // relative to the user that preceded the final assistant in the\n // current turn — not across turns.\n let currentTurnUserTimestamp: number = NaN;\n\n // Per-turn work-signal accumulators (D-027 / D.S2). Reset every time\n // we cross a new top-level user message so counts reflect only the\n // current turn window — the assistant messages between the last user\n // message and Stop. Aggregation across turns happens server-side in\n // the chat decorator, not here.\n let toolCallCount = 0;\n let bashCommandCount = 0;\n let editedFilePaths = new Set<string>();\n\n for (const rawLine of lines) {\n if (!rawLine) continue;\n let parsed: TranscriptLine;\n try {\n parsed = JSON.parse(rawLine) as TranscriptLine;\n } catch {\n continue; // skip malformed lines\n }\n\n // Skip compaction markers so they don't break the user->assistant\n // pairing used for latency.\n if (isCompactionEntry(parsed)) continue;\n\n // Skip sidechain (subagent) entries — we want the top-level session\n // conversation. If a transcript only has sidechain entries, the\n // loop below will leave us with empty strings.\n if (parsed.isSidechain === true) continue;\n\n if (parsed.type === \"user\" && parsed.message) {\n const text = extractTextContent(parsed.message.content);\n if (isMetaUserMessage(parsed, text)) continue;\n lastUserText = text;\n lastUserTimestamp = parseTimestamp(parsed.timestamp);\n currentTurnUserTimestamp = lastUserTimestamp;\n // Reset per-turn work-signal accumulators: we've just crossed\n // into a new turn window, so counts from previous turns must\n // not bleed into this one. The chat decorator aggregates across\n // turns server-side (D.S3); here we only emit per-PR counts.\n toolCallCount = 0;\n bashCommandCount = 0;\n editedFilePaths = new Set<string>();\n // Preserve the raw ISO string (only when it's actually a string)\n // for use as a dedup key. Unparseable timestamps are still kept\n // verbatim so upstream can match on exact-string equality.\n lastUserTimestampRaw =\n typeof parsed.timestamp === \"string\" && parsed.timestamp\n ? parsed.timestamp\n : undefined;\n } else if (parsed.type === \"assistant\" && parsed.message) {\n const text = extractTextContent(parsed.message.content);\n // Count every assistant entry (each represents one model response\n // turn, even if it contains only a tool_use or thinking block).\n numTurns += 1;\n if (text) lastAssistantText = text;\n if (typeof parsed.message.model === \"string\") {\n lastAssistantModel = parsed.message.model;\n }\n // Accumulate per-turn work signals. Each tool_use block\n // increments the total, Edit/Write/MultiEdit contribute their\n // file_path to a Set (distinct-path count is what we emit), and\n // Bash tool calls bump their own counter. Individual-block\n // parse failures are swallowed so one malformed entry cannot\n // zero out the whole turn's counts.\n const content = parsed.message.content;\n if (Array.isArray(content)) {\n for (const block of content) {\n try {\n if (!block || block.type !== \"tool_use\") continue;\n toolCallCount += 1;\n const name = typeof block.name === \"string\" ? block.name : \"\";\n if (name === BASH_TOOL_NAME) {\n bashCommandCount += 1;\n continue;\n }\n if (FILE_EDITING_TOOL_NAMES.has(name)) {\n const input = block.input;\n if (\n input !== null &&\n typeof input === \"object\" &&\n \"file_path\" in input\n ) {\n const filePath = (input as { file_path?: unknown }).file_path;\n if (typeof filePath === \"string\" && filePath) {\n editedFilePaths.add(filePath);\n }\n }\n }\n } catch {\n // Malformed block — skip it without failing the whole\n // transcript walk. Partial counts are better than zero.\n }\n }\n }\n const usage = parsed.message.usage;\n if (usage) {\n // Overwrite with the most recent turn's usage. Include cache\n // tokens in the input total so total token count reflects real\n // billable input.\n const input =\n (usage.input_tokens ?? 0) +\n (usage.cache_creation_input_tokens ?? 0) +\n (usage.cache_read_input_tokens ?? 0);\n const output = usage.output_tokens ?? 0;\n lastAssistantInputTokens = input;\n lastAssistantOutputTokens = output;\n }\n const ts = parseTimestamp(parsed.timestamp);\n if (!Number.isNaN(ts)) {\n lastAssistantTimestamp = ts;\n }\n }\n }\n\n const result: ExtractedTranscriptData = {\n prompt: lastUserText,\n response: lastAssistantText,\n tokens: lastAssistantInputTokens + lastAssistantOutputTokens,\n inputTokens: lastAssistantInputTokens,\n outputTokens: lastAssistantOutputTokens,\n modelName: lastAssistantModel,\n numTurns,\n toolCallCount,\n filesEditedCount: editedFilePaths.size,\n bashCommandCount,\n };\n\n if (\n !Number.isNaN(currentTurnUserTimestamp) &&\n !Number.isNaN(lastAssistantTimestamp) &&\n lastAssistantTimestamp >= currentTurnUserTimestamp\n ) {\n result.latencyMs = Math.round(\n lastAssistantTimestamp - currentTurnUserTimestamp,\n );\n }\n\n const skill = detectSkill(lastUserText);\n if (skill) {\n result.skill = skill;\n }\n\n if (lastUserTimestampRaw) {\n result.userTurnTimestamp = lastUserTimestampRaw;\n }\n\n return result;\n}\n","/**\n * Per-session dedup state for the Claude Code Stop / SubagentStop hook.\n *\n * Problem (INV-004): Claude Code occasionally fires the Stop hook twice\n * for a single user turn, a few seconds apart. Each firing calls the\n * CLI, which parses the transcript and emits the LATEST user+assistant\n * pair — so two firings on one turn produce two PromptRequests with an\n * identical `prompt` and a slightly different `response`.\n *\n * Fix: keep a small sidecar file per session id under\n * `~/.olakai/monitor-state/<sessionId>.json`, keyed by the current\n * turn's user-message timestamp. If the current Stop firing sees the\n * same user-turn timestamp as the last one we reported, skip the POST.\n *\n * The module is pure w.r.t. process state — callers pass `sessionId`\n * and (optionally) a `homeDir` override for testability. All filesystem\n * errors are swallowed and surfaced via `debugLog` callbacks supplied\n * by the caller; the hook MUST NOT break Claude Code.\n */\n\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\n/**\n * State persisted per session id. `numTurnsAtLastReport` is informational\n * only — dedup decisions use `lastUserTimestamp`.\n */\nexport interface SessionMonitorState {\n lastUserTimestamp: string;\n lastReportedAt: string;\n numTurnsAtLastReport: number;\n}\n\nconst STATE_DIR_SEGMENTS = [\".olakai\", \"monitor-state\"];\n\n/**\n * Resolve the directory that holds per-session state files. Exposed\n * indirectly through the `homeDir` parameter on the public API so tests\n * can point it at a tmp dir.\n */\nfunction getStateDir(homeDir: string): string {\n return path.join(homeDir, ...STATE_DIR_SEGMENTS);\n}\n\nfunction getStateFile(sessionId: string, homeDir: string): string {\n return path.join(getStateDir(homeDir), `${sessionId}.json`);\n}\n\n/**\n * Optional debug logger. Kept as a module-level mutable hook so the\n * caller (monitor.ts) can wire in its own `debugLog` without this file\n * importing it (avoiding circular deps).\n */\ntype DebugLogger = (label: string, data: unknown) => void;\nlet debugLogger: DebugLogger | null = null;\n\nexport function setDebugLogger(logger: DebugLogger | null): void {\n debugLogger = logger;\n}\n\nfunction log(label: string, data: unknown): void {\n if (debugLogger) {\n try {\n debugLogger(label, data);\n } catch {\n // Debug logging must never break the hook.\n }\n }\n}\n\n/**\n * Load persisted state for `sessionId`. Returns null when the file is\n * absent, unreadable, or contains malformed JSON. Never throws.\n */\nexport function loadSessionState(\n sessionId: string,\n homeDir: string = os.homedir(),\n): SessionMonitorState | null {\n if (!sessionId) return null;\n const filePath = getStateFile(sessionId, homeDir);\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<SessionMonitorState>;\n if (\n typeof parsed?.lastUserTimestamp !== \"string\" ||\n typeof parsed?.lastReportedAt !== \"string\" ||\n typeof parsed?.numTurnsAtLastReport !== \"number\"\n ) {\n // Malformed shape — treat as missing so we don't skip a real\n // report based on garbage state.\n return null;\n }\n return {\n lastUserTimestamp: parsed.lastUserTimestamp,\n lastReportedAt: parsed.lastReportedAt,\n numTurnsAtLastReport: parsed.numTurnsAtLastReport,\n };\n } catch (err) {\n log(\"state-load-failed\", {\n sessionId,\n error: (err as Error).message,\n });\n return null;\n }\n}\n\n/**\n * Persist state for `sessionId`. Creates the state directory on first\n * write. Filesystem errors are logged via `debugLog` and swallowed.\n */\nexport function saveSessionState(\n sessionId: string,\n state: SessionMonitorState,\n homeDir: string = os.homedir(),\n): void {\n if (!sessionId) return;\n const dir = getStateDir(homeDir);\n const filePath = getStateFile(sessionId, homeDir);\n try {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, JSON.stringify(state, null, 2) + \"\\n\", \"utf-8\");\n } catch (err) {\n log(\"state-save-failed\", {\n sessionId,\n error: (err as Error).message,\n });\n }\n}\n\n/**\n * Decide whether to report the current turn given the last-reported\n * state and the current turn's user timestamp.\n *\n * Rules:\n * - currentUserTimestamp missing/empty → report (can't dedup).\n * - no existing state → report (first turn for this session).\n * - currentUserTimestamp === existing.lastUserTimestamp → SKIP.\n * - otherwise → report (a new user turn).\n */\nexport function shouldReportTurn(\n existing: SessionMonitorState | null,\n currentUserTimestamp: string | undefined,\n): boolean {\n if (!currentUserTimestamp) return true;\n if (!existing) return true;\n return existing.lastUserTimestamp !== currentUserTimestamp;\n}\n"],"mappings":"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","names":["program","listCommand","getCommand","createCommand","updateCommand","deleteCommand","program","listCommand","getCommand","createCommand","updateCommand","deleteCommand","program","listCommand","getCommand","createCommand","updateCommand","deleteCommand","program","prompt","listCommand","getCommand","program","fs","path","fs","os","path","program","require"]}
|