olakai-cli 0.6.7 → 0.8.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.
@@ -0,0 +1,124 @@
1
+ import {
2
+ buildReport,
3
+ getDoctorToolAdapter,
4
+ runCheckChain,
5
+ runFixes,
6
+ targetKey
7
+ } from "./chunk-B44Y3ZQP.js";
8
+ import "./chunk-E33XD5CO.js";
9
+ import "./chunk-KNGRF4XU.js";
10
+ import {
11
+ findConfiguredWorkspace,
12
+ migrateLegacyClaudeConfigIfNeeded
13
+ } from "./chunk-KY6OHQZW.js";
14
+ import "./chunk-AVB4N2UN.js";
15
+
16
+ // src/monitor/repair.ts
17
+ import * as os from "os";
18
+ function resolveRepairTarget(tool, cwd = process.cwd()) {
19
+ const root = findConfiguredWorkspace(cwd, [tool]) ?? cwd;
20
+ return { path: root, tool };
21
+ }
22
+ async function runRepair(options) {
23
+ const homeDir = options.homeDir ?? os.homedir();
24
+ const cwd = options.cwd ?? process.cwd();
25
+ const target = resolveRepairTarget(options.tool, cwd);
26
+ const adapter = getDoctorToolAdapter(options.tool);
27
+ const migratedLegacyConfig = migrateLegacyClaudeConfigIfNeeded(
28
+ target.path,
29
+ () => {
30
+ }
31
+ );
32
+ const { report: before, outcomes } = await buildReport([target], {
33
+ homeDir,
34
+ now: options.now
35
+ });
36
+ const outcome = outcomes.get(targetKey(target)) ?? await runCheckChain(target, { homeDir, now: options.now });
37
+ const fixes = await runFixes(target, outcome, {
38
+ homeDir,
39
+ interactive: options.interactive ?? false,
40
+ recreateMissing: true
41
+ });
42
+ let forcedHookRemerge = false;
43
+ let forcedHookRemergeDetail;
44
+ const hooksAlreadyFixed = fixes.some(
45
+ (f) => f.checkId === "hooks-installed" && f.fixed
46
+ );
47
+ const agentRecreated = fixes.some(
48
+ (f) => f.checkId === "agent-exists" && f.fixed
49
+ );
50
+ if (hooksAlreadyFixed || agentRecreated) {
51
+ forcedHookRemerge = false;
52
+ forcedHookRemergeDetail = agentRecreated ? "Hooks re-installed as part of agent recreation." : "Hooks re-merged by the doctor fix (no separate force needed).";
53
+ } else {
54
+ try {
55
+ adapter.repairHooks(target.path, homeDir);
56
+ forcedHookRemerge = true;
57
+ forcedHookRemergeDetail = `Force-re-merged ${adapter.displayName} hooks (${adapter.hooksLabel}).`;
58
+ } catch (err) {
59
+ forcedHookRemerge = false;
60
+ forcedHookRemergeDetail = `Could not force-re-merge hooks: ${err instanceof Error ? err.message : String(err)}.`;
61
+ }
62
+ }
63
+ const { report: after } = await buildReport([target], { homeDir, now: options.now });
64
+ return {
65
+ path: target.path,
66
+ tool: target.tool,
67
+ migratedLegacyConfig,
68
+ fixes,
69
+ forcedHookRemerge,
70
+ forcedHookRemergeDetail,
71
+ before,
72
+ after
73
+ };
74
+ }
75
+ var ICON = { ok: "\u2713", warn: "\u26A0", fail: "\u2717" };
76
+ function formatRepairResult(result) {
77
+ const lines = [];
78
+ lines.push(`Repairing ${result.tool} \u2014 ${result.path}`);
79
+ lines.push("");
80
+ lines.push("Actions:");
81
+ if (result.migratedLegacyConfig) {
82
+ lines.push(
83
+ " \u2713 Migrated legacy .claude/olakai-monitor.json \u2192 .olakai/monitor-claude-code.json"
84
+ );
85
+ }
86
+ if (result.fixes.length === 0) {
87
+ lines.push(" \u2022 No diagnostic fixes were needed.");
88
+ } else {
89
+ for (const f of result.fixes) {
90
+ lines.push(` ${f.fixed ? ICON.ok : ICON.fail} ${f.checkId}: ${f.detail}`);
91
+ }
92
+ }
93
+ lines.push(` ${result.forcedHookRemerge ? ICON.ok : "\u2022"} ${result.forcedHookRemergeDetail}`);
94
+ lines.push("");
95
+ const beforeTarget = result.before.targets[0];
96
+ const afterTarget = result.after.targets[0];
97
+ if (beforeTarget && afterTarget) {
98
+ lines.push("Health (before \u2192 after):");
99
+ for (const afterCheck of afterTarget.checks) {
100
+ const beforeCheck = beforeTarget.checks.find((c) => c.id === afterCheck.id);
101
+ const beforeIcon = beforeCheck ? ICON[beforeCheck.status] : "?";
102
+ const arrow = beforeCheck && beforeCheck.status !== afterCheck.status ? " (changed)" : "";
103
+ lines.push(
104
+ ` ${beforeIcon} \u2192 ${ICON[afterCheck.status]} ${afterCheck.label}${arrow}`
105
+ );
106
+ }
107
+ lines.push("");
108
+ }
109
+ const overall = result.after.overall;
110
+ lines.push(
111
+ overall === "ok" ? "Repair complete \u2014 all checks pass." : overall === "warn" ? "Repair complete \u2014 some checks still warn (often expected, e.g. an idle workspace)." : "Repair ran, but some checks still fail. Run 'olakai monitor doctor' for the full diagnosis."
112
+ );
113
+ return lines.join("\n");
114
+ }
115
+ function exitCodeForRepair(result) {
116
+ return result.after.overall === "fail" ? 1 : 0;
117
+ }
118
+ export {
119
+ exitCodeForRepair,
120
+ formatRepairResult,
121
+ resolveRepairTarget,
122
+ runRepair
123
+ };
124
+ //# sourceMappingURL=repair-JYRH2ES4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/monitor/repair.ts"],"sourcesContent":["/**\n * `olakai monitor repair [--tool X] [--json]` (OLA-245, S3).\n *\n * The forceful, one-shot re-init for a single (workspace, tool). Where\n * `monitor doctor --fix` only repairs the checks it found broken — and\n * deliberately gates agent recreation behind `--recreate-missing` so a\n * transient 404 can't silently spawn a duplicate — `repair` is the\n * explicit \"make this workspace's monitoring work again\" entry point:\n *\n * 1. Migrate a legacy `.claude/olakai-monitor.json` → the new\n * `.olakai/monitor-<tool>.json` path if applicable (claude-code).\n * 2. Run the doctor check chain to learn the current state.\n * 3. Run the doctor fixes WITH `recreateMissing: true` — repair is the\n * heavy entry point doctor points users to, so it WILL recreate a\n * 404'd agent (provisioning a fresh agent + key).\n * 4. ALWAYS force an idempotent hook re-merge, even when\n * `hooks-installed` was already green. This is the \"force re-init\"\n * semantic: a partially-clobbered hooks file (someone hand-edited\n * `.claude/settings.json`) gets the Olakai entries merged back in.\n * 5. Re-check and report a before/after summary of what changed.\n *\n * Agent-linkage discipline (D-002):\n * - The agentId stays STABLE unless the agent 404s — repair re-uses the\n * existing linkage, it does not re-pick an agent.\n * - The API key is rotated ONLY when it's actually invalid (doctor's\n * `api-key-valid` failed) or when recreation rewrote the config.\n * Repair never rotates a working key.\n *\n * Reuses S2's `runCheckChain` / `runFixes` / adapter table so there is\n * exactly one implementation of every check + repair.\n */\nimport * as os from \"node:os\";\nimport {\n buildReport,\n runCheckChain,\n runFixes,\n targetKey,\n type CheckStatus,\n type DoctorReport,\n type DoctorTarget,\n type FixResult,\n} from \"./doctor.js\";\nimport { getDoctorToolAdapter } from \"./doctor-adapters.js\";\nimport { migrateLegacyClaudeConfigIfNeeded } from \"./migrations.js\";\nimport { findConfiguredWorkspace } from \"./paths.js\";\nimport type { ToolId } from \"./plugin.js\";\n\nexport interface RepairResult {\n path: string;\n tool: ToolId;\n /** Whether a legacy config file was migrated to the new path. */\n migratedLegacyConfig: boolean;\n /** Fixes the shared doctor machinery applied (recreate, re-link, …). */\n fixes: FixResult[];\n /**\n * Whether the always-on hook re-merge ran successfully. The doctor\n * fixes only touch hooks when `hooks-installed` failed; repair forces\n * the re-merge unconditionally, so this is reported separately.\n */\n forcedHookRemerge: boolean;\n /** Detail of the forced re-merge (success message or the error). */\n forcedHookRemergeDetail: string;\n /** Health snapshot BEFORE repair ran. */\n before: DoctorReport;\n /** Health snapshot AFTER repair ran. */\n after: DoctorReport;\n}\n\nexport interface RepairOptions {\n tool: ToolId;\n /** Test seams. */\n cwd?: string;\n homeDir?: string;\n now?: Date;\n interactive?: boolean;\n}\n\n/**\n * Resolve the single (workspace, tool) target repair operates on.\n * Prefers the configured workspace root (walking up from cwd); falls\n * back to cwd so repair can still attempt a fresh install in a\n * not-yet-configured directory.\n */\nexport function resolveRepairTarget(\n tool: ToolId,\n cwd: string = process.cwd(),\n): DoctorTarget {\n const root = findConfiguredWorkspace(cwd, [tool]) ?? cwd;\n return { path: root, tool };\n}\n\n/**\n * Pure orchestrator for `monitor repair`. No console I/O — the Commander\n * action wraps this with rendering + exit-code mapping. `homeDir`/`now`\n * are injectable so tests never touch the real `~/.olakai`.\n */\nexport async function runRepair(options: RepairOptions): Promise<RepairResult> {\n const homeDir = options.homeDir ?? os.homedir();\n const cwd = options.cwd ?? process.cwd();\n const target = resolveRepairTarget(options.tool, cwd);\n const adapter = getDoctorToolAdapter(options.tool);\n\n // 1) Legacy config migration must run BEFORE the `before` snapshot —\n // the doctor check chain reads the config (which itself triggers the\n // auto-migration shim), so if we snapshotted first the migration would\n // already have happened and `migratedLegacyConfig` would read false.\n // We run it explicitly here so the flag faithfully reports whether a\n // legacy file was upgraded this run. claude-code only today; the helper\n // is a no-op for other tools / when there's nothing to migrate, and it\n // never throws. A no-op notifier keeps repair's output clean.\n const migratedLegacyConfig = migrateLegacyClaudeConfigIfNeeded(\n target.path,\n () => {},\n );\n\n // 2) Snapshot health BEFORE any (further) repair. Keep the per-target\n // outcomes so the fix pass reuses them instead of re-running the whole\n // check chain — one snapshot, not two (also closes the tiny TOCTOU\n // window between a discarded snapshot and the chain fixes act on).\n const { report: before, outcomes } = await buildReport([target], {\n homeDir,\n now: options.now,\n });\n\n // 3) Run the shared doctor fixes WITH recreation enabled. Repair is the\n // explicit recreate entry point, unlike `doctor --fix`. Fall back to a\n // fresh chain run only if the snapshot somehow lacks this target.\n const outcome =\n outcomes.get(targetKey(target)) ??\n (await runCheckChain(target, { homeDir, now: options.now }));\n const fixes = await runFixes(target, outcome, {\n homeDir,\n interactive: options.interactive ?? false,\n recreateMissing: true,\n });\n\n // 4) ALWAYS force the idempotent hook re-merge — the \"force re-init\"\n // semantic. The doctor fix only re-merges when hooks-installed failed;\n // here we re-run it unconditionally so a partially-clobbered hooks file\n // is healed even when the check passed. Idempotent: a no-op when the\n // hooks are already present.\n let forcedHookRemerge = false;\n let forcedHookRemergeDetail: string;\n // Skip the redundant re-merge if a doctor fix already re-merged hooks\n // this run (avoid touching the file twice). The recreate path also\n // rewrites hooks via runMonitorInstall, so don't double-merge there.\n const hooksAlreadyFixed = fixes.some(\n (f) => f.checkId === \"hooks-installed\" && f.fixed,\n );\n const agentRecreated = fixes.some(\n (f) => f.checkId === \"agent-exists\" && f.fixed,\n );\n if (hooksAlreadyFixed || agentRecreated) {\n forcedHookRemerge = false;\n forcedHookRemergeDetail = agentRecreated\n ? \"Hooks re-installed as part of agent recreation.\"\n : \"Hooks re-merged by the doctor fix (no separate force needed).\";\n } else {\n try {\n adapter.repairHooks(target.path, homeDir);\n forcedHookRemerge = true;\n forcedHookRemergeDetail = `Force-re-merged ${adapter.displayName} hooks (${adapter.hooksLabel}).`;\n } catch (err) {\n forcedHookRemerge = false;\n forcedHookRemergeDetail = `Could not force-re-merge hooks: ${err instanceof Error ? err.message : String(err)}.`;\n }\n }\n\n // 5) Snapshot health AFTER repair.\n const { report: after } = await buildReport([target], { homeDir, now: options.now });\n\n return {\n path: target.path,\n tool: target.tool,\n migratedLegacyConfig,\n fixes,\n forcedHookRemerge,\n forcedHookRemergeDetail,\n before,\n after,\n };\n}\n\n// ===========================================================================\n// Rendering\n// ===========================================================================\n\nconst ICON: Record<CheckStatus, string> = { ok: \"✓\", warn: \"⚠\", fail: \"✗\" };\n\n/**\n * Render a before/after summary of a repair run. Shows what repair\n * changed (migration, fixes, forced re-merge) and the per-check status\n * transition so the user can see exactly what moved.\n */\nexport function formatRepairResult(result: RepairResult): string {\n const lines: string[] = [];\n lines.push(`Repairing ${result.tool} — ${result.path}`);\n lines.push(\"\");\n\n // Actions taken.\n lines.push(\"Actions:\");\n if (result.migratedLegacyConfig) {\n lines.push(\n \" ✓ Migrated legacy .claude/olakai-monitor.json → .olakai/monitor-claude-code.json\",\n );\n }\n if (result.fixes.length === 0) {\n lines.push(\" • No diagnostic fixes were needed.\");\n } else {\n for (const f of result.fixes) {\n lines.push(` ${f.fixed ? ICON.ok : ICON.fail} ${f.checkId}: ${f.detail}`);\n }\n }\n lines.push(` ${result.forcedHookRemerge ? ICON.ok : \"•\"} ${result.forcedHookRemergeDetail}`);\n lines.push(\"\");\n\n // Before/after per-check transition (single target).\n const beforeTarget = result.before.targets[0];\n const afterTarget = result.after.targets[0];\n if (beforeTarget && afterTarget) {\n lines.push(\"Health (before → after):\");\n for (const afterCheck of afterTarget.checks) {\n const beforeCheck = beforeTarget.checks.find((c) => c.id === afterCheck.id);\n const beforeIcon = beforeCheck ? ICON[beforeCheck.status] : \"?\";\n const arrow =\n beforeCheck && beforeCheck.status !== afterCheck.status ? \" (changed)\" : \"\";\n lines.push(\n ` ${beforeIcon} → ${ICON[afterCheck.status]} ${afterCheck.label}${arrow}`,\n );\n }\n lines.push(\"\");\n }\n\n const overall = result.after.overall;\n lines.push(\n overall === \"ok\"\n ? \"Repair complete — all checks pass.\"\n : overall === \"warn\"\n ? \"Repair complete — some checks still warn (often expected, e.g. an idle workspace).\"\n : \"Repair ran, but some checks still fail. Run 'olakai monitor doctor' for the full diagnosis.\",\n );\n return lines.join(\"\\n\");\n}\n\n/** Map a repair's resulting overall status to a process exit code. */\nexport function exitCodeForRepair(result: RepairResult): number {\n return result.after.overall === \"fail\" ? 1 : 0;\n}\n"],"mappings":"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","names":[]}
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  getClaudeCodeStatus,
3
3
  printClaudeCodeStatus
4
- } from "./chunk-2Q7JYGCK.js";
4
+ } from "./chunk-KY6OHQZW.js";
5
5
  import "./chunk-AVB4N2UN.js";
6
6
  export {
7
7
  getClaudeCodeStatus,
8
8
  printClaudeCodeStatus
9
9
  };
10
- //# sourceMappingURL=status-USHUUHK6.js.map
10
+ //# sourceMappingURL=status-IZCIMES2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "olakai-cli",
3
- "version": "0.6.7",
3
+ "version": "0.8.0",
4
4
  "description": "Olakai CLI tool",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1 +0,0 @@
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":[]}