skillo 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -3017,7 +3017,7 @@ var trayCommand = new Command13("tray").description("Start the system tray icon"
3017
3017
  });
3018
3018
 
3019
3019
  // src/cli.ts
3020
- var VERSION = "0.2.3";
3020
+ var VERSION = "0.2.4";
3021
3021
  var program = new Command14();
3022
3022
  program.name("skillo").description(
3023
3023
  `Skillo - Learn workflows by observation, not explanation.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/utils/logger.ts","../src/commands/status.ts","../src/utils/os-service.ts","../src/commands/config.ts","../src/commands/patterns.ts","../src/commands/skills.ts","../src/commands/shell.ts","../src/commands/daemon.ts","../src/commands/session.ts","../src/commands/claude.ts","../src/commands/project.ts","../src/utils/git.ts","../src/commands/auth.ts","../src/commands/sync.ts","../src/commands/tray.ts"],"sourcesContent":["/**\n * Skillo CLI - Autonomous workflow learning & skill generation system.\n *\n * Learn workflows by observation, not explanation.\n */\n\nimport { Command } from \"commander\";\nimport {\n initCommand,\n statusCommand,\n configCommand,\n patternsCommand,\n skillsCommand,\n shellCommand,\n recordCommand,\n setupShellCommand,\n startCommand,\n stopCommand,\n logsCommand,\n sessionCommand,\n sessionAutoCommand,\n claudeCommand,\n projectCommand,\n trackCommand,\n untrackCommand,\n} from \"./commands/index.js\";\nimport { loginCommand, logoutCommand, whoamiCommand } from \"./commands/auth.js\";\nimport { syncCommand } from \"./commands/sync.js\";\nimport { serviceCommand } from \"./commands/daemon.js\";\nimport { trayCommand } from \"./commands/tray.js\";\n\nconst VERSION = \"0.2.3\";\n\nconst program = new Command();\n\nprogram\n .name(\"skillo\")\n .description(\n `Skillo - Learn workflows by observation, not explanation.\n\nObserve your terminal and Claude Code workflows, detect patterns,\nand automatically generate reusable AI skills.\n\nQuick Start:\n $ skillo init # Initialize Skillo\n $ skillo login <key> # Connect to Skillo platform\n $ skillo shell # Launch a tracked shell session\n $ skillo sync # Sync skills from platform`\n )\n .version(VERSION, \"-v, --version\", \"Show version number\")\n .option(\"--debug\", \"Enable debug output\");\n\n// Register commands\nprogram.addCommand(initCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(patternsCommand);\nprogram.addCommand(skillsCommand);\nprogram.addCommand(shellCommand);\nprogram.addCommand(recordCommand);\nprogram.addCommand(setupShellCommand);\nprogram.addCommand(startCommand);\nprogram.addCommand(stopCommand);\nprogram.addCommand(logsCommand);\n\n// Auth and sync commands\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\nprogram.addCommand(whoamiCommand);\nprogram.addCommand(syncCommand);\n\n// Session management\nprogram.addCommand(sessionCommand);\nprogram.addCommand(sessionAutoCommand);\n\n// Claude Code integration\nprogram.addCommand(claudeCommand);\n\n// Project tracking (privacy-first)\nprogram.addCommand(projectCommand);\nprogram.addCommand(trackCommand);\nprogram.addCommand(untrackCommand);\n\n// Service and tray management\nprogram.addCommand(serviceCommand);\nprogram.addCommand(trayCommand);\n\n// Version command\nprogram\n .command(\"version\")\n .description(\"Show version information\")\n .action(() => {\n console.log(`Skillo v${VERSION}`);\n console.log(\"Autonomous workflow learning & skill generation system\");\n });\n\n// Parse and execute\nprogram.parse();\n","/**\n * Initialize Skillo configuration and directories.\n */\n\nimport { existsSync } from \"fs\";\nimport { Command } from \"commander\";\nimport { getDefaultConfig, saveConfig } from \"../core/config.js\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport {\n getDataDir,\n getConfigDir,\n getSkillsDir,\n getConfigFile,\n ensureDirectory,\n} from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\n\nexport const initCommand = new Command(\"init\")\n .description(\"Initialize Skillo configuration and directories\")\n .option(\"-f, --force\", \"Overwrite existing configuration\")\n .action(async (options: { force?: boolean }) => {\n logger.blank();\n logger.bold(\"Initializing Skillo...\");\n logger.blank();\n\n const dataDir = getDataDir();\n const configDir = getConfigDir();\n const skillsDir = getSkillsDir();\n const configFile = getConfigFile();\n\n // Check if already initialized\n if (existsSync(configFile) && !options.force) {\n logger.warn(\"Skillo is already initialized.\");\n logger.dim(\"Use --force to reinitialize and overwrite configuration.\");\n return;\n }\n\n // Create directories\n const directories = [\n { path: dataDir, name: \"~/.skillo/\" },\n { path: configDir, name: \"~/.config/skillo/\" },\n { path: skillsDir, name: \"~/.claude/skills/\" },\n ];\n\n for (const { path, name } of directories) {\n if (ensureDirectory(path)) {\n logger.success(`Created ${name}`);\n } else {\n logger.dim(` [-] ${name} already exists`);\n }\n }\n\n // Create default configuration\n const config = getDefaultConfig();\n saveConfig(config);\n logger.success(\"Created default configuration\");\n\n // Initialize database\n const db = new SkilloDatabase();\n await db.initialize();\n db.close();\n logger.success(\"Initialized database\");\n\n logger.blank();\n logger.bold(\"Skillo initialized successfully!\");\n logger.blank();\n\n // Show next steps\n logger.box(\n \"Next steps:\",\n `1. Start the daemon:\n skillo start\n\n2. Use the tracked shell:\n skillo shell\n\n3. Work normally - Skillo will notify you of patterns!`\n );\n\n logger.blank();\n });\n","/**\n * Logger utilities for Skillo CLI.\n * Uses chalk for colored output.\n */\n\nimport chalk from \"chalk\";\n\nexport const logger = {\n info: (message: string) => {\n console.log(chalk.cyan(message));\n },\n\n success: (message: string) => {\n console.log(chalk.green(`[+] ${message}`));\n },\n\n warn: (message: string) => {\n console.log(chalk.yellow(`[!] ${message}`));\n },\n\n error: (message: string) => {\n console.log(chalk.red(`[x] ${message}`));\n },\n\n dim: (message: string) => {\n console.log(chalk.dim(message));\n },\n\n bold: (message: string) => {\n console.log(chalk.bold(message));\n },\n\n highlight: (message: string) => {\n console.log(chalk.bold.cyan(message));\n },\n\n // Status indicators\n running: (message: string) => {\n console.log(chalk.green(`(*) ${message}`));\n },\n\n stopped: (message: string) => {\n console.log(chalk.dim(`(-) ${message}`));\n },\n\n // For lists and tables\n item: (label: string, value: string | number) => {\n console.log(` ${chalk.dim(label)}: ${chalk.white(value)}`);\n },\n\n // Blank line\n blank: () => {\n console.log();\n },\n\n // Box/panel output\n box: (title: string, content: string) => {\n const lines = content.split(\"\\n\");\n const maxLen = Math.max(title.length, ...lines.map((l) => l.length));\n const border = \"─\".repeat(maxLen + 2);\n\n console.log(chalk.dim(`┌${border}┐`));\n console.log(chalk.dim(\"│ \") + chalk.bold(title.padEnd(maxLen)) + chalk.dim(\" │\"));\n console.log(chalk.dim(`├${border}┤`));\n lines.forEach((line) => {\n console.log(chalk.dim(\"│ \") + line.padEnd(maxLen) + chalk.dim(\" │\"));\n });\n console.log(chalk.dim(`└${border}┘`));\n },\n\n // Table output\n table: (rows: Array<[string, string | number]>) => {\n const maxLabel = Math.max(...rows.map(([label]) => label.length));\n rows.forEach(([label, value]) => {\n console.log(` ${chalk.dim(label.padEnd(maxLabel))} ${chalk.white(value)}`);\n });\n },\n};\n\nexport default logger;\n","/**\n * Show daemon status and statistics.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport { getDataDir, getPidFile, getLogFile, getDbPath } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\nimport { getServiceStatus } from \"../utils/os-service.js\";\n\nfunction isDaemonRunning(): { running: boolean; pid: number | null } {\n const pidFile = getPidFile();\n\n if (!existsSync(pidFile)) {\n return { running: false, pid: null };\n }\n\n try {\n const pidStr = readFileSync(pidFile, \"utf-8\").trim();\n const pid = parseInt(pidStr, 10);\n\n if (isNaN(pid)) {\n return { running: false, pid: null };\n }\n\n // Check if process is running\n try {\n process.kill(pid, 0);\n return { running: true, pid };\n } catch {\n // Process doesn't exist\n return { running: false, pid: null };\n }\n } catch {\n return { running: false, pid: null };\n }\n}\n\nexport const statusCommand = new Command(\"status\")\n .description(\"Show daemon status and statistics\")\n .action(async () => {\n logger.blank();\n\n const { running, pid } = isDaemonRunning();\n\n if (running) {\n logger.running(`Daemon is running (PID: ${pid})`);\n } else {\n logger.stopped(\"Daemon is not running\");\n logger.blank();\n logger.dim(\"Start with: skillo start\");\n }\n\n // Show auto-start status\n const serviceStatus = getServiceStatus();\n if (serviceStatus.daemon.installed) {\n logger.running(\"Auto-start: enabled\");\n } else {\n logger.stopped(\"Auto-start: disabled\");\n logger.dim(\" Enable with: skillo service install\");\n }\n\n if (!running) return;\n\n logger.blank();\n\n // Check if database exists\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.warn(\"Database not found. Run 'skillo init' first.\");\n return;\n }\n\n // Show statistics from database\n const db = new SkilloDatabase();\n await db.initialize();\n const stats = await db.getStats();\n db.close();\n\n logger.table([\n [\"Commands tracked (today)\", stats.commandsToday],\n [\"Commands tracked (total)\", stats.commandsTotal],\n [\"Active patterns\", stats.patternsActive],\n [\"Skills generated\", stats.skillsTotal],\n [\"Conversations analyzed\", stats.conversationsTotal],\n ]);\n\n logger.blank();\n\n // Show log tail\n const logFile = getLogFile();\n if (existsSync(logFile)) {\n logger.dim(\"Recent log entries:\");\n try {\n const content = readFileSync(logFile, \"utf-8\");\n const lines = content.split(\"\\n\").filter(Boolean).slice(-5);\n lines.forEach((line) => {\n logger.dim(` ${line}`);\n });\n } catch {\n // Ignore log read errors\n }\n }\n\n logger.blank();\n });\n","/**\n * OS Service Manager — install/uninstall auto-start services.\n *\n * macOS: LaunchAgent plist (user-level, no sudo)\n * Linux: systemd user service (no sudo)\n * Windows: Registry Run key + VBScript hidden launcher (no admin)\n *\n * Creates two services:\n * 1. Daemon service — headless background daemon\n * 2. Tray service — GUI tray icon (only in graphical sessions)\n */\n\nimport { existsSync, writeFileSync, unlinkSync, readFileSync, mkdirSync, readdirSync } from \"fs\";\nimport { join, dirname } from \"path\";\nimport { homedir, platform } from \"os\";\nimport { execSync } from \"child_process\";\n\nconst DAEMON_LABEL = \"one.skillo.daemon\";\nconst TRAY_LABEL = \"one.skillo.tray\";\n\n// Windows registry key and value names\nconst WIN_REG_KEY = \"HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\";\nconst WIN_DAEMON_VALUE = \"SkilloDaemon\";\nconst WIN_TRAY_VALUE = \"SkilloTray\";\n\nconst isWin = platform() === \"win32\";\nconst pathSep = isWin ? \";\" : \":\";\n\n// ── Path helpers ────────────────────────────────────────────────────────────\n\nfunction getLaunchAgentsDir(): string {\n return join(homedir(), \"Library\", \"LaunchAgents\");\n}\n\nfunction getSystemdUserDir(): string {\n return join(homedir(), \".config\", \"systemd\", \"user\");\n}\n\nfunction getDaemonPlistPath(): string {\n return join(getLaunchAgentsDir(), `${DAEMON_LABEL}.plist`);\n}\n\nfunction getTrayPlistPath(): string {\n return join(getLaunchAgentsDir(), `${TRAY_LABEL}.plist`);\n}\n\nfunction getDaemonServicePath(): string {\n return join(getSystemdUserDir(), \"skillo-daemon.service\");\n}\n\nfunction getTrayServicePath(): string {\n return join(getSystemdUserDir(), \"skillo-tray.service\");\n}\n\n/** Get the ~/.skillo/ directory for placing Windows launcher scripts */\nfunction getSkilloDataDir(): string {\n return join(homedir(), \".skillo\");\n}\n\nfunction getWinDaemonVbsPath(): string {\n return join(getSkilloDataDir(), \"skillo-daemon.vbs\");\n}\n\n/** Find the skillo binary path */\nfunction findSkilloBin(): string {\n try {\n const whichCmd = isWin ? \"where skillo\" : \"which skillo\";\n const result = execSync(whichCmd, { encoding: \"utf-8\" }).trim();\n // `where` on Windows can return multiple lines; take the first\n const firstLine = result.split(/\\r?\\n/)[0].trim();\n if (firstLine) return firstLine;\n } catch {\n // fallback\n }\n\n if (isWin) {\n // Common Windows locations\n const appData = process.env.APPDATA || join(homedir(), \"AppData\", \"Roaming\");\n const candidates = [\n join(appData, \"npm\", \"skillo.cmd\"),\n join(homedir(), \"AppData\", \"Local\", \"fnm_multishells\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n } else {\n const candidates = [\n \"/usr/local/bin/skillo\",\n \"/usr/bin/skillo\",\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n }\n\n return \"skillo\"; // Rely on PATH\n}\n\n/** Build a broad PATH that includes common Node.js install locations */\nfunction buildPath(): string {\n const paths = new Set<string>();\n const home = homedir();\n\n // Current PATH\n (process.env.PATH || \"\").split(pathSep).forEach((p) => paths.add(p));\n\n if (isWin) {\n // Windows-specific Node.js locations\n const appData = process.env.APPDATA || join(home, \"AppData\", \"Roaming\");\n paths.add(join(appData, \"npm\"));\n paths.add(join(home, \"AppData\", \"Local\", \"Programs\", \"nodejs\"));\n\n // nvm-windows\n const nvmHome = process.env.NVM_HOME;\n if (nvmHome) paths.add(nvmHome);\n const nvmSymlink = process.env.NVM_SYMLINK;\n if (nvmSymlink) paths.add(nvmSymlink);\n\n // fnm on Windows\n const fnmDir = join(home, \".fnm\");\n if (existsSync(fnmDir)) paths.add(fnmDir);\n } else {\n // nvm (macOS/Linux)\n const nvmDir = process.env.NVM_DIR || join(home, \".nvm\");\n if (existsSync(nvmDir)) {\n try {\n const defaultAlias = join(nvmDir, \"alias\", \"default\");\n if (existsSync(defaultAlias)) {\n const versionsDir = join(nvmDir, \"versions\", \"node\");\n if (existsSync(versionsDir)) {\n const versions = readdirSync(versionsDir) as string[];\n for (const v of versions) {\n paths.add(join(versionsDir, v, \"bin\"));\n }\n }\n }\n } catch {\n // ignore\n }\n }\n\n // fnm\n paths.add(join(home, \".fnm\", \"current\", \"bin\"));\n\n // Homebrew\n paths.add(\"/opt/homebrew/bin\");\n paths.add(\"/usr/local/bin\");\n\n // Standard\n paths.add(\"/usr/bin\");\n paths.add(\"/bin\");\n\n // npm global\n paths.add(join(home, \".npm-global\", \"bin\"));\n paths.add(join(home, \".local\", \"bin\"));\n }\n\n return [...paths].filter(Boolean).join(pathSep);\n}\n\n// ── macOS LaunchAgent ───────────────────────────────────────────────────────\n\nfunction generateDaemonPlist(skilloBin: string, envPath: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${DAEMON_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${skilloBin}</string>\n <string>start</string>\n <string>--foreground</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n <string>${envPath}</string>\n <key>HOME</key>\n <string>${homedir()}</string>\n </dict>\n <key>StandardOutPath</key>\n <string>${join(homedir(), \".skillo\", \"launchd-stdout.log\")}</string>\n <key>StandardErrorPath</key>\n <string>${join(homedir(), \".skillo\", \"launchd-stderr.log\")}</string>\n</dict>\n</plist>`;\n}\n\nfunction generateTrayPlist(skilloBin: string, envPath: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${TRAY_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${skilloBin}</string>\n <string>tray</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>LimitLoadToSessionType</key>\n <string>Aqua</string>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n <string>${envPath}</string>\n <key>HOME</key>\n <string>${homedir()}</string>\n </dict>\n <key>StandardOutPath</key>\n <string>${join(homedir(), \".skillo\", \"launchd-tray-stdout.log\")}</string>\n <key>StandardErrorPath</key>\n <string>${join(homedir(), \".skillo\", \"launchd-tray-stderr.log\")}</string>\n</dict>\n</plist>`;\n}\n\n// ── Linux systemd ───────────────────────────────────────────────────────────\n\nfunction generateDaemonUnit(skilloBin: string, envPath: string): string {\n return `[Unit]\nDescription=Skillo Daemon\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=${skilloBin} start --foreground\nRestart=on-failure\nRestartSec=10\nEnvironment=PATH=${envPath}\nEnvironment=HOME=${homedir()}\n\n[Install]\nWantedBy=default.target\n`;\n}\n\nfunction generateTrayUnit(skilloBin: string, envPath: string): string {\n return `[Unit]\nDescription=Skillo Tray Icon\nAfter=graphical-session.target\nPartOf=graphical-session.target\n\n[Service]\nType=simple\nExecStart=${skilloBin} tray\nRestart=on-failure\nRestartSec=10\nEnvironment=PATH=${envPath}\nEnvironment=HOME=${homedir()}\nEnvironment=DISPLAY=:0\n\n[Install]\nWantedBy=graphical-session.target\n`;\n}\n\n// ── Windows Registry + VBScript ─────────────────────────────────────────────\n\n/**\n * Generate a VBScript that runs the daemon hidden (no console window).\n * WScript.Shell Run(..., 0, False) → windowStyle=hidden, waitOnReturn=false.\n */\nfunction generateDaemonVbs(skilloBin: string): string {\n // Escape backslashes for VBS string literal\n const escaped = skilloBin.replace(/\\\\/g, \"\\\\\\\\\");\n return `' Skillo Daemon — hidden launcher\\r\\nSet WshShell = CreateObject(\"WScript.Shell\")\\r\\nWshShell.Run \"\"\"${escaped}\"\" start --foreground\", 0, False\\r\\n`;\n}\n\nfunction winRegAdd(valueName: string, data: string) {\n // /f = force overwrite without prompt\n execSync(\n `reg add \"${WIN_REG_KEY}\" /v \"${valueName}\" /t REG_SZ /d \"${data}\" /f`,\n { stdio: \"ignore\" }\n );\n}\n\nfunction winRegDelete(valueName: string) {\n try {\n execSync(\n `reg delete \"${WIN_REG_KEY}\" /v \"${valueName}\" /f`,\n { stdio: \"ignore\" }\n );\n } catch {\n // Value may not exist\n }\n}\n\nfunction winRegExists(valueName: string): boolean {\n try {\n execSync(`reg query \"${WIN_REG_KEY}\" /v \"${valueName}\"`, { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\n// ── Public API ──────────────────────────────────────────────────────────────\n\nexport interface ServiceStatus {\n platform: \"macos\" | \"linux\" | \"windows\" | \"unsupported\";\n daemon: { installed: boolean; loaded: boolean };\n tray: { installed: boolean; loaded: boolean };\n}\n\nexport async function installService(options?: { includeTray?: boolean }): Promise<{ success: boolean; error?: string }> {\n const os = platform();\n const skilloBin = findSkilloBin();\n const envPath = buildPath();\n const includeTray = options?.includeTray ?? true;\n\n try {\n if (os === \"darwin\") {\n // ── macOS LaunchAgent ──\n const agentsDir = getLaunchAgentsDir();\n if (!existsSync(agentsDir)) mkdirSync(agentsDir, { recursive: true });\n\n // Daemon\n const daemonPlist = getDaemonPlistPath();\n writeFileSync(daemonPlist, generateDaemonPlist(skilloBin, envPath), \"utf-8\");\n try { execSync(`launchctl unload \"${daemonPlist}\" 2>/dev/null`); } catch { /* ignore */ }\n execSync(`launchctl load \"${daemonPlist}\"`);\n\n // Tray\n if (includeTray) {\n const trayPlist = getTrayPlistPath();\n writeFileSync(trayPlist, generateTrayPlist(skilloBin, envPath), \"utf-8\");\n try { execSync(`launchctl unload \"${trayPlist}\" 2>/dev/null`); } catch { /* ignore */ }\n execSync(`launchctl load \"${trayPlist}\"`);\n }\n\n return { success: true };\n\n } else if (os === \"linux\") {\n // ── Linux systemd ──\n const systemdDir = getSystemdUserDir();\n if (!existsSync(systemdDir)) mkdirSync(systemdDir, { recursive: true });\n\n // Daemon\n writeFileSync(getDaemonServicePath(), generateDaemonUnit(skilloBin, envPath), \"utf-8\");\n execSync(\"systemctl --user daemon-reload\");\n execSync(\"systemctl --user enable skillo-daemon.service\");\n execSync(\"systemctl --user start skillo-daemon.service\");\n\n // Tray\n if (includeTray) {\n writeFileSync(getTrayServicePath(), generateTrayUnit(skilloBin, envPath), \"utf-8\");\n execSync(\"systemctl --user daemon-reload\");\n execSync(\"systemctl --user enable skillo-tray.service\");\n try { execSync(\"systemctl --user start skillo-tray.service\"); } catch { /* may not have graphical session */ }\n }\n\n return { success: true };\n\n } else if (os === \"win32\") {\n // ── Windows Registry Run + VBScript ──\n const dataDir = getSkilloDataDir();\n if (!existsSync(dataDir)) mkdirSync(dataDir, { recursive: true });\n\n // Daemon: write a VBScript launcher that hides the console window,\n // then point the registry Run key at the VBS file.\n const vbsPath = getWinDaemonVbsPath();\n writeFileSync(vbsPath, generateDaemonVbs(skilloBin), \"utf-8\");\n winRegAdd(WIN_DAEMON_VALUE, `wscript.exe \"${vbsPath}\"`);\n\n // Tray: runs directly (it has its own window)\n if (includeTray) {\n winRegAdd(WIN_TRAY_VALUE, `\"${skilloBin}\" tray`);\n }\n\n return { success: true };\n\n } else {\n return { success: false, error: `Unsupported platform: ${os}. Auto-start is available on macOS, Linux, and Windows.` };\n }\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n}\n\nexport async function uninstallService(): Promise<{ success: boolean; error?: string }> {\n const os = platform();\n\n try {\n if (os === \"darwin\") {\n // Unload and remove daemon\n const daemonPlist = getDaemonPlistPath();\n if (existsSync(daemonPlist)) {\n try { execSync(`launchctl unload \"${daemonPlist}\" 2>/dev/null`); } catch { /* ignore */ }\n unlinkSync(daemonPlist);\n }\n\n // Unload and remove tray\n const trayPlist = getTrayPlistPath();\n if (existsSync(trayPlist)) {\n try { execSync(`launchctl unload \"${trayPlist}\" 2>/dev/null`); } catch { /* ignore */ }\n unlinkSync(trayPlist);\n }\n\n return { success: true };\n\n } else if (os === \"linux\") {\n // Stop, disable, remove daemon\n const daemonService = getDaemonServicePath();\n if (existsSync(daemonService)) {\n try { execSync(\"systemctl --user stop skillo-daemon.service 2>/dev/null\"); } catch { /* ignore */ }\n try { execSync(\"systemctl --user disable skillo-daemon.service 2>/dev/null\"); } catch { /* ignore */ }\n unlinkSync(daemonService);\n }\n\n // Stop, disable, remove tray\n const trayService = getTrayServicePath();\n if (existsSync(trayService)) {\n try { execSync(\"systemctl --user stop skillo-tray.service 2>/dev/null\"); } catch { /* ignore */ }\n try { execSync(\"systemctl --user disable skillo-tray.service 2>/dev/null\"); } catch { /* ignore */ }\n unlinkSync(trayService);\n }\n\n try { execSync(\"systemctl --user daemon-reload\"); } catch { /* ignore */ }\n\n return { success: true };\n\n } else if (os === \"win32\") {\n // Remove registry entries\n winRegDelete(WIN_DAEMON_VALUE);\n winRegDelete(WIN_TRAY_VALUE);\n\n // Remove VBS launcher\n const vbsPath = getWinDaemonVbsPath();\n if (existsSync(vbsPath)) {\n try { unlinkSync(vbsPath); } catch { /* ignore */ }\n }\n\n return { success: true };\n\n } else {\n return { success: false, error: `Unsupported platform: ${os}` };\n }\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n}\n\nexport function getServiceStatus(): ServiceStatus {\n const os = platform();\n\n if (os === \"darwin\") {\n const daemonInstalled = existsSync(getDaemonPlistPath());\n const trayInstalled = existsSync(getTrayPlistPath());\n\n let daemonLoaded = false;\n let trayLoaded = false;\n\n try {\n const output = execSync(\"launchctl list\", { encoding: \"utf-8\" });\n daemonLoaded = output.includes(DAEMON_LABEL);\n trayLoaded = output.includes(TRAY_LABEL);\n } catch {\n // ignore\n }\n\n return {\n platform: \"macos\",\n daemon: { installed: daemonInstalled, loaded: daemonLoaded },\n tray: { installed: trayInstalled, loaded: trayLoaded },\n };\n\n } else if (os === \"linux\") {\n const daemonInstalled = existsSync(getDaemonServicePath());\n const trayInstalled = existsSync(getTrayServicePath());\n\n let daemonLoaded = false;\n let trayLoaded = false;\n\n try {\n execSync(\"systemctl --user is-active skillo-daemon.service\", { encoding: \"utf-8\" });\n daemonLoaded = true;\n } catch { /* not active */ }\n\n try {\n execSync(\"systemctl --user is-active skillo-tray.service\", { encoding: \"utf-8\" });\n trayLoaded = true;\n } catch { /* not active */ }\n\n return {\n platform: \"linux\",\n daemon: { installed: daemonInstalled, loaded: daemonLoaded },\n tray: { installed: trayInstalled, loaded: trayLoaded },\n };\n\n } else if (os === \"win32\") {\n const daemonInstalled = winRegExists(WIN_DAEMON_VALUE);\n const trayInstalled = winRegExists(WIN_TRAY_VALUE);\n\n // On Windows, \"loaded\" = the Run key exists (it will run at next login).\n // We can't easily check if the process is currently running from the registry\n // alone, but the key existing means it *will* auto-start.\n return {\n platform: \"windows\",\n daemon: { installed: daemonInstalled, loaded: daemonInstalled },\n tray: { installed: trayInstalled, loaded: trayInstalled },\n };\n }\n\n return {\n platform: \"unsupported\",\n daemon: { installed: false, loaded: false },\n tray: { installed: false, loaded: false },\n };\n}\n","/**\n * Configuration management commands.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport YAML from \"yaml\";\nimport {\n loadConfig,\n saveConfig,\n getDefaultConfig,\n getConfigValue,\n setConfigValue,\n} from \"../core/config.js\";\nimport { getConfigFile } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\n\nexport const configCommand = new Command(\"config\").description(\n \"Manage Skillo configuration\"\n);\n\n// skillo config show\nconfigCommand\n .command(\"show\")\n .description(\"Show current configuration\")\n .action(async () => {\n const configFile = getConfigFile();\n\n if (!existsSync(configFile)) {\n logger.error(\"Configuration not found.\");\n logger.dim(\"Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const content = readFileSync(configFile, \"utf-8\");\n\n logger.blank();\n logger.bold(`Configuration file: ${configFile}`);\n logger.blank();\n console.log(content);\n });\n\n// skillo config get <key>\nconfigCommand\n .command(\"get <key>\")\n .description(\"Get a configuration value (use dot notation, e.g., patternDetection.minCount)\")\n .action(async (key: string) => {\n const configFile = getConfigFile();\n\n if (!existsSync(configFile)) {\n logger.error(\"Configuration not found.\");\n process.exit(1);\n }\n\n const config = loadConfig();\n const value = getConfigValue(config, key);\n\n if (value === undefined) {\n logger.error(`Key not found: ${key}`);\n process.exit(1);\n }\n\n if (typeof value === \"object\") {\n console.log(YAML.stringify(value));\n } else {\n console.log(String(value));\n }\n });\n\n// skillo config set <key> <value>\nconfigCommand\n .command(\"set <key> <value>\")\n .description(\"Set a configuration value\")\n .action(async (key: string, value: string) => {\n const configFile = getConfigFile();\n\n if (!existsSync(configFile)) {\n logger.error(\"Configuration not found.\");\n process.exit(1);\n }\n\n let config = loadConfig();\n\n // Parse value\n let parsedValue: unknown;\n if (value.toLowerCase() === \"true\") {\n parsedValue = true;\n } else if (value.toLowerCase() === \"false\") {\n parsedValue = false;\n } else if (/^\\d+$/.test(value)) {\n parsedValue = parseInt(value, 10);\n } else if (/^\\d+\\.\\d+$/.test(value)) {\n parsedValue = parseFloat(value);\n } else {\n parsedValue = value;\n }\n\n const oldValue = getConfigValue(config, key);\n config = setConfigValue(config, key, parsedValue);\n saveConfig(config);\n\n logger.success(`Updated ${key}`);\n if (oldValue !== undefined) {\n logger.dim(` ${oldValue} -> ${parsedValue}`);\n } else {\n logger.dim(` ${parsedValue}`);\n }\n });\n\n// skillo config reset\nconfigCommand\n .command(\"reset\")\n .description(\"Reset configuration to defaults\")\n .option(\"-f, --force\", \"Skip confirmation prompt\")\n .action(async (options: { force?: boolean }) => {\n if (!options.force) {\n logger.warn(\"This will reset all configuration to defaults.\");\n logger.dim(\"Use --force to confirm.\");\n return;\n }\n\n const defaultConfig = getDefaultConfig();\n saveConfig(defaultConfig);\n\n logger.success(\"Configuration reset to defaults\");\n });\n\n// skillo config path\nconfigCommand\n .command(\"path\")\n .description(\"Show configuration file path\")\n .action(async () => {\n console.log(getConfigFile());\n });\n","/**\n * Pattern management commands.\n */\n\nimport { existsSync } from \"fs\";\nimport { Command } from \"commander\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport { getDbPath } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\nimport chalk from \"chalk\";\n\nexport const patternsCommand = new Command(\"patterns\").description(\n \"Manage detected workflow patterns\"\n);\n\n// skillo patterns list\npatternsCommand\n .command(\"list\")\n .description(\"List detected patterns\")\n .option(\"-t, --type <type>\", \"Filter by type (terminal, conversation)\")\n .option(\"-s, --status <status>\", \"Filter by status (active, converted, ignored)\")\n .option(\"-n, --limit <number>\", \"Number of patterns to show\", \"20\")\n .action(async (options: { type?: string; status?: string; limit: string }) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const patterns = await db.getPatterns({\n type: options.type,\n status: options.status || \"active\",\n limit: parseInt(options.limit, 10),\n });\n db.close();\n\n if (patterns.length === 0) {\n logger.blank();\n logger.dim(\"No patterns found.\");\n logger.blank();\n logger.dim(\"Patterns are detected automatically when you use the tracked shell.\");\n logger.dim(\"Run 'skillo shell' to start tracking commands.\");\n return;\n }\n\n logger.blank();\n logger.bold(`Found ${patterns.length} pattern(s):`);\n logger.blank();\n\n patterns.forEach((pattern, index) => {\n const shortId = pattern.id.slice(0, 8);\n const statusColor =\n pattern.status === \"active\"\n ? chalk.green\n : pattern.status === \"converted\"\n ? chalk.blue\n : chalk.dim;\n\n console.log(\n ` ${chalk.cyan(shortId)} ${chalk.white(pattern.description)} ` +\n `${chalk.dim(`x${pattern.count}`)} ${statusColor(pattern.status)}`\n );\n });\n\n logger.blank();\n logger.dim(\"Use 'skillo patterns show <id>' for details\");\n logger.dim(\"Use 'skillo patterns generate <id>' to create a skill\");\n logger.blank();\n });\n\n// skillo patterns show <id>\npatternsCommand\n .command(\"show <id>\")\n .description(\"Show pattern details\")\n .action(async (id: string) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const pattern = await db.getPattern(id);\n db.close();\n\n if (!pattern) {\n logger.error(`Pattern not found: ${id}`);\n process.exit(1);\n }\n\n logger.blank();\n logger.bold(pattern.description);\n logger.blank();\n\n logger.table([\n [\"ID\", pattern.id],\n [\"Type\", pattern.sourceType],\n [\"Status\", pattern.status],\n [\"Occurrences\", pattern.count],\n [\"First seen\", new Date(pattern.firstSeen).toLocaleString()],\n [\"Last seen\", new Date(pattern.lastSeen).toLocaleString()],\n ]);\n\n logger.blank();\n\n // Show pattern data\n if (pattern.data.commands && Array.isArray(pattern.data.commands)) {\n logger.bold(\"Commands:\");\n pattern.data.commands.forEach((cmd: string, i: number) => {\n console.log(` ${chalk.dim(`${i + 1}.`)} ${cmd}`);\n });\n logger.blank();\n }\n\n if (pattern.data.description) {\n logger.bold(\"Description:\");\n logger.dim(` ${pattern.data.description}`);\n logger.blank();\n }\n\n logger.dim(\"Actions:\");\n logger.dim(` skillo patterns generate ${id.slice(0, 8)} # Create a skill`);\n logger.dim(` skillo patterns ignore ${id.slice(0, 8)} # Never suggest again`);\n logger.blank();\n });\n\n// skillo patterns ignore <id>\npatternsCommand\n .command(\"ignore <id>\")\n .description(\"Ignore a pattern (never suggest again)\")\n .option(\"-r, --reason <reason>\", \"Reason for ignoring\")\n .action(async (id: string, options: { reason?: string }) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const pattern = await db.getPattern(id);\n\n if (!pattern) {\n db.close();\n logger.error(`Pattern not found: ${id}`);\n process.exit(1);\n }\n\n await db.updatePatternStatus(id, \"ignored\");\n await db.addIgnoredPattern(pattern.id, options.reason);\n db.close();\n\n logger.success(`Pattern ignored: ${id.slice(0, 8)}`);\n if (options.reason) {\n logger.dim(` Reason: ${options.reason}`);\n }\n });\n\n// skillo patterns generate <id>\npatternsCommand\n .command(\"generate <id>\")\n .description(\"Generate a skill from a pattern\")\n .option(\"-n, --name <name>\", \"Custom skill name\")\n .option(\"--dry-run\", \"Preview without creating\")\n .action(async (id: string, options: { name?: string; dryRun?: boolean }) => {\n // Dynamic import to avoid circular deps\n const { getApiClient } = await import(\"../core/api-client.js\");\n const { writeFileSync, mkdirSync } = await import(\"fs\");\n const { join } = await import(\"path\");\n const { getSkillsDir, ensureDirectory } = await import(\"../utils/paths.js\");\n\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const pattern = await db.getPattern(id);\n\n if (!pattern) {\n db.close();\n logger.error(`Pattern not found: ${id}`);\n process.exit(1);\n }\n\n logger.blank();\n logger.bold(pattern.description);\n logger.blank();\n\n // Check if logged in\n const client = getApiClient();\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n logger.dim(\"Skill generation requires the Skillo platform.\");\n db.close();\n process.exit(1);\n }\n\n logger.info(\"Generating skill via Skillo platform...\");\n\n if (options.dryRun) {\n logger.dim(\"(dry run - skill will not be saved)\");\n }\n\n logger.blank();\n\n // Call the platform API to generate the skill\n const result = await client.generateSkill({\n commands: (pattern.data.commands as string[]) || [],\n name: options.name,\n description: pattern.description,\n category: pattern.sourceType === \"terminal\" ? \"system\" : \"other\",\n context: pattern.data as Record<string, unknown>,\n });\n\n if (!result.success || !result.data) {\n logger.error(\"Failed to generate skill: \" + (result.error || \"Unknown error\"));\n db.close();\n process.exit(1);\n }\n\n const skill = result.data.skill;\n\n logger.success(`Generated skill: ${skill.name}`);\n logger.blank();\n\n if (options.dryRun) {\n logger.bold(\"Generated SKILL.md:\");\n logger.blank();\n console.log(skill.content);\n logger.blank();\n logger.dim(\"(dry run - skill not saved)\");\n } else {\n // Write skill to ~/.claude/skills/\n const skillsDir = getSkillsDir();\n ensureDirectory(skillsDir);\n\n const skillDir = join(skillsDir, skill.slug);\n const skillFile = join(skillDir, \"SKILL.md\");\n\n mkdirSync(skillDir, { recursive: true });\n writeFileSync(skillFile, skill.content, \"utf-8\");\n\n // Update pattern status in local DB\n await db.updatePatternStatus(id, \"converted\");\n\n logger.success(`Skill saved to: ~/.claude/skills/${skill.slug}/SKILL.md`);\n logger.blank();\n logger.dim(\"The skill is now available to Claude Code!\");\n }\n\n db.close();\n });\n\n// skillo patterns clear\npatternsCommand\n .command(\"clear\")\n .description(\"Clear all patterns\")\n .option(\"-f, --force\", \"Skip confirmation\")\n .action(async (options: { force?: boolean }) => {\n if (!options.force) {\n logger.warn(\"This will delete all detected patterns.\");\n logger.dim(\"Use --force to confirm.\");\n return;\n }\n\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found.\");\n process.exit(1);\n }\n\n // TODO: Implement clear\n logger.success(\"All patterns cleared.\");\n });\n","/**\n * Skill management commands.\n */\n\nimport { existsSync, readdirSync, rmSync } from \"fs\";\nimport { join, basename } from \"path\";\nimport { Command } from \"commander\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport { getDbPath, getSkillsDir } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\nimport chalk from \"chalk\";\n\nexport const skillsCommand = new Command(\"skills\").description(\n \"Manage generated skills\"\n);\n\n// skillo skills list\nskillsCommand\n .command(\"list\")\n .description(\"List all skills\")\n .option(\"-s, --source <source>\", \"Filter by source (pattern, imported, manual)\")\n .option(\"--sort <by>\", \"Sort by (name, created, usage)\", \"name\")\n .action(async (options: { source?: string; sort: \"name\" | \"created\" | \"usage\" }) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const skills = await db.getSkills({\n source: options.source,\n sortBy: options.sort,\n });\n db.close();\n\n // Also check filesystem for skills not in DB\n const skillsDir = getSkillsDir();\n const fsSkills: string[] = [];\n if (existsSync(skillsDir)) {\n const entries = readdirSync(skillsDir, { withFileTypes: true });\n entries\n .filter((e) => e.isDirectory() && !e.name.startsWith(\".\"))\n .forEach((e) => {\n const skillMd = join(skillsDir, e.name, \"SKILL.md\");\n if (existsSync(skillMd)) {\n fsSkills.push(e.name);\n }\n });\n }\n\n const dbSkillNames = new Set(skills.map((s) => s.name));\n const unregisteredSkills = fsSkills.filter((name) => !dbSkillNames.has(name));\n\n if (skills.length === 0 && unregisteredSkills.length === 0) {\n logger.blank();\n logger.dim(\"No skills found.\");\n logger.blank();\n logger.dim(\"Generate skills from patterns with 'skillo patterns generate <id>'\");\n logger.dim(\"Or import skills with 'skillo skills import <path>'\");\n return;\n }\n\n logger.blank();\n logger.bold(`Skills (${skills.length + unregisteredSkills.length}):`);\n logger.blank();\n\n // Registered skills\n skills.forEach((skill) => {\n const sourceColor =\n skill.sourceType === \"pattern\"\n ? chalk.green\n : skill.sourceType === \"imported\"\n ? chalk.blue\n : chalk.dim;\n\n console.log(\n ` ${chalk.cyan(skill.name)} ` +\n `${sourceColor(skill.sourceType)} ` +\n `${chalk.dim(`used ${skill.usageCount}x`)}`\n );\n\n if (skill.triggerPhrase) {\n console.log(` ${chalk.dim(skill.triggerPhrase)}`);\n }\n });\n\n // Unregistered skills (found on filesystem but not in DB)\n if (unregisteredSkills.length > 0) {\n logger.blank();\n logger.dim(\" Unregistered skills (found in ~/.claude/skills/):\");\n unregisteredSkills.forEach((name) => {\n console.log(` ${chalk.yellow(name)} ${chalk.dim(\"filesystem only\")}`);\n });\n }\n\n logger.blank();\n logger.dim(\"Use 'skillo skills show <name>' for details\");\n logger.blank();\n });\n\n// skillo skills show <name>\nskillsCommand\n .command(\"show <name>\")\n .description(\"Show skill details\")\n .action(async (name: string) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const skill = await db.getSkill(name);\n db.close();\n\n if (!skill) {\n // Check if it exists on filesystem\n const skillPath = join(getSkillsDir(), name, \"SKILL.md\");\n if (existsSync(skillPath)) {\n logger.blank();\n logger.bold(name);\n logger.blank();\n logger.dim(` Path: ${join(getSkillsDir(), name)}`);\n logger.dim(` Status: Not registered in database`);\n logger.blank();\n return;\n }\n\n logger.error(`Skill not found: ${name}`);\n process.exit(1);\n }\n\n logger.blank();\n logger.bold(skill.name);\n logger.blank();\n\n logger.table([\n [\"Path\", skill.path],\n [\"Source\", skill.sourceType],\n [\"Created\", new Date(skill.createdAt).toLocaleString()],\n [\"Usage count\", skill.usageCount],\n [\"Last used\", skill.lastUsedAt ? new Date(skill.lastUsedAt).toLocaleString() : \"Never\"],\n ]);\n\n if (skill.triggerPhrase) {\n logger.blank();\n logger.bold(\"Trigger phrase:\");\n logger.dim(` ${skill.triggerPhrase}`);\n }\n\n logger.blank();\n });\n\n// skillo skills delete <name>\nskillsCommand\n .command(\"delete <name>\")\n .description(\"Delete a skill\")\n .option(\"-f, --force\", \"Skip confirmation\")\n .action(async (name: string, options: { force?: boolean }) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const skill = await db.getSkill(name);\n\n const skillDir = skill?.path || join(getSkillsDir(), name);\n\n if (!skill && !existsSync(skillDir)) {\n db.close();\n logger.error(`Skill not found: ${name}`);\n process.exit(1);\n }\n\n if (!options.force) {\n logger.warn(`This will delete skill '${name}'. This cannot be undone.`);\n logger.dim(\"Use --force to confirm.\");\n db.close();\n return;\n }\n\n // Delete from filesystem\n if (existsSync(skillDir)) {\n rmSync(skillDir, { recursive: true, force: true });\n }\n\n // Delete from database\n if (skill) {\n await db.deleteSkill(name);\n }\n\n db.close();\n\n logger.success(`Skill deleted: ${name}`);\n });\n\n// skillo skills path\nskillsCommand\n .command(\"path\")\n .description(\"Show skills directory path\")\n .action(async () => {\n console.log(getSkillsDir());\n });\n\n// skillo skills open\nskillsCommand\n .command(\"open\")\n .description(\"Open skills directory in file manager\")\n .action(async () => {\n const skillsDir = getSkillsDir();\n\n if (!existsSync(skillsDir)) {\n logger.error(\"Skills directory not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n // Open in file manager based on platform\n const { exec } = await import(\"child_process\");\n const command =\n process.platform === \"win32\"\n ? `explorer \"${skillsDir}\"`\n : process.platform === \"darwin\"\n ? `open \"${skillsDir}\"`\n : `xdg-open \"${skillsDir}\"`;\n\n exec(command, (error) => {\n if (error) {\n logger.error(`Failed to open directory: ${error.message}`);\n logger.dim(`Path: ${skillsDir}`);\n }\n });\n });\n","/**\n * Shell command - Start a tracked terminal session.\n */\n\nimport { existsSync, writeFileSync, readFileSync, appendFileSync } from \"fs\";\nimport { spawn } from \"child_process\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\nimport { Command } from \"commander\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport { loadConfig } from \"../core/config.js\";\nimport { getDbPath, getConfigFile, ensureDirectory, getDataDir } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\n\n/**\n * Normalize a command by replacing variable parts with placeholders.\n * This helps with pattern detection.\n */\nfunction normalizeCommand(cmd: string): { normalized: string; variables: Record<string, string> } {\n const variables: Record<string, string> = {};\n let normalized = cmd;\n let varIndex = 0;\n\n // Replace file paths\n normalized = normalized.replace(/(?:^|\\s)(\\/[\\w\\-.\\/]+)/g, (match, path) => {\n const key = `$PATH${varIndex++}`;\n variables[key] = path;\n return match.replace(path, key);\n });\n\n // Replace URLs\n normalized = normalized.replace(\n /https?:\\/\\/[^\\s]+/g,\n (match) => {\n const key = `$URL${varIndex++}`;\n variables[key] = match;\n return key;\n }\n );\n\n // Replace numbers (but not in common commands)\n normalized = normalized.replace(/\\b\\d{4,}\\b/g, (match) => {\n const key = `$NUM${varIndex++}`;\n variables[key] = match;\n return key;\n });\n\n // Replace quoted strings\n normalized = normalized.replace(/\"[^\"]+\"/g, (match) => {\n const key = `$STR${varIndex++}`;\n variables[key] = match;\n return key;\n });\n\n normalized = normalized.replace(/'[^']+'/g, (match) => {\n const key = `$STR${varIndex++}`;\n variables[key] = match;\n return key;\n });\n\n return { normalized: normalized.trim(), variables };\n}\n\nexport const shellCommand = new Command(\"shell\")\n .description(\"Start a tracked terminal session\")\n .option(\"-s, --shell <shell>\", \"Shell to use (default: $SHELL or cmd on Windows)\")\n .option(\"-p, --project <path>\", \"Project path to track\")\n .action(async (options: { shell?: string; project?: string }) => {\n // Check if initialized\n if (!existsSync(getConfigFile())) {\n logger.error(\"Skillo not initialized. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const config = loadConfig();\n\n // Determine shell to use\n let shell = options.shell || config.defaultShell;\n if (!shell) {\n if (process.platform === \"win32\") {\n shell = process.env.COMSPEC || \"cmd.exe\";\n } else {\n shell = process.env.SHELL || \"/bin/bash\";\n }\n }\n\n const projectPath = options.project || process.cwd();\n\n logger.blank();\n logger.info(\"Starting tracked shell session...\");\n logger.dim(`Shell: ${shell}`);\n logger.dim(`Project: ${projectPath}`);\n logger.blank();\n logger.dim(\"All commands will be tracked. Type 'exit' to end the session.\");\n logger.blank();\n\n // Initialize database and create session\n const db = new SkilloDatabase();\n await db.initialize();\n const sessionId = await db.createSession(shell, projectPath);\n\n let commandCount = 0;\n let currentCommand = \"\";\n let commandStartTime: number | null = null;\n\n // Spawn shell process\n const shellArgs = process.platform === \"win32\" ? [] : [\"-i\"];\n\n const child = spawn(shell, shellArgs, {\n stdio: [\"inherit\", \"inherit\", \"inherit\"],\n shell: false,\n cwd: projectPath,\n env: {\n ...process.env,\n SKILLO_SESSION: sessionId,\n SKILLO_TRACKING: \"1\",\n },\n });\n\n // Handle shell exit\n child.on(\"exit\", async (code) => {\n await db.endSession(sessionId);\n db.close();\n\n logger.blank();\n logger.success(`Session ended. Tracked ${commandCount} command(s).`);\n logger.dim(`Session ID: ${sessionId.slice(0, 8)}`);\n logger.blank();\n\n process.exit(code || 0);\n });\n\n // Handle errors\n child.on(\"error\", async (error) => {\n logger.error(`Failed to start shell: ${error.message}`);\n await db.endSession(sessionId);\n db.close();\n process.exit(1);\n });\n\n // Note: For proper command tracking, we would need to use node-pty\n // or integrate with shell hooks (like bash PROMPT_COMMAND or zsh precmd)\n // This basic implementation spawns an interactive shell but doesn't\n // capture individual commands without additional shell integration.\n\n // For now, we'll rely on shell integration scripts that users can install\n // to send commands to Skillo via a local API or file-based IPC.\n });\n\n// Additional command to record a command (called by shell integration)\nexport const recordCommand = new Command(\"record\")\n .description(\"Record a command (used by shell integration)\")\n .argument(\"<command>\", \"Command that was executed\")\n .option(\"--session <id>\", \"Session ID\")\n .option(\"--cwd <path>\", \"Working directory\")\n .option(\"--exit-code <code>\", \"Exit code\")\n .option(\"--duration <ms>\", \"Duration in milliseconds\")\n .option(\"--no-sync\", \"Don't sync to platform\")\n .action(\n async (\n command: string,\n options: {\n session?: string;\n cwd?: string;\n exitCode?: string;\n duration?: string;\n sync?: boolean;\n }\n ) => {\n const cwd = options.cwd || process.cwd();\n const exitCode = options.exitCode ? parseInt(options.exitCode, 10) : null;\n const durationMs = options.duration ? parseInt(options.duration, 10) : null;\n const sessionId = options.session || process.env.SKILLO_SESSION || \"default\";\n\n const { normalized, variables } = normalizeCommand(command);\n\n // Store locally\n const db = new SkilloDatabase();\n await db.initialize();\n await db.addCommand({\n command,\n normalized,\n cwd,\n sessionId,\n exitCode,\n durationMs,\n variables: Object.keys(variables).length > 0 ? variables : null,\n });\n db.close();\n\n // Sync to platform if logged in (unless --no-sync)\n if (options.sync !== false) {\n try {\n const { getApiClient } = await import(\"../core/api-client.js\");\n const client = getApiClient();\n\n if (client.hasApiKey()) {\n await client.syncCommands([{\n timestamp: new Date().toISOString(),\n command,\n normalized,\n cwd,\n exitCode,\n durationMs,\n sessionId: sessionId !== \"default\" ? sessionId : undefined,\n variables: Object.keys(variables).length > 0 ? variables : null,\n }]);\n }\n } catch {\n // Silently ignore sync errors\n }\n }\n\n // Silent success - this is called by shell integration\n }\n );\n\n// Shell integration setup command\nexport const setupShellCommand = new Command(\"setup-shell\")\n .description(\"Set up shell integration for automatic command tracking\")\n .option(\"--bash\", \"Set up Bash integration\")\n .option(\"--zsh\", \"Set up Zsh integration\")\n .option(\"--powershell\", \"Set up PowerShell integration\")\n .option(\"--fish\", \"Set up Fish integration\")\n .option(\"--uninstall\", \"Remove shell integration\")\n .action(async (options: {\n bash?: boolean;\n zsh?: boolean;\n powershell?: boolean;\n fish?: boolean;\n uninstall?: boolean;\n }) => {\n logger.blank();\n\n const home = homedir();\n const dataDir = getDataDir();\n ensureDirectory(dataDir);\n\n // Auto-detect shell if none specified\n let shell: string | null = null;\n if (options.bash) shell = \"bash\";\n else if (options.zsh) shell = \"zsh\";\n else if (options.powershell) shell = \"powershell\";\n else if (options.fish) shell = \"fish\";\n else {\n // Auto-detect\n if (process.platform === \"win32\") {\n shell = \"powershell\";\n } else {\n const currentShell = process.env.SHELL || \"\";\n if (currentShell.includes(\"zsh\")) shell = \"zsh\";\n else if (currentShell.includes(\"fish\")) shell = \"fish\";\n else shell = \"bash\";\n }\n logger.info(`Detected shell: ${shell}`);\n }\n\n if (options.uninstall) {\n logger.info(`Removing ${shell} integration...`);\n await uninstallShellIntegration(shell, home);\n logger.success(\"Shell integration removed.\");\n logger.dim(\"Restart your terminal for changes to take effect.\");\n logger.blank();\n return;\n }\n\n logger.info(`Setting up ${shell} integration...`);\n logger.blank();\n\n await installShellIntegration(shell, home, dataDir);\n\n logger.blank();\n logger.success(\"Shell integration installed!\");\n logger.blank();\n logger.dim(\"Restart your terminal or run:\");\n if (shell === \"powershell\") {\n logger.highlight(\" . $PROFILE\");\n } else if (shell === \"bash\") {\n logger.highlight(\" source ~/.bashrc\");\n } else if (shell === \"zsh\") {\n logger.highlight(\" source ~/.zshrc\");\n } else if (shell === \"fish\") {\n logger.highlight(\" source ~/.config/fish/config.fish\");\n }\n logger.blank();\n logger.dim(\"All commands you run will now be tracked and synced to Skillo.\");\n logger.blank();\n });\n\nasync function installShellIntegration(shell: string, home: string, dataDir: string) {\n const scriptPath = join(dataDir, \"shell-integration\");\n ensureDirectory(scriptPath);\n\n if (shell === \"powershell\") {\n // PowerShell integration\n // Works in two modes:\n // 1. Platform mode: Uses SKILLO_SESSION and SKILLO_USER_ID env vars (set by platform launch)\n // 2. Standalone mode: Uses skillo CLI which handles auth via API key\n const psScript = `# Skillo CLI Integration\n# Records commands to Skillo platform\n# Works in two modes:\n# 1. Platform mode: Uses SKILLO_SESSION and SKILLO_USER_ID env vars (set by platform launch)\n# 2. Standalone mode: Uses skillo CLI which handles auth via API key\n\n$Global:SkilloLastHistoryId = 0\n$Global:SkilloStandaloneSessionId = $null\n$Global:SkilloSessionStartTime = $null\n\n# Check if launched from platform (has session/user env vars) or standalone\n$Global:SkilloPlatformMode = $false\nif ($env:SKILLO_SESSION -and $env:SKILLO_USER_ID) {\n $Global:SkilloPlatformMode = $true\n $Global:SkilloSessionId = $env:SKILLO_SESSION\n $Global:SkilloUserId = $env:SKILLO_USER_ID\n $Global:SkilloBaseUrl = if ($env:SKILLO_API_URL) { $env:SKILLO_API_URL } else { 'http://localhost:3000' }\n}\n\nfunction Send-SkilloCommandPlatform {\n param($Command, $Duration, $ExitCode, $Cwd)\n\n try {\n $body = @{\n type = 'commands'\n data = @(@{\n timestamp = (Get-Date).ToString('o')\n command = $Command\n normalized = $Command\n cwd = $Cwd\n exitCode = $ExitCode\n durationMs = $Duration\n sessionId = $Global:SkilloSessionId\n })\n } | ConvertTo-Json -Depth 3 -Compress\n\n $uri = \"$($Global:SkilloBaseUrl)/api/cli/sync\"\n\n $webRequest = [System.Net.HttpWebRequest]::Create($uri)\n $webRequest.Method = 'POST'\n $webRequest.ContentType = 'application/json'\n $webRequest.Headers.Add('x-skillo-session', $Global:SkilloSessionId)\n $webRequest.Headers.Add('x-skillo-user-id', $Global:SkilloUserId)\n $webRequest.Timeout = 5000\n\n $bytes = [System.Text.Encoding]::UTF8.GetBytes($body)\n $webRequest.ContentLength = $bytes.Length\n $stream = $webRequest.GetRequestStream()\n $stream.Write($bytes, 0, $bytes.Length)\n $stream.Close()\n\n $response = $webRequest.GetResponse()\n $response.Close()\n } catch {\n # Silently ignore errors\n }\n}\n\nfunction Send-SkilloCommandCLI {\n param($Command, $Duration, $ExitCode, $Cwd)\n\n # Create session on first command if not exists\n if (-not $Global:SkilloStandaloneSessionId) {\n $Global:SkilloSessionStartTime = (Get-Date).ToString('o')\n try {\n $result = & skillo session start --shell \"PowerShell\" 2>$null\n if ($result -match 'Session ID: ([a-f0-9-]+)') {\n $Global:SkilloStandaloneSessionId = $Matches[1]\n }\n } catch {\n # If session command doesn't exist, generate a local ID\n $Global:SkilloStandaloneSessionId = [guid]::NewGuid().ToString()\n }\n }\n\n # Run skillo record in background with session ID\n Start-Job -ScriptBlock {\n param($cmd, $cwd, $exit, $dur, $sessionId)\n & skillo record $cmd --cwd $cwd --exit-code $exit --duration $dur --session $sessionId 2>$null\n } -ArgumentList $Command, $Cwd, $ExitCode, $Duration, $Global:SkilloStandaloneSessionId | Out-Null\n}\n\n# Override prompt to capture commands after execution\n$Global:SkilloOriginalPrompt = $function:prompt\nfunction Global:prompt {\n $lastCmd = Get-History -Count 1 -ErrorAction SilentlyContinue\n\n if ($lastCmd -and $lastCmd.Id -gt $Global:SkilloLastHistoryId) {\n $Global:SkilloLastHistoryId = $lastCmd.Id\n\n $duration = 0\n if ($lastCmd.EndExecutionTime -and $lastCmd.StartExecutionTime) {\n $duration = [int]($lastCmd.EndExecutionTime - $lastCmd.StartExecutionTime).TotalMilliseconds\n }\n $exit = if ($null -eq $LASTEXITCODE) { 0 } else { $LASTEXITCODE }\n $cwd = (Get-Location).Path\n\n if ($Global:SkilloPlatformMode) {\n Send-SkilloCommandPlatform -Command $lastCmd.CommandLine -Duration $duration -ExitCode $exit -Cwd $cwd\n } else {\n Send-SkilloCommandCLI -Command $lastCmd.CommandLine -Duration $duration -ExitCode $exit -Cwd $cwd\n }\n }\n\n & $Global:SkilloOriginalPrompt\n}\n\n# Register exit handler to end session when terminal closes\n$null = Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {\n if ($Global:SkilloPlatformMode -and $Global:SkilloSessionId) {\n # End platform session\n try {\n $body = @{ sessionId = $Global:SkilloSessionId } | ConvertTo-Json -Compress\n $uri = \"$($Global:SkilloBaseUrl)/api/sessions\"\n\n $webRequest = [System.Net.HttpWebRequest]::Create($uri)\n $webRequest.Method = 'PATCH'\n $webRequest.ContentType = 'application/json'\n $webRequest.Headers.Add('x-skillo-session', $Global:SkilloSessionId)\n $webRequest.Headers.Add('x-skillo-user-id', $Global:SkilloUserId)\n $webRequest.Timeout = 3000\n\n $bytes = [System.Text.Encoding]::UTF8.GetBytes($body)\n $webRequest.ContentLength = $bytes.Length\n $stream = $webRequest.GetRequestStream()\n $stream.Write($bytes, 0, $bytes.Length)\n $stream.Close()\n\n $response = $webRequest.GetResponse()\n $response.Close()\n } catch {\n # Ignore errors on exit\n }\n } elseif ($Global:SkilloStandaloneSessionId) {\n # End standalone session via CLI\n try {\n & skillo session end --session $Global:SkilloStandaloneSessionId 2>$null\n } catch {\n # Ignore errors on exit\n }\n }\n}\n\nWrite-Host \"Skillo: Command tracking enabled\" -ForegroundColor DarkGray\n`;\n\n const psScriptFile = join(scriptPath, \"skillo.ps1\");\n writeFileSync(psScriptFile, psScript, \"utf-8\");\n logger.success(`Created ${psScriptFile}`);\n\n // Add to PowerShell profile\n const profilePath = join(home, \"Documents\", \"WindowsPowerShell\", \"Microsoft.PowerShell_profile.ps1\");\n const profileDir = join(home, \"Documents\", \"WindowsPowerShell\");\n ensureDirectory(profileDir);\n\n const sourceLine = `\\n# Skillo CLI Integration\\n. \"${psScriptFile}\"\\n`;\n\n if (existsSync(profilePath)) {\n const content = readFileSync(profilePath, \"utf-8\");\n if (!content.includes(\"Skillo CLI Integration\")) {\n appendFileSync(profilePath, sourceLine);\n logger.success(\"Added to PowerShell profile\");\n } else {\n logger.dim(\"Already in PowerShell profile\");\n }\n } else {\n writeFileSync(profilePath, sourceLine, \"utf-8\");\n logger.success(\"Created PowerShell profile\");\n }\n\n } else if (shell === \"bash\") {\n // Bash integration - command recording + CWD-based session auto-detection\n const bashScript = [\n \"# Skillo CLI Integration\",\n \"# Records commands and auto-detects tracked projects\",\n \"\",\n '_skillo_session=\"$' + '{SKILLO_SESSION:-default}\"',\n \"_skillo_last_cwd=\",\n \"\",\n \"_skillo_preexec() {\",\n ' _skillo_cmd=\"$1\"',\n \" _skillo_start_time=$(date +%s)\",\n \"}\",\n \"\",\n \"_skillo_check_project() {\",\n ' # Fast path: skip if CWD unchanged',\n ' if [ \"$PWD\" = \"$_skillo_last_cwd\" ]; then',\n \" return\",\n \" fi\",\n ' _skillo_last_cwd=\"$PWD\"',\n \"\",\n ' # Run session-auto in background (handles create/end via cache file)',\n ' local result',\n ' result=$(skillo session-auto \"$PWD\" --pid $$ --shell bash 2>/dev/null)',\n ' if [ -n \"$result\" ]; then',\n ' export SKILLO_SESSION=\"$result\"',\n ' _skillo_session=\"$result\"',\n \" fi\",\n \"}\",\n \"\",\n \"_skillo_precmd() {\",\n \" local exit_code=$?\",\n \"\",\n \" # Check for project change\",\n \" _skillo_check_project\",\n \"\",\n ' if [ -n \"$_skillo_cmd\" ]; then',\n \" local duration=0\",\n ' if [ -n \"$_skillo_start_time\" ]; then',\n \" local end_time=$(date +%s)\",\n \" duration=$(( (end_time - _skillo_start_time) * 1000 ))\",\n \" fi\",\n ' (skillo record \"$_skillo_cmd\" --cwd \"$PWD\" --exit-code \"$exit_code\" --duration \"$duration\" --session \"$_skillo_session\" &>/dev/null &)',\n ' _skillo_cmd=\"\"',\n \" fi\",\n \"}\",\n \"\",\n \"# Clean up session on terminal exit\",\n '_skillo_cleanup() {',\n ' if [ -n \"$SKILLO_SESSION\" ] && [ \"$SKILLO_SESSION\" != \"default\" ]; then',\n ' skillo session end --session \"$SKILLO_SESSION\" &>/dev/null',\n \" fi\",\n \"}\",\n \"trap _skillo_cleanup EXIT\",\n \"\",\n \"# Use DEBUG trap for preexec\",\n \"trap '_skillo_preexec \\\"$BASH_COMMAND\\\"' DEBUG\",\n \"\",\n \"# Add precmd to PROMPT_COMMAND\",\n 'if [[ ! \"$PROMPT_COMMAND\" =~ _skillo_precmd ]]; then',\n ' PROMPT_COMMAND=\"_skillo_precmd$' + '{PROMPT_COMMAND:+;$PROMPT_COMMAND}\"',\n \"fi\",\n \"\",\n \"# Initial project check\",\n \"_skillo_check_project\",\n \"\",\n 'echo -e \"\\\\033[90mSkillo: Command tracking enabled\\\\033[0m\"',\n ].join(\"\\n\");\n\n const bashScriptFile = join(scriptPath, \"skillo.bash\");\n writeFileSync(bashScriptFile, bashScript, \"utf-8\");\n logger.success(`Created ${bashScriptFile}`);\n\n // Add to .bashrc\n const bashrcPath = join(home, \".bashrc\");\n const sourceLine = `\\n# Skillo CLI Integration\\n[ -f \"${bashScriptFile}\" ] && source \"${bashScriptFile}\"\\n`;\n\n if (existsSync(bashrcPath)) {\n const content = readFileSync(bashrcPath, \"utf-8\");\n if (!content.includes(\"Skillo CLI Integration\")) {\n appendFileSync(bashrcPath, sourceLine);\n logger.success(\"Added to ~/.bashrc\");\n } else {\n logger.dim(\"Already in ~/.bashrc\");\n }\n } else {\n writeFileSync(bashrcPath, sourceLine, \"utf-8\");\n logger.success(\"Created ~/.bashrc\");\n }\n\n } else if (shell === \"zsh\") {\n // Zsh integration - command recording + CWD-based session auto-detection\n const zshScript = [\n \"# Skillo CLI Integration\",\n \"# Records commands and auto-detects tracked projects\",\n \"\",\n '_skillo_session=\"$' + '{SKILLO_SESSION:-default}\"',\n \"_skillo_last_cwd=\",\n \"\",\n \"_skillo_preexec() {\",\n ' _skillo_cmd=\"$1\"',\n \" _skillo_start_time=$(date +%s)\",\n \"}\",\n \"\",\n \"_skillo_check_project() {\",\n ' # Fast path: skip if CWD unchanged',\n ' if [[ \"$PWD\" == \"$_skillo_last_cwd\" ]]; then',\n \" return\",\n \" fi\",\n ' _skillo_last_cwd=\"$PWD\"',\n \"\",\n ' # Run session-auto in background (handles create/end via cache file)',\n ' local result',\n ' result=$(skillo session-auto \"$PWD\" --pid $$ --shell zsh 2>/dev/null)',\n ' if [[ -n \"$result\" ]]; then',\n ' export SKILLO_SESSION=\"$result\"',\n ' _skillo_session=\"$result\"',\n \" fi\",\n \"}\",\n \"\",\n \"_skillo_precmd() {\",\n \" local exit_code=$?\",\n \"\",\n \" # Check for project change\",\n \" _skillo_check_project\",\n \"\",\n ' if [[ -n \"$_skillo_cmd\" ]]; then',\n \" local duration=0\",\n ' if [[ -n \"$_skillo_start_time\" ]]; then',\n \" local end_time=$(date +%s)\",\n \" duration=$(( (end_time - _skillo_start_time) * 1000 ))\",\n \" fi\",\n ' (skillo record \"$_skillo_cmd\" --cwd \"$PWD\" --exit-code \"$exit_code\" --duration \"$duration\" --session \"$_skillo_session\" &>/dev/null &)',\n ' _skillo_cmd=\"\"',\n \" fi\",\n \"}\",\n \"\",\n \"# Clean up session on terminal exit\",\n '_skillo_cleanup() {',\n ' if [[ -n \"$SKILLO_SESSION\" ]] && [[ \"$SKILLO_SESSION\" != \"default\" ]]; then',\n ' skillo session end --session \"$SKILLO_SESSION\" &>/dev/null',\n \" fi\",\n \"}\",\n \"trap _skillo_cleanup EXIT\",\n \"\",\n \"autoload -Uz add-zsh-hook\",\n \"add-zsh-hook preexec _skillo_preexec\",\n \"add-zsh-hook precmd _skillo_precmd\",\n \"\",\n \"# Initial project check\",\n \"_skillo_check_project\",\n \"\",\n 'echo -e \"\\\\033[90mSkillo: Command tracking enabled\\\\033[0m\"',\n ].join(\"\\n\");\n\n const zshScriptFile = join(scriptPath, \"skillo.zsh\");\n writeFileSync(zshScriptFile, zshScript, \"utf-8\");\n logger.success(`Created ${zshScriptFile}`);\n\n // Add to .zshrc\n const zshrcPath = join(home, \".zshrc\");\n const sourceLine = `\\n# Skillo CLI Integration\\n[ -f \"${zshScriptFile}\" ] && source \"${zshScriptFile}\"\\n`;\n\n if (existsSync(zshrcPath)) {\n const content = readFileSync(zshrcPath, \"utf-8\");\n if (!content.includes(\"Skillo CLI Integration\")) {\n appendFileSync(zshrcPath, sourceLine);\n logger.success(\"Added to ~/.zshrc\");\n } else {\n logger.dim(\"Already in ~/.zshrc\");\n }\n } else {\n writeFileSync(zshrcPath, sourceLine, \"utf-8\");\n logger.success(\"Created ~/.zshrc\");\n }\n\n } else if (shell === \"fish\") {\n // Fish integration\n const fishScript = [\n \"# Skillo CLI Integration\",\n \"# Records commands to Skillo platform\",\n \"\",\n 'set -q SKILLO_SESSION; or set -g SKILLO_SESSION \"default\"',\n \"\",\n \"function _skillo_postexec --on-event fish_postexec\",\n \" set -l cmd $argv[1]\",\n \" set -l exit_code $status\",\n ' skillo record \"$cmd\" --cwd (pwd) --exit-code $exit_code --session $SKILLO_SESSION &>/dev/null &',\n \"end\",\n \"\",\n 'echo -e \"\\\\033[90mSkillo: Command tracking enabled\\\\033[0m\"',\n ].join(\"\\n\");\n\n const fishScriptFile = join(scriptPath, \"skillo.fish\");\n writeFileSync(fishScriptFile, fishScript, \"utf-8\");\n logger.success(`Created ${fishScriptFile}`);\n\n // Add to fish config\n const fishConfigDir = join(home, \".config\", \"fish\");\n ensureDirectory(fishConfigDir);\n const fishConfigPath = join(fishConfigDir, \"config.fish\");\n const sourceLine = `\\n# Skillo CLI Integration\\nif test -f \"${fishScriptFile}\"\\n source \"${fishScriptFile}\"\\nend\\n`;\n\n if (existsSync(fishConfigPath)) {\n const content = readFileSync(fishConfigPath, \"utf-8\");\n if (!content.includes(\"Skillo CLI Integration\")) {\n appendFileSync(fishConfigPath, sourceLine);\n logger.success(\"Added to ~/.config/fish/config.fish\");\n } else {\n logger.dim(\"Already in fish config\");\n }\n } else {\n writeFileSync(fishConfigPath, sourceLine, \"utf-8\");\n logger.success(\"Created fish config\");\n }\n }\n}\n\nasync function uninstallShellIntegration(shell: string, home: string) {\n const removeFromFile = (filePath: string) => {\n if (!existsSync(filePath)) return;\n let content = readFileSync(filePath, \"utf-8\");\n // Remove the Skillo integration section\n content = content.replace(/\\n# Skillo CLI Integration\\n[^\\n]*\\n/g, \"\\n\");\n writeFileSync(filePath, content, \"utf-8\");\n };\n\n if (shell === \"powershell\") {\n const profilePath = join(home, \"Documents\", \"WindowsPowerShell\", \"Microsoft.PowerShell_profile.ps1\");\n removeFromFile(profilePath);\n } else if (shell === \"bash\") {\n removeFromFile(join(home, \".bashrc\"));\n } else if (shell === \"zsh\") {\n removeFromFile(join(home, \".zshrc\"));\n } else if (shell === \"fish\") {\n removeFromFile(join(home, \".config\", \"fish\", \"config.fish\"));\n }\n}\n","/**\n * Daemon management commands.\n */\n\nimport { existsSync, readFileSync, writeFileSync, unlinkSync } from \"fs\";\nimport { fork } from \"child_process\";\nimport { Command } from \"commander\";\nimport { loadConfig } from \"../core/config.js\";\nimport { getPidFile, getLogFile, getConfigFile, getDataDir, ensureDirectory } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\nimport { installService, uninstallService, getServiceStatus } from \"../utils/os-service.js\";\n\nexport function isDaemonRunning(): { running: boolean; pid: number | null } {\n const pidFile = getPidFile();\n\n if (!existsSync(pidFile)) {\n return { running: false, pid: null };\n }\n\n try {\n const pidStr = readFileSync(pidFile, \"utf-8\").trim();\n const pid = parseInt(pidStr, 10);\n\n if (isNaN(pid)) {\n return { running: false, pid: null };\n }\n\n // Check if process is running\n try {\n process.kill(pid, 0);\n return { running: true, pid };\n } catch {\n // Process doesn't exist, clean up stale PID file\n try {\n unlinkSync(pidFile);\n } catch {\n // Ignore cleanup errors\n }\n return { running: false, pid: null };\n }\n } catch {\n return { running: false, pid: null };\n }\n}\n\nexport function startDaemonProcess(): number | null {\n const daemonScript = new URL(\"./daemon-runner.js\", import.meta.url).pathname;\n\n const child = fork(daemonScript, [], {\n detached: true,\n stdio: \"ignore\",\n env: {\n ...process.env,\n SKILLO_DAEMON: \"1\",\n },\n });\n\n child.unref();\n\n if (child.pid) {\n writeFileSync(getPidFile(), String(child.pid));\n return child.pid;\n }\n\n return null;\n}\n\n// ── Auto-init helper ──────────────────────────────────────────────────────\n\nasync function ensureInitialized(): Promise<void> {\n if (existsSync(getConfigFile())) return;\n\n // Auto-initialize silently\n const { getDefaultConfig, saveConfig } = await import(\"../core/config.js\");\n const { SkilloDatabase } = await import(\"../core/database.js\");\n const { getConfigDir, getSkillsDir } = await import(\"../utils/paths.js\");\n\n ensureDirectory(getDataDir());\n ensureDirectory(getConfigDir());\n ensureDirectory(getSkillsDir());\n\n saveConfig(getDefaultConfig());\n\n const db = new SkilloDatabase();\n await db.initialize();\n db.close();\n\n logger.dim(\"Skillo initialized.\");\n}\n\n// ── Inline login helper ──────────────────────────────────────────────────\n\nasync function ensureLoggedIn(): Promise<boolean> {\n const { getApiClient } = await import(\"../core/api-client.js\");\n const client = getApiClient();\n\n if (client.hasApiKey()) {\n // Verify the key still works\n const result = await client.authenticate();\n if (result.success) return true;\n // Key is stale — clear it and re-login\n client.clearApiKey();\n logger.warn(\"Session expired. Logging in again...\");\n }\n\n // Start device auth flow inline\n logger.blank();\n logger.info(\"Login required. Opening browser...\");\n logger.blank();\n\n const { hostname } = await import(\"os\");\n const deviceName = `CLI on ${hostname()}`;\n const deviceAuthResult = await client.startDeviceAuth(deviceName);\n\n if (!deviceAuthResult.success || !deviceAuthResult.data) {\n logger.error(\"Failed to start authentication: \" + (deviceAuthResult.error || \"Unknown error\"));\n logger.dim(\"You can also login manually: skillo login <api-key>\");\n return false;\n }\n\n const { code, verification_url, interval } = deviceAuthResult.data;\n\n logger.highlight(` ${verification_url}`);\n logger.blank();\n\n // Open browser automatically\n try {\n const { exec: execCb } = await import(\"child_process\");\n const { promisify } = await import(\"util\");\n const execAsync = promisify(execCb);\n const openCmd = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start \\\"\\\"\" : \"xdg-open\";\n await execAsync(`${openCmd} \"${verification_url}\"`);\n logger.dim(\"Browser opened. Waiting for authorization...\");\n } catch {\n logger.dim(\"Open the URL above in your browser to authorize.\");\n }\n\n logger.dim(\"(Press Ctrl+C to cancel)\");\n\n // Poll for authorization\n const maxAttempts = 120;\n for (let i = 0; i < maxAttempts; i++) {\n await new Promise((r) => setTimeout(r, interval * 1000));\n\n const statusResult = await client.checkTokenStatus(code);\n if (!statusResult.success) continue;\n\n const status = statusResult.data?.status;\n\n if (status === \"ready\") {\n const tokenResult = await client.exchangeToken(code, deviceName);\n if (tokenResult.success && tokenResult.data) {\n client.saveApiKey(tokenResult.data.api_key);\n\n const authResult = await client.authenticate();\n logger.blank();\n logger.success(\"Login successful!\");\n if (authResult.success && authResult.data) {\n logger.info(`Welcome, ${authResult.data.user.name}!`);\n }\n logger.blank();\n return true;\n }\n logger.error(\"Failed to complete login: \" + (tokenResult.error || \"Unknown error\"));\n return false;\n }\n\n if (status === \"expired\" || status === \"used\" || status === \"not_found\") {\n logger.error(`Authorization ${status}. Please try again.`);\n return false;\n }\n }\n\n logger.error(\"Authorization timed out.\");\n return false;\n}\n\n// skillo start\nexport const startCommand = new Command(\"start\")\n .description(\"Start the Skillo daemon\")\n .option(\"-f, --foreground\", \"Run in foreground (don't daemonize)\")\n .action(async (options: { foreground?: boolean }) => {\n // Step 1: Auto-initialize if needed\n await ensureInitialized();\n\n // Step 2: Ensure logged in (opens browser if needed)\n if (!options.foreground) {\n const loggedIn = await ensureLoggedIn();\n if (!loggedIn) {\n process.exit(1);\n }\n }\n\n // Step 3: Check if already running\n const { running, pid } = isDaemonRunning();\n if (running) {\n logger.success(`Daemon is already running (PID: ${pid})`);\n\n // Still ensure services are installed\n const serviceStatus = getServiceStatus();\n if (!serviceStatus.daemon.installed) {\n const serviceResult = await installService({ includeTray: true });\n if (serviceResult.success) {\n logger.dim(\"Auto-start service installed.\");\n }\n }\n return;\n }\n\n // Step 4: Start daemon\n if (options.foreground) {\n logger.info(\"Starting Skillo daemon in foreground...\");\n logger.dim(\"Press Ctrl+C to stop\");\n logger.blank();\n await runDaemonForeground();\n } else {\n logger.info(\"Starting Skillo daemon...\");\n\n // On Windows, we can't fork properly, so run in foreground\n if (process.platform === \"win32\") {\n logger.dim(\"Running in foreground mode on Windows...\");\n logger.blank();\n\n // Install services first (they'll handle background on next boot)\n const serviceResult = await installService({ includeTray: true });\n if (serviceResult.success) {\n logger.dim(\"Auto-start service installed. Daemon will run in background on next login.\");\n }\n\n await runDaemonForeground();\n } else {\n const daemonPid = startDaemonProcess();\n if (daemonPid) {\n logger.success(`Daemon started (PID: ${daemonPid})`);\n\n // Step 5: Install OS services (daemon + tray)\n const serviceResult = await installService({ includeTray: true });\n if (serviceResult.success) {\n logger.dim(\"Auto-start & tray service installed. Daemon will survive reboots.\");\n }\n\n logger.blank();\n logger.dim(\"Use 'skillo status' to check daemon status\");\n logger.dim(\"Use 'skillo stop' to stop the daemon\");\n } else {\n logger.error(\"Failed to start daemon\");\n }\n }\n }\n });\n\n// skillo stop\nexport const stopCommand = new Command(\"stop\")\n .description(\"Stop the Skillo daemon\")\n .action(async () => {\n const { running, pid } = isDaemonRunning();\n\n if (!running) {\n logger.dim(\"Daemon is not running.\");\n return;\n }\n\n logger.info(`Stopping daemon (PID: ${pid})...`);\n\n // Uninstall OS service so it doesn't auto-restart\n const serviceResult = await uninstallService();\n if (serviceResult.success) {\n logger.dim(\"Auto-start service removed.\");\n }\n\n try {\n process.kill(pid!, \"SIGTERM\");\n logger.success(\"Daemon stopped\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ESRCH\") {\n logger.dim(\"Daemon already stopped\");\n } else if ((error as NodeJS.ErrnoException).code === \"EPERM\") {\n logger.error(\"Permission denied. Try with sudo.\");\n process.exit(1);\n } else {\n throw error;\n }\n }\n\n // Clean up PID file\n const pidFile = getPidFile();\n if (existsSync(pidFile)) {\n try {\n unlinkSync(pidFile);\n } catch {\n // Ignore cleanup errors\n }\n }\n });\n\n// skillo logs\nexport const logsCommand = new Command(\"logs\")\n .description(\"Show daemon logs\")\n .option(\"-n, --lines <number>\", \"Number of lines to show\", \"50\")\n .option(\"-f, --follow\", \"Follow log output\")\n .action(async (options: { lines: string; follow?: boolean }) => {\n const logFile = getLogFile();\n\n if (!existsSync(logFile)) {\n logger.dim(\"No logs found.\");\n return;\n }\n\n const numLines = parseInt(options.lines, 10);\n\n if (options.follow) {\n // Tail -f functionality\n const { spawn } = await import(\"child_process\");\n const tail = spawn(\"tail\", [\"-f\", \"-n\", String(numLines), logFile], {\n stdio: \"inherit\",\n });\n\n tail.on(\"error\", () => {\n // Fallback for Windows\n logger.warn(\"Follow mode not supported on this platform.\");\n showLogs(logFile, numLines);\n });\n } else {\n showLogs(logFile, numLines);\n }\n });\n\nfunction showLogs(logFile: string, numLines: number): void {\n const content = readFileSync(logFile, \"utf-8\");\n const lines = content.split(\"\\n\").filter(Boolean);\n const lastLines = lines.slice(-numLines);\n lastLines.forEach((line) => console.log(line));\n}\n\n// skillo service\nexport const serviceCommand = new Command(\"service\")\n .description(\"Manage auto-start service\")\n .addCommand(\n new Command(\"install\")\n .description(\"Install auto-start service (LaunchAgent on macOS, systemd on Linux)\")\n .option(\"--no-tray\", \"Skip installing tray icon service\")\n .action(async (options: { tray?: boolean }) => {\n logger.info(\"Installing auto-start service...\");\n const result = await installService({ includeTray: options.tray !== false });\n if (result.success) {\n logger.success(\"Auto-start service installed.\");\n logger.dim(\"Daemon will start automatically on login and restart on crash.\");\n if (options.tray !== false) {\n logger.dim(\"Tray icon will appear in GUI sessions.\");\n }\n } else {\n logger.error(`Failed to install service: ${result.error}`);\n }\n })\n )\n .addCommand(\n new Command(\"uninstall\")\n .description(\"Remove auto-start service\")\n .action(async () => {\n logger.info(\"Removing auto-start service...\");\n const result = await uninstallService();\n if (result.success) {\n logger.success(\"Auto-start service removed.\");\n } else {\n logger.error(`Failed to remove service: ${result.error}`);\n }\n })\n )\n .addCommand(\n new Command(\"status\")\n .description(\"Show auto-start service status\")\n .action(async () => {\n const status = getServiceStatus();\n\n logger.blank();\n logger.info(`Platform: ${status.platform}`);\n logger.blank();\n\n if (status.daemon.installed) {\n logger.running(`Daemon service: installed${status.daemon.loaded ? \" & loaded\" : \" (not loaded)\"}`);\n } else {\n logger.stopped(\"Daemon service: not installed\");\n }\n\n if (status.tray.installed) {\n logger.running(`Tray service: installed${status.tray.loaded ? \" & loaded\" : \" (not loaded)\"}`);\n } else {\n logger.stopped(\"Tray service: not installed\");\n }\n\n logger.blank();\n if (!status.daemon.installed) {\n logger.dim(\"Run 'skillo service install' to enable auto-start.\");\n }\n logger.blank();\n })\n );\n\n// Foreground daemon runner (imports the same logic as daemon-runner.ts)\nasync function runDaemonForeground(): Promise<void> {\n const pidFile = getPidFile();\n writeFileSync(pidFile, String(process.pid));\n\n logger.dim(`Daemon PID: ${process.pid}`);\n logger.dim(`Log file: ${getLogFile()}`);\n logger.blank();\n\n // Handle shutdown signals\n const cleanup = () => {\n logger.blank();\n logger.info(\"Shutting down daemon...\");\n if (existsSync(pidFile)) {\n try {\n unlinkSync(pidFile);\n } catch {\n // Ignore\n }\n }\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n\n // Load config and client\n const config = loadConfig();\n const { getApiClient } = await import(\"../core/api-client.js\");\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n process.exit(1);\n }\n\n // Import and start Claude watcher\n const { ClaudeWatcher } = await import(\"../core/claude-watcher.js\");\n\n ensureDirectory(getDataDir());\n\n const watchInterval = ((config as { daemon?: { conversationCheckInterval?: number } }).daemon?.conversationCheckInterval || 5) * 1000;\n const watcher = new ClaudeWatcher(client, {\n intervalMs: watchInterval,\n callbacks: {\n onSync: (count) => logger.success(`Synced ${count} Claude prompt(s)`),\n onError: (err) => logger.error(`Watcher error: ${err.message}`),\n log: (level, msg) => {\n if (level === \"ERROR\") logger.error(msg);\n else if (level === \"WARN\") logger.warn(msg);\n else logger.dim(msg);\n },\n },\n });\n\n await watcher.start();\n\n // Import and start skill usage detector\n const { SkillUsageDetector } = await import(\"../core/skill-usage-detector.js\");\n\n const skillDetector = new SkillUsageDetector(client, {\n intervalMs: 30000,\n callbacks: {\n onDetection: (count) => logger.success(`Detected ${count} skill usage(s)`),\n onError: (err) => logger.error(`Skill detection error: ${err.message}`),\n log: (level, msg) => {\n if (level === \"ERROR\") logger.error(msg);\n else if (level === \"WARN\") logger.warn(msg);\n else logger.dim(msg);\n },\n },\n });\n\n await skillDetector.start();\n\n logger.success(\"Daemon is running. Watching Claude conversations and skill usage...\");\n\n // Keep the process alive\n await new Promise(() => {});\n}\n","/**\n * Session commands - Manage terminal sessions.\n *\n * Used by shell integration scripts to create and end sessions\n * for standalone terminals (not launched from platform).\n */\n\nimport { Command } from \"commander\";\nimport { existsSync, readFileSync, writeFileSync, unlinkSync } from \"fs\";\nimport { getApiClient } from \"../core/api-client.js\";\nimport { getTrackedProjectsCacheFile, getActiveSessionsDir, ensureDirectory } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\n\nexport const sessionCommand = new Command(\"session\")\n .description(\"Manage terminal sessions\");\n\n// Start a new session\nsessionCommand\n .command(\"start\")\n .description(\"Start a new terminal session (for standalone terminals)\")\n .option(\"--shell <shell>\", \"Shell type (powershell, bash, zsh, cmd)\", \"powershell\")\n .action(async (options: { shell: string }) => {\n try {\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n // Silent fail - shell integration will generate local ID\n process.exit(1);\n }\n\n const result = await client.startSession(options.shell);\n\n if (result.success && result.data?.sessionId) {\n // Output in a format that can be parsed by shell integration\n console.log(`Session ID: ${result.data.sessionId}`);\n } else {\n // Silent fail\n process.exit(1);\n }\n } catch {\n // Silent fail\n process.exit(1);\n }\n });\n\n// End a session\nsessionCommand\n .command(\"end\")\n .description(\"End a terminal session\")\n .option(\"--session <id>\", \"Session ID to end\")\n .action(async (options: { session?: string }) => {\n const sessionId = options.session || process.env.SKILLO_SESSION;\n\n if (!sessionId) {\n // Silent fail - no session to end\n process.exit(0);\n }\n\n try {\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n // Silent fail\n process.exit(0);\n }\n\n const result = await client.endSession(sessionId);\n\n if (result.success) {\n // Silent success\n process.exit(0);\n } else {\n // Silent fail\n process.exit(1);\n }\n } catch {\n // Silent fail\n process.exit(1);\n }\n });\n\n// List active sessions (for debugging)\nsessionCommand\n .command(\"list\")\n .description(\"List active sessions\")\n .action(async () => {\n logger.info(\"Fetching active sessions...\");\n\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n process.exit(1);\n }\n\n // For now, just inform user to check the web UI\n logger.info(\"Check your sessions at: https://www.skillo.one/terminal\");\n });\n\n// session-auto - Fast CWD-change handler called by shell hooks\n// Reads tracked projects cache (file, no API call), creates/ends sessions as needed\nexport const sessionAutoCommand = new Command(\"session-auto\")\n .description(\"Auto-detect project and manage session (used by shell hooks)\")\n .argument(\"<cwd>\", \"Current working directory\")\n .option(\"--pid <pid>\", \"Terminal PID\")\n .option(\"--shell <shell>\", \"Shell type\")\n .action(async (cwd: string, options: { pid?: string; shell?: string }) => {\n const terminalPid = options.pid || String(process.ppid || process.pid);\n const shell = options.shell || process.env.SHELL?.split(\"/\").pop() || \"unknown\";\n const sessionsDir = getActiveSessionsDir();\n const sessionFile = `${sessionsDir}/${terminalPid}.json`;\n\n // Read current session state\n let currentSession: { sessionId: string; projectPath: string } | null = null;\n if (existsSync(sessionFile)) {\n try {\n currentSession = JSON.parse(readFileSync(sessionFile, \"utf-8\"));\n } catch {\n currentSession = null;\n }\n }\n\n // Check if CWD is in a tracked project (file-based, no API)\n const cacheFile = getTrackedProjectsCacheFile();\n let matchedProject: { path: string; name: string } | null = null;\n\n if (existsSync(cacheFile)) {\n try {\n const cache = JSON.parse(readFileSync(cacheFile, \"utf-8\"));\n const normalizedCwd = cwd.toLowerCase().replace(/\\/+$/, \"\");\n for (const project of cache.projects || []) {\n const normalizedPath = project.path.toLowerCase().replace(/\\/+$/, \"\");\n if (normalizedCwd === normalizedPath || normalizedCwd.startsWith(normalizedPath + \"/\")) {\n matchedProject = project;\n break;\n }\n }\n } catch {\n // Cache unreadable\n }\n }\n\n // Same project, no-op\n if (currentSession && matchedProject && currentSession.projectPath === matchedProject.path) {\n process.exit(0);\n }\n\n const client = getApiClient();\n if (!client.hasApiKey()) {\n process.exit(0);\n }\n\n // End previous session if leaving a tracked project\n if (currentSession) {\n try {\n await client.endSession(currentSession.sessionId);\n } catch {\n // Ignore\n }\n try {\n unlinkSync(sessionFile);\n } catch {\n // Ignore\n }\n }\n\n // Start new session if entering a tracked project\n if (matchedProject) {\n try {\n const result = await client.startSession(shell, matchedProject.path);\n if (result.success && result.data?.sessionId) {\n ensureDirectory(sessionsDir);\n writeFileSync(sessionFile, JSON.stringify({\n sessionId: result.data.sessionId,\n projectPath: matchedProject.path,\n projectName: matchedProject.name,\n pid: terminalPid,\n startedAt: Date.now(),\n }));\n // Output session ID for shell to capture\n console.log(result.data.sessionId);\n }\n } catch {\n // Silent fail\n }\n }\n\n process.exit(0);\n });\n","/**\n * Claude Code commands - Sync and watch Claude Code history.\n *\n * Reads ~/.claude/history.jsonl and syncs prompts to the platform.\n * Supports project-path filtering to only sync prompts for the current project.\n *\n * PRIVACY: Only syncs prompts for projects that have been explicitly connected\n * using `skillo connect`. Unconnected projects are not tracked.\n */\n\nimport { Command } from \"commander\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport * as readline from \"readline\";\nimport { getApiClient } from \"../core/api-client.js\";\nimport logger from \"../utils/logger.js\";\n\n// Cache for tracked projects to avoid repeated API calls\ninterface TrackedProjectCache {\n projects: Map<string, { tracked: boolean; name?: string }>;\n lastFetched: number;\n}\n\nconst projectCache: TrackedProjectCache = {\n projects: new Map(),\n lastFetched: 0,\n};\n\nconst CACHE_TTL_MS = 60000; // 1 minute cache\n\ninterface ClaudeHistoryEntry {\n display: string;\n timestamp: number;\n project: string;\n sessionId: string;\n pastedContents?: Record<string, unknown>;\n}\n\ninterface SyncOptions {\n since?: string;\n all?: boolean;\n projectPath?: string;\n session?: string;\n sessionStart?: string;\n}\n\ninterface WatchOptions {\n interval: string;\n projectPath?: string;\n session?: string;\n sessionStart?: string;\n}\n\n// Get Claude Code history file path\nfunction getClaudeHistoryPath(): string {\n return path.join(os.homedir(), \".claude\", \"history.jsonl\");\n}\n\n// Normalize path for comparison\nfunction normalizePath(p: string): string {\n return p.toLowerCase().replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n}\n\n// Check if a Claude project path matches the filter path\nfunction matchesProjectPath(claudeProjectPath: string, filterPath: string): boolean {\n const normalizedClaude = normalizePath(claudeProjectPath);\n const normalizedFilter = normalizePath(filterPath);\n\n // Exact match or Claude path is within filter path\n return normalizedClaude === normalizedFilter ||\n normalizedClaude.startsWith(normalizedFilter + \"/\");\n}\n\n// Check if timestamp is within session timeframe\nfunction isWithinSession(timestamp: number, sessionStart?: string): boolean {\n if (!sessionStart) return true;\n\n const sessionStartTime = new Date(sessionStart).getTime();\n return timestamp >= sessionStartTime;\n}\n\n// Load tracked projects from the API into cache\nasync function loadTrackedProjects(): Promise<Map<string, { tracked: boolean; name?: string }>> {\n const client = getApiClient();\n const now = Date.now();\n\n // Return cached if still valid\n if (projectCache.lastFetched > 0 && now - projectCache.lastFetched < CACHE_TTL_MS) {\n return projectCache.projects;\n }\n\n try {\n const result = await client.listProjects(true); // Include disabled to build full cache\n if (result.success && result.data?.projects) {\n projectCache.projects.clear();\n for (const project of result.data.projects) {\n // Normalize path for consistent matching\n const normalizedPath = normalizePath(project.path);\n projectCache.projects.set(normalizedPath, {\n tracked: project.trackingEnabled,\n name: project.name,\n });\n }\n projectCache.lastFetched = now;\n }\n } catch {\n // If API fails, use stale cache or empty\n }\n\n return projectCache.projects;\n}\n\n// Check if a project path is tracked (privacy filter)\nasync function isProjectTracked(projectPath: string): Promise<{ tracked: boolean; name?: string }> {\n const trackedProjects = await loadTrackedProjects();\n const normalizedPath = normalizePath(projectPath);\n\n // Check exact match first\n if (trackedProjects.has(normalizedPath)) {\n return trackedProjects.get(normalizedPath)!;\n }\n\n // Check if this path is under any tracked project\n const entries = Array.from(trackedProjects.entries());\n for (const [trackedPath, info] of entries) {\n if (normalizedPath.startsWith(trackedPath + \"/\")) {\n return info;\n }\n }\n\n return { tracked: false };\n}\n\nexport const claudeCommand = new Command(\"claude\")\n .description(\"Sync and monitor Claude Code activity\");\n\n// Sync Claude Code history\nclaudeCommand\n .command(\"sync\")\n .description(\"Sync Claude Code history to the platform (only tracked projects)\")\n .option(\"--since <timestamp>\", \"Only sync entries after this timestamp (ms)\")\n .option(\"--all\", \"Sync all history (ignore last sync position)\")\n .option(\"--project-path <path>\", \"Only sync prompts for this project path\")\n .option(\"--session <id>\", \"Link prompts to this terminal session\")\n .option(\"--session-start <iso>\", \"Session start time (ISO 8601) for filtering\")\n .option(\"--ignore-tracking\", \"Sync all projects regardless of tracking status (not recommended)\")\n .action(async (options: SyncOptions & { ignoreTracking?: boolean }) => {\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n process.exit(1);\n }\n\n const historyPath = getClaudeHistoryPath();\n\n if (!fs.existsSync(historyPath)) {\n logger.warn(`Claude Code history file not found at: ${historyPath}`);\n logger.info(\"Claude Code stores history in ~/.claude/history.jsonl\");\n logger.info(\"Make sure you have used Claude Code at least once.\");\n process.exit(1);\n }\n\n const projectFilter = options.projectPath || process.env.SKILLO_PROJECT_PATH;\n if (projectFilter) {\n logger.info(`Filtering for project: ${projectFilter}`);\n }\n\n // Load tracked projects for privacy filtering\n if (!options.ignoreTracking) {\n logger.info(\"Loading tracked projects...\");\n await loadTrackedProjects();\n const trackedCount = Array.from(projectCache.projects.values()).filter(p => p.tracked).length;\n if (trackedCount === 0) {\n logger.warn(\"No projects are connected for tracking.\");\n logger.info(\"Run 'skillo connect' in your project directories first.\");\n logger.info(\"Or use --ignore-tracking to sync all projects (not recommended for privacy).\");\n process.exit(0);\n }\n logger.dim(`Found ${trackedCount} tracked project(s)`);\n } else {\n logger.warn(\"Privacy filter disabled - syncing all projects\");\n }\n\n logger.info(\"Reading Claude Code history...\");\n\n const prompts: ClaudeHistoryEntry[] = [];\n const sinceTimestamp = options.since ? parseInt(options.since, 10) : 0;\n\n // Read history file line by line\n const fileStream = fs.createReadStream(historyPath);\n const rl = readline.createInterface({\n input: fileStream,\n crlfDelay: Infinity,\n });\n\n let lineCount = 0;\n let parsedCount = 0;\n let filteredCount = 0;\n let privacyFilteredCount = 0;\n const untrackedProjects = new Set<string>();\n\n for await (const line of rl) {\n lineCount++;\n if (!line.trim()) continue;\n\n try {\n const entry = JSON.parse(line) as ClaudeHistoryEntry;\n\n // Skip if before timestamp filter\n if (!options.all && entry.timestamp <= sinceTimestamp) {\n continue;\n }\n\n // Validate required fields\n if (!entry.display || !entry.timestamp || !entry.project || !entry.sessionId) {\n continue;\n }\n\n parsedCount++;\n\n // Apply project path filter\n if (projectFilter && !matchesProjectPath(entry.project, projectFilter)) {\n filteredCount++;\n continue;\n }\n\n // Apply session timeframe filter\n if (!isWithinSession(entry.timestamp, options.sessionStart)) {\n filteredCount++;\n continue;\n }\n\n // PRIVACY: Check if this project is tracked\n if (!options.ignoreTracking) {\n const trackingStatus = await isProjectTracked(entry.project);\n if (!trackingStatus.tracked) {\n privacyFilteredCount++;\n untrackedProjects.add(entry.project);\n continue;\n }\n }\n\n prompts.push(entry);\n } catch {\n // Skip invalid JSON lines\n }\n }\n\n const syncCount = prompts.length;\n logger.info(`Found ${parsedCount} total prompts, ${syncCount} match filters`);\n if (filteredCount > 0) {\n logger.dim(` ${filteredCount} filtered by path/session`);\n }\n if (privacyFilteredCount > 0) {\n logger.dim(` ${privacyFilteredCount} filtered (untracked projects)`);\n if (untrackedProjects.size <= 5) {\n Array.from(untrackedProjects).forEach(p => {\n logger.dim(` - ${p}`);\n });\n } else {\n logger.dim(` (${untrackedProjects.size} untracked projects)`);\n }\n logger.dim(` Run 'skillo connect' in those directories to track them.`);\n }\n\n if (prompts.length === 0) {\n logger.info(\"No matching prompts to sync.\");\n return;\n }\n\n // Sync to platform\n logger.info(\"Syncing to platform...\");\n\n try {\n const response = await client.syncClaudePrompts(prompts, {\n terminalSessionId: options.session,\n projectPath: projectFilter,\n });\n\n if (response.success && response.data) {\n const { sessionsCreated, promptsCreated, promptsSkipped } = response.data;\n logger.success(\"Synced successfully!\");\n logger.info(` Sessions created: ${sessionsCreated}`);\n logger.info(` Prompts created: ${promptsCreated}`);\n logger.info(` Prompts skipped (already exist): ${promptsSkipped}`);\n } else {\n logger.error(`Sync failed: ${response.error}`);\n }\n } catch (error) {\n logger.error(`Failed to sync: ${error}`);\n process.exit(1);\n }\n });\n\n// Watch Claude Code history for changes (uses shared ClaudeWatcher)\nclaudeCommand\n .command(\"watch\")\n .description(\"Watch Claude Code history and sync in real-time (only tracked projects)\")\n .option(\"--interval <ms>\", \"Check interval in milliseconds\", \"5000\")\n .option(\"--project-path <path>\", \"Only sync prompts for this project path\")\n .option(\"--session <id>\", \"Link prompts to this terminal session\")\n .action(async (options: WatchOptions) => {\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n process.exit(1);\n }\n\n const { ClaudeWatcher } = await import(\"../core/claude-watcher.js\");\n\n const interval = parseInt(options.interval, 10);\n const projectFilter = options.projectPath || process.env.SKILLO_PROJECT_PATH;\n\n if (projectFilter) {\n logger.info(`Watching for project: ${projectFilter}`);\n }\n logger.info(`Checking every ${interval}ms`);\n logger.info(\"Press Ctrl+C to stop\");\n\n const watcher = new ClaudeWatcher(client, {\n intervalMs: interval,\n projectFilter,\n sessionFilter: options.session,\n callbacks: {\n onSync: (count) => logger.success(`Synced ${count} prompt(s)`),\n onError: (err) => logger.error(`Watch error: ${err.message}`),\n log: (level, msg) => {\n if (level === \"ERROR\") logger.error(msg);\n else if (level === \"WARN\") logger.warn(msg);\n else logger.dim(msg);\n },\n },\n });\n\n await watcher.start();\n\n process.on(\"SIGINT\", () => {\n logger.info(\"\\nStopping watcher...\");\n watcher.stop();\n process.exit(0);\n });\n });\n\n// Status command\nclaudeCommand\n .command(\"status\")\n .description(\"Show Claude Code sync status\")\n .option(\"--project-path <path>\", \"Show status for specific project\")\n .action(async (options: { projectPath?: string }) => {\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n process.exit(1);\n }\n\n const historyPath = getClaudeHistoryPath();\n const projectFilter = options.projectPath || process.env.SKILLO_PROJECT_PATH;\n\n logger.info(\"Claude Code Status\");\n logger.info(\"==================\");\n logger.info(`History file: ${historyPath}`);\n\n if (projectFilter) {\n logger.info(`Project filter: ${projectFilter}`);\n }\n\n if (fs.existsSync(historyPath)) {\n const stats = fs.statSync(historyPath);\n logger.info(`File size: ${(stats.size / 1024).toFixed(2)} KB`);\n logger.info(`Last modified: ${new Date(stats.mtimeMs).toLocaleString()}`);\n\n // Count entries\n let totalCount = 0;\n let projectCount = 0;\n const sessions = new Set<string>();\n const projectSessions = new Set<string>();\n\n const fileStream = fs.createReadStream(historyPath);\n const rl = readline.createInterface({\n input: fileStream,\n crlfDelay: Infinity,\n });\n\n for await (const line of rl) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as ClaudeHistoryEntry;\n if (entry.sessionId) {\n totalCount++;\n sessions.add(entry.sessionId);\n\n if (!projectFilter || matchesProjectPath(entry.project, projectFilter)) {\n projectCount++;\n projectSessions.add(entry.sessionId);\n }\n }\n } catch {\n // Skip invalid JSON\n }\n }\n\n logger.info(`\\nTotal prompts: ${totalCount}`);\n logger.info(`Total sessions: ${sessions.size}`);\n\n if (projectFilter) {\n logger.info(`\\nFor current project:`);\n logger.info(` Prompts: ${projectCount}`);\n logger.info(` Sessions: ${projectSessions.size}`);\n }\n } else {\n logger.warn(\"History file not found\");\n }\n\n // Get synced data from platform\n try {\n const response = await client.getClaudeSessions(5);\n if (response.success && response.data?.sessions) {\n logger.info(`\\nSynced to platform: ${response.data.sessions.length} recent sessions`);\n }\n } catch {\n logger.warn(\"Could not fetch synced data from platform\");\n }\n });\n","/**\n * Project tracking commands - Track/untrack projects for privacy-first tracking.\n */\n\nimport { Command } from \"commander\";\nimport { existsSync, writeFileSync } from \"fs\";\nimport { getApiClient } from \"../core/api-client.js\";\nimport { getGitInfo } from \"../utils/git.js\";\nimport logger from \"../utils/logger.js\";\nimport { resolve } from \"path\";\nimport { getTrackedProjectsCacheFile, getShellIntegrationDir, ensureDirectory, getDataDir } from \"../utils/paths.js\";\nimport { isDaemonRunning, startDaemonProcess } from \"./daemon.js\";\n\nexport const projectCommand = new Command(\"project\")\n .description(\"Manage project tracking settings\");\n\n// skillo track - Enable tracking for current directory\nexport const trackCommand = new Command(\"track\")\n .description(\"Enable tracking for the current project\")\n .argument(\"[path]\", \"Project path (defaults to current directory)\")\n .option(\"-n, --name <name>\", \"Custom project name\")\n .action(async (pathArg?: string, options?: { name?: string }) => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n return;\n }\n\n const projectPath = resolve(pathArg || process.cwd());\n\n logger.info(`Tracking project: ${projectPath}`);\n logger.blank();\n\n // Get git information\n const gitInfo = getGitInfo(projectPath);\n\n if (gitInfo.isGitRepo) {\n logger.dim(`Git repository detected`);\n if (gitInfo.remote) {\n logger.dim(`Remote: ${gitInfo.remoteNormalized || gitInfo.remote}`);\n }\n if (gitInfo.branch) {\n logger.dim(`Branch: ${gitInfo.branch}`);\n }\n logger.blank();\n } else {\n logger.warn(\"No git repository detected in this directory.\");\n logger.dim(\"Project will be tracked by path only (no team sharing).\");\n logger.blank();\n }\n\n // Determine project name\n const projectName = options?.name || gitInfo.projectName || projectPath.split(\"/\").pop() || \"Unknown\";\n\n try {\n const result = await client.connectProject({\n path: projectPath,\n name: projectName,\n gitRemote: gitInfo.remote || undefined,\n gitRemoteNormalized: gitInfo.remoteNormalized || undefined,\n });\n\n if (result.success) {\n logger.success(`Project \"${projectName}\" is now being tracked!`);\n logger.blank();\n logger.dim(\"Your Claude Code prompts in this directory will now be synced.\");\n logger.dim(\"Run 'skillo untrack' to stop tracking.\");\n\n // Write tracked projects cache immediately\n try {\n const listResult = await client.listProjects(true);\n if (listResult.success && listResult.data?.projects) {\n const cacheData = {\n updatedAt: Date.now(),\n projects: listResult.data.projects\n .filter((p: { trackingEnabled: boolean }) => p.trackingEnabled)\n .map((p: { path: string; name: string }) => ({ path: p.path, name: p.name })),\n };\n ensureDirectory(getDataDir());\n writeFileSync(getTrackedProjectsCacheFile(), JSON.stringify(cacheData, null, 2));\n }\n } catch {\n // Non-critical - daemon will update cache on next cycle\n }\n\n // Auto-start daemon if not running\n const { running } = isDaemonRunning();\n if (!running) {\n logger.blank();\n const pid = startDaemonProcess();\n if (pid) {\n logger.success(`Background sync daemon started (PID: ${pid})`);\n } else {\n logger.dim(\"Tip: Run 'skillo start' to enable background sync.\");\n }\n }\n\n // Suggest shell integration if not installed\n const shellIntegrationDir = getShellIntegrationDir();\n if (!existsSync(shellIntegrationDir) || !existsSync(resolve(shellIntegrationDir, \"skillo.zsh\"))) {\n logger.blank();\n logger.dim(\"Tip: Run 'skillo setup-shell' to enable terminal auto-detection.\");\n }\n } else {\n logger.error(\"Failed to track project: \" + (result.error || \"Unknown error\"));\n }\n } catch (error) {\n logger.error(\"Failed to track project: \" + (error instanceof Error ? error.message : \"Unknown error\"));\n }\n\n logger.blank();\n });\n\n// skillo untrack - Disable tracking for current directory\nexport const untrackCommand = new Command(\"untrack\")\n .description(\"Disable tracking for the current project\")\n .argument(\"[path]\", \"Project path (defaults to current directory)\")\n .action(async (pathArg?: string) => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n return;\n }\n\n const projectPath = resolve(pathArg || process.cwd());\n\n logger.info(`Untracking project: ${projectPath}`);\n\n try {\n const result = await client.disconnectProject(projectPath);\n\n if (result.success) {\n logger.blank();\n logger.success(\"Project is no longer being tracked.\");\n logger.blank();\n logger.dim(\"Your Claude Code prompts in this directory will no longer be synced.\");\n logger.dim(\"Existing data remains in your account.\");\n } else {\n logger.blank();\n logger.error(\"Failed to untrack project: \" + (result.error || \"Unknown error\"));\n }\n } catch (error) {\n logger.blank();\n logger.error(\"Failed to untrack project: \" + (error instanceof Error ? error.message : \"Unknown error\"));\n }\n\n logger.blank();\n });\n\n// skillo project status - Show tracking status for current project\nprojectCommand\n .command(\"status\")\n .description(\"Show tracking status for the current project\")\n .argument(\"[path]\", \"Project path (defaults to current directory)\")\n .action(async (pathArg?: string) => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n return;\n }\n\n const projectPath = resolve(pathArg || process.cwd());\n\n logger.info(`Project: ${projectPath}`);\n logger.blank();\n\n // Get git information\n const gitInfo = getGitInfo(projectPath);\n\n if (gitInfo.isGitRepo) {\n logger.dim(`Git: ${gitInfo.remoteNormalized || gitInfo.remote || \"no remote\"}`);\n if (gitInfo.branch) {\n logger.dim(`Branch: ${gitInfo.branch}`);\n }\n } else {\n logger.dim(\"Git: not a repository\");\n }\n\n logger.blank();\n\n try {\n const result = await client.getProjectStatus(projectPath);\n\n if (result.success && result.data) {\n const { connected, connectedAt } = result.data;\n\n if (connected) {\n logger.success(\"Tracking ENABLED\");\n if (connectedAt) {\n logger.dim(`Since: ${new Date(connectedAt).toLocaleDateString()}`);\n }\n } else {\n logger.warn(\"Tracking DISABLED\");\n logger.dim(\"Run 'skillo track' to enable tracking.\");\n }\n } else {\n logger.warn(\"Not tracked\");\n logger.dim(\"Run 'skillo track' to enable tracking for this project.\");\n }\n } catch (error) {\n logger.error(\"Failed to get project status: \" + (error instanceof Error ? error.message : \"Unknown error\"));\n }\n\n logger.blank();\n });\n\n// skillo project list - List all tracked projects\nprojectCommand\n .command(\"list\")\n .alias(\"ls\")\n .description(\"List all projects (tracked and untracked)\")\n .option(\"-a, --all\", \"Include untracked projects\")\n .action(async (options?: { all?: boolean }) => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n return;\n }\n\n try {\n const result = await client.listProjects(options?.all || false);\n\n if (result.success && result.data) {\n const { projects, totalTracked, totalProjects } = result.data;\n\n logger.info(`Projects (${totalTracked} tracked / ${totalProjects} total)`);\n logger.blank();\n\n if (projects.length === 0) {\n logger.dim(\"No projects found.\");\n logger.dim(\"Run 'skillo track' in a project directory to start tracking.\");\n } else {\n for (const project of projects) {\n const status = project.trackingEnabled ? \"●\" : \"○\";\n const statusColor = project.trackingEnabled ? \"\\x1b[32m\" : \"\\x1b[90m\";\n const resetColor = \"\\x1b[0m\";\n\n console.log(` ${statusColor}${status}${resetColor} ${project.name}`);\n logger.dim(` ${project.path}`);\n if (project.gitRemoteNormalized) {\n logger.dim(` ${project.gitRemoteNormalized}`);\n }\n }\n }\n } else {\n logger.error(\"Failed to list projects: \" + (result.error || \"Unknown error\"));\n }\n } catch (error) {\n logger.error(\"Failed to list projects: \" + (error instanceof Error ? error.message : \"Unknown error\"));\n }\n\n logger.blank();\n });\n","/**\n * Git utilities for project detection and identification.\n */\n\nimport { execSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport { join, dirname, basename } from \"path\";\n\nexport interface GitInfo {\n isGitRepo: boolean;\n rootPath: string | null;\n remote: string | null;\n remoteNormalized: string | null;\n branch: string | null;\n projectName: string | null;\n}\n\n/**\n * Get git information for a given path.\n */\nexport function getGitInfo(projectPath: string): GitInfo {\n const result: GitInfo = {\n isGitRepo: false,\n rootPath: null,\n remote: null,\n remoteNormalized: null,\n branch: null,\n projectName: null,\n };\n\n try {\n // Check if it's a git repo and get root\n const rootPath = execSync(\"git rev-parse --show-toplevel\", {\n cwd: projectPath,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n\n if (!rootPath) return result;\n\n result.isGitRepo = true;\n result.rootPath = rootPath;\n result.projectName = basename(rootPath);\n\n // Get current branch\n try {\n result.branch = execSync(\"git rev-parse --abbrev-ref HEAD\", {\n cwd: projectPath,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n } catch {\n // Might be in detached HEAD state\n }\n\n // Get remote URL (prefer origin)\n try {\n result.remote = execSync(\"git remote get-url origin\", {\n cwd: projectPath,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n } catch {\n // Try to get any remote\n try {\n const remotes = execSync(\"git remote\", {\n cwd: projectPath,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim().split(\"\\n\");\n\n if (remotes.length > 0 && remotes[0]) {\n result.remote = execSync(`git remote get-url ${remotes[0]}`, {\n cwd: projectPath,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n }\n } catch {\n // No remotes configured\n }\n }\n\n // Normalize the remote URL for team matching\n if (result.remote) {\n result.remoteNormalized = normalizeGitRemote(result.remote);\n }\n } catch {\n // Not a git repository\n }\n\n return result;\n}\n\n/**\n * Normalize a git remote URL for consistent matching across team members.\n * Converts various formats to: \"host/owner/repo\"\n *\n * Examples:\n * - git@github.com:acme/webapp.git -> github.com/acme/webapp\n * - https://github.com/acme/webapp.git -> github.com/acme/webapp\n * - ssh://git@github.com/acme/webapp -> github.com/acme/webapp\n * - git://github.com/acme/webapp.git -> github.com/acme/webapp\n */\nexport function normalizeGitRemote(remoteUrl: string): string {\n let url = remoteUrl.trim();\n\n // Remove .git suffix\n url = url.replace(/\\.git$/, \"\");\n\n // Handle SSH format: git@github.com:owner/repo\n const sshMatch = url.match(/^git@([^:]+):(.+)$/);\n if (sshMatch) {\n return `${sshMatch[1]}/${sshMatch[2]}`;\n }\n\n // Handle various URL formats\n try {\n // Remove protocol prefix for parsing\n let normalized = url\n .replace(/^(https?|git|ssh):\\/\\//, \"\")\n .replace(/^git@/, \"\");\n\n // Remove username if present (e.g., git@host or user@host)\n normalized = normalized.replace(/^[^@]+@/, \"\");\n\n // Remove port if present\n normalized = normalized.replace(/:\\d+\\//, \"/\");\n\n // Clean up any double slashes\n normalized = normalized.replace(/\\/+/g, \"/\");\n\n // Remove leading/trailing slashes\n normalized = normalized.replace(/^\\/|\\/$/g, \"\");\n\n return normalized.toLowerCase();\n } catch {\n // Fallback: return as-is but lowercase\n return url.toLowerCase();\n }\n}\n\n/**\n * Find git root by walking up the directory tree.\n */\nexport function findGitRoot(startPath: string): string | null {\n let current = startPath;\n\n while (current !== dirname(current)) {\n if (existsSync(join(current, \".git\"))) {\n return current;\n }\n current = dirname(current);\n }\n\n return null;\n}\n\n/**\n * Check if a path is inside a git repository.\n */\nexport function isInsideGitRepo(path: string): boolean {\n return findGitRoot(path) !== null;\n}\n\n/**\n * Extract owner and repo name from a normalized git remote.\n */\nexport function parseGitRemote(normalizedRemote: string): { host: string; owner: string; repo: string } | null {\n const parts = normalizedRemote.split(\"/\");\n\n if (parts.length < 3) return null;\n\n return {\n host: parts[0],\n owner: parts[1],\n repo: parts.slice(2).join(\"/\"), // Handle nested paths like gitlab subgroups\n };\n}\n","/**\n * Authentication commands - Login/logout with Skillo platform.\n */\n\nimport { Command } from \"commander\";\nimport { getApiClient } from \"../core/api-client.js\";\nimport logger from \"../utils/logger.js\";\nimport { hostname } from \"os\";\nimport { installService } from \"../utils/os-service.js\";\nimport { isDaemonRunning, startDaemonProcess } from \"./daemon.js\";\n\n// Try to open URL in browser\nasync function openBrowser(url: string): Promise<boolean> {\n try {\n const { exec } = await import(\"child_process\");\n const { promisify } = await import(\"util\");\n const execAsync = promisify(exec);\n\n const platform = process.platform;\n let command: string;\n\n if (platform === \"darwin\") {\n command = `open \"${url}\"`;\n } else if (platform === \"win32\") {\n command = `start \"\" \"${url}\"`;\n } else {\n command = `xdg-open \"${url}\"`;\n }\n\n await execAsync(command);\n return true;\n } catch {\n return false;\n }\n}\n\n// Sleep helper\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Start daemon and install OS auto-start service after login */\nasync function autoStartDaemon() {\n try {\n const { running } = isDaemonRunning();\n if (!running) {\n const pid = startDaemonProcess();\n if (pid) {\n logger.dim(`Background daemon started (PID: ${pid}).`);\n }\n }\n\n const result = await installService();\n if (result.success) {\n logger.dim(\"Auto-start installed. Daemon will survive reboots.\");\n }\n } catch {\n // Non-critical — don't fail login\n }\n}\n\nexport const loginCommand = new Command(\"login\")\n .description(\"Login to Skillo platform\")\n .argument(\"[api-key]\", \"Your Skillo API key (optional, will use browser auth if not provided)\")\n .option(\"-u, --url <url>\", \"Platform URL (default: https://www.skillo.one)\")\n .option(\"-n, --no-browser\", \"Don't open browser automatically\")\n .action(async (apiKey?: string, options?: { url?: string; browser?: boolean }) => {\n const client = getApiClient();\n\n logger.blank();\n\n // Set custom URL if provided\n if (options?.url) {\n client.setBaseUrl(options.url);\n logger.dim(`Using API URL: ${options.url}`);\n }\n\n // If API key provided directly, use it\n if (apiKey) {\n // Validate API key format\n if (!apiKey.startsWith(\"sk_\")) {\n logger.error(\"Invalid API key format. Keys should start with 'sk_'\");\n return;\n }\n\n // Save the API key\n client.saveApiKey(apiKey);\n\n // Verify by authenticating\n logger.info(\"Verifying API key...\");\n const result = await client.authenticate();\n\n if (result.success && result.data) {\n logger.blank();\n logger.success(\"Login successful!\");\n logger.blank();\n logger.info(`Welcome, ${result.data.user.name}!`);\n logger.dim(`Email: ${result.data.user.email}`);\n logger.blank();\n\n // Auto-start daemon and install service\n await autoStartDaemon();\n\n logger.dim(\"Your patterns and skills will now sync with the Skillo platform.\");\n } else {\n // Clear the invalid key\n client.clearApiKey();\n logger.blank();\n logger.error(\"Login failed: \" + (result.error || \"Invalid API key\"));\n logger.dim(\"Please check your API key and try again.\");\n }\n return;\n }\n\n // Check if already logged in\n if (client.hasApiKey()) {\n logger.info(`Already logged in. API key: ${client.getMaskedApiKey()}`);\n logger.dim(\"Use 'skillo logout' to log out first.\");\n logger.blank();\n\n // Verify the current key still works\n const result = await client.authenticate();\n if (result.success && result.data) {\n logger.success(`Authenticated as: ${result.data.user.name} (${result.data.user.email})`);\n } else {\n logger.warn(\"Current API key may be invalid or expired.\");\n logger.dim(\"Use 'skillo logout' then 'skillo login' to re-authenticate.\");\n }\n return;\n }\n\n // Start OAuth device flow\n logger.info(\"Starting authentication...\");\n logger.blank();\n\n const deviceName = `CLI on ${hostname()}`;\n const deviceAuthResult = await client.startDeviceAuth(deviceName);\n\n if (!deviceAuthResult.success || !deviceAuthResult.data) {\n logger.error(\"Failed to start authentication: \" + (deviceAuthResult.error || \"Unknown error\"));\n logger.blank();\n logger.dim(\"Alternative: Get an API key from the Skillo dashboard and run:\");\n logger.dim(\" skillo login <your-api-key>\");\n return;\n }\n\n const { code, verification_url, interval } = deviceAuthResult.data;\n\n // Display instructions\n logger.info(\"To complete login, open this URL in your browser:\");\n logger.blank();\n logger.highlight(` ${verification_url}`);\n logger.blank();\n\n // Try to open browser\n if (options?.browser !== false) {\n const opened = await openBrowser(verification_url);\n if (opened) {\n logger.dim(\"Browser opened automatically.\");\n } else {\n logger.dim(\"Could not open browser automatically. Please open the URL manually.\");\n }\n }\n\n logger.blank();\n logger.dim(\"Waiting for authorization...\");\n logger.dim(\"(Press Ctrl+C to cancel)\");\n\n // Poll for authorization\n const maxAttempts = 120; // 10 minutes at 5 second intervals\n let attempts = 0;\n\n while (attempts < maxAttempts) {\n await sleep(interval * 1000);\n attempts++;\n\n const statusResult = await client.checkTokenStatus(code);\n\n if (!statusResult.success) {\n // Network error, continue polling\n continue;\n }\n\n const status = statusResult.data?.status;\n\n if (status === \"ready\") {\n // Authorization complete, exchange for token\n const tokenResult = await client.exchangeToken(code, deviceName);\n\n if (tokenResult.success && tokenResult.data) {\n // Save the API key\n client.saveApiKey(tokenResult.data.api_key);\n\n // Verify and get user info\n const authResult = await client.authenticate();\n\n logger.blank();\n logger.success(\"Login successful!\");\n logger.blank();\n\n if (authResult.success && authResult.data) {\n logger.info(`Welcome, ${authResult.data.user.name}!`);\n logger.dim(`Email: ${authResult.data.user.email}`);\n }\n\n logger.blank();\n\n // Auto-start daemon and install service\n await autoStartDaemon();\n\n logger.dim(\"Your patterns and skills will now sync with the Skillo platform.\");\n return;\n } else {\n logger.blank();\n logger.error(\"Failed to complete login: \" + (tokenResult.error || \"Unknown error\"));\n return;\n }\n } else if (status === \"expired\") {\n logger.blank();\n logger.error(\"Authorization expired. Please try again.\");\n return;\n } else if (status === \"used\") {\n logger.blank();\n logger.error(\"This authorization code has already been used.\");\n return;\n } else if (status === \"not_found\") {\n logger.blank();\n logger.error(\"Authorization code not found. Please try again.\");\n return;\n }\n\n // Still pending, continue polling\n }\n\n // Timeout\n logger.blank();\n logger.error(\"Authorization timed out. Please try again.\");\n });\n\nexport const logoutCommand = new Command(\"logout\")\n .description(\"Logout from Skillo platform\")\n .action(async () => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.dim(\"Not logged in.\");\n return;\n }\n\n client.clearApiKey();\n logger.success(\"Logged out successfully.\");\n logger.blank();\n logger.dim(\"Your local data remains intact. Use 'skillo login' to reconnect.\");\n });\n\nexport const whoamiCommand = new Command(\"whoami\")\n .description(\"Show current login status\")\n .action(async () => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.dim(\"Not logged in.\");\n logger.blank();\n logger.dim(\"Use 'skillo login' to connect to the Skillo platform.\");\n return;\n }\n\n logger.info(`API key: ${client.getMaskedApiKey()}`);\n logger.dim(\"Checking authentication...\");\n\n const result = await client.authenticate();\n\n if (result.success && result.data) {\n logger.blank();\n logger.success(\"Authenticated\");\n logger.blank();\n logger.table([\n [\"Name\", result.data.user.name],\n [\"Email\", result.data.user.email],\n [\"User ID\", result.data.user.id],\n ]);\n } else {\n logger.blank();\n logger.warn(\"Authentication failed: \" + (result.error || \"Unknown error\"));\n logger.dim(\"Your API key may be invalid or expired.\");\n logger.dim(\"Use 'skillo logout' then 'skillo login' to re-authenticate.\");\n }\n\n logger.blank();\n });\n","/**\n * Sync commands - Sync data with Skillo platform.\n */\n\nimport { existsSync, writeFileSync, mkdirSync } from \"fs\";\nimport { join } from \"path\";\nimport { Command } from \"commander\";\nimport { getApiClient } from \"../core/api-client.js\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport { getDbPath, getSkillsDir, ensureDirectory } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\n\nexport const syncCommand = new Command(\"sync\")\n .description(\"Sync data with Skillo platform\")\n .option(\"--push\", \"Push local data to platform\")\n .option(\"--pull\", \"Pull data from platform\")\n .option(\"--patterns\", \"Sync patterns only\")\n .option(\"--skills\", \"Sync skills only\")\n .option(\"--commands\", \"Sync commands only\")\n .action(\n async (options: {\n push?: boolean;\n pull?: boolean;\n patterns?: boolean;\n skills?: boolean;\n commands?: boolean;\n }) => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n return;\n }\n\n // Default to pull if neither specified\n const doPush = options.push || false;\n const doPull = options.pull || (!options.push && !options.pull);\n\n // Default to all if none specified\n const syncPatterns = options.patterns || (!options.patterns && !options.skills && !options.commands);\n const syncSkills = options.skills || (!options.patterns && !options.skills && !options.commands);\n const syncCommands = options.commands || (!options.patterns && !options.skills && !options.commands);\n\n // Check database exists\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n return;\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n\n try {\n if (doPush) {\n logger.bold(\"Pushing local data to platform...\");\n logger.blank();\n\n if (syncCommands) {\n await pushCommands(db, client);\n }\n\n if (syncPatterns) {\n await pushPatterns(db, client);\n }\n\n if (syncSkills) {\n logger.dim(\"Skill push not yet implemented.\");\n }\n }\n\n if (doPull) {\n logger.bold(\"Pulling data from platform...\");\n logger.blank();\n\n const type = syncSkills && syncPatterns ? \"all\" : syncSkills ? \"skills\" : \"patterns\";\n const result = await client.downloadData(type);\n\n if (!result.success) {\n logger.error(\"Failed to download: \" + result.error);\n return;\n }\n\n if (result.data?.skills && syncSkills) {\n await pullSkills(result.data.skills);\n }\n\n if (result.data?.patterns && syncPatterns) {\n logger.success(`Downloaded ${result.data.patterns.length} patterns`);\n // Patterns are stored in platform, not locally synced back\n }\n }\n\n logger.blank();\n logger.success(\"Sync complete!\");\n } finally {\n db.close();\n }\n\n logger.blank();\n }\n );\n\n/**\n * Push commands to platform\n */\nasync function pushCommands(db: SkilloDatabase, client: ReturnType<typeof getApiClient>) {\n const commands = await db.getRecentCommands({ days: 7 });\n\n if (commands.length === 0) {\n logger.dim(\"No commands to sync.\");\n return;\n }\n\n logger.info(`Syncing ${commands.length} commands...`);\n\n const result = await client.syncCommands(\n commands.map((cmd) => ({\n timestamp: cmd.timestamp,\n command: cmd.command,\n normalized: cmd.normalized,\n cwd: cmd.cwd,\n exitCode: cmd.exitCode,\n durationMs: cmd.durationMs,\n variables: cmd.variables ? JSON.parse(cmd.variables) : null,\n }))\n );\n\n if (result.success) {\n logger.success(`Synced ${commands.length} commands`);\n } else {\n logger.error(\"Failed to sync commands: \" + result.error);\n }\n}\n\n/**\n * Push patterns to platform\n */\nasync function pushPatterns(db: SkilloDatabase, client: ReturnType<typeof getApiClient>) {\n const patterns = await db.getPatterns({ status: \"active\" });\n\n if (patterns.length === 0) {\n logger.dim(\"No patterns to sync.\");\n return;\n }\n\n logger.info(`Syncing ${patterns.length} patterns...`);\n\n let synced = 0;\n for (const pattern of patterns) {\n const result = await client.syncPattern({\n sourceType: pattern.sourceType,\n name: pattern.description.substring(0, 100),\n description: pattern.description,\n commands: pattern.data.commands as string[] || [],\n frequency: pattern.count,\n firstSeen: pattern.firstSeen,\n lastSeen: pattern.lastSeen,\n });\n\n if (result.success) {\n synced++;\n }\n }\n\n logger.success(`Synced ${synced}/${patterns.length} patterns`);\n}\n\n/**\n * Pull skills from platform and write to ~/.claude/skills/\n */\nasync function pullSkills(\n skills: Array<{\n id: string;\n name: string;\n slug: string;\n description: string;\n content: string;\n commands: string[];\n }>\n) {\n if (skills.length === 0) {\n logger.dim(\"No skills to download.\");\n return;\n }\n\n const skillsDir = getSkillsDir();\n ensureDirectory(skillsDir);\n\n let downloaded = 0;\n for (const skill of skills) {\n if (!skill.content) continue;\n\n const skillDir = join(skillsDir, skill.slug);\n const skillFile = join(skillDir, \"SKILL.md\");\n\n // Create skill directory\n if (!existsSync(skillDir)) {\n mkdirSync(skillDir, { recursive: true });\n }\n\n // Write SKILL.md\n writeFileSync(skillFile, skill.content, \"utf-8\");\n downloaded++;\n logger.dim(` Downloaded: ${skill.name}`);\n }\n\n logger.success(`Downloaded ${downloaded} skills to ~/.claude/skills/`);\n}\n","/**\n * Tray command — starts the system tray icon.\n */\n\nimport { Command } from \"commander\";\nimport logger from \"../utils/logger.js\";\n\nexport const trayCommand = new Command(\"tray\")\n .description(\"Start the system tray icon\")\n .action(async () => {\n try {\n const { startTray } = await import(\"../tray/tray.js\");\n await startTray();\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"Cannot find module\")) {\n logger.error(\"System tray not available. The systray2 package may not be installed.\");\n logger.dim(\"Try: npm install -g skillo\");\n } else {\n logger.error(`Tray error: ${error instanceof Error ? error.message : error}`);\n }\n process.exit(1);\n }\n });\n"],"mappings":"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","names":["Command","path","existsSync","readFileSync","Command","existsSync","os","existsSync","readFileSync","Command","existsSync","readFileSync","Command","Command","existsSync","readFileSync","existsSync","Command","chalk","Command","existsSync","getApiClient","writeFileSync","mkdirSync","join","getSkillsDir","ensureDirectory","existsSync","readdirSync","join","Command","chalk","Command","existsSync","readdirSync","join","existsSync","writeFileSync","readFileSync","homedir","join","Command","path","Command","existsSync","getApiClient","homedir","join","writeFileSync","readFileSync","existsSync","readFileSync","writeFileSync","unlinkSync","Command","isDaemonRunning","existsSync","readFileSync","unlinkSync","writeFileSync","getDefaultConfig","saveConfig","SkilloDatabase","getConfigDir","getSkillsDir","getApiClient","hostname","Command","spawn","Command","existsSync","readFileSync","writeFileSync","unlinkSync","Command","existsSync","readFileSync","unlinkSync","writeFileSync","Command","Command","Command","existsSync","writeFileSync","execSync","join","dirname","basename","execSync","Command","writeFileSync","isDaemonRunning","existsSync","Command","platform","resolve","isDaemonRunning","Command","existsSync","writeFileSync","mkdirSync","join","Command","Command","existsSync","join","mkdirSync","writeFileSync","Command","Command","Command"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/utils/logger.ts","../src/commands/status.ts","../src/utils/os-service.ts","../src/commands/config.ts","../src/commands/patterns.ts","../src/commands/skills.ts","../src/commands/shell.ts","../src/commands/daemon.ts","../src/commands/session.ts","../src/commands/claude.ts","../src/commands/project.ts","../src/utils/git.ts","../src/commands/auth.ts","../src/commands/sync.ts","../src/commands/tray.ts"],"sourcesContent":["/**\n * Skillo CLI - Autonomous workflow learning & skill generation system.\n *\n * Learn workflows by observation, not explanation.\n */\n\nimport { Command } from \"commander\";\nimport {\n initCommand,\n statusCommand,\n configCommand,\n patternsCommand,\n skillsCommand,\n shellCommand,\n recordCommand,\n setupShellCommand,\n startCommand,\n stopCommand,\n logsCommand,\n sessionCommand,\n sessionAutoCommand,\n claudeCommand,\n projectCommand,\n trackCommand,\n untrackCommand,\n} from \"./commands/index.js\";\nimport { loginCommand, logoutCommand, whoamiCommand } from \"./commands/auth.js\";\nimport { syncCommand } from \"./commands/sync.js\";\nimport { serviceCommand } from \"./commands/daemon.js\";\nimport { trayCommand } from \"./commands/tray.js\";\n\nconst VERSION = \"0.2.4\";\n\nconst program = new Command();\n\nprogram\n .name(\"skillo\")\n .description(\n `Skillo - Learn workflows by observation, not explanation.\n\nObserve your terminal and Claude Code workflows, detect patterns,\nand automatically generate reusable AI skills.\n\nQuick Start:\n $ skillo init # Initialize Skillo\n $ skillo login <key> # Connect to Skillo platform\n $ skillo shell # Launch a tracked shell session\n $ skillo sync # Sync skills from platform`\n )\n .version(VERSION, \"-v, --version\", \"Show version number\")\n .option(\"--debug\", \"Enable debug output\");\n\n// Register commands\nprogram.addCommand(initCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(patternsCommand);\nprogram.addCommand(skillsCommand);\nprogram.addCommand(shellCommand);\nprogram.addCommand(recordCommand);\nprogram.addCommand(setupShellCommand);\nprogram.addCommand(startCommand);\nprogram.addCommand(stopCommand);\nprogram.addCommand(logsCommand);\n\n// Auth and sync commands\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\nprogram.addCommand(whoamiCommand);\nprogram.addCommand(syncCommand);\n\n// Session management\nprogram.addCommand(sessionCommand);\nprogram.addCommand(sessionAutoCommand);\n\n// Claude Code integration\nprogram.addCommand(claudeCommand);\n\n// Project tracking (privacy-first)\nprogram.addCommand(projectCommand);\nprogram.addCommand(trackCommand);\nprogram.addCommand(untrackCommand);\n\n// Service and tray management\nprogram.addCommand(serviceCommand);\nprogram.addCommand(trayCommand);\n\n// Version command\nprogram\n .command(\"version\")\n .description(\"Show version information\")\n .action(() => {\n console.log(`Skillo v${VERSION}`);\n console.log(\"Autonomous workflow learning & skill generation system\");\n });\n\n// Parse and execute\nprogram.parse();\n","/**\n * Initialize Skillo configuration and directories.\n */\n\nimport { existsSync } from \"fs\";\nimport { Command } from \"commander\";\nimport { getDefaultConfig, saveConfig } from \"../core/config.js\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport {\n getDataDir,\n getConfigDir,\n getSkillsDir,\n getConfigFile,\n ensureDirectory,\n} from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\n\nexport const initCommand = new Command(\"init\")\n .description(\"Initialize Skillo configuration and directories\")\n .option(\"-f, --force\", \"Overwrite existing configuration\")\n .action(async (options: { force?: boolean }) => {\n logger.blank();\n logger.bold(\"Initializing Skillo...\");\n logger.blank();\n\n const dataDir = getDataDir();\n const configDir = getConfigDir();\n const skillsDir = getSkillsDir();\n const configFile = getConfigFile();\n\n // Check if already initialized\n if (existsSync(configFile) && !options.force) {\n logger.warn(\"Skillo is already initialized.\");\n logger.dim(\"Use --force to reinitialize and overwrite configuration.\");\n return;\n }\n\n // Create directories\n const directories = [\n { path: dataDir, name: \"~/.skillo/\" },\n { path: configDir, name: \"~/.config/skillo/\" },\n { path: skillsDir, name: \"~/.claude/skills/\" },\n ];\n\n for (const { path, name } of directories) {\n if (ensureDirectory(path)) {\n logger.success(`Created ${name}`);\n } else {\n logger.dim(` [-] ${name} already exists`);\n }\n }\n\n // Create default configuration\n const config = getDefaultConfig();\n saveConfig(config);\n logger.success(\"Created default configuration\");\n\n // Initialize database\n const db = new SkilloDatabase();\n await db.initialize();\n db.close();\n logger.success(\"Initialized database\");\n\n logger.blank();\n logger.bold(\"Skillo initialized successfully!\");\n logger.blank();\n\n // Show next steps\n logger.box(\n \"Next steps:\",\n `1. Start the daemon:\n skillo start\n\n2. Use the tracked shell:\n skillo shell\n\n3. Work normally - Skillo will notify you of patterns!`\n );\n\n logger.blank();\n });\n","/**\n * Logger utilities for Skillo CLI.\n * Uses chalk for colored output.\n */\n\nimport chalk from \"chalk\";\n\nexport const logger = {\n info: (message: string) => {\n console.log(chalk.cyan(message));\n },\n\n success: (message: string) => {\n console.log(chalk.green(`[+] ${message}`));\n },\n\n warn: (message: string) => {\n console.log(chalk.yellow(`[!] ${message}`));\n },\n\n error: (message: string) => {\n console.log(chalk.red(`[x] ${message}`));\n },\n\n dim: (message: string) => {\n console.log(chalk.dim(message));\n },\n\n bold: (message: string) => {\n console.log(chalk.bold(message));\n },\n\n highlight: (message: string) => {\n console.log(chalk.bold.cyan(message));\n },\n\n // Status indicators\n running: (message: string) => {\n console.log(chalk.green(`(*) ${message}`));\n },\n\n stopped: (message: string) => {\n console.log(chalk.dim(`(-) ${message}`));\n },\n\n // For lists and tables\n item: (label: string, value: string | number) => {\n console.log(` ${chalk.dim(label)}: ${chalk.white(value)}`);\n },\n\n // Blank line\n blank: () => {\n console.log();\n },\n\n // Box/panel output\n box: (title: string, content: string) => {\n const lines = content.split(\"\\n\");\n const maxLen = Math.max(title.length, ...lines.map((l) => l.length));\n const border = \"─\".repeat(maxLen + 2);\n\n console.log(chalk.dim(`┌${border}┐`));\n console.log(chalk.dim(\"│ \") + chalk.bold(title.padEnd(maxLen)) + chalk.dim(\" │\"));\n console.log(chalk.dim(`├${border}┤`));\n lines.forEach((line) => {\n console.log(chalk.dim(\"│ \") + line.padEnd(maxLen) + chalk.dim(\" │\"));\n });\n console.log(chalk.dim(`└${border}┘`));\n },\n\n // Table output\n table: (rows: Array<[string, string | number]>) => {\n const maxLabel = Math.max(...rows.map(([label]) => label.length));\n rows.forEach(([label, value]) => {\n console.log(` ${chalk.dim(label.padEnd(maxLabel))} ${chalk.white(value)}`);\n });\n },\n};\n\nexport default logger;\n","/**\n * Show daemon status and statistics.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport { getDataDir, getPidFile, getLogFile, getDbPath } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\nimport { getServiceStatus } from \"../utils/os-service.js\";\n\nfunction isDaemonRunning(): { running: boolean; pid: number | null } {\n const pidFile = getPidFile();\n\n if (!existsSync(pidFile)) {\n return { running: false, pid: null };\n }\n\n try {\n const pidStr = readFileSync(pidFile, \"utf-8\").trim();\n const pid = parseInt(pidStr, 10);\n\n if (isNaN(pid)) {\n return { running: false, pid: null };\n }\n\n // Check if process is running\n try {\n process.kill(pid, 0);\n return { running: true, pid };\n } catch {\n // Process doesn't exist\n return { running: false, pid: null };\n }\n } catch {\n return { running: false, pid: null };\n }\n}\n\nexport const statusCommand = new Command(\"status\")\n .description(\"Show daemon status and statistics\")\n .action(async () => {\n logger.blank();\n\n const { running, pid } = isDaemonRunning();\n\n if (running) {\n logger.running(`Daemon is running (PID: ${pid})`);\n } else {\n logger.stopped(\"Daemon is not running\");\n logger.blank();\n logger.dim(\"Start with: skillo start\");\n }\n\n // Show auto-start status\n const serviceStatus = getServiceStatus();\n if (serviceStatus.daemon.installed) {\n logger.running(\"Auto-start: enabled\");\n } else {\n logger.stopped(\"Auto-start: disabled\");\n logger.dim(\" Enable with: skillo service install\");\n }\n\n if (!running) return;\n\n logger.blank();\n\n // Check if database exists\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.warn(\"Database not found. Run 'skillo init' first.\");\n return;\n }\n\n // Show statistics from database\n const db = new SkilloDatabase();\n await db.initialize();\n const stats = await db.getStats();\n db.close();\n\n logger.table([\n [\"Commands tracked (today)\", stats.commandsToday],\n [\"Commands tracked (total)\", stats.commandsTotal],\n [\"Active patterns\", stats.patternsActive],\n [\"Skills generated\", stats.skillsTotal],\n [\"Conversations analyzed\", stats.conversationsTotal],\n ]);\n\n logger.blank();\n\n // Show log tail\n const logFile = getLogFile();\n if (existsSync(logFile)) {\n logger.dim(\"Recent log entries:\");\n try {\n const content = readFileSync(logFile, \"utf-8\");\n const lines = content.split(\"\\n\").filter(Boolean).slice(-5);\n lines.forEach((line) => {\n logger.dim(` ${line}`);\n });\n } catch {\n // Ignore log read errors\n }\n }\n\n logger.blank();\n });\n","/**\n * OS Service Manager — install/uninstall auto-start services.\n *\n * macOS: LaunchAgent plist (user-level, no sudo)\n * Linux: systemd user service (no sudo)\n * Windows: Registry Run key + VBScript hidden launcher (no admin)\n *\n * Creates two services:\n * 1. Daemon service — headless background daemon\n * 2. Tray service — GUI tray icon (only in graphical sessions)\n */\n\nimport { existsSync, writeFileSync, unlinkSync, readFileSync, mkdirSync, readdirSync } from \"fs\";\nimport { join, dirname } from \"path\";\nimport { homedir, platform } from \"os\";\nimport { execSync } from \"child_process\";\n\nconst DAEMON_LABEL = \"one.skillo.daemon\";\nconst TRAY_LABEL = \"one.skillo.tray\";\n\n// Windows registry key and value names\nconst WIN_REG_KEY = \"HKCU\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\";\nconst WIN_DAEMON_VALUE = \"SkilloDaemon\";\nconst WIN_TRAY_VALUE = \"SkilloTray\";\n\nconst isWin = platform() === \"win32\";\nconst pathSep = isWin ? \";\" : \":\";\n\n// ── Path helpers ────────────────────────────────────────────────────────────\n\nfunction getLaunchAgentsDir(): string {\n return join(homedir(), \"Library\", \"LaunchAgents\");\n}\n\nfunction getSystemdUserDir(): string {\n return join(homedir(), \".config\", \"systemd\", \"user\");\n}\n\nfunction getDaemonPlistPath(): string {\n return join(getLaunchAgentsDir(), `${DAEMON_LABEL}.plist`);\n}\n\nfunction getTrayPlistPath(): string {\n return join(getLaunchAgentsDir(), `${TRAY_LABEL}.plist`);\n}\n\nfunction getDaemonServicePath(): string {\n return join(getSystemdUserDir(), \"skillo-daemon.service\");\n}\n\nfunction getTrayServicePath(): string {\n return join(getSystemdUserDir(), \"skillo-tray.service\");\n}\n\n/** Get the ~/.skillo/ directory for placing Windows launcher scripts */\nfunction getSkilloDataDir(): string {\n return join(homedir(), \".skillo\");\n}\n\nfunction getWinDaemonVbsPath(): string {\n return join(getSkilloDataDir(), \"skillo-daemon.vbs\");\n}\n\n/** Find the skillo binary path */\nfunction findSkilloBin(): string {\n try {\n const whichCmd = isWin ? \"where skillo\" : \"which skillo\";\n const result = execSync(whichCmd, { encoding: \"utf-8\" }).trim();\n // `where` on Windows can return multiple lines; take the first\n const firstLine = result.split(/\\r?\\n/)[0].trim();\n if (firstLine) return firstLine;\n } catch {\n // fallback\n }\n\n if (isWin) {\n // Common Windows locations\n const appData = process.env.APPDATA || join(homedir(), \"AppData\", \"Roaming\");\n const candidates = [\n join(appData, \"npm\", \"skillo.cmd\"),\n join(homedir(), \"AppData\", \"Local\", \"fnm_multishells\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n } else {\n const candidates = [\n \"/usr/local/bin/skillo\",\n \"/usr/bin/skillo\",\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n }\n\n return \"skillo\"; // Rely on PATH\n}\n\n/** Build a broad PATH that includes common Node.js install locations */\nfunction buildPath(): string {\n const paths = new Set<string>();\n const home = homedir();\n\n // Current PATH\n (process.env.PATH || \"\").split(pathSep).forEach((p) => paths.add(p));\n\n if (isWin) {\n // Windows-specific Node.js locations\n const appData = process.env.APPDATA || join(home, \"AppData\", \"Roaming\");\n paths.add(join(appData, \"npm\"));\n paths.add(join(home, \"AppData\", \"Local\", \"Programs\", \"nodejs\"));\n\n // nvm-windows\n const nvmHome = process.env.NVM_HOME;\n if (nvmHome) paths.add(nvmHome);\n const nvmSymlink = process.env.NVM_SYMLINK;\n if (nvmSymlink) paths.add(nvmSymlink);\n\n // fnm on Windows\n const fnmDir = join(home, \".fnm\");\n if (existsSync(fnmDir)) paths.add(fnmDir);\n } else {\n // nvm (macOS/Linux)\n const nvmDir = process.env.NVM_DIR || join(home, \".nvm\");\n if (existsSync(nvmDir)) {\n try {\n const defaultAlias = join(nvmDir, \"alias\", \"default\");\n if (existsSync(defaultAlias)) {\n const versionsDir = join(nvmDir, \"versions\", \"node\");\n if (existsSync(versionsDir)) {\n const versions = readdirSync(versionsDir) as string[];\n for (const v of versions) {\n paths.add(join(versionsDir, v, \"bin\"));\n }\n }\n }\n } catch {\n // ignore\n }\n }\n\n // fnm\n paths.add(join(home, \".fnm\", \"current\", \"bin\"));\n\n // Homebrew\n paths.add(\"/opt/homebrew/bin\");\n paths.add(\"/usr/local/bin\");\n\n // Standard\n paths.add(\"/usr/bin\");\n paths.add(\"/bin\");\n\n // npm global\n paths.add(join(home, \".npm-global\", \"bin\"));\n paths.add(join(home, \".local\", \"bin\"));\n }\n\n return [...paths].filter(Boolean).join(pathSep);\n}\n\n// ── macOS LaunchAgent ───────────────────────────────────────────────────────\n\nfunction generateDaemonPlist(skilloBin: string, envPath: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${DAEMON_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${skilloBin}</string>\n <string>start</string>\n <string>--foreground</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n <string>${envPath}</string>\n <key>HOME</key>\n <string>${homedir()}</string>\n </dict>\n <key>StandardOutPath</key>\n <string>${join(homedir(), \".skillo\", \"launchd-stdout.log\")}</string>\n <key>StandardErrorPath</key>\n <string>${join(homedir(), \".skillo\", \"launchd-stderr.log\")}</string>\n</dict>\n</plist>`;\n}\n\nfunction generateTrayPlist(skilloBin: string, envPath: string): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${TRAY_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${skilloBin}</string>\n <string>tray</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>LimitLoadToSessionType</key>\n <string>Aqua</string>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n <string>${envPath}</string>\n <key>HOME</key>\n <string>${homedir()}</string>\n </dict>\n <key>StandardOutPath</key>\n <string>${join(homedir(), \".skillo\", \"launchd-tray-stdout.log\")}</string>\n <key>StandardErrorPath</key>\n <string>${join(homedir(), \".skillo\", \"launchd-tray-stderr.log\")}</string>\n</dict>\n</plist>`;\n}\n\n// ── Linux systemd ───────────────────────────────────────────────────────────\n\nfunction generateDaemonUnit(skilloBin: string, envPath: string): string {\n return `[Unit]\nDescription=Skillo Daemon\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=${skilloBin} start --foreground\nRestart=on-failure\nRestartSec=10\nEnvironment=PATH=${envPath}\nEnvironment=HOME=${homedir()}\n\n[Install]\nWantedBy=default.target\n`;\n}\n\nfunction generateTrayUnit(skilloBin: string, envPath: string): string {\n return `[Unit]\nDescription=Skillo Tray Icon\nAfter=graphical-session.target\nPartOf=graphical-session.target\n\n[Service]\nType=simple\nExecStart=${skilloBin} tray\nRestart=on-failure\nRestartSec=10\nEnvironment=PATH=${envPath}\nEnvironment=HOME=${homedir()}\nEnvironment=DISPLAY=:0\n\n[Install]\nWantedBy=graphical-session.target\n`;\n}\n\n// ── Windows Registry + VBScript ─────────────────────────────────────────────\n\n/**\n * Generate a VBScript that runs the daemon hidden (no console window).\n * WScript.Shell Run(..., 0, False) → windowStyle=hidden, waitOnReturn=false.\n */\nfunction generateDaemonVbs(skilloBin: string): string {\n // Escape backslashes for VBS string literal\n const escaped = skilloBin.replace(/\\\\/g, \"\\\\\\\\\");\n return `' Skillo Daemon — hidden launcher\\r\\nSet WshShell = CreateObject(\"WScript.Shell\")\\r\\nWshShell.Run \"\"\"${escaped}\"\" start --foreground\", 0, False\\r\\n`;\n}\n\nfunction winRegAdd(valueName: string, data: string) {\n // /f = force overwrite without prompt\n execSync(\n `reg add \"${WIN_REG_KEY}\" /v \"${valueName}\" /t REG_SZ /d \"${data}\" /f`,\n { stdio: \"ignore\" }\n );\n}\n\nfunction winRegDelete(valueName: string) {\n try {\n execSync(\n `reg delete \"${WIN_REG_KEY}\" /v \"${valueName}\" /f`,\n { stdio: \"ignore\" }\n );\n } catch {\n // Value may not exist\n }\n}\n\nfunction winRegExists(valueName: string): boolean {\n try {\n execSync(`reg query \"${WIN_REG_KEY}\" /v \"${valueName}\"`, { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\n// ── Public API ──────────────────────────────────────────────────────────────\n\nexport interface ServiceStatus {\n platform: \"macos\" | \"linux\" | \"windows\" | \"unsupported\";\n daemon: { installed: boolean; loaded: boolean };\n tray: { installed: boolean; loaded: boolean };\n}\n\nexport async function installService(options?: { includeTray?: boolean }): Promise<{ success: boolean; error?: string }> {\n const os = platform();\n const skilloBin = findSkilloBin();\n const envPath = buildPath();\n const includeTray = options?.includeTray ?? true;\n\n try {\n if (os === \"darwin\") {\n // ── macOS LaunchAgent ──\n const agentsDir = getLaunchAgentsDir();\n if (!existsSync(agentsDir)) mkdirSync(agentsDir, { recursive: true });\n\n // Daemon\n const daemonPlist = getDaemonPlistPath();\n writeFileSync(daemonPlist, generateDaemonPlist(skilloBin, envPath), \"utf-8\");\n try { execSync(`launchctl unload \"${daemonPlist}\" 2>/dev/null`); } catch { /* ignore */ }\n execSync(`launchctl load \"${daemonPlist}\"`);\n\n // Tray\n if (includeTray) {\n const trayPlist = getTrayPlistPath();\n writeFileSync(trayPlist, generateTrayPlist(skilloBin, envPath), \"utf-8\");\n try { execSync(`launchctl unload \"${trayPlist}\" 2>/dev/null`); } catch { /* ignore */ }\n execSync(`launchctl load \"${trayPlist}\"`);\n }\n\n return { success: true };\n\n } else if (os === \"linux\") {\n // ── Linux systemd ──\n const systemdDir = getSystemdUserDir();\n if (!existsSync(systemdDir)) mkdirSync(systemdDir, { recursive: true });\n\n // Daemon\n writeFileSync(getDaemonServicePath(), generateDaemonUnit(skilloBin, envPath), \"utf-8\");\n execSync(\"systemctl --user daemon-reload\");\n execSync(\"systemctl --user enable skillo-daemon.service\");\n execSync(\"systemctl --user start skillo-daemon.service\");\n\n // Tray\n if (includeTray) {\n writeFileSync(getTrayServicePath(), generateTrayUnit(skilloBin, envPath), \"utf-8\");\n execSync(\"systemctl --user daemon-reload\");\n execSync(\"systemctl --user enable skillo-tray.service\");\n try { execSync(\"systemctl --user start skillo-tray.service\"); } catch { /* may not have graphical session */ }\n }\n\n return { success: true };\n\n } else if (os === \"win32\") {\n // ── Windows Registry Run + VBScript ──\n const dataDir = getSkilloDataDir();\n if (!existsSync(dataDir)) mkdirSync(dataDir, { recursive: true });\n\n // Daemon: write a VBScript launcher that hides the console window,\n // then point the registry Run key at the VBS file.\n const vbsPath = getWinDaemonVbsPath();\n writeFileSync(vbsPath, generateDaemonVbs(skilloBin), \"utf-8\");\n winRegAdd(WIN_DAEMON_VALUE, `wscript.exe \"${vbsPath}\"`);\n\n // Tray: runs directly (it has its own window)\n if (includeTray) {\n winRegAdd(WIN_TRAY_VALUE, `\"${skilloBin}\" tray`);\n }\n\n return { success: true };\n\n } else {\n return { success: false, error: `Unsupported platform: ${os}. Auto-start is available on macOS, Linux, and Windows.` };\n }\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n}\n\nexport async function uninstallService(): Promise<{ success: boolean; error?: string }> {\n const os = platform();\n\n try {\n if (os === \"darwin\") {\n // Unload and remove daemon\n const daemonPlist = getDaemonPlistPath();\n if (existsSync(daemonPlist)) {\n try { execSync(`launchctl unload \"${daemonPlist}\" 2>/dev/null`); } catch { /* ignore */ }\n unlinkSync(daemonPlist);\n }\n\n // Unload and remove tray\n const trayPlist = getTrayPlistPath();\n if (existsSync(trayPlist)) {\n try { execSync(`launchctl unload \"${trayPlist}\" 2>/dev/null`); } catch { /* ignore */ }\n unlinkSync(trayPlist);\n }\n\n return { success: true };\n\n } else if (os === \"linux\") {\n // Stop, disable, remove daemon\n const daemonService = getDaemonServicePath();\n if (existsSync(daemonService)) {\n try { execSync(\"systemctl --user stop skillo-daemon.service 2>/dev/null\"); } catch { /* ignore */ }\n try { execSync(\"systemctl --user disable skillo-daemon.service 2>/dev/null\"); } catch { /* ignore */ }\n unlinkSync(daemonService);\n }\n\n // Stop, disable, remove tray\n const trayService = getTrayServicePath();\n if (existsSync(trayService)) {\n try { execSync(\"systemctl --user stop skillo-tray.service 2>/dev/null\"); } catch { /* ignore */ }\n try { execSync(\"systemctl --user disable skillo-tray.service 2>/dev/null\"); } catch { /* ignore */ }\n unlinkSync(trayService);\n }\n\n try { execSync(\"systemctl --user daemon-reload\"); } catch { /* ignore */ }\n\n return { success: true };\n\n } else if (os === \"win32\") {\n // Remove registry entries\n winRegDelete(WIN_DAEMON_VALUE);\n winRegDelete(WIN_TRAY_VALUE);\n\n // Remove VBS launcher\n const vbsPath = getWinDaemonVbsPath();\n if (existsSync(vbsPath)) {\n try { unlinkSync(vbsPath); } catch { /* ignore */ }\n }\n\n return { success: true };\n\n } else {\n return { success: false, error: `Unsupported platform: ${os}` };\n }\n } catch (error) {\n return { success: false, error: error instanceof Error ? error.message : String(error) };\n }\n}\n\nexport function getServiceStatus(): ServiceStatus {\n const os = platform();\n\n if (os === \"darwin\") {\n const daemonInstalled = existsSync(getDaemonPlistPath());\n const trayInstalled = existsSync(getTrayPlistPath());\n\n let daemonLoaded = false;\n let trayLoaded = false;\n\n try {\n const output = execSync(\"launchctl list\", { encoding: \"utf-8\" });\n daemonLoaded = output.includes(DAEMON_LABEL);\n trayLoaded = output.includes(TRAY_LABEL);\n } catch {\n // ignore\n }\n\n return {\n platform: \"macos\",\n daemon: { installed: daemonInstalled, loaded: daemonLoaded },\n tray: { installed: trayInstalled, loaded: trayLoaded },\n };\n\n } else if (os === \"linux\") {\n const daemonInstalled = existsSync(getDaemonServicePath());\n const trayInstalled = existsSync(getTrayServicePath());\n\n let daemonLoaded = false;\n let trayLoaded = false;\n\n try {\n execSync(\"systemctl --user is-active skillo-daemon.service\", { encoding: \"utf-8\" });\n daemonLoaded = true;\n } catch { /* not active */ }\n\n try {\n execSync(\"systemctl --user is-active skillo-tray.service\", { encoding: \"utf-8\" });\n trayLoaded = true;\n } catch { /* not active */ }\n\n return {\n platform: \"linux\",\n daemon: { installed: daemonInstalled, loaded: daemonLoaded },\n tray: { installed: trayInstalled, loaded: trayLoaded },\n };\n\n } else if (os === \"win32\") {\n const daemonInstalled = winRegExists(WIN_DAEMON_VALUE);\n const trayInstalled = winRegExists(WIN_TRAY_VALUE);\n\n // On Windows, \"loaded\" = the Run key exists (it will run at next login).\n // We can't easily check if the process is currently running from the registry\n // alone, but the key existing means it *will* auto-start.\n return {\n platform: \"windows\",\n daemon: { installed: daemonInstalled, loaded: daemonInstalled },\n tray: { installed: trayInstalled, loaded: trayInstalled },\n };\n }\n\n return {\n platform: \"unsupported\",\n daemon: { installed: false, loaded: false },\n tray: { installed: false, loaded: false },\n };\n}\n","/**\n * Configuration management commands.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { Command } from \"commander\";\nimport YAML from \"yaml\";\nimport {\n loadConfig,\n saveConfig,\n getDefaultConfig,\n getConfigValue,\n setConfigValue,\n} from \"../core/config.js\";\nimport { getConfigFile } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\n\nexport const configCommand = new Command(\"config\").description(\n \"Manage Skillo configuration\"\n);\n\n// skillo config show\nconfigCommand\n .command(\"show\")\n .description(\"Show current configuration\")\n .action(async () => {\n const configFile = getConfigFile();\n\n if (!existsSync(configFile)) {\n logger.error(\"Configuration not found.\");\n logger.dim(\"Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const content = readFileSync(configFile, \"utf-8\");\n\n logger.blank();\n logger.bold(`Configuration file: ${configFile}`);\n logger.blank();\n console.log(content);\n });\n\n// skillo config get <key>\nconfigCommand\n .command(\"get <key>\")\n .description(\"Get a configuration value (use dot notation, e.g., patternDetection.minCount)\")\n .action(async (key: string) => {\n const configFile = getConfigFile();\n\n if (!existsSync(configFile)) {\n logger.error(\"Configuration not found.\");\n process.exit(1);\n }\n\n const config = loadConfig();\n const value = getConfigValue(config, key);\n\n if (value === undefined) {\n logger.error(`Key not found: ${key}`);\n process.exit(1);\n }\n\n if (typeof value === \"object\") {\n console.log(YAML.stringify(value));\n } else {\n console.log(String(value));\n }\n });\n\n// skillo config set <key> <value>\nconfigCommand\n .command(\"set <key> <value>\")\n .description(\"Set a configuration value\")\n .action(async (key: string, value: string) => {\n const configFile = getConfigFile();\n\n if (!existsSync(configFile)) {\n logger.error(\"Configuration not found.\");\n process.exit(1);\n }\n\n let config = loadConfig();\n\n // Parse value\n let parsedValue: unknown;\n if (value.toLowerCase() === \"true\") {\n parsedValue = true;\n } else if (value.toLowerCase() === \"false\") {\n parsedValue = false;\n } else if (/^\\d+$/.test(value)) {\n parsedValue = parseInt(value, 10);\n } else if (/^\\d+\\.\\d+$/.test(value)) {\n parsedValue = parseFloat(value);\n } else {\n parsedValue = value;\n }\n\n const oldValue = getConfigValue(config, key);\n config = setConfigValue(config, key, parsedValue);\n saveConfig(config);\n\n logger.success(`Updated ${key}`);\n if (oldValue !== undefined) {\n logger.dim(` ${oldValue} -> ${parsedValue}`);\n } else {\n logger.dim(` ${parsedValue}`);\n }\n });\n\n// skillo config reset\nconfigCommand\n .command(\"reset\")\n .description(\"Reset configuration to defaults\")\n .option(\"-f, --force\", \"Skip confirmation prompt\")\n .action(async (options: { force?: boolean }) => {\n if (!options.force) {\n logger.warn(\"This will reset all configuration to defaults.\");\n logger.dim(\"Use --force to confirm.\");\n return;\n }\n\n const defaultConfig = getDefaultConfig();\n saveConfig(defaultConfig);\n\n logger.success(\"Configuration reset to defaults\");\n });\n\n// skillo config path\nconfigCommand\n .command(\"path\")\n .description(\"Show configuration file path\")\n .action(async () => {\n console.log(getConfigFile());\n });\n","/**\n * Pattern management commands.\n */\n\nimport { existsSync } from \"fs\";\nimport { Command } from \"commander\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport { getDbPath } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\nimport chalk from \"chalk\";\n\nexport const patternsCommand = new Command(\"patterns\").description(\n \"Manage detected workflow patterns\"\n);\n\n// skillo patterns list\npatternsCommand\n .command(\"list\")\n .description(\"List detected patterns\")\n .option(\"-t, --type <type>\", \"Filter by type (terminal, conversation)\")\n .option(\"-s, --status <status>\", \"Filter by status (active, converted, ignored)\")\n .option(\"-n, --limit <number>\", \"Number of patterns to show\", \"20\")\n .action(async (options: { type?: string; status?: string; limit: string }) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const patterns = await db.getPatterns({\n type: options.type,\n status: options.status || \"active\",\n limit: parseInt(options.limit, 10),\n });\n db.close();\n\n if (patterns.length === 0) {\n logger.blank();\n logger.dim(\"No patterns found.\");\n logger.blank();\n logger.dim(\"Patterns are detected automatically when you use the tracked shell.\");\n logger.dim(\"Run 'skillo shell' to start tracking commands.\");\n return;\n }\n\n logger.blank();\n logger.bold(`Found ${patterns.length} pattern(s):`);\n logger.blank();\n\n patterns.forEach((pattern, index) => {\n const shortId = pattern.id.slice(0, 8);\n const statusColor =\n pattern.status === \"active\"\n ? chalk.green\n : pattern.status === \"converted\"\n ? chalk.blue\n : chalk.dim;\n\n console.log(\n ` ${chalk.cyan(shortId)} ${chalk.white(pattern.description)} ` +\n `${chalk.dim(`x${pattern.count}`)} ${statusColor(pattern.status)}`\n );\n });\n\n logger.blank();\n logger.dim(\"Use 'skillo patterns show <id>' for details\");\n logger.dim(\"Use 'skillo patterns generate <id>' to create a skill\");\n logger.blank();\n });\n\n// skillo patterns show <id>\npatternsCommand\n .command(\"show <id>\")\n .description(\"Show pattern details\")\n .action(async (id: string) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const pattern = await db.getPattern(id);\n db.close();\n\n if (!pattern) {\n logger.error(`Pattern not found: ${id}`);\n process.exit(1);\n }\n\n logger.blank();\n logger.bold(pattern.description);\n logger.blank();\n\n logger.table([\n [\"ID\", pattern.id],\n [\"Type\", pattern.sourceType],\n [\"Status\", pattern.status],\n [\"Occurrences\", pattern.count],\n [\"First seen\", new Date(pattern.firstSeen).toLocaleString()],\n [\"Last seen\", new Date(pattern.lastSeen).toLocaleString()],\n ]);\n\n logger.blank();\n\n // Show pattern data\n if (pattern.data.commands && Array.isArray(pattern.data.commands)) {\n logger.bold(\"Commands:\");\n pattern.data.commands.forEach((cmd: string, i: number) => {\n console.log(` ${chalk.dim(`${i + 1}.`)} ${cmd}`);\n });\n logger.blank();\n }\n\n if (pattern.data.description) {\n logger.bold(\"Description:\");\n logger.dim(` ${pattern.data.description}`);\n logger.blank();\n }\n\n logger.dim(\"Actions:\");\n logger.dim(` skillo patterns generate ${id.slice(0, 8)} # Create a skill`);\n logger.dim(` skillo patterns ignore ${id.slice(0, 8)} # Never suggest again`);\n logger.blank();\n });\n\n// skillo patterns ignore <id>\npatternsCommand\n .command(\"ignore <id>\")\n .description(\"Ignore a pattern (never suggest again)\")\n .option(\"-r, --reason <reason>\", \"Reason for ignoring\")\n .action(async (id: string, options: { reason?: string }) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const pattern = await db.getPattern(id);\n\n if (!pattern) {\n db.close();\n logger.error(`Pattern not found: ${id}`);\n process.exit(1);\n }\n\n await db.updatePatternStatus(id, \"ignored\");\n await db.addIgnoredPattern(pattern.id, options.reason);\n db.close();\n\n logger.success(`Pattern ignored: ${id.slice(0, 8)}`);\n if (options.reason) {\n logger.dim(` Reason: ${options.reason}`);\n }\n });\n\n// skillo patterns generate <id>\npatternsCommand\n .command(\"generate <id>\")\n .description(\"Generate a skill from a pattern\")\n .option(\"-n, --name <name>\", \"Custom skill name\")\n .option(\"--dry-run\", \"Preview without creating\")\n .action(async (id: string, options: { name?: string; dryRun?: boolean }) => {\n // Dynamic import to avoid circular deps\n const { getApiClient } = await import(\"../core/api-client.js\");\n const { writeFileSync, mkdirSync } = await import(\"fs\");\n const { join } = await import(\"path\");\n const { getSkillsDir, ensureDirectory } = await import(\"../utils/paths.js\");\n\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const pattern = await db.getPattern(id);\n\n if (!pattern) {\n db.close();\n logger.error(`Pattern not found: ${id}`);\n process.exit(1);\n }\n\n logger.blank();\n logger.bold(pattern.description);\n logger.blank();\n\n // Check if logged in\n const client = getApiClient();\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n logger.dim(\"Skill generation requires the Skillo platform.\");\n db.close();\n process.exit(1);\n }\n\n logger.info(\"Generating skill via Skillo platform...\");\n\n if (options.dryRun) {\n logger.dim(\"(dry run - skill will not be saved)\");\n }\n\n logger.blank();\n\n // Call the platform API to generate the skill\n const result = await client.generateSkill({\n commands: (pattern.data.commands as string[]) || [],\n name: options.name,\n description: pattern.description,\n category: pattern.sourceType === \"terminal\" ? \"system\" : \"other\",\n context: pattern.data as Record<string, unknown>,\n });\n\n if (!result.success || !result.data) {\n logger.error(\"Failed to generate skill: \" + (result.error || \"Unknown error\"));\n db.close();\n process.exit(1);\n }\n\n const skill = result.data.skill;\n\n logger.success(`Generated skill: ${skill.name}`);\n logger.blank();\n\n if (options.dryRun) {\n logger.bold(\"Generated SKILL.md:\");\n logger.blank();\n console.log(skill.content);\n logger.blank();\n logger.dim(\"(dry run - skill not saved)\");\n } else {\n // Write skill to ~/.claude/skills/\n const skillsDir = getSkillsDir();\n ensureDirectory(skillsDir);\n\n const skillDir = join(skillsDir, skill.slug);\n const skillFile = join(skillDir, \"SKILL.md\");\n\n mkdirSync(skillDir, { recursive: true });\n writeFileSync(skillFile, skill.content, \"utf-8\");\n\n // Update pattern status in local DB\n await db.updatePatternStatus(id, \"converted\");\n\n logger.success(`Skill saved to: ~/.claude/skills/${skill.slug}/SKILL.md`);\n logger.blank();\n logger.dim(\"The skill is now available to Claude Code!\");\n }\n\n db.close();\n });\n\n// skillo patterns clear\npatternsCommand\n .command(\"clear\")\n .description(\"Clear all patterns\")\n .option(\"-f, --force\", \"Skip confirmation\")\n .action(async (options: { force?: boolean }) => {\n if (!options.force) {\n logger.warn(\"This will delete all detected patterns.\");\n logger.dim(\"Use --force to confirm.\");\n return;\n }\n\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found.\");\n process.exit(1);\n }\n\n // TODO: Implement clear\n logger.success(\"All patterns cleared.\");\n });\n","/**\n * Skill management commands.\n */\n\nimport { existsSync, readdirSync, rmSync } from \"fs\";\nimport { join, basename } from \"path\";\nimport { Command } from \"commander\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport { getDbPath, getSkillsDir } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\nimport chalk from \"chalk\";\n\nexport const skillsCommand = new Command(\"skills\").description(\n \"Manage generated skills\"\n);\n\n// skillo skills list\nskillsCommand\n .command(\"list\")\n .description(\"List all skills\")\n .option(\"-s, --source <source>\", \"Filter by source (pattern, imported, manual)\")\n .option(\"--sort <by>\", \"Sort by (name, created, usage)\", \"name\")\n .action(async (options: { source?: string; sort: \"name\" | \"created\" | \"usage\" }) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const skills = await db.getSkills({\n source: options.source,\n sortBy: options.sort,\n });\n db.close();\n\n // Also check filesystem for skills not in DB\n const skillsDir = getSkillsDir();\n const fsSkills: string[] = [];\n if (existsSync(skillsDir)) {\n const entries = readdirSync(skillsDir, { withFileTypes: true });\n entries\n .filter((e) => e.isDirectory() && !e.name.startsWith(\".\"))\n .forEach((e) => {\n const skillMd = join(skillsDir, e.name, \"SKILL.md\");\n if (existsSync(skillMd)) {\n fsSkills.push(e.name);\n }\n });\n }\n\n const dbSkillNames = new Set(skills.map((s) => s.name));\n const unregisteredSkills = fsSkills.filter((name) => !dbSkillNames.has(name));\n\n if (skills.length === 0 && unregisteredSkills.length === 0) {\n logger.blank();\n logger.dim(\"No skills found.\");\n logger.blank();\n logger.dim(\"Generate skills from patterns with 'skillo patterns generate <id>'\");\n logger.dim(\"Or import skills with 'skillo skills import <path>'\");\n return;\n }\n\n logger.blank();\n logger.bold(`Skills (${skills.length + unregisteredSkills.length}):`);\n logger.blank();\n\n // Registered skills\n skills.forEach((skill) => {\n const sourceColor =\n skill.sourceType === \"pattern\"\n ? chalk.green\n : skill.sourceType === \"imported\"\n ? chalk.blue\n : chalk.dim;\n\n console.log(\n ` ${chalk.cyan(skill.name)} ` +\n `${sourceColor(skill.sourceType)} ` +\n `${chalk.dim(`used ${skill.usageCount}x`)}`\n );\n\n if (skill.triggerPhrase) {\n console.log(` ${chalk.dim(skill.triggerPhrase)}`);\n }\n });\n\n // Unregistered skills (found on filesystem but not in DB)\n if (unregisteredSkills.length > 0) {\n logger.blank();\n logger.dim(\" Unregistered skills (found in ~/.claude/skills/):\");\n unregisteredSkills.forEach((name) => {\n console.log(` ${chalk.yellow(name)} ${chalk.dim(\"filesystem only\")}`);\n });\n }\n\n logger.blank();\n logger.dim(\"Use 'skillo skills show <name>' for details\");\n logger.blank();\n });\n\n// skillo skills show <name>\nskillsCommand\n .command(\"show <name>\")\n .description(\"Show skill details\")\n .action(async (name: string) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const skill = await db.getSkill(name);\n db.close();\n\n if (!skill) {\n // Check if it exists on filesystem\n const skillPath = join(getSkillsDir(), name, \"SKILL.md\");\n if (existsSync(skillPath)) {\n logger.blank();\n logger.bold(name);\n logger.blank();\n logger.dim(` Path: ${join(getSkillsDir(), name)}`);\n logger.dim(` Status: Not registered in database`);\n logger.blank();\n return;\n }\n\n logger.error(`Skill not found: ${name}`);\n process.exit(1);\n }\n\n logger.blank();\n logger.bold(skill.name);\n logger.blank();\n\n logger.table([\n [\"Path\", skill.path],\n [\"Source\", skill.sourceType],\n [\"Created\", new Date(skill.createdAt).toLocaleString()],\n [\"Usage count\", skill.usageCount],\n [\"Last used\", skill.lastUsedAt ? new Date(skill.lastUsedAt).toLocaleString() : \"Never\"],\n ]);\n\n if (skill.triggerPhrase) {\n logger.blank();\n logger.bold(\"Trigger phrase:\");\n logger.dim(` ${skill.triggerPhrase}`);\n }\n\n logger.blank();\n });\n\n// skillo skills delete <name>\nskillsCommand\n .command(\"delete <name>\")\n .description(\"Delete a skill\")\n .option(\"-f, --force\", \"Skip confirmation\")\n .action(async (name: string, options: { force?: boolean }) => {\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found.\");\n process.exit(1);\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n const skill = await db.getSkill(name);\n\n const skillDir = skill?.path || join(getSkillsDir(), name);\n\n if (!skill && !existsSync(skillDir)) {\n db.close();\n logger.error(`Skill not found: ${name}`);\n process.exit(1);\n }\n\n if (!options.force) {\n logger.warn(`This will delete skill '${name}'. This cannot be undone.`);\n logger.dim(\"Use --force to confirm.\");\n db.close();\n return;\n }\n\n // Delete from filesystem\n if (existsSync(skillDir)) {\n rmSync(skillDir, { recursive: true, force: true });\n }\n\n // Delete from database\n if (skill) {\n await db.deleteSkill(name);\n }\n\n db.close();\n\n logger.success(`Skill deleted: ${name}`);\n });\n\n// skillo skills path\nskillsCommand\n .command(\"path\")\n .description(\"Show skills directory path\")\n .action(async () => {\n console.log(getSkillsDir());\n });\n\n// skillo skills open\nskillsCommand\n .command(\"open\")\n .description(\"Open skills directory in file manager\")\n .action(async () => {\n const skillsDir = getSkillsDir();\n\n if (!existsSync(skillsDir)) {\n logger.error(\"Skills directory not found. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n // Open in file manager based on platform\n const { exec } = await import(\"child_process\");\n const command =\n process.platform === \"win32\"\n ? `explorer \"${skillsDir}\"`\n : process.platform === \"darwin\"\n ? `open \"${skillsDir}\"`\n : `xdg-open \"${skillsDir}\"`;\n\n exec(command, (error) => {\n if (error) {\n logger.error(`Failed to open directory: ${error.message}`);\n logger.dim(`Path: ${skillsDir}`);\n }\n });\n });\n","/**\n * Shell command - Start a tracked terminal session.\n */\n\nimport { existsSync, writeFileSync, readFileSync, appendFileSync } from \"fs\";\nimport { spawn } from \"child_process\";\nimport { homedir } from \"os\";\nimport { join } from \"path\";\nimport { Command } from \"commander\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport { loadConfig } from \"../core/config.js\";\nimport { getDbPath, getConfigFile, ensureDirectory, getDataDir } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\n\n/**\n * Normalize a command by replacing variable parts with placeholders.\n * This helps with pattern detection.\n */\nfunction normalizeCommand(cmd: string): { normalized: string; variables: Record<string, string> } {\n const variables: Record<string, string> = {};\n let normalized = cmd;\n let varIndex = 0;\n\n // Replace file paths\n normalized = normalized.replace(/(?:^|\\s)(\\/[\\w\\-.\\/]+)/g, (match, path) => {\n const key = `$PATH${varIndex++}`;\n variables[key] = path;\n return match.replace(path, key);\n });\n\n // Replace URLs\n normalized = normalized.replace(\n /https?:\\/\\/[^\\s]+/g,\n (match) => {\n const key = `$URL${varIndex++}`;\n variables[key] = match;\n return key;\n }\n );\n\n // Replace numbers (but not in common commands)\n normalized = normalized.replace(/\\b\\d{4,}\\b/g, (match) => {\n const key = `$NUM${varIndex++}`;\n variables[key] = match;\n return key;\n });\n\n // Replace quoted strings\n normalized = normalized.replace(/\"[^\"]+\"/g, (match) => {\n const key = `$STR${varIndex++}`;\n variables[key] = match;\n return key;\n });\n\n normalized = normalized.replace(/'[^']+'/g, (match) => {\n const key = `$STR${varIndex++}`;\n variables[key] = match;\n return key;\n });\n\n return { normalized: normalized.trim(), variables };\n}\n\nexport const shellCommand = new Command(\"shell\")\n .description(\"Start a tracked terminal session\")\n .option(\"-s, --shell <shell>\", \"Shell to use (default: $SHELL or cmd on Windows)\")\n .option(\"-p, --project <path>\", \"Project path to track\")\n .action(async (options: { shell?: string; project?: string }) => {\n // Check if initialized\n if (!existsSync(getConfigFile())) {\n logger.error(\"Skillo not initialized. Run 'skillo init' first.\");\n process.exit(1);\n }\n\n const config = loadConfig();\n\n // Determine shell to use\n let shell = options.shell || config.defaultShell;\n if (!shell) {\n if (process.platform === \"win32\") {\n shell = process.env.COMSPEC || \"cmd.exe\";\n } else {\n shell = process.env.SHELL || \"/bin/bash\";\n }\n }\n\n const projectPath = options.project || process.cwd();\n\n logger.blank();\n logger.info(\"Starting tracked shell session...\");\n logger.dim(`Shell: ${shell}`);\n logger.dim(`Project: ${projectPath}`);\n logger.blank();\n logger.dim(\"All commands will be tracked. Type 'exit' to end the session.\");\n logger.blank();\n\n // Initialize database and create session\n const db = new SkilloDatabase();\n await db.initialize();\n const sessionId = await db.createSession(shell, projectPath);\n\n let commandCount = 0;\n let currentCommand = \"\";\n let commandStartTime: number | null = null;\n\n // Spawn shell process\n const shellArgs = process.platform === \"win32\" ? [] : [\"-i\"];\n\n const child = spawn(shell, shellArgs, {\n stdio: [\"inherit\", \"inherit\", \"inherit\"],\n shell: false,\n cwd: projectPath,\n env: {\n ...process.env,\n SKILLO_SESSION: sessionId,\n SKILLO_TRACKING: \"1\",\n },\n });\n\n // Handle shell exit\n child.on(\"exit\", async (code) => {\n await db.endSession(sessionId);\n db.close();\n\n logger.blank();\n logger.success(`Session ended. Tracked ${commandCount} command(s).`);\n logger.dim(`Session ID: ${sessionId.slice(0, 8)}`);\n logger.blank();\n\n process.exit(code || 0);\n });\n\n // Handle errors\n child.on(\"error\", async (error) => {\n logger.error(`Failed to start shell: ${error.message}`);\n await db.endSession(sessionId);\n db.close();\n process.exit(1);\n });\n\n // Note: For proper command tracking, we would need to use node-pty\n // or integrate with shell hooks (like bash PROMPT_COMMAND or zsh precmd)\n // This basic implementation spawns an interactive shell but doesn't\n // capture individual commands without additional shell integration.\n\n // For now, we'll rely on shell integration scripts that users can install\n // to send commands to Skillo via a local API or file-based IPC.\n });\n\n// Additional command to record a command (called by shell integration)\nexport const recordCommand = new Command(\"record\")\n .description(\"Record a command (used by shell integration)\")\n .argument(\"<command>\", \"Command that was executed\")\n .option(\"--session <id>\", \"Session ID\")\n .option(\"--cwd <path>\", \"Working directory\")\n .option(\"--exit-code <code>\", \"Exit code\")\n .option(\"--duration <ms>\", \"Duration in milliseconds\")\n .option(\"--no-sync\", \"Don't sync to platform\")\n .action(\n async (\n command: string,\n options: {\n session?: string;\n cwd?: string;\n exitCode?: string;\n duration?: string;\n sync?: boolean;\n }\n ) => {\n const cwd = options.cwd || process.cwd();\n const exitCode = options.exitCode ? parseInt(options.exitCode, 10) : null;\n const durationMs = options.duration ? parseInt(options.duration, 10) : null;\n const sessionId = options.session || process.env.SKILLO_SESSION || \"default\";\n\n const { normalized, variables } = normalizeCommand(command);\n\n // Store locally\n const db = new SkilloDatabase();\n await db.initialize();\n await db.addCommand({\n command,\n normalized,\n cwd,\n sessionId,\n exitCode,\n durationMs,\n variables: Object.keys(variables).length > 0 ? variables : null,\n });\n db.close();\n\n // Sync to platform if logged in (unless --no-sync)\n if (options.sync !== false) {\n try {\n const { getApiClient } = await import(\"../core/api-client.js\");\n const client = getApiClient();\n\n if (client.hasApiKey()) {\n await client.syncCommands([{\n timestamp: new Date().toISOString(),\n command,\n normalized,\n cwd,\n exitCode,\n durationMs,\n sessionId: sessionId !== \"default\" ? sessionId : undefined,\n variables: Object.keys(variables).length > 0 ? variables : null,\n }]);\n }\n } catch {\n // Silently ignore sync errors\n }\n }\n\n // Silent success - this is called by shell integration\n }\n );\n\n// Shell integration setup command\nexport const setupShellCommand = new Command(\"setup-shell\")\n .description(\"Set up shell integration for automatic command tracking\")\n .option(\"--bash\", \"Set up Bash integration\")\n .option(\"--zsh\", \"Set up Zsh integration\")\n .option(\"--powershell\", \"Set up PowerShell integration\")\n .option(\"--fish\", \"Set up Fish integration\")\n .option(\"--uninstall\", \"Remove shell integration\")\n .action(async (options: {\n bash?: boolean;\n zsh?: boolean;\n powershell?: boolean;\n fish?: boolean;\n uninstall?: boolean;\n }) => {\n logger.blank();\n\n const home = homedir();\n const dataDir = getDataDir();\n ensureDirectory(dataDir);\n\n // Auto-detect shell if none specified\n let shell: string | null = null;\n if (options.bash) shell = \"bash\";\n else if (options.zsh) shell = \"zsh\";\n else if (options.powershell) shell = \"powershell\";\n else if (options.fish) shell = \"fish\";\n else {\n // Auto-detect\n if (process.platform === \"win32\") {\n shell = \"powershell\";\n } else {\n const currentShell = process.env.SHELL || \"\";\n if (currentShell.includes(\"zsh\")) shell = \"zsh\";\n else if (currentShell.includes(\"fish\")) shell = \"fish\";\n else shell = \"bash\";\n }\n logger.info(`Detected shell: ${shell}`);\n }\n\n if (options.uninstall) {\n logger.info(`Removing ${shell} integration...`);\n await uninstallShellIntegration(shell, home);\n logger.success(\"Shell integration removed.\");\n logger.dim(\"Restart your terminal for changes to take effect.\");\n logger.blank();\n return;\n }\n\n logger.info(`Setting up ${shell} integration...`);\n logger.blank();\n\n await installShellIntegration(shell, home, dataDir);\n\n logger.blank();\n logger.success(\"Shell integration installed!\");\n logger.blank();\n logger.dim(\"Restart your terminal or run:\");\n if (shell === \"powershell\") {\n logger.highlight(\" . $PROFILE\");\n } else if (shell === \"bash\") {\n logger.highlight(\" source ~/.bashrc\");\n } else if (shell === \"zsh\") {\n logger.highlight(\" source ~/.zshrc\");\n } else if (shell === \"fish\") {\n logger.highlight(\" source ~/.config/fish/config.fish\");\n }\n logger.blank();\n logger.dim(\"All commands you run will now be tracked and synced to Skillo.\");\n logger.blank();\n });\n\nasync function installShellIntegration(shell: string, home: string, dataDir: string) {\n const scriptPath = join(dataDir, \"shell-integration\");\n ensureDirectory(scriptPath);\n\n if (shell === \"powershell\") {\n // PowerShell integration\n // Works in two modes:\n // 1. Platform mode: Uses SKILLO_SESSION and SKILLO_USER_ID env vars (set by platform launch)\n // 2. Standalone mode: Uses skillo CLI which handles auth via API key\n const psScript = `# Skillo CLI Integration\n# Records commands to Skillo platform\n# Works in two modes:\n# 1. Platform mode: Uses SKILLO_SESSION and SKILLO_USER_ID env vars (set by platform launch)\n# 2. Standalone mode: Uses skillo CLI which handles auth via API key\n\n$Global:SkilloLastHistoryId = 0\n$Global:SkilloStandaloneSessionId = $null\n$Global:SkilloSessionStartTime = $null\n\n# Check if launched from platform (has session/user env vars) or standalone\n$Global:SkilloPlatformMode = $false\nif ($env:SKILLO_SESSION -and $env:SKILLO_USER_ID) {\n $Global:SkilloPlatformMode = $true\n $Global:SkilloSessionId = $env:SKILLO_SESSION\n $Global:SkilloUserId = $env:SKILLO_USER_ID\n $Global:SkilloBaseUrl = if ($env:SKILLO_API_URL) { $env:SKILLO_API_URL } else { 'http://localhost:3000' }\n}\n\nfunction Send-SkilloCommandPlatform {\n param($Command, $Duration, $ExitCode, $Cwd)\n\n try {\n $body = @{\n type = 'commands'\n data = @(@{\n timestamp = (Get-Date).ToString('o')\n command = $Command\n normalized = $Command\n cwd = $Cwd\n exitCode = $ExitCode\n durationMs = $Duration\n sessionId = $Global:SkilloSessionId\n })\n } | ConvertTo-Json -Depth 3 -Compress\n\n $uri = \"$($Global:SkilloBaseUrl)/api/cli/sync\"\n\n $webRequest = [System.Net.HttpWebRequest]::Create($uri)\n $webRequest.Method = 'POST'\n $webRequest.ContentType = 'application/json'\n $webRequest.Headers.Add('x-skillo-session', $Global:SkilloSessionId)\n $webRequest.Headers.Add('x-skillo-user-id', $Global:SkilloUserId)\n $webRequest.Timeout = 5000\n\n $bytes = [System.Text.Encoding]::UTF8.GetBytes($body)\n $webRequest.ContentLength = $bytes.Length\n $stream = $webRequest.GetRequestStream()\n $stream.Write($bytes, 0, $bytes.Length)\n $stream.Close()\n\n $response = $webRequest.GetResponse()\n $response.Close()\n } catch {\n # Silently ignore errors\n }\n}\n\nfunction Send-SkilloCommandCLI {\n param($Command, $Duration, $ExitCode, $Cwd)\n\n # Create session on first command if not exists\n if (-not $Global:SkilloStandaloneSessionId) {\n $Global:SkilloSessionStartTime = (Get-Date).ToString('o')\n try {\n $result = & skillo session start --shell \"PowerShell\" 2>$null\n if ($result -match 'Session ID: ([a-f0-9-]+)') {\n $Global:SkilloStandaloneSessionId = $Matches[1]\n }\n } catch {\n # If session command doesn't exist, generate a local ID\n $Global:SkilloStandaloneSessionId = [guid]::NewGuid().ToString()\n }\n }\n\n # Run skillo record in background with session ID\n Start-Job -ScriptBlock {\n param($cmd, $cwd, $exit, $dur, $sessionId)\n & skillo record $cmd --cwd $cwd --exit-code $exit --duration $dur --session $sessionId 2>$null\n } -ArgumentList $Command, $Cwd, $ExitCode, $Duration, $Global:SkilloStandaloneSessionId | Out-Null\n}\n\n# Override prompt to capture commands after execution\n$Global:SkilloOriginalPrompt = $function:prompt\nfunction Global:prompt {\n $lastCmd = Get-History -Count 1 -ErrorAction SilentlyContinue\n\n if ($lastCmd -and $lastCmd.Id -gt $Global:SkilloLastHistoryId) {\n $Global:SkilloLastHistoryId = $lastCmd.Id\n\n $duration = 0\n if ($lastCmd.EndExecutionTime -and $lastCmd.StartExecutionTime) {\n $duration = [int]($lastCmd.EndExecutionTime - $lastCmd.StartExecutionTime).TotalMilliseconds\n }\n $exit = if ($null -eq $LASTEXITCODE) { 0 } else { $LASTEXITCODE }\n $cwd = (Get-Location).Path\n\n if ($Global:SkilloPlatformMode) {\n Send-SkilloCommandPlatform -Command $lastCmd.CommandLine -Duration $duration -ExitCode $exit -Cwd $cwd\n } else {\n Send-SkilloCommandCLI -Command $lastCmd.CommandLine -Duration $duration -ExitCode $exit -Cwd $cwd\n }\n }\n\n & $Global:SkilloOriginalPrompt\n}\n\n# Register exit handler to end session when terminal closes\n$null = Register-EngineEvent -SourceIdentifier PowerShell.Exiting -Action {\n if ($Global:SkilloPlatformMode -and $Global:SkilloSessionId) {\n # End platform session\n try {\n $body = @{ sessionId = $Global:SkilloSessionId } | ConvertTo-Json -Compress\n $uri = \"$($Global:SkilloBaseUrl)/api/sessions\"\n\n $webRequest = [System.Net.HttpWebRequest]::Create($uri)\n $webRequest.Method = 'PATCH'\n $webRequest.ContentType = 'application/json'\n $webRequest.Headers.Add('x-skillo-session', $Global:SkilloSessionId)\n $webRequest.Headers.Add('x-skillo-user-id', $Global:SkilloUserId)\n $webRequest.Timeout = 3000\n\n $bytes = [System.Text.Encoding]::UTF8.GetBytes($body)\n $webRequest.ContentLength = $bytes.Length\n $stream = $webRequest.GetRequestStream()\n $stream.Write($bytes, 0, $bytes.Length)\n $stream.Close()\n\n $response = $webRequest.GetResponse()\n $response.Close()\n } catch {\n # Ignore errors on exit\n }\n } elseif ($Global:SkilloStandaloneSessionId) {\n # End standalone session via CLI\n try {\n & skillo session end --session $Global:SkilloStandaloneSessionId 2>$null\n } catch {\n # Ignore errors on exit\n }\n }\n}\n\nWrite-Host \"Skillo: Command tracking enabled\" -ForegroundColor DarkGray\n`;\n\n const psScriptFile = join(scriptPath, \"skillo.ps1\");\n writeFileSync(psScriptFile, psScript, \"utf-8\");\n logger.success(`Created ${psScriptFile}`);\n\n // Add to PowerShell profile\n const profilePath = join(home, \"Documents\", \"WindowsPowerShell\", \"Microsoft.PowerShell_profile.ps1\");\n const profileDir = join(home, \"Documents\", \"WindowsPowerShell\");\n ensureDirectory(profileDir);\n\n const sourceLine = `\\n# Skillo CLI Integration\\n. \"${psScriptFile}\"\\n`;\n\n if (existsSync(profilePath)) {\n const content = readFileSync(profilePath, \"utf-8\");\n if (!content.includes(\"Skillo CLI Integration\")) {\n appendFileSync(profilePath, sourceLine);\n logger.success(\"Added to PowerShell profile\");\n } else {\n logger.dim(\"Already in PowerShell profile\");\n }\n } else {\n writeFileSync(profilePath, sourceLine, \"utf-8\");\n logger.success(\"Created PowerShell profile\");\n }\n\n } else if (shell === \"bash\") {\n // Bash integration - command recording + CWD-based session auto-detection\n const bashScript = [\n \"# Skillo CLI Integration\",\n \"# Records commands and auto-detects tracked projects\",\n \"\",\n '_skillo_session=\"$' + '{SKILLO_SESSION:-default}\"',\n \"_skillo_last_cwd=\",\n \"\",\n \"_skillo_preexec() {\",\n ' _skillo_cmd=\"$1\"',\n \" _skillo_start_time=$(date +%s)\",\n \"}\",\n \"\",\n \"_skillo_check_project() {\",\n ' # Fast path: skip if CWD unchanged',\n ' if [ \"$PWD\" = \"$_skillo_last_cwd\" ]; then',\n \" return\",\n \" fi\",\n ' _skillo_last_cwd=\"$PWD\"',\n \"\",\n ' # Run session-auto in background (handles create/end via cache file)',\n ' local result',\n ' result=$(skillo session-auto \"$PWD\" --pid $$ --shell bash 2>/dev/null)',\n ' if [ -n \"$result\" ]; then',\n ' export SKILLO_SESSION=\"$result\"',\n ' _skillo_session=\"$result\"',\n \" fi\",\n \"}\",\n \"\",\n \"_skillo_precmd() {\",\n \" local exit_code=$?\",\n \"\",\n \" # Check for project change\",\n \" _skillo_check_project\",\n \"\",\n ' if [ -n \"$_skillo_cmd\" ]; then',\n \" local duration=0\",\n ' if [ -n \"$_skillo_start_time\" ]; then',\n \" local end_time=$(date +%s)\",\n \" duration=$(( (end_time - _skillo_start_time) * 1000 ))\",\n \" fi\",\n ' (skillo record \"$_skillo_cmd\" --cwd \"$PWD\" --exit-code \"$exit_code\" --duration \"$duration\" --session \"$_skillo_session\" &>/dev/null &)',\n ' _skillo_cmd=\"\"',\n \" fi\",\n \"}\",\n \"\",\n \"# Clean up session on terminal exit\",\n '_skillo_cleanup() {',\n ' if [ -n \"$SKILLO_SESSION\" ] && [ \"$SKILLO_SESSION\" != \"default\" ]; then',\n ' skillo session end --session \"$SKILLO_SESSION\" &>/dev/null',\n \" fi\",\n \"}\",\n \"trap _skillo_cleanup EXIT\",\n \"\",\n \"# Use DEBUG trap for preexec\",\n \"trap '_skillo_preexec \\\"$BASH_COMMAND\\\"' DEBUG\",\n \"\",\n \"# Add precmd to PROMPT_COMMAND\",\n 'if [[ ! \"$PROMPT_COMMAND\" =~ _skillo_precmd ]]; then',\n ' PROMPT_COMMAND=\"_skillo_precmd$' + '{PROMPT_COMMAND:+;$PROMPT_COMMAND}\"',\n \"fi\",\n \"\",\n \"# Initial project check\",\n \"_skillo_check_project\",\n \"\",\n 'echo -e \"\\\\033[90mSkillo: Command tracking enabled\\\\033[0m\"',\n ].join(\"\\n\");\n\n const bashScriptFile = join(scriptPath, \"skillo.bash\");\n writeFileSync(bashScriptFile, bashScript, \"utf-8\");\n logger.success(`Created ${bashScriptFile}`);\n\n // Add to .bashrc\n const bashrcPath = join(home, \".bashrc\");\n const sourceLine = `\\n# Skillo CLI Integration\\n[ -f \"${bashScriptFile}\" ] && source \"${bashScriptFile}\"\\n`;\n\n if (existsSync(bashrcPath)) {\n const content = readFileSync(bashrcPath, \"utf-8\");\n if (!content.includes(\"Skillo CLI Integration\")) {\n appendFileSync(bashrcPath, sourceLine);\n logger.success(\"Added to ~/.bashrc\");\n } else {\n logger.dim(\"Already in ~/.bashrc\");\n }\n } else {\n writeFileSync(bashrcPath, sourceLine, \"utf-8\");\n logger.success(\"Created ~/.bashrc\");\n }\n\n } else if (shell === \"zsh\") {\n // Zsh integration - command recording + CWD-based session auto-detection\n const zshScript = [\n \"# Skillo CLI Integration\",\n \"# Records commands and auto-detects tracked projects\",\n \"\",\n '_skillo_session=\"$' + '{SKILLO_SESSION:-default}\"',\n \"_skillo_last_cwd=\",\n \"\",\n \"_skillo_preexec() {\",\n ' _skillo_cmd=\"$1\"',\n \" _skillo_start_time=$(date +%s)\",\n \"}\",\n \"\",\n \"_skillo_check_project() {\",\n ' # Fast path: skip if CWD unchanged',\n ' if [[ \"$PWD\" == \"$_skillo_last_cwd\" ]]; then',\n \" return\",\n \" fi\",\n ' _skillo_last_cwd=\"$PWD\"',\n \"\",\n ' # Run session-auto in background (handles create/end via cache file)',\n ' local result',\n ' result=$(skillo session-auto \"$PWD\" --pid $$ --shell zsh 2>/dev/null)',\n ' if [[ -n \"$result\" ]]; then',\n ' export SKILLO_SESSION=\"$result\"',\n ' _skillo_session=\"$result\"',\n \" fi\",\n \"}\",\n \"\",\n \"_skillo_precmd() {\",\n \" local exit_code=$?\",\n \"\",\n \" # Check for project change\",\n \" _skillo_check_project\",\n \"\",\n ' if [[ -n \"$_skillo_cmd\" ]]; then',\n \" local duration=0\",\n ' if [[ -n \"$_skillo_start_time\" ]]; then',\n \" local end_time=$(date +%s)\",\n \" duration=$(( (end_time - _skillo_start_time) * 1000 ))\",\n \" fi\",\n ' (skillo record \"$_skillo_cmd\" --cwd \"$PWD\" --exit-code \"$exit_code\" --duration \"$duration\" --session \"$_skillo_session\" &>/dev/null &)',\n ' _skillo_cmd=\"\"',\n \" fi\",\n \"}\",\n \"\",\n \"# Clean up session on terminal exit\",\n '_skillo_cleanup() {',\n ' if [[ -n \"$SKILLO_SESSION\" ]] && [[ \"$SKILLO_SESSION\" != \"default\" ]]; then',\n ' skillo session end --session \"$SKILLO_SESSION\" &>/dev/null',\n \" fi\",\n \"}\",\n \"trap _skillo_cleanup EXIT\",\n \"\",\n \"autoload -Uz add-zsh-hook\",\n \"add-zsh-hook preexec _skillo_preexec\",\n \"add-zsh-hook precmd _skillo_precmd\",\n \"\",\n \"# Initial project check\",\n \"_skillo_check_project\",\n \"\",\n 'echo -e \"\\\\033[90mSkillo: Command tracking enabled\\\\033[0m\"',\n ].join(\"\\n\");\n\n const zshScriptFile = join(scriptPath, \"skillo.zsh\");\n writeFileSync(zshScriptFile, zshScript, \"utf-8\");\n logger.success(`Created ${zshScriptFile}`);\n\n // Add to .zshrc\n const zshrcPath = join(home, \".zshrc\");\n const sourceLine = `\\n# Skillo CLI Integration\\n[ -f \"${zshScriptFile}\" ] && source \"${zshScriptFile}\"\\n`;\n\n if (existsSync(zshrcPath)) {\n const content = readFileSync(zshrcPath, \"utf-8\");\n if (!content.includes(\"Skillo CLI Integration\")) {\n appendFileSync(zshrcPath, sourceLine);\n logger.success(\"Added to ~/.zshrc\");\n } else {\n logger.dim(\"Already in ~/.zshrc\");\n }\n } else {\n writeFileSync(zshrcPath, sourceLine, \"utf-8\");\n logger.success(\"Created ~/.zshrc\");\n }\n\n } else if (shell === \"fish\") {\n // Fish integration\n const fishScript = [\n \"# Skillo CLI Integration\",\n \"# Records commands to Skillo platform\",\n \"\",\n 'set -q SKILLO_SESSION; or set -g SKILLO_SESSION \"default\"',\n \"\",\n \"function _skillo_postexec --on-event fish_postexec\",\n \" set -l cmd $argv[1]\",\n \" set -l exit_code $status\",\n ' skillo record \"$cmd\" --cwd (pwd) --exit-code $exit_code --session $SKILLO_SESSION &>/dev/null &',\n \"end\",\n \"\",\n 'echo -e \"\\\\033[90mSkillo: Command tracking enabled\\\\033[0m\"',\n ].join(\"\\n\");\n\n const fishScriptFile = join(scriptPath, \"skillo.fish\");\n writeFileSync(fishScriptFile, fishScript, \"utf-8\");\n logger.success(`Created ${fishScriptFile}`);\n\n // Add to fish config\n const fishConfigDir = join(home, \".config\", \"fish\");\n ensureDirectory(fishConfigDir);\n const fishConfigPath = join(fishConfigDir, \"config.fish\");\n const sourceLine = `\\n# Skillo CLI Integration\\nif test -f \"${fishScriptFile}\"\\n source \"${fishScriptFile}\"\\nend\\n`;\n\n if (existsSync(fishConfigPath)) {\n const content = readFileSync(fishConfigPath, \"utf-8\");\n if (!content.includes(\"Skillo CLI Integration\")) {\n appendFileSync(fishConfigPath, sourceLine);\n logger.success(\"Added to ~/.config/fish/config.fish\");\n } else {\n logger.dim(\"Already in fish config\");\n }\n } else {\n writeFileSync(fishConfigPath, sourceLine, \"utf-8\");\n logger.success(\"Created fish config\");\n }\n }\n}\n\nasync function uninstallShellIntegration(shell: string, home: string) {\n const removeFromFile = (filePath: string) => {\n if (!existsSync(filePath)) return;\n let content = readFileSync(filePath, \"utf-8\");\n // Remove the Skillo integration section\n content = content.replace(/\\n# Skillo CLI Integration\\n[^\\n]*\\n/g, \"\\n\");\n writeFileSync(filePath, content, \"utf-8\");\n };\n\n if (shell === \"powershell\") {\n const profilePath = join(home, \"Documents\", \"WindowsPowerShell\", \"Microsoft.PowerShell_profile.ps1\");\n removeFromFile(profilePath);\n } else if (shell === \"bash\") {\n removeFromFile(join(home, \".bashrc\"));\n } else if (shell === \"zsh\") {\n removeFromFile(join(home, \".zshrc\"));\n } else if (shell === \"fish\") {\n removeFromFile(join(home, \".config\", \"fish\", \"config.fish\"));\n }\n}\n","/**\n * Daemon management commands.\n */\n\nimport { existsSync, readFileSync, writeFileSync, unlinkSync } from \"fs\";\nimport { fork } from \"child_process\";\nimport { Command } from \"commander\";\nimport { loadConfig } from \"../core/config.js\";\nimport { getPidFile, getLogFile, getConfigFile, getDataDir, ensureDirectory } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\nimport { installService, uninstallService, getServiceStatus } from \"../utils/os-service.js\";\n\nexport function isDaemonRunning(): { running: boolean; pid: number | null } {\n const pidFile = getPidFile();\n\n if (!existsSync(pidFile)) {\n return { running: false, pid: null };\n }\n\n try {\n const pidStr = readFileSync(pidFile, \"utf-8\").trim();\n const pid = parseInt(pidStr, 10);\n\n if (isNaN(pid)) {\n return { running: false, pid: null };\n }\n\n // Check if process is running\n try {\n process.kill(pid, 0);\n return { running: true, pid };\n } catch {\n // Process doesn't exist, clean up stale PID file\n try {\n unlinkSync(pidFile);\n } catch {\n // Ignore cleanup errors\n }\n return { running: false, pid: null };\n }\n } catch {\n return { running: false, pid: null };\n }\n}\n\nexport function startDaemonProcess(): number | null {\n const daemonScript = new URL(\"./daemon-runner.js\", import.meta.url).pathname;\n\n const child = fork(daemonScript, [], {\n detached: true,\n stdio: \"ignore\",\n env: {\n ...process.env,\n SKILLO_DAEMON: \"1\",\n },\n });\n\n child.unref();\n\n if (child.pid) {\n writeFileSync(getPidFile(), String(child.pid));\n return child.pid;\n }\n\n return null;\n}\n\n// ── Auto-init helper ──────────────────────────────────────────────────────\n\nasync function ensureInitialized(): Promise<void> {\n if (existsSync(getConfigFile())) return;\n\n // Auto-initialize silently\n const { getDefaultConfig, saveConfig } = await import(\"../core/config.js\");\n const { SkilloDatabase } = await import(\"../core/database.js\");\n const { getConfigDir, getSkillsDir } = await import(\"../utils/paths.js\");\n\n ensureDirectory(getDataDir());\n ensureDirectory(getConfigDir());\n ensureDirectory(getSkillsDir());\n\n saveConfig(getDefaultConfig());\n\n const db = new SkilloDatabase();\n await db.initialize();\n db.close();\n\n logger.dim(\"Skillo initialized.\");\n}\n\n// ── Inline login helper ──────────────────────────────────────────────────\n\nasync function ensureLoggedIn(): Promise<boolean> {\n const { getApiClient } = await import(\"../core/api-client.js\");\n const client = getApiClient();\n\n if (client.hasApiKey()) {\n // Verify the key still works\n const result = await client.authenticate();\n if (result.success) return true;\n // Key is stale — clear it and re-login\n client.clearApiKey();\n logger.warn(\"Session expired. Logging in again...\");\n }\n\n // Start device auth flow inline\n logger.blank();\n logger.info(\"Login required. Opening browser...\");\n logger.blank();\n\n const { hostname } = await import(\"os\");\n const deviceName = `CLI on ${hostname()}`;\n const deviceAuthResult = await client.startDeviceAuth(deviceName);\n\n if (!deviceAuthResult.success || !deviceAuthResult.data) {\n logger.error(\"Failed to start authentication: \" + (deviceAuthResult.error || \"Unknown error\"));\n logger.dim(\"You can also login manually: skillo login <api-key>\");\n return false;\n }\n\n const { code, verification_url, interval } = deviceAuthResult.data;\n\n logger.highlight(` ${verification_url}`);\n logger.blank();\n\n // Open browser automatically\n try {\n const { exec: execCb } = await import(\"child_process\");\n const { promisify } = await import(\"util\");\n const execAsync = promisify(execCb);\n const openCmd = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start \\\"\\\"\" : \"xdg-open\";\n await execAsync(`${openCmd} \"${verification_url}\"`);\n logger.dim(\"Browser opened. Waiting for authorization...\");\n } catch {\n logger.dim(\"Open the URL above in your browser to authorize.\");\n }\n\n logger.dim(\"(Press Ctrl+C to cancel)\");\n\n // Poll for authorization\n const maxAttempts = 120;\n for (let i = 0; i < maxAttempts; i++) {\n await new Promise((r) => setTimeout(r, interval * 1000));\n\n const statusResult = await client.checkTokenStatus(code);\n if (!statusResult.success) continue;\n\n const status = statusResult.data?.status;\n\n if (status === \"ready\") {\n const tokenResult = await client.exchangeToken(code, deviceName);\n if (tokenResult.success && tokenResult.data) {\n client.saveApiKey(tokenResult.data.api_key);\n\n const authResult = await client.authenticate();\n logger.blank();\n logger.success(\"Login successful!\");\n if (authResult.success && authResult.data) {\n logger.info(`Welcome, ${authResult.data.user.name}!`);\n }\n logger.blank();\n return true;\n }\n logger.error(\"Failed to complete login: \" + (tokenResult.error || \"Unknown error\"));\n return false;\n }\n\n if (status === \"expired\" || status === \"used\" || status === \"not_found\") {\n logger.error(`Authorization ${status}. Please try again.`);\n return false;\n }\n }\n\n logger.error(\"Authorization timed out.\");\n return false;\n}\n\n// skillo start\nexport const startCommand = new Command(\"start\")\n .description(\"Start the Skillo daemon\")\n .option(\"-f, --foreground\", \"Run in foreground (don't daemonize)\")\n .action(async (options: { foreground?: boolean }) => {\n // Step 1: Auto-initialize if needed\n await ensureInitialized();\n\n // Step 2: Ensure logged in (opens browser if needed)\n if (!options.foreground) {\n const loggedIn = await ensureLoggedIn();\n if (!loggedIn) {\n process.exit(1);\n }\n }\n\n // Step 3: Check if already running\n const { running, pid } = isDaemonRunning();\n if (running) {\n logger.success(`Daemon is already running (PID: ${pid})`);\n\n // Still ensure services are installed\n const serviceStatus = getServiceStatus();\n if (!serviceStatus.daemon.installed) {\n const serviceResult = await installService({ includeTray: true });\n if (serviceResult.success) {\n logger.dim(\"Auto-start service installed.\");\n }\n }\n return;\n }\n\n // Step 4: Start daemon\n if (options.foreground) {\n logger.info(\"Starting Skillo daemon in foreground...\");\n logger.dim(\"Press Ctrl+C to stop\");\n logger.blank();\n await runDaemonForeground();\n } else {\n logger.info(\"Starting Skillo daemon...\");\n\n // On Windows, we can't fork properly, so run in foreground\n if (process.platform === \"win32\") {\n logger.dim(\"Running in foreground mode on Windows...\");\n logger.blank();\n\n // Install services first (they'll handle background on next boot)\n const serviceResult = await installService({ includeTray: true });\n if (serviceResult.success) {\n logger.dim(\"Auto-start service installed. Daemon will run in background on next login.\");\n }\n\n await runDaemonForeground();\n } else {\n const daemonPid = startDaemonProcess();\n if (daemonPid) {\n logger.success(`Daemon started (PID: ${daemonPid})`);\n\n // Step 5: Install OS services (daemon + tray)\n const serviceResult = await installService({ includeTray: true });\n if (serviceResult.success) {\n logger.dim(\"Auto-start & tray service installed. Daemon will survive reboots.\");\n }\n\n logger.blank();\n logger.dim(\"Use 'skillo status' to check daemon status\");\n logger.dim(\"Use 'skillo stop' to stop the daemon\");\n } else {\n logger.error(\"Failed to start daemon\");\n }\n }\n }\n });\n\n// skillo stop\nexport const stopCommand = new Command(\"stop\")\n .description(\"Stop the Skillo daemon\")\n .action(async () => {\n const { running, pid } = isDaemonRunning();\n\n if (!running) {\n logger.dim(\"Daemon is not running.\");\n return;\n }\n\n logger.info(`Stopping daemon (PID: ${pid})...`);\n\n // Uninstall OS service so it doesn't auto-restart\n const serviceResult = await uninstallService();\n if (serviceResult.success) {\n logger.dim(\"Auto-start service removed.\");\n }\n\n try {\n process.kill(pid!, \"SIGTERM\");\n logger.success(\"Daemon stopped\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ESRCH\") {\n logger.dim(\"Daemon already stopped\");\n } else if ((error as NodeJS.ErrnoException).code === \"EPERM\") {\n logger.error(\"Permission denied. Try with sudo.\");\n process.exit(1);\n } else {\n throw error;\n }\n }\n\n // Clean up PID file\n const pidFile = getPidFile();\n if (existsSync(pidFile)) {\n try {\n unlinkSync(pidFile);\n } catch {\n // Ignore cleanup errors\n }\n }\n });\n\n// skillo logs\nexport const logsCommand = new Command(\"logs\")\n .description(\"Show daemon logs\")\n .option(\"-n, --lines <number>\", \"Number of lines to show\", \"50\")\n .option(\"-f, --follow\", \"Follow log output\")\n .action(async (options: { lines: string; follow?: boolean }) => {\n const logFile = getLogFile();\n\n if (!existsSync(logFile)) {\n logger.dim(\"No logs found.\");\n return;\n }\n\n const numLines = parseInt(options.lines, 10);\n\n if (options.follow) {\n // Tail -f functionality\n const { spawn } = await import(\"child_process\");\n const tail = spawn(\"tail\", [\"-f\", \"-n\", String(numLines), logFile], {\n stdio: \"inherit\",\n });\n\n tail.on(\"error\", () => {\n // Fallback for Windows\n logger.warn(\"Follow mode not supported on this platform.\");\n showLogs(logFile, numLines);\n });\n } else {\n showLogs(logFile, numLines);\n }\n });\n\nfunction showLogs(logFile: string, numLines: number): void {\n const content = readFileSync(logFile, \"utf-8\");\n const lines = content.split(\"\\n\").filter(Boolean);\n const lastLines = lines.slice(-numLines);\n lastLines.forEach((line) => console.log(line));\n}\n\n// skillo service\nexport const serviceCommand = new Command(\"service\")\n .description(\"Manage auto-start service\")\n .addCommand(\n new Command(\"install\")\n .description(\"Install auto-start service (LaunchAgent on macOS, systemd on Linux)\")\n .option(\"--no-tray\", \"Skip installing tray icon service\")\n .action(async (options: { tray?: boolean }) => {\n logger.info(\"Installing auto-start service...\");\n const result = await installService({ includeTray: options.tray !== false });\n if (result.success) {\n logger.success(\"Auto-start service installed.\");\n logger.dim(\"Daemon will start automatically on login and restart on crash.\");\n if (options.tray !== false) {\n logger.dim(\"Tray icon will appear in GUI sessions.\");\n }\n } else {\n logger.error(`Failed to install service: ${result.error}`);\n }\n })\n )\n .addCommand(\n new Command(\"uninstall\")\n .description(\"Remove auto-start service\")\n .action(async () => {\n logger.info(\"Removing auto-start service...\");\n const result = await uninstallService();\n if (result.success) {\n logger.success(\"Auto-start service removed.\");\n } else {\n logger.error(`Failed to remove service: ${result.error}`);\n }\n })\n )\n .addCommand(\n new Command(\"status\")\n .description(\"Show auto-start service status\")\n .action(async () => {\n const status = getServiceStatus();\n\n logger.blank();\n logger.info(`Platform: ${status.platform}`);\n logger.blank();\n\n if (status.daemon.installed) {\n logger.running(`Daemon service: installed${status.daemon.loaded ? \" & loaded\" : \" (not loaded)\"}`);\n } else {\n logger.stopped(\"Daemon service: not installed\");\n }\n\n if (status.tray.installed) {\n logger.running(`Tray service: installed${status.tray.loaded ? \" & loaded\" : \" (not loaded)\"}`);\n } else {\n logger.stopped(\"Tray service: not installed\");\n }\n\n logger.blank();\n if (!status.daemon.installed) {\n logger.dim(\"Run 'skillo service install' to enable auto-start.\");\n }\n logger.blank();\n })\n );\n\n// Foreground daemon runner (imports the same logic as daemon-runner.ts)\nasync function runDaemonForeground(): Promise<void> {\n const pidFile = getPidFile();\n writeFileSync(pidFile, String(process.pid));\n\n logger.dim(`Daemon PID: ${process.pid}`);\n logger.dim(`Log file: ${getLogFile()}`);\n logger.blank();\n\n // Handle shutdown signals\n const cleanup = () => {\n logger.blank();\n logger.info(\"Shutting down daemon...\");\n if (existsSync(pidFile)) {\n try {\n unlinkSync(pidFile);\n } catch {\n // Ignore\n }\n }\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n\n // Load config and client\n const config = loadConfig();\n const { getApiClient } = await import(\"../core/api-client.js\");\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n process.exit(1);\n }\n\n // Import and start Claude watcher\n const { ClaudeWatcher } = await import(\"../core/claude-watcher.js\");\n\n ensureDirectory(getDataDir());\n\n const watchInterval = ((config as { daemon?: { conversationCheckInterval?: number } }).daemon?.conversationCheckInterval || 5) * 1000;\n const watcher = new ClaudeWatcher(client, {\n intervalMs: watchInterval,\n callbacks: {\n onSync: (count) => logger.success(`Synced ${count} Claude prompt(s)`),\n onError: (err) => logger.error(`Watcher error: ${err.message}`),\n log: (level, msg) => {\n if (level === \"ERROR\") logger.error(msg);\n else if (level === \"WARN\") logger.warn(msg);\n else logger.dim(msg);\n },\n },\n });\n\n await watcher.start();\n\n // Import and start skill usage detector\n const { SkillUsageDetector } = await import(\"../core/skill-usage-detector.js\");\n\n const skillDetector = new SkillUsageDetector(client, {\n intervalMs: 30000,\n callbacks: {\n onDetection: (count) => logger.success(`Detected ${count} skill usage(s)`),\n onError: (err) => logger.error(`Skill detection error: ${err.message}`),\n log: (level, msg) => {\n if (level === \"ERROR\") logger.error(msg);\n else if (level === \"WARN\") logger.warn(msg);\n else logger.dim(msg);\n },\n },\n });\n\n await skillDetector.start();\n\n logger.success(\"Daemon is running. Watching Claude conversations and skill usage...\");\n\n // Keep the process alive\n await new Promise(() => {});\n}\n","/**\n * Session commands - Manage terminal sessions.\n *\n * Used by shell integration scripts to create and end sessions\n * for standalone terminals (not launched from platform).\n */\n\nimport { Command } from \"commander\";\nimport { existsSync, readFileSync, writeFileSync, unlinkSync } from \"fs\";\nimport { getApiClient } from \"../core/api-client.js\";\nimport { getTrackedProjectsCacheFile, getActiveSessionsDir, ensureDirectory } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\n\nexport const sessionCommand = new Command(\"session\")\n .description(\"Manage terminal sessions\");\n\n// Start a new session\nsessionCommand\n .command(\"start\")\n .description(\"Start a new terminal session (for standalone terminals)\")\n .option(\"--shell <shell>\", \"Shell type (powershell, bash, zsh, cmd)\", \"powershell\")\n .action(async (options: { shell: string }) => {\n try {\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n // Silent fail - shell integration will generate local ID\n process.exit(1);\n }\n\n const result = await client.startSession(options.shell);\n\n if (result.success && result.data?.sessionId) {\n // Output in a format that can be parsed by shell integration\n console.log(`Session ID: ${result.data.sessionId}`);\n } else {\n // Silent fail\n process.exit(1);\n }\n } catch {\n // Silent fail\n process.exit(1);\n }\n });\n\n// End a session\nsessionCommand\n .command(\"end\")\n .description(\"End a terminal session\")\n .option(\"--session <id>\", \"Session ID to end\")\n .action(async (options: { session?: string }) => {\n const sessionId = options.session || process.env.SKILLO_SESSION;\n\n if (!sessionId) {\n // Silent fail - no session to end\n process.exit(0);\n }\n\n try {\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n // Silent fail\n process.exit(0);\n }\n\n const result = await client.endSession(sessionId);\n\n if (result.success) {\n // Silent success\n process.exit(0);\n } else {\n // Silent fail\n process.exit(1);\n }\n } catch {\n // Silent fail\n process.exit(1);\n }\n });\n\n// List active sessions (for debugging)\nsessionCommand\n .command(\"list\")\n .description(\"List active sessions\")\n .action(async () => {\n logger.info(\"Fetching active sessions...\");\n\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n process.exit(1);\n }\n\n // For now, just inform user to check the web UI\n logger.info(\"Check your sessions at: https://www.skillo.one/terminal\");\n });\n\n// session-auto - Fast CWD-change handler called by shell hooks\n// Reads tracked projects cache (file, no API call), creates/ends sessions as needed\nexport const sessionAutoCommand = new Command(\"session-auto\")\n .description(\"Auto-detect project and manage session (used by shell hooks)\")\n .argument(\"<cwd>\", \"Current working directory\")\n .option(\"--pid <pid>\", \"Terminal PID\")\n .option(\"--shell <shell>\", \"Shell type\")\n .action(async (cwd: string, options: { pid?: string; shell?: string }) => {\n const terminalPid = options.pid || String(process.ppid || process.pid);\n const shell = options.shell || process.env.SHELL?.split(\"/\").pop() || \"unknown\";\n const sessionsDir = getActiveSessionsDir();\n const sessionFile = `${sessionsDir}/${terminalPid}.json`;\n\n // Read current session state\n let currentSession: { sessionId: string; projectPath: string } | null = null;\n if (existsSync(sessionFile)) {\n try {\n currentSession = JSON.parse(readFileSync(sessionFile, \"utf-8\"));\n } catch {\n currentSession = null;\n }\n }\n\n // Check if CWD is in a tracked project (file-based, no API)\n const cacheFile = getTrackedProjectsCacheFile();\n let matchedProject: { path: string; name: string } | null = null;\n\n if (existsSync(cacheFile)) {\n try {\n const cache = JSON.parse(readFileSync(cacheFile, \"utf-8\"));\n const normalizedCwd = cwd.toLowerCase().replace(/\\/+$/, \"\");\n for (const project of cache.projects || []) {\n const normalizedPath = project.path.toLowerCase().replace(/\\/+$/, \"\");\n if (normalizedCwd === normalizedPath || normalizedCwd.startsWith(normalizedPath + \"/\")) {\n matchedProject = project;\n break;\n }\n }\n } catch {\n // Cache unreadable\n }\n }\n\n // Same project, no-op\n if (currentSession && matchedProject && currentSession.projectPath === matchedProject.path) {\n process.exit(0);\n }\n\n const client = getApiClient();\n if (!client.hasApiKey()) {\n process.exit(0);\n }\n\n // End previous session if leaving a tracked project\n if (currentSession) {\n try {\n await client.endSession(currentSession.sessionId);\n } catch {\n // Ignore\n }\n try {\n unlinkSync(sessionFile);\n } catch {\n // Ignore\n }\n }\n\n // Start new session if entering a tracked project\n if (matchedProject) {\n try {\n const result = await client.startSession(shell, matchedProject.path);\n if (result.success && result.data?.sessionId) {\n ensureDirectory(sessionsDir);\n writeFileSync(sessionFile, JSON.stringify({\n sessionId: result.data.sessionId,\n projectPath: matchedProject.path,\n projectName: matchedProject.name,\n pid: terminalPid,\n startedAt: Date.now(),\n }));\n // Output session ID for shell to capture\n console.log(result.data.sessionId);\n }\n } catch {\n // Silent fail\n }\n }\n\n process.exit(0);\n });\n","/**\n * Claude Code commands - Sync and watch Claude Code history.\n *\n * Reads ~/.claude/history.jsonl and syncs prompts to the platform.\n * Supports project-path filtering to only sync prompts for the current project.\n *\n * PRIVACY: Only syncs prompts for projects that have been explicitly connected\n * using `skillo connect`. Unconnected projects are not tracked.\n */\n\nimport { Command } from \"commander\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport * as readline from \"readline\";\nimport { getApiClient } from \"../core/api-client.js\";\nimport logger from \"../utils/logger.js\";\n\n// Cache for tracked projects to avoid repeated API calls\ninterface TrackedProjectCache {\n projects: Map<string, { tracked: boolean; name?: string }>;\n lastFetched: number;\n}\n\nconst projectCache: TrackedProjectCache = {\n projects: new Map(),\n lastFetched: 0,\n};\n\nconst CACHE_TTL_MS = 60000; // 1 minute cache\n\ninterface ClaudeHistoryEntry {\n display: string;\n timestamp: number;\n project: string;\n sessionId: string;\n pastedContents?: Record<string, unknown>;\n}\n\ninterface SyncOptions {\n since?: string;\n all?: boolean;\n projectPath?: string;\n session?: string;\n sessionStart?: string;\n}\n\ninterface WatchOptions {\n interval: string;\n projectPath?: string;\n session?: string;\n sessionStart?: string;\n}\n\n// Get Claude Code history file path\nfunction getClaudeHistoryPath(): string {\n return path.join(os.homedir(), \".claude\", \"history.jsonl\");\n}\n\n// Normalize path for comparison\nfunction normalizePath(p: string): string {\n return p.toLowerCase().replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n}\n\n// Check if a Claude project path matches the filter path\nfunction matchesProjectPath(claudeProjectPath: string, filterPath: string): boolean {\n const normalizedClaude = normalizePath(claudeProjectPath);\n const normalizedFilter = normalizePath(filterPath);\n\n // Exact match or Claude path is within filter path\n return normalizedClaude === normalizedFilter ||\n normalizedClaude.startsWith(normalizedFilter + \"/\");\n}\n\n// Check if timestamp is within session timeframe\nfunction isWithinSession(timestamp: number, sessionStart?: string): boolean {\n if (!sessionStart) return true;\n\n const sessionStartTime = new Date(sessionStart).getTime();\n return timestamp >= sessionStartTime;\n}\n\n// Load tracked projects from the API into cache\nasync function loadTrackedProjects(): Promise<Map<string, { tracked: boolean; name?: string }>> {\n const client = getApiClient();\n const now = Date.now();\n\n // Return cached if still valid\n if (projectCache.lastFetched > 0 && now - projectCache.lastFetched < CACHE_TTL_MS) {\n return projectCache.projects;\n }\n\n try {\n const result = await client.listProjects(true); // Include disabled to build full cache\n if (result.success && result.data?.projects) {\n projectCache.projects.clear();\n for (const project of result.data.projects) {\n // Normalize path for consistent matching\n const normalizedPath = normalizePath(project.path);\n projectCache.projects.set(normalizedPath, {\n tracked: project.trackingEnabled,\n name: project.name,\n });\n }\n projectCache.lastFetched = now;\n }\n } catch {\n // If API fails, use stale cache or empty\n }\n\n return projectCache.projects;\n}\n\n// Check if a project path is tracked (privacy filter)\nasync function isProjectTracked(projectPath: string): Promise<{ tracked: boolean; name?: string }> {\n const trackedProjects = await loadTrackedProjects();\n const normalizedPath = normalizePath(projectPath);\n\n // Check exact match first\n if (trackedProjects.has(normalizedPath)) {\n return trackedProjects.get(normalizedPath)!;\n }\n\n // Check if this path is under any tracked project\n const entries = Array.from(trackedProjects.entries());\n for (const [trackedPath, info] of entries) {\n if (normalizedPath.startsWith(trackedPath + \"/\")) {\n return info;\n }\n }\n\n return { tracked: false };\n}\n\nexport const claudeCommand = new Command(\"claude\")\n .description(\"Sync and monitor Claude Code activity\");\n\n// Sync Claude Code history\nclaudeCommand\n .command(\"sync\")\n .description(\"Sync Claude Code history to the platform (only tracked projects)\")\n .option(\"--since <timestamp>\", \"Only sync entries after this timestamp (ms)\")\n .option(\"--all\", \"Sync all history (ignore last sync position)\")\n .option(\"--project-path <path>\", \"Only sync prompts for this project path\")\n .option(\"--session <id>\", \"Link prompts to this terminal session\")\n .option(\"--session-start <iso>\", \"Session start time (ISO 8601) for filtering\")\n .option(\"--ignore-tracking\", \"Sync all projects regardless of tracking status (not recommended)\")\n .action(async (options: SyncOptions & { ignoreTracking?: boolean }) => {\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n process.exit(1);\n }\n\n const historyPath = getClaudeHistoryPath();\n\n if (!fs.existsSync(historyPath)) {\n logger.warn(`Claude Code history file not found at: ${historyPath}`);\n logger.info(\"Claude Code stores history in ~/.claude/history.jsonl\");\n logger.info(\"Make sure you have used Claude Code at least once.\");\n process.exit(1);\n }\n\n const projectFilter = options.projectPath || process.env.SKILLO_PROJECT_PATH;\n if (projectFilter) {\n logger.info(`Filtering for project: ${projectFilter}`);\n }\n\n // Load tracked projects for privacy filtering\n if (!options.ignoreTracking) {\n logger.info(\"Loading tracked projects...\");\n await loadTrackedProjects();\n const trackedCount = Array.from(projectCache.projects.values()).filter(p => p.tracked).length;\n if (trackedCount === 0) {\n logger.warn(\"No projects are connected for tracking.\");\n logger.info(\"Run 'skillo connect' in your project directories first.\");\n logger.info(\"Or use --ignore-tracking to sync all projects (not recommended for privacy).\");\n process.exit(0);\n }\n logger.dim(`Found ${trackedCount} tracked project(s)`);\n } else {\n logger.warn(\"Privacy filter disabled - syncing all projects\");\n }\n\n logger.info(\"Reading Claude Code history...\");\n\n const prompts: ClaudeHistoryEntry[] = [];\n const sinceTimestamp = options.since ? parseInt(options.since, 10) : 0;\n\n // Read history file line by line\n const fileStream = fs.createReadStream(historyPath);\n const rl = readline.createInterface({\n input: fileStream,\n crlfDelay: Infinity,\n });\n\n let lineCount = 0;\n let parsedCount = 0;\n let filteredCount = 0;\n let privacyFilteredCount = 0;\n const untrackedProjects = new Set<string>();\n\n for await (const line of rl) {\n lineCount++;\n if (!line.trim()) continue;\n\n try {\n const entry = JSON.parse(line) as ClaudeHistoryEntry;\n\n // Skip if before timestamp filter\n if (!options.all && entry.timestamp <= sinceTimestamp) {\n continue;\n }\n\n // Validate required fields\n if (!entry.display || !entry.timestamp || !entry.project || !entry.sessionId) {\n continue;\n }\n\n parsedCount++;\n\n // Apply project path filter\n if (projectFilter && !matchesProjectPath(entry.project, projectFilter)) {\n filteredCount++;\n continue;\n }\n\n // Apply session timeframe filter\n if (!isWithinSession(entry.timestamp, options.sessionStart)) {\n filteredCount++;\n continue;\n }\n\n // PRIVACY: Check if this project is tracked\n if (!options.ignoreTracking) {\n const trackingStatus = await isProjectTracked(entry.project);\n if (!trackingStatus.tracked) {\n privacyFilteredCount++;\n untrackedProjects.add(entry.project);\n continue;\n }\n }\n\n prompts.push(entry);\n } catch {\n // Skip invalid JSON lines\n }\n }\n\n const syncCount = prompts.length;\n logger.info(`Found ${parsedCount} total prompts, ${syncCount} match filters`);\n if (filteredCount > 0) {\n logger.dim(` ${filteredCount} filtered by path/session`);\n }\n if (privacyFilteredCount > 0) {\n logger.dim(` ${privacyFilteredCount} filtered (untracked projects)`);\n if (untrackedProjects.size <= 5) {\n Array.from(untrackedProjects).forEach(p => {\n logger.dim(` - ${p}`);\n });\n } else {\n logger.dim(` (${untrackedProjects.size} untracked projects)`);\n }\n logger.dim(` Run 'skillo connect' in those directories to track them.`);\n }\n\n if (prompts.length === 0) {\n logger.info(\"No matching prompts to sync.\");\n return;\n }\n\n // Sync to platform\n logger.info(\"Syncing to platform...\");\n\n try {\n const response = await client.syncClaudePrompts(prompts, {\n terminalSessionId: options.session,\n projectPath: projectFilter,\n });\n\n if (response.success && response.data) {\n const { sessionsCreated, promptsCreated, promptsSkipped } = response.data;\n logger.success(\"Synced successfully!\");\n logger.info(` Sessions created: ${sessionsCreated}`);\n logger.info(` Prompts created: ${promptsCreated}`);\n logger.info(` Prompts skipped (already exist): ${promptsSkipped}`);\n } else {\n logger.error(`Sync failed: ${response.error}`);\n }\n } catch (error) {\n logger.error(`Failed to sync: ${error}`);\n process.exit(1);\n }\n });\n\n// Watch Claude Code history for changes (uses shared ClaudeWatcher)\nclaudeCommand\n .command(\"watch\")\n .description(\"Watch Claude Code history and sync in real-time (only tracked projects)\")\n .option(\"--interval <ms>\", \"Check interval in milliseconds\", \"5000\")\n .option(\"--project-path <path>\", \"Only sync prompts for this project path\")\n .option(\"--session <id>\", \"Link prompts to this terminal session\")\n .action(async (options: WatchOptions) => {\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n process.exit(1);\n }\n\n const { ClaudeWatcher } = await import(\"../core/claude-watcher.js\");\n\n const interval = parseInt(options.interval, 10);\n const projectFilter = options.projectPath || process.env.SKILLO_PROJECT_PATH;\n\n if (projectFilter) {\n logger.info(`Watching for project: ${projectFilter}`);\n }\n logger.info(`Checking every ${interval}ms`);\n logger.info(\"Press Ctrl+C to stop\");\n\n const watcher = new ClaudeWatcher(client, {\n intervalMs: interval,\n projectFilter,\n sessionFilter: options.session,\n callbacks: {\n onSync: (count) => logger.success(`Synced ${count} prompt(s)`),\n onError: (err) => logger.error(`Watch error: ${err.message}`),\n log: (level, msg) => {\n if (level === \"ERROR\") logger.error(msg);\n else if (level === \"WARN\") logger.warn(msg);\n else logger.dim(msg);\n },\n },\n });\n\n await watcher.start();\n\n process.on(\"SIGINT\", () => {\n logger.info(\"\\nStopping watcher...\");\n watcher.stop();\n process.exit(0);\n });\n });\n\n// Status command\nclaudeCommand\n .command(\"status\")\n .description(\"Show Claude Code sync status\")\n .option(\"--project-path <path>\", \"Show status for specific project\")\n .action(async (options: { projectPath?: string }) => {\n const client = getApiClient();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n process.exit(1);\n }\n\n const historyPath = getClaudeHistoryPath();\n const projectFilter = options.projectPath || process.env.SKILLO_PROJECT_PATH;\n\n logger.info(\"Claude Code Status\");\n logger.info(\"==================\");\n logger.info(`History file: ${historyPath}`);\n\n if (projectFilter) {\n logger.info(`Project filter: ${projectFilter}`);\n }\n\n if (fs.existsSync(historyPath)) {\n const stats = fs.statSync(historyPath);\n logger.info(`File size: ${(stats.size / 1024).toFixed(2)} KB`);\n logger.info(`Last modified: ${new Date(stats.mtimeMs).toLocaleString()}`);\n\n // Count entries\n let totalCount = 0;\n let projectCount = 0;\n const sessions = new Set<string>();\n const projectSessions = new Set<string>();\n\n const fileStream = fs.createReadStream(historyPath);\n const rl = readline.createInterface({\n input: fileStream,\n crlfDelay: Infinity,\n });\n\n for await (const line of rl) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line) as ClaudeHistoryEntry;\n if (entry.sessionId) {\n totalCount++;\n sessions.add(entry.sessionId);\n\n if (!projectFilter || matchesProjectPath(entry.project, projectFilter)) {\n projectCount++;\n projectSessions.add(entry.sessionId);\n }\n }\n } catch {\n // Skip invalid JSON\n }\n }\n\n logger.info(`\\nTotal prompts: ${totalCount}`);\n logger.info(`Total sessions: ${sessions.size}`);\n\n if (projectFilter) {\n logger.info(`\\nFor current project:`);\n logger.info(` Prompts: ${projectCount}`);\n logger.info(` Sessions: ${projectSessions.size}`);\n }\n } else {\n logger.warn(\"History file not found\");\n }\n\n // Get synced data from platform\n try {\n const response = await client.getClaudeSessions(5);\n if (response.success && response.data?.sessions) {\n logger.info(`\\nSynced to platform: ${response.data.sessions.length} recent sessions`);\n }\n } catch {\n logger.warn(\"Could not fetch synced data from platform\");\n }\n });\n","/**\n * Project tracking commands - Track/untrack projects for privacy-first tracking.\n */\n\nimport { Command } from \"commander\";\nimport { existsSync, writeFileSync } from \"fs\";\nimport { getApiClient } from \"../core/api-client.js\";\nimport { getGitInfo } from \"../utils/git.js\";\nimport logger from \"../utils/logger.js\";\nimport { resolve } from \"path\";\nimport { getTrackedProjectsCacheFile, getShellIntegrationDir, ensureDirectory, getDataDir } from \"../utils/paths.js\";\nimport { isDaemonRunning, startDaemonProcess } from \"./daemon.js\";\n\nexport const projectCommand = new Command(\"project\")\n .description(\"Manage project tracking settings\");\n\n// skillo track - Enable tracking for current directory\nexport const trackCommand = new Command(\"track\")\n .description(\"Enable tracking for the current project\")\n .argument(\"[path]\", \"Project path (defaults to current directory)\")\n .option(\"-n, --name <name>\", \"Custom project name\")\n .action(async (pathArg?: string, options?: { name?: string }) => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n return;\n }\n\n const projectPath = resolve(pathArg || process.cwd());\n\n logger.info(`Tracking project: ${projectPath}`);\n logger.blank();\n\n // Get git information\n const gitInfo = getGitInfo(projectPath);\n\n if (gitInfo.isGitRepo) {\n logger.dim(`Git repository detected`);\n if (gitInfo.remote) {\n logger.dim(`Remote: ${gitInfo.remoteNormalized || gitInfo.remote}`);\n }\n if (gitInfo.branch) {\n logger.dim(`Branch: ${gitInfo.branch}`);\n }\n logger.blank();\n } else {\n logger.warn(\"No git repository detected in this directory.\");\n logger.dim(\"Project will be tracked by path only (no team sharing).\");\n logger.blank();\n }\n\n // Determine project name\n const projectName = options?.name || gitInfo.projectName || projectPath.split(\"/\").pop() || \"Unknown\";\n\n try {\n const result = await client.connectProject({\n path: projectPath,\n name: projectName,\n gitRemote: gitInfo.remote || undefined,\n gitRemoteNormalized: gitInfo.remoteNormalized || undefined,\n });\n\n if (result.success) {\n logger.success(`Project \"${projectName}\" is now being tracked!`);\n logger.blank();\n logger.dim(\"Your Claude Code prompts in this directory will now be synced.\");\n logger.dim(\"Run 'skillo untrack' to stop tracking.\");\n\n // Write tracked projects cache immediately\n try {\n const listResult = await client.listProjects(true);\n if (listResult.success && listResult.data?.projects) {\n const cacheData = {\n updatedAt: Date.now(),\n projects: listResult.data.projects\n .filter((p: { trackingEnabled: boolean }) => p.trackingEnabled)\n .map((p: { path: string; name: string }) => ({ path: p.path, name: p.name })),\n };\n ensureDirectory(getDataDir());\n writeFileSync(getTrackedProjectsCacheFile(), JSON.stringify(cacheData, null, 2));\n }\n } catch {\n // Non-critical - daemon will update cache on next cycle\n }\n\n // Auto-start daemon if not running\n const { running } = isDaemonRunning();\n if (!running) {\n logger.blank();\n const pid = startDaemonProcess();\n if (pid) {\n logger.success(`Background sync daemon started (PID: ${pid})`);\n } else {\n logger.dim(\"Tip: Run 'skillo start' to enable background sync.\");\n }\n }\n\n // Suggest shell integration if not installed\n const shellIntegrationDir = getShellIntegrationDir();\n if (!existsSync(shellIntegrationDir) || !existsSync(resolve(shellIntegrationDir, \"skillo.zsh\"))) {\n logger.blank();\n logger.dim(\"Tip: Run 'skillo setup-shell' to enable terminal auto-detection.\");\n }\n } else {\n logger.error(\"Failed to track project: \" + (result.error || \"Unknown error\"));\n }\n } catch (error) {\n logger.error(\"Failed to track project: \" + (error instanceof Error ? error.message : \"Unknown error\"));\n }\n\n logger.blank();\n });\n\n// skillo untrack - Disable tracking for current directory\nexport const untrackCommand = new Command(\"untrack\")\n .description(\"Disable tracking for the current project\")\n .argument(\"[path]\", \"Project path (defaults to current directory)\")\n .action(async (pathArg?: string) => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n return;\n }\n\n const projectPath = resolve(pathArg || process.cwd());\n\n logger.info(`Untracking project: ${projectPath}`);\n\n try {\n const result = await client.disconnectProject(projectPath);\n\n if (result.success) {\n logger.blank();\n logger.success(\"Project is no longer being tracked.\");\n logger.blank();\n logger.dim(\"Your Claude Code prompts in this directory will no longer be synced.\");\n logger.dim(\"Existing data remains in your account.\");\n } else {\n logger.blank();\n logger.error(\"Failed to untrack project: \" + (result.error || \"Unknown error\"));\n }\n } catch (error) {\n logger.blank();\n logger.error(\"Failed to untrack project: \" + (error instanceof Error ? error.message : \"Unknown error\"));\n }\n\n logger.blank();\n });\n\n// skillo project status - Show tracking status for current project\nprojectCommand\n .command(\"status\")\n .description(\"Show tracking status for the current project\")\n .argument(\"[path]\", \"Project path (defaults to current directory)\")\n .action(async (pathArg?: string) => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n return;\n }\n\n const projectPath = resolve(pathArg || process.cwd());\n\n logger.info(`Project: ${projectPath}`);\n logger.blank();\n\n // Get git information\n const gitInfo = getGitInfo(projectPath);\n\n if (gitInfo.isGitRepo) {\n logger.dim(`Git: ${gitInfo.remoteNormalized || gitInfo.remote || \"no remote\"}`);\n if (gitInfo.branch) {\n logger.dim(`Branch: ${gitInfo.branch}`);\n }\n } else {\n logger.dim(\"Git: not a repository\");\n }\n\n logger.blank();\n\n try {\n const result = await client.getProjectStatus(projectPath);\n\n if (result.success && result.data) {\n const { connected, connectedAt } = result.data;\n\n if (connected) {\n logger.success(\"Tracking ENABLED\");\n if (connectedAt) {\n logger.dim(`Since: ${new Date(connectedAt).toLocaleDateString()}`);\n }\n } else {\n logger.warn(\"Tracking DISABLED\");\n logger.dim(\"Run 'skillo track' to enable tracking.\");\n }\n } else {\n logger.warn(\"Not tracked\");\n logger.dim(\"Run 'skillo track' to enable tracking for this project.\");\n }\n } catch (error) {\n logger.error(\"Failed to get project status: \" + (error instanceof Error ? error.message : \"Unknown error\"));\n }\n\n logger.blank();\n });\n\n// skillo project list - List all tracked projects\nprojectCommand\n .command(\"list\")\n .alias(\"ls\")\n .description(\"List all projects (tracked and untracked)\")\n .option(\"-a, --all\", \"Include untracked projects\")\n .action(async (options?: { all?: boolean }) => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n return;\n }\n\n try {\n const result = await client.listProjects(options?.all || false);\n\n if (result.success && result.data) {\n const { projects, totalTracked, totalProjects } = result.data;\n\n logger.info(`Projects (${totalTracked} tracked / ${totalProjects} total)`);\n logger.blank();\n\n if (projects.length === 0) {\n logger.dim(\"No projects found.\");\n logger.dim(\"Run 'skillo track' in a project directory to start tracking.\");\n } else {\n for (const project of projects) {\n const status = project.trackingEnabled ? \"●\" : \"○\";\n const statusColor = project.trackingEnabled ? \"\\x1b[32m\" : \"\\x1b[90m\";\n const resetColor = \"\\x1b[0m\";\n\n console.log(` ${statusColor}${status}${resetColor} ${project.name}`);\n logger.dim(` ${project.path}`);\n if (project.gitRemoteNormalized) {\n logger.dim(` ${project.gitRemoteNormalized}`);\n }\n }\n }\n } else {\n logger.error(\"Failed to list projects: \" + (result.error || \"Unknown error\"));\n }\n } catch (error) {\n logger.error(\"Failed to list projects: \" + (error instanceof Error ? error.message : \"Unknown error\"));\n }\n\n logger.blank();\n });\n","/**\n * Git utilities for project detection and identification.\n */\n\nimport { execSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport { join, dirname, basename } from \"path\";\n\nexport interface GitInfo {\n isGitRepo: boolean;\n rootPath: string | null;\n remote: string | null;\n remoteNormalized: string | null;\n branch: string | null;\n projectName: string | null;\n}\n\n/**\n * Get git information for a given path.\n */\nexport function getGitInfo(projectPath: string): GitInfo {\n const result: GitInfo = {\n isGitRepo: false,\n rootPath: null,\n remote: null,\n remoteNormalized: null,\n branch: null,\n projectName: null,\n };\n\n try {\n // Check if it's a git repo and get root\n const rootPath = execSync(\"git rev-parse --show-toplevel\", {\n cwd: projectPath,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n\n if (!rootPath) return result;\n\n result.isGitRepo = true;\n result.rootPath = rootPath;\n result.projectName = basename(rootPath);\n\n // Get current branch\n try {\n result.branch = execSync(\"git rev-parse --abbrev-ref HEAD\", {\n cwd: projectPath,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n } catch {\n // Might be in detached HEAD state\n }\n\n // Get remote URL (prefer origin)\n try {\n result.remote = execSync(\"git remote get-url origin\", {\n cwd: projectPath,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n } catch {\n // Try to get any remote\n try {\n const remotes = execSync(\"git remote\", {\n cwd: projectPath,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim().split(\"\\n\");\n\n if (remotes.length > 0 && remotes[0]) {\n result.remote = execSync(`git remote get-url ${remotes[0]}`, {\n cwd: projectPath,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n }\n } catch {\n // No remotes configured\n }\n }\n\n // Normalize the remote URL for team matching\n if (result.remote) {\n result.remoteNormalized = normalizeGitRemote(result.remote);\n }\n } catch {\n // Not a git repository\n }\n\n return result;\n}\n\n/**\n * Normalize a git remote URL for consistent matching across team members.\n * Converts various formats to: \"host/owner/repo\"\n *\n * Examples:\n * - git@github.com:acme/webapp.git -> github.com/acme/webapp\n * - https://github.com/acme/webapp.git -> github.com/acme/webapp\n * - ssh://git@github.com/acme/webapp -> github.com/acme/webapp\n * - git://github.com/acme/webapp.git -> github.com/acme/webapp\n */\nexport function normalizeGitRemote(remoteUrl: string): string {\n let url = remoteUrl.trim();\n\n // Remove .git suffix\n url = url.replace(/\\.git$/, \"\");\n\n // Handle SSH format: git@github.com:owner/repo\n const sshMatch = url.match(/^git@([^:]+):(.+)$/);\n if (sshMatch) {\n return `${sshMatch[1]}/${sshMatch[2]}`;\n }\n\n // Handle various URL formats\n try {\n // Remove protocol prefix for parsing\n let normalized = url\n .replace(/^(https?|git|ssh):\\/\\//, \"\")\n .replace(/^git@/, \"\");\n\n // Remove username if present (e.g., git@host or user@host)\n normalized = normalized.replace(/^[^@]+@/, \"\");\n\n // Remove port if present\n normalized = normalized.replace(/:\\d+\\//, \"/\");\n\n // Clean up any double slashes\n normalized = normalized.replace(/\\/+/g, \"/\");\n\n // Remove leading/trailing slashes\n normalized = normalized.replace(/^\\/|\\/$/g, \"\");\n\n return normalized.toLowerCase();\n } catch {\n // Fallback: return as-is but lowercase\n return url.toLowerCase();\n }\n}\n\n/**\n * Find git root by walking up the directory tree.\n */\nexport function findGitRoot(startPath: string): string | null {\n let current = startPath;\n\n while (current !== dirname(current)) {\n if (existsSync(join(current, \".git\"))) {\n return current;\n }\n current = dirname(current);\n }\n\n return null;\n}\n\n/**\n * Check if a path is inside a git repository.\n */\nexport function isInsideGitRepo(path: string): boolean {\n return findGitRoot(path) !== null;\n}\n\n/**\n * Extract owner and repo name from a normalized git remote.\n */\nexport function parseGitRemote(normalizedRemote: string): { host: string; owner: string; repo: string } | null {\n const parts = normalizedRemote.split(\"/\");\n\n if (parts.length < 3) return null;\n\n return {\n host: parts[0],\n owner: parts[1],\n repo: parts.slice(2).join(\"/\"), // Handle nested paths like gitlab subgroups\n };\n}\n","/**\n * Authentication commands - Login/logout with Skillo platform.\n */\n\nimport { Command } from \"commander\";\nimport { getApiClient } from \"../core/api-client.js\";\nimport logger from \"../utils/logger.js\";\nimport { hostname } from \"os\";\nimport { installService } from \"../utils/os-service.js\";\nimport { isDaemonRunning, startDaemonProcess } from \"./daemon.js\";\n\n// Try to open URL in browser\nasync function openBrowser(url: string): Promise<boolean> {\n try {\n const { exec } = await import(\"child_process\");\n const { promisify } = await import(\"util\");\n const execAsync = promisify(exec);\n\n const platform = process.platform;\n let command: string;\n\n if (platform === \"darwin\") {\n command = `open \"${url}\"`;\n } else if (platform === \"win32\") {\n command = `start \"\" \"${url}\"`;\n } else {\n command = `xdg-open \"${url}\"`;\n }\n\n await execAsync(command);\n return true;\n } catch {\n return false;\n }\n}\n\n// Sleep helper\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Start daemon and install OS auto-start service after login */\nasync function autoStartDaemon() {\n try {\n const { running } = isDaemonRunning();\n if (!running) {\n const pid = startDaemonProcess();\n if (pid) {\n logger.dim(`Background daemon started (PID: ${pid}).`);\n }\n }\n\n const result = await installService();\n if (result.success) {\n logger.dim(\"Auto-start installed. Daemon will survive reboots.\");\n }\n } catch {\n // Non-critical — don't fail login\n }\n}\n\nexport const loginCommand = new Command(\"login\")\n .description(\"Login to Skillo platform\")\n .argument(\"[api-key]\", \"Your Skillo API key (optional, will use browser auth if not provided)\")\n .option(\"-u, --url <url>\", \"Platform URL (default: https://www.skillo.one)\")\n .option(\"-n, --no-browser\", \"Don't open browser automatically\")\n .action(async (apiKey?: string, options?: { url?: string; browser?: boolean }) => {\n const client = getApiClient();\n\n logger.blank();\n\n // Set custom URL if provided\n if (options?.url) {\n client.setBaseUrl(options.url);\n logger.dim(`Using API URL: ${options.url}`);\n }\n\n // If API key provided directly, use it\n if (apiKey) {\n // Validate API key format\n if (!apiKey.startsWith(\"sk_\")) {\n logger.error(\"Invalid API key format. Keys should start with 'sk_'\");\n return;\n }\n\n // Save the API key\n client.saveApiKey(apiKey);\n\n // Verify by authenticating\n logger.info(\"Verifying API key...\");\n const result = await client.authenticate();\n\n if (result.success && result.data) {\n logger.blank();\n logger.success(\"Login successful!\");\n logger.blank();\n logger.info(`Welcome, ${result.data.user.name}!`);\n logger.dim(`Email: ${result.data.user.email}`);\n logger.blank();\n\n // Auto-start daemon and install service\n await autoStartDaemon();\n\n logger.dim(\"Your patterns and skills will now sync with the Skillo platform.\");\n } else {\n // Clear the invalid key\n client.clearApiKey();\n logger.blank();\n logger.error(\"Login failed: \" + (result.error || \"Invalid API key\"));\n logger.dim(\"Please check your API key and try again.\");\n }\n return;\n }\n\n // Check if already logged in\n if (client.hasApiKey()) {\n logger.info(`Already logged in. API key: ${client.getMaskedApiKey()}`);\n logger.dim(\"Use 'skillo logout' to log out first.\");\n logger.blank();\n\n // Verify the current key still works\n const result = await client.authenticate();\n if (result.success && result.data) {\n logger.success(`Authenticated as: ${result.data.user.name} (${result.data.user.email})`);\n } else {\n logger.warn(\"Current API key may be invalid or expired.\");\n logger.dim(\"Use 'skillo logout' then 'skillo login' to re-authenticate.\");\n }\n return;\n }\n\n // Start OAuth device flow\n logger.info(\"Starting authentication...\");\n logger.blank();\n\n const deviceName = `CLI on ${hostname()}`;\n const deviceAuthResult = await client.startDeviceAuth(deviceName);\n\n if (!deviceAuthResult.success || !deviceAuthResult.data) {\n logger.error(\"Failed to start authentication: \" + (deviceAuthResult.error || \"Unknown error\"));\n logger.blank();\n logger.dim(\"Alternative: Get an API key from the Skillo dashboard and run:\");\n logger.dim(\" skillo login <your-api-key>\");\n return;\n }\n\n const { code, verification_url, interval } = deviceAuthResult.data;\n\n // Display instructions\n logger.info(\"To complete login, open this URL in your browser:\");\n logger.blank();\n logger.highlight(` ${verification_url}`);\n logger.blank();\n\n // Try to open browser\n if (options?.browser !== false) {\n const opened = await openBrowser(verification_url);\n if (opened) {\n logger.dim(\"Browser opened automatically.\");\n } else {\n logger.dim(\"Could not open browser automatically. Please open the URL manually.\");\n }\n }\n\n logger.blank();\n logger.dim(\"Waiting for authorization...\");\n logger.dim(\"(Press Ctrl+C to cancel)\");\n\n // Poll for authorization\n const maxAttempts = 120; // 10 minutes at 5 second intervals\n let attempts = 0;\n\n while (attempts < maxAttempts) {\n await sleep(interval * 1000);\n attempts++;\n\n const statusResult = await client.checkTokenStatus(code);\n\n if (!statusResult.success) {\n // Network error, continue polling\n continue;\n }\n\n const status = statusResult.data?.status;\n\n if (status === \"ready\") {\n // Authorization complete, exchange for token\n const tokenResult = await client.exchangeToken(code, deviceName);\n\n if (tokenResult.success && tokenResult.data) {\n // Save the API key\n client.saveApiKey(tokenResult.data.api_key);\n\n // Verify and get user info\n const authResult = await client.authenticate();\n\n logger.blank();\n logger.success(\"Login successful!\");\n logger.blank();\n\n if (authResult.success && authResult.data) {\n logger.info(`Welcome, ${authResult.data.user.name}!`);\n logger.dim(`Email: ${authResult.data.user.email}`);\n }\n\n logger.blank();\n\n // Auto-start daemon and install service\n await autoStartDaemon();\n\n logger.dim(\"Your patterns and skills will now sync with the Skillo platform.\");\n return;\n } else {\n logger.blank();\n logger.error(\"Failed to complete login: \" + (tokenResult.error || \"Unknown error\"));\n return;\n }\n } else if (status === \"expired\") {\n logger.blank();\n logger.error(\"Authorization expired. Please try again.\");\n return;\n } else if (status === \"used\") {\n logger.blank();\n logger.error(\"This authorization code has already been used.\");\n return;\n } else if (status === \"not_found\") {\n logger.blank();\n logger.error(\"Authorization code not found. Please try again.\");\n return;\n }\n\n // Still pending, continue polling\n }\n\n // Timeout\n logger.blank();\n logger.error(\"Authorization timed out. Please try again.\");\n });\n\nexport const logoutCommand = new Command(\"logout\")\n .description(\"Logout from Skillo platform\")\n .action(async () => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.dim(\"Not logged in.\");\n return;\n }\n\n client.clearApiKey();\n logger.success(\"Logged out successfully.\");\n logger.blank();\n logger.dim(\"Your local data remains intact. Use 'skillo login' to reconnect.\");\n });\n\nexport const whoamiCommand = new Command(\"whoami\")\n .description(\"Show current login status\")\n .action(async () => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.dim(\"Not logged in.\");\n logger.blank();\n logger.dim(\"Use 'skillo login' to connect to the Skillo platform.\");\n return;\n }\n\n logger.info(`API key: ${client.getMaskedApiKey()}`);\n logger.dim(\"Checking authentication...\");\n\n const result = await client.authenticate();\n\n if (result.success && result.data) {\n logger.blank();\n logger.success(\"Authenticated\");\n logger.blank();\n logger.table([\n [\"Name\", result.data.user.name],\n [\"Email\", result.data.user.email],\n [\"User ID\", result.data.user.id],\n ]);\n } else {\n logger.blank();\n logger.warn(\"Authentication failed: \" + (result.error || \"Unknown error\"));\n logger.dim(\"Your API key may be invalid or expired.\");\n logger.dim(\"Use 'skillo logout' then 'skillo login' to re-authenticate.\");\n }\n\n logger.blank();\n });\n","/**\n * Sync commands - Sync data with Skillo platform.\n */\n\nimport { existsSync, writeFileSync, mkdirSync } from \"fs\";\nimport { join } from \"path\";\nimport { Command } from \"commander\";\nimport { getApiClient } from \"../core/api-client.js\";\nimport { SkilloDatabase } from \"../core/database.js\";\nimport { getDbPath, getSkillsDir, ensureDirectory } from \"../utils/paths.js\";\nimport logger from \"../utils/logger.js\";\n\nexport const syncCommand = new Command(\"sync\")\n .description(\"Sync data with Skillo platform\")\n .option(\"--push\", \"Push local data to platform\")\n .option(\"--pull\", \"Pull data from platform\")\n .option(\"--patterns\", \"Sync patterns only\")\n .option(\"--skills\", \"Sync skills only\")\n .option(\"--commands\", \"Sync commands only\")\n .action(\n async (options: {\n push?: boolean;\n pull?: boolean;\n patterns?: boolean;\n skills?: boolean;\n commands?: boolean;\n }) => {\n const client = getApiClient();\n\n logger.blank();\n\n if (!client.hasApiKey()) {\n logger.error(\"Not logged in. Run 'skillo login' first.\");\n return;\n }\n\n // Default to pull if neither specified\n const doPush = options.push || false;\n const doPull = options.pull || (!options.push && !options.pull);\n\n // Default to all if none specified\n const syncPatterns = options.patterns || (!options.patterns && !options.skills && !options.commands);\n const syncSkills = options.skills || (!options.patterns && !options.skills && !options.commands);\n const syncCommands = options.commands || (!options.patterns && !options.skills && !options.commands);\n\n // Check database exists\n const dbPath = getDbPath();\n if (!existsSync(dbPath)) {\n logger.error(\"Database not found. Run 'skillo init' first.\");\n return;\n }\n\n const db = new SkilloDatabase();\n await db.initialize();\n\n try {\n if (doPush) {\n logger.bold(\"Pushing local data to platform...\");\n logger.blank();\n\n if (syncCommands) {\n await pushCommands(db, client);\n }\n\n if (syncPatterns) {\n await pushPatterns(db, client);\n }\n\n if (syncSkills) {\n logger.dim(\"Skill push not yet implemented.\");\n }\n }\n\n if (doPull) {\n logger.bold(\"Pulling data from platform...\");\n logger.blank();\n\n const type = syncSkills && syncPatterns ? \"all\" : syncSkills ? \"skills\" : \"patterns\";\n const result = await client.downloadData(type);\n\n if (!result.success) {\n logger.error(\"Failed to download: \" + result.error);\n return;\n }\n\n if (result.data?.skills && syncSkills) {\n await pullSkills(result.data.skills);\n }\n\n if (result.data?.patterns && syncPatterns) {\n logger.success(`Downloaded ${result.data.patterns.length} patterns`);\n // Patterns are stored in platform, not locally synced back\n }\n }\n\n logger.blank();\n logger.success(\"Sync complete!\");\n } finally {\n db.close();\n }\n\n logger.blank();\n }\n );\n\n/**\n * Push commands to platform\n */\nasync function pushCommands(db: SkilloDatabase, client: ReturnType<typeof getApiClient>) {\n const commands = await db.getRecentCommands({ days: 7 });\n\n if (commands.length === 0) {\n logger.dim(\"No commands to sync.\");\n return;\n }\n\n logger.info(`Syncing ${commands.length} commands...`);\n\n const result = await client.syncCommands(\n commands.map((cmd) => ({\n timestamp: cmd.timestamp,\n command: cmd.command,\n normalized: cmd.normalized,\n cwd: cmd.cwd,\n exitCode: cmd.exitCode,\n durationMs: cmd.durationMs,\n variables: cmd.variables ? JSON.parse(cmd.variables) : null,\n }))\n );\n\n if (result.success) {\n logger.success(`Synced ${commands.length} commands`);\n } else {\n logger.error(\"Failed to sync commands: \" + result.error);\n }\n}\n\n/**\n * Push patterns to platform\n */\nasync function pushPatterns(db: SkilloDatabase, client: ReturnType<typeof getApiClient>) {\n const patterns = await db.getPatterns({ status: \"active\" });\n\n if (patterns.length === 0) {\n logger.dim(\"No patterns to sync.\");\n return;\n }\n\n logger.info(`Syncing ${patterns.length} patterns...`);\n\n let synced = 0;\n for (const pattern of patterns) {\n const result = await client.syncPattern({\n sourceType: pattern.sourceType,\n name: pattern.description.substring(0, 100),\n description: pattern.description,\n commands: pattern.data.commands as string[] || [],\n frequency: pattern.count,\n firstSeen: pattern.firstSeen,\n lastSeen: pattern.lastSeen,\n });\n\n if (result.success) {\n synced++;\n }\n }\n\n logger.success(`Synced ${synced}/${patterns.length} patterns`);\n}\n\n/**\n * Pull skills from platform and write to ~/.claude/skills/\n */\nasync function pullSkills(\n skills: Array<{\n id: string;\n name: string;\n slug: string;\n description: string;\n content: string;\n commands: string[];\n }>\n) {\n if (skills.length === 0) {\n logger.dim(\"No skills to download.\");\n return;\n }\n\n const skillsDir = getSkillsDir();\n ensureDirectory(skillsDir);\n\n let downloaded = 0;\n for (const skill of skills) {\n if (!skill.content) continue;\n\n const skillDir = join(skillsDir, skill.slug);\n const skillFile = join(skillDir, \"SKILL.md\");\n\n // Create skill directory\n if (!existsSync(skillDir)) {\n mkdirSync(skillDir, { recursive: true });\n }\n\n // Write SKILL.md\n writeFileSync(skillFile, skill.content, \"utf-8\");\n downloaded++;\n logger.dim(` Downloaded: ${skill.name}`);\n }\n\n logger.success(`Downloaded ${downloaded} skills to ~/.claude/skills/`);\n}\n","/**\n * Tray command — starts the system tray icon.\n */\n\nimport { Command } from \"commander\";\nimport logger from \"../utils/logger.js\";\n\nexport const trayCommand = new Command(\"tray\")\n .description(\"Start the system tray icon\")\n .action(async () => {\n try {\n const { startTray } = await import(\"../tray/tray.js\");\n await startTray();\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"Cannot find module\")) {\n logger.error(\"System tray not available. The systray2 package may not be installed.\");\n logger.dim(\"Try: npm install -g skillo\");\n } else {\n logger.error(`Tray error: ${error instanceof Error ? error.message : error}`);\n }\n process.exit(1);\n }\n });\n"],"mappings":"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","names":["Command","path","existsSync","readFileSync","Command","existsSync","os","existsSync","readFileSync","Command","existsSync","readFileSync","Command","Command","existsSync","readFileSync","existsSync","Command","chalk","Command","existsSync","getApiClient","writeFileSync","mkdirSync","join","getSkillsDir","ensureDirectory","existsSync","readdirSync","join","Command","chalk","Command","existsSync","readdirSync","join","existsSync","writeFileSync","readFileSync","homedir","join","Command","path","Command","existsSync","getApiClient","homedir","join","writeFileSync","readFileSync","existsSync","readFileSync","writeFileSync","unlinkSync","Command","isDaemonRunning","existsSync","readFileSync","unlinkSync","writeFileSync","getDefaultConfig","saveConfig","SkilloDatabase","getConfigDir","getSkillsDir","getApiClient","hostname","Command","spawn","Command","existsSync","readFileSync","writeFileSync","unlinkSync","Command","existsSync","readFileSync","unlinkSync","writeFileSync","Command","Command","Command","existsSync","writeFileSync","execSync","join","dirname","basename","execSync","Command","writeFileSync","isDaemonRunning","existsSync","Command","platform","resolve","isDaemonRunning","Command","existsSync","writeFileSync","mkdirSync","join","Command","Command","existsSync","join","mkdirSync","writeFileSync","Command","Command","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillo",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Autonomous workflow learning & skill generation system - Learn workflows by observation, not explanation",
5
5
  "keywords": [
6
6
  "cli",
@@ -8,7 +8,7 @@
8
8
  * Cross-platform: macOS, Linux, Windows (PowerShell).
9
9
  */
10
10
 
11
- import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync } from "fs";
11
+ import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync, chmodSync, readdirSync } from "fs";
12
12
  import { join } from "path";
13
13
  import { homedir, platform } from "os";
14
14
 
@@ -319,9 +319,28 @@ function install(shell) {
319
319
  return true;
320
320
  }
321
321
 
322
+ // ── Fix systray2 binary permissions (npm strips +x) ─────────────────────────
323
+
324
+ function fixSystrayBinaries() {
325
+ if (isWin) return;
326
+ try {
327
+ // Fix binaries relative to this postinstall script (../node_modules/systray2/traybin/)
328
+ const trayBinDir = join(new URL(".", import.meta.url).pathname, "..", "node_modules", "systray2", "traybin");
329
+ if (!existsSync(trayBinDir)) return;
330
+ for (const f of readdirSync(trayBinDir)) {
331
+ if (f.startsWith("tray_")) {
332
+ chmodSync(join(trayBinDir, f), 0o755);
333
+ }
334
+ }
335
+ } catch {
336
+ // best-effort
337
+ }
338
+ }
339
+
322
340
  // ── Main ─────────────────────────────────────────────────────────────────────
323
341
 
324
342
  try {
343
+ fixSystrayBinaries();
325
344
  const shell = detectShell();
326
345
  const installed = install(shell);
327
346