olakai-cli 0.4.0 → 0.5.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.
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getClaudeCodeStatus,
3
3
  printClaudeCodeStatus
4
- } from "./chunk-HI5R5CP2.js";
4
+ } from "./chunk-NJ3O5MBL.js";
5
5
  export {
6
6
  getClaudeCodeStatus,
7
7
  printClaudeCodeStatus
8
8
  };
9
- //# sourceMappingURL=status-PPSSB7FV.js.map
9
+ //# sourceMappingURL=status-SIQPCNCZ.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "olakai-cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Olakai CLI tool",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -10,6 +10,16 @@
10
10
  "files": [
11
11
  "dist"
12
12
  ],
13
+ "scripts": {
14
+ "build": "tsup",
15
+ "dev": "tsx src/index.ts",
16
+ "start": "node dist/index.js",
17
+ "lint": "eslint src --ext .ts",
18
+ "type-check": "tsc --noEmit",
19
+ "test": "vitest run",
20
+ "test:watch": "vitest",
21
+ "prepublishOnly": "pnpm build"
22
+ },
13
23
  "keywords": [
14
24
  "olakai",
15
25
  "cli"
@@ -34,13 +44,5 @@
34
44
  "commander": "^12.0.0",
35
45
  "open": "^10.0.0"
36
46
  },
