olakai-cli 0.6.6 → 0.6.7

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.
@@ -31,7 +31,7 @@ import {
31
31
  updateWorkflow,
32
32
  validateKpiFormula,
33
33
  validateMonitoringApiKey
34
- } from "./chunk-GU4HEL24.js";
34
+ } from "./chunk-43E2A3O2.js";
35
35
  import "./chunk-AVB4N2UN.js";
36
36
  export {
37
37
  createAgent,
@@ -67,4 +67,4 @@ export {
67
67
  validateKpiFormula,
68
68
  validateMonitoringApiKey
69
69
  };
70
- //# sourceMappingURL=api-63UDJX5M.js.map
70
+ //# sourceMappingURL=api-OAWRQIZM.js.map
@@ -873,4 +873,4 @@ export {
873
873
  updateCustomDataConfig,
874
874
  deleteCustomDataConfig
875
875
  };
876
- //# sourceMappingURL=chunk-GU4HEL24.js.map
876
+ //# sourceMappingURL=chunk-43E2A3O2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/api.ts"],"sourcesContent":["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 * Optional `git config --global user.email` captured at install time.\n * Self-monitor-only — the backend uses it to pre-seed a developer\n * identity row keyed on this email so future VCS PRs authored under\n * this address auto-link to the same Olakai User. Omit when git is\n * unavailable or the user hasn't configured an email.\n */\n vcsEmailHint?: 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 const errorBody = (await response.json().catch(() => ({}))) as {\n error?: string;\n message?: string;\n forbiddenFields?: string[];\n tier?: string;\n limit?: number;\n };\n // Typed backend errors get role-aware, action-oriented messages.\n // Anything else falls through to the generic string the backend\n // sends, or a status-code summary if the body had no message.\n if (response.status === 403) {\n throw new Error(\n \"Your role can't create monitoring agents on this workspace. \" +\n \"Ask an admin to enable employee self-monitoring (or create the agent for you).\",\n );\n }\n if (\n response.status === 400 &&\n errorBody.error === \"self_monitor_admin_field_forbidden\"\n ) {\n const fields = errorBody.forbiddenFields?.join(\", \") ?? \"admin-only\";\n throw new Error(\n `Self-monitoring agents cannot be attached to admin-curated structures (${fields}). The CLI should be sending only name/description/role/source/createApiKey — this is a CLI bug, please report it.`,\n );\n }\n if (\n (response.status === 402 || response.status === 403) &&\n errorBody.error === \"tier_agent_limit_reached\"\n ) {\n throw new Error(\n errorBody.message ??\n `Your account is at its agent limit${errorBody.limit ? ` (${errorBody.limit}/${errorBody.limit} on ${errorBody.tier ?? \"FREE\"} tier)` : \"\"}. Ask your admin to upgrade or remove unused agents.`,\n );\n }\n if (response.status === 409 && errorBody.error === \"name_conflict\") {\n throw new Error(\n errorBody.message ??\n \"An agent with this name already exists on this account. Pick a different name and retry.\",\n );\n }\n if (response.status === 409) {\n throw new Error(\"An agent with this name already exists\");\n }\n if (response.status === 429) {\n throw new Error(\n errorBody.message ??\n \"Too many agent-creation requests. Try again in a minute.\",\n );\n }\n throw new Error(errorBody.error || errorBody.message || \"Failed to create agent\");\n }\n\n return (await response.json()) as Agent;\n}\n\n/**\n * GET /api/config/agents/mine — list agents the caller created.\n *\n * Used by the monitor-init flow to detect an existing self-monitor\n * agent before attempting create (idempotent re-runs across\n * workspaces, plus collision avoidance on shared-repo setups).\n *\n * The response includes only MASKED API keys; to recover the\n * unmasked key for an existing agent the CLI must call\n * `regenerateAgentApiKey()` (loud rotation, intentional).\n */\nexport interface MineAgent {\n id: string;\n name: string;\n description: string;\n role: \"WORKER\" | \"COORDINATOR\";\n source: string;\n creatorUserId: string | null;\n createdAt: string;\n apiKey: { id: string; keyMasked: string; isActive: boolean } | null;\n}\n\nexport async function listMyAgents(filter?: {\n source?: string;\n name?: string;\n}): Promise<MineAgent[]> {\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 (filter?.source) params.set(\"source\", filter.source);\n if (filter?.name) params.set(\"name\", filter.name);\n const qs = params.toString();\n const url = `${getBaseUrl()}/api/config/agents/mine${qs ? `?${qs}` : \"\"}`;\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${token}` },\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 === 403) {\n throw new Error(\"Your role can't list agents on this workspace.\");\n }\n const errorBody = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(errorBody.error || \"Failed to list your agents\");\n }\n\n const data = (await response.json()) as { agents: MineAgent[] };\n return data.agents;\n}\n\n/**\n * POST /api/config/agents/:id/regenerate-api-key — mint a fresh key,\n * revoke the old one. Owner-or-admin only (backend enforces).\n *\n * The returned `key` is plaintext, shown ONCE. Other workspaces using\n * the old key will start 401-ing on the next monitor request and need\n * to re-init.\n */\nexport async function regenerateAgentApiKey(\n agentId: string,\n): Promise<{ id: string; key: string; keyMasked: string; isActive: boolean }> {\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(\n `${getBaseUrl()}/api/config/agents/${agentId}/regenerate-api-key`,\n {\n method: \"POST\",\n headers: { 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 === 403) {\n throw new Error(\n \"Only the agent's creator or an ADMIN may rotate its API key.\",\n );\n }\n if (response.status === 404) {\n throw new Error(\"Agent not found.\");\n }\n if (response.status === 429) {\n throw new Error(\"Too many key-rotation requests. Try again in a minute.\");\n }\n const errorBody = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(errorBody.error || \"Failed to regenerate API key\");\n }\n\n return (await response.json()) as {\n id: string;\n key: string;\n keyMasked: string;\n isActive: boolean;\n };\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 === 403) {\n throw new Error(\n \"Only the agent's creator or an ADMIN may delete it.\",\n );\n }\n if (response.status === 404) {\n throw new Error(\"Agent not found\");\n }\n const error = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\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// Monitoring API - API Key Validation\n// ============================================\n\nexport interface ApiKeyValidationResult {\n apiKeyId: string;\n accountId: string;\n}\n\n/**\n * Validates a monitoring API key by calling /api/monitoring/prompt/me.\n * Returns the apiKeyId + accountId the key resolves to, or null if the\n * key is invalid (any non-2xx) or the request fails for any reason.\n *\n * Used by `monitor init` to verify the user pasted a key that belongs\n * to the agent they picked. The endpoint is derived from the monitoring\n * endpoint by appending \"/me\".\n */\nexport async function validateMonitoringApiKey(\n monitoringEndpoint: string,\n apiKey: string,\n): Promise<ApiKeyValidationResult | null> {\n // Strip a single trailing slash before appending \"/me\" so we don't\n // produce a double slash in the resolved URL.\n const normalizedEndpoint = monitoringEndpoint.replace(/\\/+$/, \"\");\n const url = `${normalizedEndpoint}/me`;\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 5000);\n\n try {\n const response = await fetch(url, {\n method: \"GET\",\n headers: {\n \"x-api-key\": apiKey,\n },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n return null;\n }\n\n const data = (await response.json()) as Partial<ApiKeyValidationResult>;\n if (\n typeof data?.accountId !== \"string\" ||\n typeof data?.apiKeyId !== \"string\"\n ) {\n return null;\n }\n\n return { accountId: data.accountId, apiKeyId: data.apiKeyId };\n } catch {\n // Network failure, abort timeout, JSON parse error — any failure\n // soft-fails to null so callers can decide how to surface it.\n return null;\n } finally {\n clearTimeout(timeout);\n }\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"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ import {
31
31
  updateKpi,
32
32
  updateWorkflow,
33
33
  validateKpiFormula
34
- } from "./chunk-GU4HEL24.js";
34
+ } from "./chunk-43E2A3O2.js";
35
35
  import {
36
36
  CLAUDE_DIR,
37
37
  OLAKAI_DIR,
@@ -440,7 +440,7 @@ function getCodexSessionsDir() {
440
440
 
441
441
  // src/monitor/plugins/claude-code/index.ts
442
442
  import * as fs4 from "fs";
443
- import { spawnSync } from "child_process";
443
+ import { spawnSync as spawnSync2 } from "child_process";
444
444
 
445
445
  // src/monitor/plugin.ts
446
446
  var TOOL_IDS = [
@@ -546,6 +546,37 @@ import * as fs2 from "fs";
546
546
 
547
547
  // src/monitor/self-monitor-provision.ts
548
548
  import path3 from "path";
549
+
550
+ // src/lib/git.ts
551
+ import { spawnSync } from "child_process";
552
+ function getGitConfigEmail() {
553
+ let result;
554
+ try {
555
+ result = spawnSync("git", ["config", "--global", "user.email"], {
556
+ encoding: "utf8",
557
+ // Cap stdout. A normal `user.email` value is well under 320 bytes
558
+ // (RFC 5321 max email length); 64KB leaves headroom for git config
559
+ // wrappers that print a banner without ever truncating real
560
+ // values. spawnSync sets `result.error` (ENOBUFS) on overflow
561
+ // rather than truncating silently — we check it below.
562
+ maxBuffer: 65536,
563
+ // Don't pipe stderr to our process; we treat any error as "no email".
564
+ stdio: ["ignore", "pipe", "ignore"]
565
+ });
566
+ } catch {
567
+ return null;
568
+ }
569
+ if (result.error) return null;
570
+ if (result.status !== 0) return null;
571
+ const raw = (result.stdout || "").toString().trim();
572
+ if (!raw) return null;
573
+ const EMAIL_RE = /^[^\s@.]+(?:\.[^\s@.]+)*@[^\s@.]+(?:\.[^\s@.]+)*\.[a-zA-Z]{2,}$/;
574
+ if (!EMAIL_RE.test(raw)) return null;
575
+ if (raw.length > 320) return null;
576
+ return raw;
577
+ }
578
+
579
+ // src/monitor/self-monitor-provision.ts
549
580
  async function provisionSelfMonitorAgent(opts) {
550
581
  const me = await getCurrentUser();
551
582
  const localPart = (me.email.split("@")[0] ?? "user").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -598,15 +629,19 @@ Found your existing ${opts.displayName} agent "${found.name}".`
598
629
  category: opts.category
599
630
  };
600
631
  }
601
- const nameInput = await promptUser(`Agent name [${defaultName}]: `);
632
+ const nameInput = await promptUser(
633
+ `Enter a descriptive name for this agent or accept the recommended name [${defaultName}]: `
634
+ );
602
635
  const agentName = nameInput.trim() || defaultName;
636
+ const vcsEmailHint = getGitConfigEmail() ?? void 0;
603
637
  try {
604
638
  return await createAgent({
605
639
  name: agentName,
606
640
  description: `${opts.displayName} local agent for ${agentName}`,
607
641
  role: "WORKER",
608
642
  createApiKey: true,
609
- source: opts.source
643
+ source: opts.source,
644
+ ...vcsEmailHint ? { vcsEmailHint } : {}
610
645
  });
611
646
  } catch (err) {
612
647
  const message = err instanceof Error ? err.message : String(err);
@@ -625,7 +660,8 @@ An agent named "${agentName}" already exists on this account (created by someone
625
660
  description: `${opts.displayName} local agent for ${retry.trim()}`,
626
661
  role: "WORKER",
627
662
  createApiKey: true,
628
- source: opts.source
663
+ source: opts.source,
664
+ ...vcsEmailHint ? { vcsEmailHint } : {}
629
665
  });
630
666
  }
631
667
  throw err;
@@ -693,9 +729,9 @@ async function installClaudeCode(opts) {
693
729
  console.log(`\u2713 Monitor config saved to ${configRel}`);
694
730
  console.log("");
695
731
  console.log(
696
- "Monitoring is now active. Claude Code will report activity to Olakai"
732
+ "Congrats! Monitoring is now active. Claude Code will report activity to Olakai"
697
733
  );
698
- console.log(`on each turn. View activity at: ${getBaseUrl()}/dashboard`);
734
+ console.log(`on each turn.`);
699
735
  console.log("");
700
736
  console.log(
701
737
  `\u26A0 Ensure ${OLAKAI_DIR}/ is in your .gitignore (it contains your API key)`
@@ -730,9 +766,7 @@ async function uninstallClaudeCode(opts) {
730
766
  delete settings.hooks;
731
767
  }
732
768
  writeJsonFile(settingsPath, settings);
733
- console.log(
734
- `\u2713 Olakai hooks removed from ${CLAUDE_DIR}/${SETTINGS_FILE}`
735
- );
769
+ console.log(`\u2713 Olakai hooks removed from ${CLAUDE_DIR}/${SETTINGS_FILE}`);
736
770
  } else {
737
771
  console.log("No hooks found in settings.json.");
738
772
  }
@@ -1125,7 +1159,7 @@ var claudeCodePlugin = {
1125
1159
  };
1126
1160
  function detectClaudeBinaryOnPath() {
1127
1161
  try {
1128
- const probe = spawnSync(
1162
+ const probe = spawnSync2(
1129
1163
  process.platform === "win32" ? "where" : "which",
1130
1164
  ["claude"],
1131
1165
  {
@@ -1144,7 +1178,7 @@ registerPlugin(claudeCodePlugin);
1144
1178
 
1145
1179
  // src/monitor/plugins/codex/index.ts
1146
1180
  import * as fs9 from "fs";
1147
- import { spawnSync as spawnSync2 } from "child_process";
1181
+ import { spawnSync as spawnSync3 } from "child_process";
1148
1182
 
1149
1183
  // src/monitor/plugins/codex/install.ts
1150
1184
  import * as fs6 from "fs";
@@ -1310,9 +1344,9 @@ async function installCodex(opts) {
1310
1344
  console.log(`\u2713 Monitor config saved to ${configRel}`);
1311
1345
  console.log("");
1312
1346
  console.log(
1313
- "Monitoring is now active. Codex CLI will report activity to Olakai"
1347
+ "Congrats! Monitoring is now active. Codex CLI will report activity to Olakai"
1314
1348
  );
1315
- console.log(`on each turn. View activity at: ${getBaseUrl()}/dashboard`);
1349
+ console.log(`on each turn.`);
1316
1350
  console.log("");
1317
1351
  console.log(
1318
1352
  `\u26A0 Ensure ${OLAKAI_DIR}/ is in your .gitignore (it contains your API key).`
@@ -1789,7 +1823,7 @@ var codexPlugin = {
1789
1823
  };
1790
1824
  function detectCodexBinaryOnPath() {
1791
1825
  try {
1792
- const probe = spawnSync2(
1826
+ const probe = spawnSync3(
1793
1827
  process.platform === "win32" ? "where" : "which",
1794
1828
  ["codex"],
1795
1829
  {
@@ -2026,9 +2060,8 @@ async function installCursor(opts) {
2026
2060
  console.log(`\u2713 Monitor config saved to ${configRel}`);
2027
2061
  console.log("");
2028
2062
  console.log(
2029
- "Monitoring is now active. Restart Cursor for the new hooks to take effect."
2063
+ "Congrats! Monitoring is now active. Restart Cursor for the new hooks to take effect."
2030
2064
  );
2031
- console.log(`View activity at: ${getBaseUrl()}/dashboard`);
2032
2065
  console.log("");
2033
2066
  console.log(
2034
2067
  `\u26A0 Ensure ${OLAKAI_DIR}/ is in your .gitignore (it contains your API key)`
@@ -2733,7 +2766,7 @@ function colorize(text, color) {
2733
2766
  function printLogoHeader() {
2734
2767
  if (!process.stdout.isTTY) return;
2735
2768
  const mark = colorize("\u25C9", CYAN);
2736
- const tagline = colorize("Enterprise AI observability", DIM);
2769
+ const tagline = colorize("Enterprise AI Adoption, ROI and Governance", DIM);
2737
2770
  console.log("");
2738
2771
  console.log(` ${mark} olakai`);
2739
2772
  console.log(` ${tagline}`);
@@ -2785,7 +2818,9 @@ async function initCommand(options) {
2785
2818
  `Already authenticated as ${who} on ${where} (profile: ${profileName}). Re-authenticate? [y/N]: `
2786
2819
  );
2787
2820
  if (answer.trim().toLowerCase() !== "y") {
2788
- console.log("Keeping existing credentials. Run 'olakai logout' to sign out.");
2821
+ console.log(
2822
+ "Keeping existing credentials. Run 'olakai logout' to sign out."
2823
+ );
2789
2824
  return;
2790
2825
  }
2791
2826
  optedReAuth = true;
@@ -2911,7 +2946,7 @@ async function resolveHost(profileName, options, interactive, forceHostPrompt =
2911
2946
  }
2912
2947
  const keep = await promptUser(
2913
2948
  `
2914
- Connect to ${existing.host}? [Y/n] (or pick a different workspace): `
2949
+ Connect to ${existing.host}? [Y/n] (or pick a different domain such as on-prem): `
2915
2950
  );
2916
2951
  if (keep.trim().toLowerCase() !== "n") {
2917
2952
  return existing.host;
@@ -2937,12 +2972,16 @@ Connect to ${existing.host}? [Y/n] (or pick a different workspace): `
2937
2972
  if (idx === PRESET_HOSTS.length + 1) {
2938
2973
  return promptForCustomHost();
2939
2974
  }
2940
- console.error("Invalid choice. Re-run 'olakai init' and pick a valid option.");
2975
+ console.error(
2976
+ "Invalid choice. Re-run 'olakai init' and pick a valid option."
2977
+ );
2941
2978
  throw new InitAbortedError("", 1);
2942
2979
  }
2943
2980
  async function promptForCustomHost() {
2944
2981
  for (let attempt = 0; attempt < 3; attempt += 1) {
2945
- const raw = await promptUser("On-prem URL or hostname (e.g. olakai.acme.com): ");
2982
+ const raw = await promptUser(
2983
+ "On-prem URL or hostname (e.g. olakai.acme.com): "
2984
+ );
2946
2985
  const normalized = normalizeHost(raw.trim());
2947
2986
  if (normalized) {
2948
2987
  return normalized;
@@ -2982,7 +3021,7 @@ async function resolveEmail(options, interactive) {
2982
3021
  );
2983
3022
  }
2984
3023
  for (let attempt = 0; attempt < 3; attempt += 1) {
2985
- const raw = await promptUser("Work email: ");
3024
+ const raw = await promptUser("Enter your primary work email address: ");
2986
3025
  const trimmed = raw.trim();
2987
3026
  if (EMAIL_REGEX.test(trimmed)) {
2988
3027
  return trimmed;
@@ -2995,10 +3034,12 @@ async function runOtpFlow(email, profileName, ctx) {
2995
3034
  const expiryMin = Math.max(1, Math.round(ctx.expiresIn / 60));
2996
3035
  console.log(
2997
3036
  `
2998
- We sent a 6-digit code to ${ctx.emailObfuscated} (expires in ${expiryMin} min).`
3037
+ We sent a 6-digit code to your email ${ctx.emailObfuscated} (expires in ${expiryMin} min).`
2999
3038
  );
3000
3039
  for (; ; ) {
3001
- const code = await promptUser("Enter the 6-digit code: ");
3040
+ const code = await promptUser(
3041
+ "Please enter the 6-digit code you received: "
3042
+ );
3002
3043
  const trimmed = code.trim();
3003
3044
  if (!OTP_REGEX.test(trimmed)) {
3004
3045
  console.log("Codes are 6 digits. Try again.");
@@ -3123,7 +3164,9 @@ function handleHandshakeError(err) {
3123
3164
  break;
3124
3165
  }
3125
3166
  case "service_unavailable":
3126
- console.error("Olakai is temporarily unavailable. Try again in a minute.");
3167
+ console.error(
3168
+ "Olakai is temporarily unavailable. Try again in a minute."
3169
+ );
3127
3170
  break;
3128
3171
  case "network_error":
3129
3172
  console.error(
@@ -3139,9 +3182,7 @@ async function offerMonitorSetup(options, interactive) {
3139
3182
  if (options.skipMonitor) return;
3140
3183
  const detected = await detectInstalledTools(process.cwd());
3141
3184
  if (detected.length === 0) {
3142
- console.log(
3143
- "\nNo coding agents detected in this workspace."
3144
- );
3185
+ console.log("\nNo coding agents detected in this workspace.");
3145
3186
  console.log(
3146
3187
  "Install Claude Code, Codex, or Cursor and run 'olakai monitor init' to start tracking."
3147
3188
  );
@@ -3173,9 +3214,7 @@ Set up monitoring for ${tool}? (${reason}) [Y/n]: `
3173
3214
  } catch (err) {
3174
3215
  const message = err instanceof Error ? err.message : String(err);
3175
3216
  console.error(`${tool} setup failed: ${message}`);
3176
- console.error(
3177
- `Run 'olakai monitor init --tool ${tool}' to retry.`
3178
- );
3217
+ console.error(`Run 'olakai monitor init --tool ${tool}' to retry.`);
3179
3218
  }
3180
3219
  }
3181
3220
  }
@@ -4576,7 +4615,7 @@ async function disableCommand(options) {
4576
4615
  })
4577
4616
  );
4578
4617
  if (agentIdToDelete) {
4579
- const { deleteAgent: deleteAgent2 } = await import("./api-63UDJX5M.js");
4618
+ const { deleteAgent: deleteAgent2 } = await import("./api-OAWRQIZM.js");
4580
4619
  try {
4581
4620
  await deleteAgent2(agentIdToDelete);
4582
4621
  console.log(`\u2713 Remote agent ${agentIdToDelete} deleted.`);