37
- "scripts": {
38
- "build": "tsup",
39
- "dev": "tsx src/index.ts",
40
- "start": "node dist/index.js",
41
- "lint": "eslint src --ext .ts",
42
- "type-check": "tsc --noEmit",
43
- "test": "vitest run",
44
- "test:watch": "vitest"
45
- }
46
- }
47
+ "packageManager": "pnpm@10.10.0"
48
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/monitor/plugins/claude-code/status.ts","../src/lib/auth.ts","../src/lib/config.ts","../src/monitor/plugins/claude-code/settings.ts","../src/monitor/plugins/claude-code/config.ts","../src/monitor/paths.ts","../src/monitor/migrations.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { StatusReport } from \"../../plugin.js\";\nimport { getValidToken } from \"../../../lib/auth.js\";\nimport { getBaseUrl } from \"../../../lib/config.js\";\nimport {\n OLAKAI_HOOK_MARKER,\n getSettingsPath,\n readJsonFile,\n type ClaudeSettings,\n} from \"./settings.js\";\nimport {\n getClaudeCodeConfigPath,\n loadClaudeCodeConfig,\n} from \"./config.js\";\n\nexport async function getClaudeCodeStatus(opts?: {\n projectRoot?: string;\n}): Promise<StatusReport> {\n const projectRoot = opts?.projectRoot ?? process.cwd();\n const configPath = getClaudeCodeConfigPath(projectRoot);\n const config = loadClaudeCodeConfig(projectRoot);\n\n const settings = readJsonFile<ClaudeSettings>(getSettingsPath(projectRoot));\n const hooksConfigured = settings?.hooks\n ? Object.values(settings.hooks).some((entries) =>\n entries.some((e) =>\n e.hooks.some((h) => h.command.includes(OLAKAI_HOOK_MARKER)),\n ),\n )\n : false;\n\n if (!config) {\n return {\n toolId: \"claude-code\",\n configured: false,\n hooksConfigured,\n configPath,\n notes: hooksConfigured\n ? [\"Hooks present in settings.json but no monitor config — re-run init.\"]\n : [],\n };\n }\n\n return {\n toolId: \"claude-code\",\n configured: true,\n hooksConfigured,\n agentId: config.agentId,\n agentName: config.agentName,\n source: config.source,\n apiKeyMasked: config.apiKey.slice(0, 12) + \"...\",\n monitoringEndpoint: config.monitoringEndpoint,\n configuredAt: config.createdAt,\n configPath,\n };\n}\n\n/**\n * Print a human-readable status summary for the Claude Code plugin\n * (non-JSON path). Also fetches recent activity if a token is\n * available — same behavior as pre-Stage-2 `monitor status`.\n */\nexport async function printClaudeCodeStatus(opts?: {\n projectRoot?: string;\n}): Promise<void> {\n const projectRoot = opts?.projectRoot ?? process.cwd();\n const status = await getClaudeCodeStatus({ projectRoot });\n\n if (!status.configured) {\n console.log(\"Monitoring is not configured for this workspace.\");\n console.log(\n \"Run 'olakai monitor init --tool claude-code' to set up monitoring.\",\n );\n process.exit(1);\n }\n\n const configRel = status.configPath\n ? path.relative(projectRoot, status.configPath)\n : \"(unknown)\";\n\n console.log(\"Olakai Monitor Status (Claude Code)\");\n console.log(\"===================================\");\n console.log(`Agent: ${status.agentName}`);\n console.log(`Agent ID: ${status.agentId}`);\n console.log(`API Key: ${status.apiKeyMasked}`);\n console.log(`Endpoint: ${status.monitoringEndpoint}`);\n console.log(`Source: ${status.source}`);\n console.log(`Configured: ${status.configuredAt}`);\n console.log(`Config file: ${configRel}`);\n console.log(\n `Hooks: ${status.hooksConfigured ? \"Active\" : \"Missing (re-run 'olakai monitor init --tool claude-code')\"}`,\n );\n\n try {\n const token = getValidToken();\n if (token && status.agentId) {\n const params = new URLSearchParams({\n agentId: status.agentId,\n limit: \"5\",\n });\n const response = await fetch(\n `${getBaseUrl()}/api/activity/prompts?${params}`,\n {\n headers: { Authorization: `Bearer ${token}` },\n },\n );\n if (response.ok) {\n const data = (await response.json()) as {\n prompts: Array<{ id: string; createdAt: string }>;\n };\n if (data.prompts && data.prompts.length > 0) {\n console.log(\"\");\n console.log(\"Recent Activity:\");\n for (const p of data.prompts) {\n console.log(` ${p.createdAt} ${p.id.slice(0, 12)}...`);\n }\n } else {\n console.log(\"\");\n console.log(\"No activity recorded yet.\");\n }\n }\n }\n } catch {\n // Activity check is optional — don't fail\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { type Environment, getEnvironment } from \"./config.js\";\n\ninterface StoredCredentials {\n token: string;\n expiresAt: number; // Unix timestamp in seconds\n environment: Environment;\n}\n\n/**\n * Get the credentials file path\n */\nfunction getCredentialsPath(): string {\n const configDir = path.join(os.homedir(), \".config\", \"olakai\");\n return path.join(configDir, \"credentials.json\");\n}\n\n/**\n * Ensure the config directory exists\n */\nfunction ensureConfigDir(): void {\n const configDir = path.dirname(getCredentialsPath());\n if (!fs.existsSync(configDir)) {\n fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });\n }\n}\n\n/**\n * Save an access token to disk\n */\nexport function saveToken(token: string, expiresIn: number): void {\n ensureConfigDir();\n\n const credentials: StoredCredentials = {\n token,\n expiresAt: Math.floor(Date.now() / 1000) + expiresIn,\n environment: getEnvironment(),\n };\n\n const credentialsPath = getCredentialsPath();\n fs.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {\n mode: 0o600, // Read/write for owner only\n });\n}\n\n/**\n * Load the stored token\n */\nexport function loadToken(): StoredCredentials | null {\n const credentialsPath = getCredentialsPath();\n\n if (!fs.existsSync(credentialsPath)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(credentialsPath, \"utf-8\");\n const credentials = JSON.parse(content) as StoredCredentials;\n return credentials;\n } catch {\n return null;\n }\n}\n\n/**\n * Clear stored credentials\n */\nexport function clearToken(): void {\n const credentialsPath = getCredentialsPath();\n\n if (fs.existsSync(credentialsPath)) {\n fs.unlinkSync(credentialsPath);\n }\n}\n\n/**\n * Check if the stored token is valid (exists and not expired)\n */\nexport function isTokenValid(): boolean {\n const credentials = loadToken();\n\n if (!credentials) {\n return false;\n }\n\n // Check if expired (with 60 second buffer)\n const now = Math.floor(Date.now() / 1000);\n if (credentials.expiresAt <= now + 60) {\n return false;\n }\n\n // Check if environment matches\n if (credentials.environment !== getEnvironment()) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Get the current valid token or null\n */\nexport function getValidToken(): string | null {\n if (!isTokenValid()) {\n return null;\n }\n\n const credentials = loadToken();\n return credentials?.token ?? null;\n}\n","export type Environment = \"production\" | \"staging\" | \"local\";\n\nconst HOSTS: Record<Environment, string> = {\n production: \"https://app.olakai.ai\",\n staging: \"https://staging.app.olakai.ai\",\n local: \"http://localhost:3000\",\n};\n\n// CLI client identifier\nexport const CLIENT_ID = \"olakai-cli\";\n\nlet currentEnvironment: Environment = \"production\";\n\n/**\n * Set the current environment\n */\nexport function setEnvironment(env: Environment): void {\n currentEnvironment = env;\n}\n\n/**\n * Get the current environment from:\n * 1. Environment variable OLAKAI_ENV\n * 2. Programmatically set value\n * 3. Default to \"production\"\n */\nexport function getEnvironment(): Environment {\n const envVar = process.env.OLAKAI_ENV as Environment | undefined;\n if (envVar && isValidEnvironment(envVar)) {\n return envVar;\n }\n return currentEnvironment;\n}\n\n/**\n * Get the API base URL for the current environment\n */\nexport function getBaseUrl(): string {\n return HOSTS[getEnvironment()];\n}\n\n/**\n * Check if a string is a valid environment\n */\nexport function isValidEnvironment(env: string): env is Environment {\n return env === \"production\" || env === \"staging\" || env === \"local\";\n}\n\n/**\n * Get list of valid environments for CLI help\n */\nexport function getValidEnvironments(): Environment[] {\n return [\"production\", \"staging\", \"local\"];\n}\n","/**\n * Claude Code `settings.json` hook-block helpers.\n *\n * Pure functions extracted out of the original `monitor.ts` so they\n * remain unit-testable without touching the filesystem. The dispatcher\n * is owned by `install.ts` / `uninstall.ts`.\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nexport const CLAUDE_DIR = \".claude\";\nexport const SETTINGS_FILE = \"settings.json\";\n\n/**\n * Substring used to identify Olakai-installed hook commands inside an\n * existing Claude `settings.json`. Both stop and subagent-stop entries\n * carry this marker as a prefix of the command string.\n */\nexport const OLAKAI_HOOK_MARKER = \"olakai monitor hook\";\n\nexport interface HookCommand {\n type: string;\n command: string;\n}\n\nexport interface HookMatcherEntry {\n matcher: string;\n hooks: HookCommand[];\n}\n\nexport interface ClaudeSettings {\n hooks?: Record<string, HookMatcherEntry[]>;\n [key: string]: unknown;\n}\n\nexport const HOOK_DEFINITIONS: Record<string, HookMatcherEntry[]> = {\n Stop: [\n {\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: \"olakai monitor hook stop\",\n },\n ],\n },\n ],\n SubagentStop: [\n {\n matcher: \"\",\n hooks: [\n {\n type: \"command\",\n command: \"olakai monitor hook subagent-stop\",\n },\n ],\n },\n ],\n};\n\n/**\n * Layer the Olakai default hook definitions onto an existing hooks\n * block. See the original docstring in `monitor.ts` for the merge\n * rules — preserved verbatim during the Stage 2 refactor.\n */\nexport function mergeHooksSettings(\n existing: Record<string, HookMatcherEntry[]> | undefined,\n definitions: Record<string, HookMatcherEntry[]> = HOOK_DEFINITIONS,\n): Record<string, HookMatcherEntry[]> {\n const merged: Record<string, HookMatcherEntry[]> = {\n ...(existing ?? {}),\n };\n\n for (const [event, defaultEntries] of Object.entries(definitions)) {\n const existingEntries = merged[event] ?? [];\n const hasOlakaiHook = existingEntries.some((e) =>\n e.hooks.some((h) => h.command.includes(OLAKAI_HOOK_MARKER)),\n );\n\n if (hasOlakaiHook) {\n merged[event] = existingEntries;\n } else {\n merged[event] = [...existingEntries, ...defaultEntries];\n }\n }\n\n return merged;\n}\n\nexport function getClaudeDir(projectRoot: string): string {\n return path.join(projectRoot, CLAUDE_DIR);\n}\n\nexport function getSettingsPath(projectRoot: string): string {\n return path.join(getClaudeDir(projectRoot), SETTINGS_FILE);\n}\n\nexport function readJsonFile<T>(filePath: string): T | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const content = fs.readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nexport function writeJsonFile(filePath: string, data: unknown): void {\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + \"\\n\", \"utf-8\");\n}\n","/**\n * Per-tool monitor config storage for Claude Code. Lives at\n * `.olakai/monitor-claude-code.json` (post-Stage-2). Pre-Stage-2 the\n * file lived at `.claude/olakai-monitor.json`; the auto-migration\n * shim in `monitor/migrations.ts` upgrades old workspaces transparently.\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n getMonitorConfigPath as resolveMonitorConfigPath,\n getOlakaiDir,\n} from \"../../paths.js\";\nimport { migrateLegacyClaudeConfigIfNeeded } from \"../../migrations.js\";\n\nexport interface MonitorConfig {\n agentId: string;\n apiKey: string;\n agentName: string;\n source: string;\n createdAt: string;\n monitoringEndpoint: string;\n}\n\nexport function getClaudeCodeConfigPath(projectRoot: string): string {\n return resolveMonitorConfigPath(projectRoot, \"claude-code\");\n}\n\n/**\n * Load the Claude Code monitor config. Migrates legacy\n * `.claude/olakai-monitor.json` to the new path on first read when\n * needed. `notify` is plumbed through so the hook path can pass a\n * no-op (silent), while init/status/disable use stderr.\n */\nexport function loadClaudeCodeConfig(\n projectRoot: string,\n notify?: (msg: string) => void,\n): MonitorConfig | null {\n migrateLegacyClaudeConfigIfNeeded(projectRoot, notify);\n const filePath = getClaudeCodeConfigPath(projectRoot);\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, \"utf-8\");\n return JSON.parse(raw) as MonitorConfig;\n } catch {\n return null;\n }\n}\n\nexport function writeClaudeCodeConfig(\n projectRoot: string,\n config: MonitorConfig,\n): void {\n const filePath = getClaudeCodeConfigPath(projectRoot);\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n try {\n fs.chmodSync(filePath, 0o600);\n } catch {\n // chmod failures are non-fatal — Windows / unusual filesystems\n }\n}\n\nexport function deleteClaudeCodeConfig(projectRoot: string): boolean {\n const filePath = getClaudeCodeConfigPath(projectRoot);\n if (!fs.existsSync(filePath)) return false;\n try {\n fs.unlinkSync(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Path to the directory that the new config lives in. Exposed for\n * messages like \"config saved to <dir>\".\n */\nexport function getOlakaiConfigDir(projectRoot: string): string {\n return getOlakaiDir(projectRoot);\n}\n","/**\n * Per-tool config-path resolver. Centralized so plugins, the\n * auto-migration shim, and the hook dispatcher all agree on where each\n * tool's config lives.\n *\n * Layout:\n * .olakai/\n * monitor-claude-code.json\n * monitor-codex.json\n * monitor-cursor.json\n *\n * Pre-Stage-2 layout (Claude Code only):\n * .claude/\n * olakai-monitor.json <-- migrated to the new path on first read\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { ToolId } from \"./plugin.js\";\n\nexport const OLAKAI_DIR = \".olakai\";\nexport const LEGACY_CLAUDE_DIR = \".claude\";\nexport const LEGACY_CLAUDE_CONFIG_FILE = \"olakai-monitor.json\";\n\nexport function getOlakaiDir(projectRoot: string): string {\n return path.join(projectRoot, OLAKAI_DIR);\n}\n\nexport function getMonitorConfigFileName(toolId: ToolId): string {\n return `monitor-${toolId}.json`;\n}\n\nexport function getMonitorConfigPath(\n projectRoot: string,\n toolId: ToolId,\n): string {\n return path.join(getOlakaiDir(projectRoot), getMonitorConfigFileName(toolId));\n}\n\nexport function getLegacyClaudeMonitorConfigPath(projectRoot: string): string {\n return path.join(\n projectRoot,\n LEGACY_CLAUDE_DIR,\n LEGACY_CLAUDE_CONFIG_FILE,\n );\n}\n\n/**\n * Walk up from `startDir` looking for ANY indicator that this tree was\n * configured by `olakai monitor init`. Used by the hook dispatcher to\n * locate the configured workspace independently of the calling\n * process's CWD (Claude Code, Codex, and Cursor all reserve the right\n * to spawn hooks from arbitrary directories — see INV-002).\n *\n * Returns the closest ancestor directory containing either the new\n * `.olakai/monitor-<tool>.json` file (for any tool) OR the legacy\n * `.claude/olakai-monitor.json` file. Returns null when nothing is\n * found — callers MUST treat that as silent-exit.\n *\n * Exported for unit tests.\n */\nexport function findConfiguredWorkspace(\n startDir: string,\n toolIds: readonly ToolId[],\n): string | null {\n let dir = startDir;\n while (true) {\n if (hasConfiguredMonitorIn(dir, toolIds)) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\nfunction hasConfiguredMonitorIn(\n dir: string,\n toolIds: readonly ToolId[],\n): boolean {\n for (const toolId of toolIds) {\n if (fs.existsSync(getMonitorConfigPath(dir, toolId))) {\n return true;\n }\n }\n if (fs.existsSync(getLegacyClaudeMonitorConfigPath(dir))) {\n return true;\n }\n return false;\n}\n","/**\n * Auto-migration: pre-Stage-2 layout\n * .claude/olakai-monitor.json\n * to the new per-tool layout\n * .olakai/monitor-claude-code.json\n *\n * Trigger: any read path that asks for the Claude Code monitor config.\n * If the new path is missing AND the legacy path exists, we copy the\n * legacy file's contents to the new location (preserving fields and\n * 0600 permissions) and emit a one-line notice via `notify`.\n *\n * The legacy file is intentionally NOT deleted — users may have it in\n * automation, and leaving it in place gives a clear rollback path.\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport {\n getLegacyClaudeMonitorConfigPath,\n getMonitorConfigPath,\n getOlakaiDir,\n LEGACY_CLAUDE_CONFIG_FILE,\n LEGACY_CLAUDE_DIR,\n OLAKAI_DIR,\n} from \"./paths.js\";\n\nexport type MigrationNotifier = (message: string) => void;\n\nconst defaultNotifier: MigrationNotifier = (msg) => {\n console.error(msg);\n};\n\n/**\n * If a legacy `.claude/olakai-monitor.json` exists at `projectRoot`\n * and the new `.olakai/monitor-claude-code.json` does not, copy the\n * legacy content to the new path. Returns true when a migration\n * happened, false otherwise. Never throws.\n *\n * The hook code path is silent-only — pass a no-op `notify` there so\n * we don't spam stderr (which could break Claude Code). Init/status/\n * disable use the default notifier.\n */\nexport function migrateLegacyClaudeConfigIfNeeded(\n projectRoot: string,\n notify: MigrationNotifier = defaultNotifier,\n): boolean {\n try {\n const legacyPath = getLegacyClaudeMonitorConfigPath(projectRoot);\n const newPath = getMonitorConfigPath(projectRoot, \"claude-code\");\n if (fs.existsSync(newPath)) return false;\n if (!fs.existsSync(legacyPath)) return false;\n\n const raw = fs.readFileSync(legacyPath, \"utf-8\");\n // Validate the legacy file is parseable JSON before writing — a\n // corrupt legacy file shouldn't seed a corrupt new file.\n JSON.parse(raw);\n\n const newDir = getOlakaiDir(projectRoot);\n if (!fs.existsSync(newDir)) {\n fs.mkdirSync(newDir, { recursive: true });\n }\n fs.writeFileSync(newPath, raw, \"utf-8\");\n try {\n fs.chmodSync(newPath, 0o600);\n } catch {\n // chmod can fail on Windows / weird filesystems — non-fatal\n }\n\n try {\n notify(\n `[olakai] Migrated ${path.join(LEGACY_CLAUDE_DIR, LEGACY_CLAUDE_CONFIG_FILE)} -> ${path.join(OLAKAI_DIR, \"monitor-claude-code.json\")} (legacy file kept).`,\n );\n } catch {\n // Notifier failures must not break the caller\n }\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":["path","fs","path","fs","path","fs","path","fs","path","path"]}