@burdenoff/vibe-agent 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{app-6mmbmske.js → app-8dgv7s3y.js} +13 -14
- package/dist/{app-6mmbmske.js.map → app-8dgv7s3y.js.map} +3 -3
- package/dist/cli.js +28 -27
- package/dist/cli.js.map +5 -5
- package/dist/{index-41m1exz7.js → index-3rjnbp97.js} +3 -4
- package/dist/index-3rjnbp97.js.map +13 -0
- package/dist/{index-q4ytrfx7.js → index-6vry08rz.js} +4 -5
- package/dist/index-6vry08rz.js.map +13 -0
- package/dist/{index-wdtxbebz.js → index-fm6gqenc.js} +3 -4
- package/dist/index-fm6gqenc.js.map +13 -0
- package/dist/{index-3v78e2cn.js → index-s7ff1fj1.js} +88 -46
- package/dist/index-s7ff1fj1.js.map +11 -0
- package/dist/{index-9tgyd3ep.js → index-wjsms9jw.js} +11 -9
- package/dist/{index-9tgyd3ep.js.map → index-wjsms9jw.js.map} +3 -3
- package/dist/{index-qthbtg9n.js → index-wmvkjcjj.js} +4 -5
- package/dist/index-wmvkjcjj.js.map +13 -0
- package/dist/{index-xn4tarcd.js → index-x82yjxw7.js} +4 -4
- package/dist/index.js +2 -2
- package/dist/{package-ywexp6sg.js → package-04nkt49b.js} +5 -3
- package/dist/{package-ywexp6sg.js.map → package-04nkt49b.js.map} +1 -1
- package/dist/{plugin-system-v7a7xnhk.js → plugin-system-bc4rvt1c.js} +46 -14
- package/dist/plugin-system-bc4rvt1c.js.map +10 -0
- package/package.json +3 -1
- package/dist/index-3v78e2cn.js.map +0 -11
- package/dist/index-41m1exz7.js.map +0 -13
- package/dist/index-q4ytrfx7.js.map +0 -13
- package/dist/index-qthbtg9n.js.map +0 -13
- package/dist/index-wdtxbebz.js.map +0 -13
- package/dist/plugin-system-v7a7xnhk.js.map +0 -10
- /package/dist/{index-xn4tarcd.js.map → index-x82yjxw7.js.map} +0 -0
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/services/bootstrap.service.ts", "../src/services/service-manager.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Bootstrap Service\n *\n * Handles dependency checking and auto-installation for the vibe agent.\n * Checks for required system tools and optionally installs them.\n *\n * Required prerequisites:\n * - bun (runtime - already present if running this code)\n * - tmux (installed via session-tmux plugin, but checked here for setup)\n * - ttyd (installed via session-tmux plugin, but checked here for setup)\n * - cloudflared (installed via tunnel-cloudflare plugin, but checked here for setup)\n */\n\nimport { execSync } from \"node:child_process\";\nimport os from \"node:os\";\n\nimport { logger } from \"./logger.js\";\n\n// ── Types ────────────────────────────────────────────────────────────────\n\nexport interface DependencyCheck {\n name: string;\n installed: boolean;\n version?: string;\n required: boolean;\n category: \"runtime\" | \"session\" | \"tunnel\" | \"tool\";\n}\n\nexport interface SetupResult {\n success: boolean;\n installed: string[];\n failed: string[];\n skipped: string[];\n}\n\n// ── Check Functions ─────────────────────────────────────────────────────\n\nfunction checkCommand(cmd: string): { installed: boolean; version?: string } {\n try {\n const version = execSync(`${cmd} --version 2>&1 || ${cmd} -v 2>&1`, {\n timeout: 5000,\n stdio: \"pipe\",\n })\n .toString()\n .trim()\n .split(\"\\n\")[0];\n return { installed: true, version };\n } catch {\n return { installed: false };\n }\n}\n\n/**\n * Check all dependencies and return their status.\n */\nexport function checkDependencies(): DependencyCheck[] {\n const deps: Array<{\n name: string;\n cmd: string;\n required: boolean;\n category: DependencyCheck[\"category\"];\n }> = [\n { name: \"bun\", cmd: \"bun\", required: true, category: \"runtime\" },\n { name: \"tmux\", cmd: \"tmux\", required: false, category: \"session\" },\n { name: \"ttyd\", cmd: \"ttyd\", required: false, category: \"session\" },\n {\n name: \"cloudflared\",\n cmd: \"cloudflared\",\n required: false,\n category: \"tunnel\",\n },\n ];\n\n return deps.map((dep) => {\n const { installed, version } = checkCommand(dep.cmd);\n return {\n name: dep.name,\n installed,\n version,\n required: dep.required,\n category: dep.category,\n };\n });\n}\n\n/**\n * Install missing dependencies.\n */\nexport async function installDependencies(\n deps?: string[],\n): Promise<SetupResult> {\n const platform = os.platform();\n const result: SetupResult = {\n success: true,\n installed: [],\n failed: [],\n skipped: [],\n };\n\n const checks = checkDependencies();\n const toInstall = deps\n ? checks.filter((d) => deps.includes(d.name) && !d.installed)\n : checks.filter((d) => !d.installed);\n\n for (const dep of toInstall) {\n try {\n logger.info(\"bootstrap\", `Installing ${dep.name}...`);\n\n if (dep.name === \"tmux\") {\n await installTmux(platform);\n } else if (dep.name === \"ttyd\") {\n await installTtyd(platform);\n } else if (dep.name === \"cloudflared\") {\n await installCloudflared(platform);\n } else {\n result.skipped.push(dep.name);\n continue;\n }\n\n // Verify installation\n const check = checkCommand(dep.name);\n if (check.installed) {\n result.installed.push(dep.name);\n logger.info(\n \"bootstrap\",\n `Successfully installed ${dep.name}: ${check.version}`,\n );\n } else {\n result.failed.push(dep.name);\n result.success = false;\n logger.error(\n \"bootstrap\",\n `Failed to install ${dep.name}: command not found after install`,\n );\n }\n } catch (err) {\n result.failed.push(dep.name);\n result.success = false;\n logger.error(\"bootstrap\", `Failed to install ${dep.name}: ${err}`);\n }\n }\n\n return result;\n}\n\n// ── Platform-Specific Installers ────────────────────────────────────────\n\nasync function installTmux(platform: string): Promise<void> {\n if (platform === \"darwin\") {\n execSync(\"brew install tmux\", { timeout: 120_000, stdio: \"pipe\" });\n } else if (platform === \"linux\") {\n try {\n execSync(\"sudo apt-get install -y tmux\", {\n timeout: 120_000,\n stdio: \"pipe\",\n });\n } catch {\n execSync(\"sudo yum install -y tmux\", { timeout: 120_000, stdio: \"pipe\" });\n }\n } else {\n throw new Error(`Unsupported platform for tmux: ${platform}`);\n }\n}\n\nasync function installTtyd(platform: string): Promise<void> {\n if (platform === \"darwin\") {\n execSync(\"brew install ttyd\", { timeout: 120_000, stdio: \"pipe\" });\n } else if (platform === \"linux\") {\n try {\n execSync(\"sudo snap install ttyd --classic\", {\n timeout: 120_000,\n stdio: \"pipe\",\n });\n } catch {\n // Try direct download\n const arch = os.arch() === \"x64\" ? \"x86_64\" : os.arch();\n execSync(\n `curl -sLo /tmp/ttyd https://github.com/tsl0922/ttyd/releases/latest/download/ttyd.${arch} && sudo install /tmp/ttyd /usr/local/bin/ttyd`,\n { timeout: 120_000, stdio: \"pipe\" },\n );\n }\n } else {\n throw new Error(`Unsupported platform for ttyd: ${platform}`);\n }\n}\n\nasync function installCloudflared(platform: string): Promise<void> {\n if (platform === \"darwin\") {\n execSync(\"brew install cloudflared\", { timeout: 120_000, stdio: \"pipe\" });\n } else if (platform === \"linux\") {\n const arch = os.arch();\n let archStr = \"amd64\";\n if (arch === \"arm64\" || (arch as string) === \"aarch64\") archStr = \"arm64\";\n else if (arch === \"arm\") archStr = \"arm\";\n\n execSync(\n `curl -sLo /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${archStr} && sudo install /tmp/cloudflared /usr/local/bin/cloudflared`,\n { timeout: 120_000, stdio: \"pipe\" },\n );\n } else {\n throw new Error(`Unsupported platform for cloudflared: ${platform}`);\n }\n}\n",
|
|
6
|
-
"/**\n * Service Manager\n *\n * Manages multiple agent instances as background daemon processes.\n * Handles start, stop, restart, kill, status, and log operations.\n *\n * Process registry persisted at ~/.vibecontrols/agents.json\n * Logs written to ~/.vibecontrols/logs/{name}.log\n */\n\nimport { spawn } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n openSync,\n closeSync,\n} from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { homedir } from \"node:os\";\nimport { exec } from \"node:child_process\";\n\nimport type { AgentConfig } from \"./agent.service.js\";\n\nconst execAsync = promisify(exec);\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport interface ProcessInfo {\n name: string;\n pid: number;\n port: number;\n config: AgentConfig;\n startTime: string;\n status: \"running\" | \"stopped\" | \"unknown\";\n}\n\nexport interface LogOptions {\n follow: boolean;\n tail: number;\n}\n\nexport class ServiceManager {\n private registryPath: string;\n private logsDir: string;\n\n constructor() {\n const configDir = join(homedir(), \".vibecontrols\");\n this.registryPath = join(configDir, \"agents.json\");\n this.logsDir = join(configDir, \"logs\");\n\n mkdirSync(configDir, { recursive: true });\n mkdirSync(this.logsDir, { recursive: true });\n }\n\n async startDaemon(config: AgentConfig): Promise<void> {\n // Check if already running\n const existing = await this.findProcessByName(config.name);\n if (existing && existing.status === \"running\") {\n console.log(\n `⚠️ Agent '${config.name}' is already running on port ${existing.port}`,\n );\n return;\n }\n\n // Create log file FD for direct redirect\n const logFile = join(this.logsDir, `${config.name}.log`);\n const logFd = openSync(logFile, \"a\");\n\n // Spawn the process using bun\n // index.js lives alongside this compiled file in dist/\n const indexPath = join(__dirname, \"..\", \"index.js\");\n const child = spawn(\"bun\", [\"run\", indexPath], {\n detached: true,\n stdio: [\"ignore\", logFd, logFd],\n env: {\n ...process.env,\n PORT: config.port.toString(),\n DB_PATH: config.dbPath,\n NODE_ENV: \"production\",\n },\n });\n\n closeSync(logFd);\n child.unref();\n\n // Wait for process to start\n await new Promise((resolve) => setTimeout(resolve, 2000));\n\n const isRunning = await this.isProcessRunning(child.pid!);\n if (!isRunning) {\n throw new Error(`Failed to start agent '${config.name}'`);\n }\n\n await this.saveProcessInfo(config.name, child.pid!, config);\n console.log(\n `🚀 Agent '${config.name}' started (PID: ${child.pid}, Port: ${config.port})`,\n );\n }\n\n async stop(name: string): Promise<void> {\n const agentProcess = await this.findProcessByName(name);\n if (!agentProcess || agentProcess.status !== \"running\") {\n console.log(`⚠️ Agent '${name}' is not running`);\n return;\n }\n\n try {\n process.kill(agentProcess.pid, \"SIGTERM\");\n await new Promise((resolve) => setTimeout(resolve, 3000));\n\n const stillRunning = await this.isProcessRunning(agentProcess.pid);\n if (stillRunning) {\n process.kill(agentProcess.pid, \"SIGKILL\");\n }\n\n await this.updateProcessStatus(name, \"stopped\");\n console.log(`✅ Agent '${name}' stopped`);\n } catch (err) {\n throw new Error(`Failed to stop agent '${name}': ${err}`, { cause: err });\n }\n }\n\n async restart(name: string, config: AgentConfig): Promise<void> {\n const existing = await this.findProcessByName(name);\n if (existing && existing.status === \"running\") {\n await this.stop(name);\n }\n await this.startDaemon(config);\n console.log(`🔄 Agent '${name}' restarted`);\n }\n\n async kill(name: string): Promise<void> {\n const agentProcess = await this.findProcessByName(name);\n if (!agentProcess || agentProcess.status !== \"running\") {\n console.log(`⚠️ Agent '${name}' is not running`);\n return;\n }\n\n await this.killProcessTree(agentProcess.pid);\n await this.updateProcessStatus(name, \"stopped\");\n console.log(`💀 Agent '${name}' killed`);\n }\n\n async getStatus(name: string): Promise<ProcessInfo | null> {\n return this.findProcessByName(name);\n }\n\n async getStatusAll(): Promise<ProcessInfo[]> {\n const registry = this.loadRegistry();\n const processes: ProcessInfo[] = [];\n\n for (const processInfo of registry) {\n const isRunning = await this.isProcessRunning(processInfo.pid);\n processes.push({\n ...processInfo,\n status: isRunning ? \"running\" : \"stopped\",\n });\n }\n\n return processes;\n }\n\n async listInstances(): Promise<ProcessInfo[]> {\n return this.getStatusAll();\n }\n\n async showLogs(name: string, options: LogOptions): Promise<void> {\n const logFile = join(this.logsDir, `${name}.log`);\n\n if (!existsSync(logFile)) {\n console.log(`No logs found for agent '${name}'`);\n return;\n }\n\n if (options.follow) {\n const tail = spawn(\"tail\", [\n \"-f\",\n \"-n\",\n options.tail.toString(),\n logFile,\n ]);\n tail.stdout?.on(\"data\", (data) => process.stdout.write(data));\n tail.stderr?.on(\"data\", (data) => process.stderr.write(data));\n process.on(\"SIGINT\", () => {\n tail.kill();\n process.exit(0);\n });\n } else {\n try {\n const { stdout } = await execAsync(\n `tail -n ${options.tail} \"${logFile}\"`,\n );\n console.log(stdout);\n } catch (err) {\n console.error(\"Failed to read logs:\", err);\n }\n }\n }\n\n async checkHealth(\n name: string,\n ): Promise<{ healthy: boolean; details: unknown }> {\n const proc = await this.findProcessByName(name);\n\n if (!proc || proc.status !== \"running\") {\n return { healthy: false, details: { error: \"Process not running\" } };\n }\n\n try {\n const response = await fetch(`http://localhost:${proc.port}/health`);\n const data = await response.json();\n return { healthy: response.ok, details: data };\n } catch (err) {\n return {\n healthy: false,\n details: {\n error: \"Health check failed\",\n message: (err as Error).message,\n },\n };\n }\n }\n\n async setConfig(key: string, value: string): Promise<void> {\n const configFile = join(homedir(), \".vibecontrols\", \"config.json\");\n let config: Record<string, unknown> = {};\n if (existsSync(configFile)) {\n config = JSON.parse(readFileSync(configFile, \"utf8\"));\n }\n config[key] = value;\n writeFileSync(configFile, JSON.stringify(config, null, 2));\n }\n\n async getConfig(key?: string): Promise<unknown> {\n const configFile = join(homedir(), \".vibecontrols\", \"config.json\");\n if (!existsSync(configFile)) return key ? undefined : {};\n const config = JSON.parse(readFileSync(configFile, \"utf8\"));\n return key ? config[key] : config;\n }\n\n // ── Private Helpers ───────────────────────────────────────────────\n\n private loadRegistry(): ProcessInfo[] {\n if (!existsSync(this.registryPath)) return [];\n try {\n return JSON.parse(readFileSync(this.registryPath, \"utf8\"));\n } catch {\n return [];\n }\n }\n\n private saveRegistry(processes: ProcessInfo[]): void {\n writeFileSync(this.registryPath, JSON.stringify(processes, null, 2));\n }\n\n private async saveProcessInfo(\n name: string,\n pid: number,\n config: AgentConfig,\n ): Promise<void> {\n const registry = this.loadRegistry();\n const filtered = registry.filter((p) => p.name !== name);\n filtered.push({\n name,\n pid,\n port: config.port,\n config,\n startTime: new Date().toISOString(),\n status: \"running\",\n });\n this.saveRegistry(filtered);\n }\n\n private async updateProcessStatus(\n name: string,\n status: \"running\" | \"stopped\" | \"unknown\",\n ): Promise<void> {\n const registry = this.loadRegistry();\n const proc = registry.find((p) => p.name === name);\n if (proc) {\n proc.status = status;\n this.saveRegistry(registry);\n }\n }\n\n private async findProcessByName(name: string): Promise<ProcessInfo | null> {\n const registry = this.loadRegistry();\n const proc = registry.find((p) => p.name === name);\n if (!proc) return null;\n const isRunning = await this.isProcessRunning(proc.pid);\n proc.status = isRunning ? \"running\" : \"stopped\";\n return proc;\n }\n\n private async isProcessRunning(pid: number): Promise<boolean> {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n }\n\n private async killProcessTree(pid: number): Promise<void> {\n try {\n // Kill process group\n process.kill(-pid, \"SIGKILL\");\n } catch {\n try {\n process.kill(pid, \"SIGKILL\");\n } catch {\n // Process already dead\n }\n }\n }\n}\n"
|
|
7
|
-
],
|
|
8
|
-
"mappings": "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",
|
|
9
|
-
"debugId": "1F2B497AC857BCC064756E2164756E21",
|
|
10
|
-
"names": []
|
|
11
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/plugins/task/routes.ts", "../src/cli/commands/task.cmd.ts", "../src/plugins/task/commands.ts", "../src/plugins/task/index.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Task Plugin — Routes\n *\n * Background task management — create, run, poll, cancel.\n *\n * Endpoints (mounted by plugin system at /api/tasks):\n * GET / — List all tasks (optionally filter by status)\n * GET /:id — Get task by ID\n * POST / — Create and execute a new task\n * POST /:id/cancel — Cancel a pending task\n */\n\nimport { Elysia, t } from \"elysia\";\nimport crypto from \"node:crypto\";\nimport { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nimport type { AgentDatabase } from \"../../db/database.js\";\nimport type { Task, PluginRouteDeps } from \"../../core/types.js\";\n\n// ── Task Execution ──────────────────────────────────────────────────────\n\nasync function executeCommand(payload: {\n command: string;\n cwd?: string;\n env?: Record<string, string>;\n}): Promise<{ stdout: string; stderr: string }> {\n const proc = Bun.spawn([\"sh\", \"-c\", payload.command], {\n cwd: payload.cwd,\n env: { ...process.env, ...payload.env },\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n\n const [stdout, stderr] = await Promise.all([\n new Response(proc.stdout).text(),\n new Response(proc.stderr).text(),\n ]);\n\n await proc.exited;\n return { stdout, stderr };\n}\n\nasync function executeScript(payload: {\n script: string;\n interpreter?: string;\n cwd?: string;\n}): Promise<{ stdout: string; stderr: string }> {\n const interpreter = payload.interpreter || \"bash\";\n const tmpDir = os.tmpdir();\n const scriptFile = path.join(tmpDir, `vibecontrols-script-${Date.now()}.sh`);\n\n await fs.writeFile(scriptFile, payload.script, { mode: 0o755 });\n\n try {\n const proc = Bun.spawn([interpreter, scriptFile], {\n cwd: payload.cwd,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n\n const [stdout, stderr] = await Promise.all([\n new Response(proc.stdout).text(),\n new Response(proc.stderr).text(),\n ]);\n\n await proc.exited;\n return { stdout, stderr };\n } finally {\n await fs.unlink(scriptFile).catch(() => {});\n }\n}\n\nasync function executeFileOperation(payload: {\n operation: \"read\" | \"write\" | \"delete\" | \"exists\" | \"list\";\n path: string;\n content?: string;\n}): Promise<Record<string, unknown>> {\n switch (payload.operation) {\n case \"read\": {\n const data = await fs.readFile(payload.path, \"utf-8\");\n return { content: data };\n }\n case \"write\": {\n if (!payload.content)\n throw new Error(\"Content is required for write operation\");\n await fs.writeFile(payload.path, payload.content);\n return { success: true };\n }\n case \"delete\": {\n await fs.unlink(payload.path);\n return { success: true };\n }\n case \"exists\": {\n try {\n await fs.access(payload.path);\n return { exists: true };\n } catch {\n return { exists: false };\n }\n }\n case \"list\": {\n const files = await fs.readdir(payload.path);\n return { files };\n }\n default:\n throw new Error(`Unknown file operation: ${payload.operation}`);\n }\n}\n\nasync function processTask(db: AgentDatabase, task: Task): Promise<void> {\n try {\n db.updateTask(task.id, { status: \"running\" });\n\n const payload = JSON.parse(task.payload);\n let result: Record<string, unknown>;\n\n switch (task.type) {\n case \"command\":\n result = await executeCommand(payload);\n break;\n case \"script\":\n result = await executeScript(payload);\n break;\n case \"file_operation\":\n result = await executeFileOperation(payload);\n break;\n default:\n throw new Error(`Unknown task type: ${task.type}`);\n }\n\n db.updateTask(task.id, {\n status: \"completed\",\n result: JSON.stringify(result),\n });\n } catch (err) {\n db.updateTask(task.id, {\n status: \"failed\",\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\n// ── Routes ──────────────────────────────────────────────────────────────\n\nexport function createRoutes(deps: PluginRouteDeps) {\n const { db } = deps;\n\n return (\n new Elysia()\n // List tasks\n .get(\"/\", ({ query }) => {\n const status = (query as Record<string, string>).status;\n if (status === \"pending\") {\n return { tasks: db.getPendingTasks() };\n }\n return { tasks: db.getAllTasks() };\n })\n\n // Get task by ID\n .get(\"/:id\", ({ params, set }) => {\n const task = db.getTask(params.id);\n if (!task) {\n set.status = 404;\n return { error: \"Task not found\" };\n }\n return { task };\n })\n\n // Create new task\n .post(\n \"/\",\n async ({ body, set }) => {\n try {\n const task = db.createTask({\n id: crypto.randomUUID(),\n type: body.type,\n status: \"pending\",\n payload: JSON.stringify(body.payload),\n });\n\n // Process task asynchronously (fire-and-forget)\n processTask(db, task);\n\n return { task };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to create task\", details: String(err) };\n }\n },\n {\n body: t.Object({\n type: t.Union([\n t.Literal(\"command\"),\n t.Literal(\"script\"),\n t.Literal(\"file_operation\"),\n ]),\n payload: t.Object({\n command: t.Optional(t.String()),\n cwd: t.Optional(t.String()),\n env: t.Optional(t.Record(t.String(), t.String())),\n script: t.Optional(t.String()),\n interpreter: t.Optional(t.String()),\n operation: t.Optional(\n t.Union([\n t.Literal(\"read\"),\n t.Literal(\"write\"),\n t.Literal(\"delete\"),\n t.Literal(\"exists\"),\n t.Literal(\"list\"),\n ]),\n ),\n path: t.Optional(t.String()),\n content: t.Optional(t.String()),\n }),\n }),\n },\n )\n\n // Cancel task\n .post(\"/:id/cancel\", ({ params, set }) => {\n const task = db.getTask(params.id);\n if (!task) {\n set.status = 404;\n return { error: \"Task not found\" };\n }\n\n if (task.status !== \"pending\") {\n set.status = 400;\n return { error: \"Only pending tasks can be cancelled\" };\n }\n\n db.updateTask(params.id, {\n status: \"failed\",\n error: \"Task cancelled by user\",\n });\n\n return { success: true };\n })\n );\n}\n",
|
|
6
|
-
"import { Command } from \"commander\";\nimport {\n getAgentUrl,\n apiGet,\n apiPost,\n apiPut,\n fail,\n success,\n info,\n header,\n formatTable,\n formatStatus,\n timeAgo,\n shortId,\n} from \"../utils/index.js\";\n\nconst DEFAULT_AGENT_URL = \"http://localhost:3005\";\n\nexport function register(program: Command): void {\n const cmd = program.command(\"task\").description(\"Manage background tasks\");\n\n // task list\n cmd\n .command(\"list\")\n .description(\"List tasks\")\n .option(\"--status <status>\", \"Filter by status\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const query = options.status\n ? `/api/tasks/?status=${encodeURIComponent(options.status)}`\n : \"/api/tasks/\";\n const data = await apiGet<{ tasks: any[] }>(url, query);\n const tasks = data.tasks || [];\n if (!tasks || tasks.length === 0) {\n info(\"No tasks found.\");\n return;\n }\n header(\"Tasks\");\n formatTable(\n tasks.map((t: any) => ({\n ID: shortId(t.id),\n Type: t.type || \"-\",\n Status: formatStatus(t.status),\n Created: t.createdAt ? timeAgo(t.createdAt) : \"-\",\n })),\n );\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // task run\n cmd\n .command(\"run\")\n .description(\"Run a new task\")\n .requiredOption(\"-c, --command <cmd>\", \"Command to run\")\n .option(\"--cwd <dir>\", \"Working directory\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const payload: Record<string, any> = { command: options.command };\n if (options.cwd) payload.cwd = options.cwd;\n const body = {\n type: \"command\",\n payload: JSON.stringify(payload),\n };\n const result = await apiPost<any>(url, \"/api/tasks/\", body);\n success(`Task created: ${shortId(result?.id || result?.taskId)}`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // task cancel\n cmd\n .command(\"cancel\")\n .description(\"Cancel a running task\")\n .requiredOption(\"-i, --id <id>\", \"Task ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiPut<any>(url, `/api/tasks/${options.id}/cancel`, {});\n success(`Task ${shortId(options.id)} cancelled.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n}\n",
|
|
7
|
-
"import type { Command } from \"commander\";\nimport type { HostServices } from \"../../core/plugin-system.js\";\nimport { register as registerTask } from \"../../cli/commands/task.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerTask(program);\n}\n",
|
|
8
|
-
"import type { VibePlugin } from \"../../core/plugin-system.js\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport { createRoutes } from \"./routes.js\";\nimport { registerCommands } from \"./commands.js\";\n\nexport const vibePlugin: VibePlugin = {\n name: \"task\",\n version: \"2.2.0\",\n description: \"Background task execution — commands, scripts, file operations\",\n tags: [\"backend\", \"cli\"],\n cliCommand: \"task\",\n apiPrefix: \"/api/tasks\",\n createRoutes: (deps: PluginRouteDeps) => createRoutes(deps),\n onCliSetup: async (program, hostServices) => {\n registerCommands(program, hostServices);\n },\n};\n"
|
|
9
|
-
],
|
|
10
|
-
"mappings": "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",
|
|
11
|
-
"debugId": "84A2CB11789A3BBD64756E2164756E21",
|
|
12
|
-
"names": []
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/plugins/bookmark/routes.ts", "../src/cli/commands/bookmark.cmd.ts", "../src/plugins/bookmark/commands.ts", "../src/plugins/bookmark/index.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Bookmark Plugin — Routes\n *\n * Bookmarked command management — CRUD + execute in session or as task.\n *\n * Endpoints (mounted by plugin system at /api/bookmarks):\n * GET / — List bookmarks (optional projectId filter)\n * GET /global — Get global (no project) bookmarks\n * GET /project/:projectId — Get bookmarks by project\n * GET /category/:category — Get bookmarks by category\n * GET /:id — Get bookmark by ID\n * POST / — Create new bookmark\n * PUT /:id — Update bookmark\n * DELETE /:id — Delete bookmark\n * POST /:id/execute — Execute bookmarked command\n */\n\nimport { Elysia, t } from \"elysia\";\nimport crypto from \"node:crypto\";\n\nimport type { AgentDatabase } from \"../../db/database.js\";\nimport type { ServiceRegistry } from \"../../core/service-registry.js\";\nimport type { SessionProvider } from \"../../core/providers/session.provider.js\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\n\n// ── Routes ──────────────────────────────────────────────────────────────\n\nexport function createRoutes(deps: PluginRouteDeps) {\n const { db, serviceRegistry } = deps;\n\n return (\n new Elysia()\n // List bookmarks (optional projectId filter)\n .get(\"/\", ({ query }) => {\n const q = query as Record<string, string>;\n const bookmarks =\n q.projectId !== undefined\n ? db.getBookmarkedCommandsByProject(q.projectId)\n : db.getAllBookmarkedCommands();\n return { bookmarks };\n })\n\n // Get global bookmarks (no project)\n .get(\"/global\", () => {\n const bookmarks = db.getBookmarkedCommandsByProject(null);\n return { bookmarks };\n })\n\n // Get bookmarks by project\n .get(\"/project/:projectId\", ({ params }) => {\n const bookmarks = db.getBookmarkedCommandsByProject(params.projectId);\n return { bookmarks };\n })\n\n // Get bookmarks by category\n .get(\"/category/:category\", ({ params }) => {\n const bookmarks = db.getBookmarkedCommandsByCategory(params.category);\n return { bookmarks, category: params.category };\n })\n\n // Get bookmark by ID\n .get(\"/:id\", ({ params, set }) => {\n const bookmark = db.getBookmarkedCommand(params.id);\n if (!bookmark) {\n set.status = 404;\n return { error: \"Bookmarked command not found\" };\n }\n return { bookmark };\n })\n\n // Create new bookmark\n .post(\n \"/\",\n ({ body, set }) => {\n try {\n const bookmark = db.createBookmarkedCommand({\n id: crypto.randomUUID(),\n projectId: body.projectId,\n command: body.command,\n description: body.description,\n category: body.category,\n });\n return { bookmark };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to create bookmarked command\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n projectId: t.Optional(t.String()),\n command: t.String(),\n description: t.Optional(t.String()),\n category: t.Optional(t.String()),\n }),\n },\n )\n\n // Update bookmark\n .put(\n \"/:id\",\n ({ params, body, set }) => {\n const bookmark = db.getBookmarkedCommand(params.id);\n if (!bookmark) {\n set.status = 404;\n return { error: \"Bookmarked command not found\" };\n }\n\n try {\n const updates: Record<string, string | undefined> = {};\n if (body.command !== undefined) updates.command = body.command;\n if (body.description !== undefined)\n updates.description = body.description;\n if (body.category !== undefined) updates.category = body.category;\n\n db.updateBookmarkedCommand(params.id, updates);\n const updatedBookmark = db.getBookmarkedCommand(params.id)!;\n return { bookmark: updatedBookmark };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to update bookmarked command\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n command: t.Optional(t.String()),\n description: t.Optional(t.String()),\n category: t.Optional(t.String()),\n }),\n },\n )\n\n // Delete bookmark\n .delete(\"/:id\", ({ params, set }) => {\n const bookmark = db.getBookmarkedCommand(params.id);\n if (!bookmark) {\n set.status = 404;\n return { error: \"Bookmarked command not found\" };\n }\n\n try {\n db.deleteBookmarkedCommand(params.id);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to delete bookmarked command\",\n details: String(err),\n };\n }\n })\n\n // Execute bookmarked command\n .post(\n \"/:id/execute\",\n async ({ params, body, set }) => {\n const bookmark = db.getBookmarkedCommand(params.id);\n if (!bookmark) {\n set.status = 404;\n return { error: \"Bookmarked command not found\" };\n }\n\n try {\n // If sessionId provided, execute in session via SessionProvider\n if (body.sessionId) {\n const sessionProvider =\n serviceRegistry.getProvider<SessionProvider>(\"session\");\n if (!sessionProvider) {\n set.status = 400;\n return { error: \"No session provider registered\" };\n }\n\n const session = await sessionProvider.get(body.sessionId);\n if (!session) {\n set.status = 404;\n return { error: \"Session not found\" };\n }\n\n await sessionProvider.sendCommand(\n body.sessionId,\n bookmark.command,\n );\n\n return {\n success: true,\n executedIn: \"session\",\n sessionId: body.sessionId,\n };\n }\n\n // Otherwise, execute as a background task\n const task = db.createTask({\n id: crypto.randomUUID(),\n type: \"command\",\n status: \"pending\",\n payload: JSON.stringify({\n command: bookmark.command,\n cwd: body.cwd || process.cwd(),\n }),\n });\n\n return {\n success: true,\n executedIn: \"task\",\n taskId: task.id,\n };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to execute bookmarked command\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n sessionId: t.Optional(t.String()),\n cwd: t.Optional(t.String()),\n }),\n },\n )\n );\n}\n",
|
|
6
|
-
"import { Command } from \"commander\";\nimport {\n getAgentUrl,\n apiGet,\n apiPost,\n apiPut,\n apiDelete,\n fail,\n success,\n info,\n header,\n kv,\n formatTable,\n shortId,\n} from \"../utils/index.js\";\n\nconst DEFAULT_AGENT_URL = \"http://localhost:3005\";\n\nexport function register(program: Command): void {\n const cmd = program\n .command(\"bookmark\")\n .description(\"Manage command bookmarks\");\n\n // bookmark list\n cmd\n .command(\"list\")\n .description(\"List bookmarks\")\n .option(\"--project <id>\", \"Filter by project ID\")\n .option(\"--category <cat>\", \"Filter by category\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const params = new URLSearchParams();\n if (options.project) params.set(\"project\", options.project);\n if (options.category) params.set(\"category\", options.category);\n const query = params.toString();\n const endpoint = query ? `/api/bookmarks?${query}` : \"/api/bookmarks\";\n const data = await apiGet<{ bookmarks: any[] }>(url, endpoint);\n const bookmarks = data.bookmarks || [];\n if (!bookmarks || bookmarks.length === 0) {\n info(\"No bookmarks found.\");\n return;\n }\n header(\"Bookmarks\");\n formatTable(\n bookmarks.map((b: any) => ({\n ID: shortId(b.id),\n Command: b.command || \"-\",\n Description: b.description || \"-\",\n Category: b.category || \"-\",\n Project: b.project || b.projectId || \"-\",\n })),\n );\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // bookmark create\n cmd\n .command(\"create\")\n .description(\"Create a new bookmark\")\n .requiredOption(\"-c, --command <cmd>\", \"Command to bookmark\")\n .option(\"--description <desc>\", \"Bookmark description\")\n .option(\"--category <cat>\", \"Category\")\n .option(\"--project <id>\", \"Project ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = { command: options.command };\n if (options.description) body.description = options.description;\n if (options.category) body.category = options.category;\n if (options.project) body.project = options.project;\n const result = await apiPost<any>(url, \"/api/bookmarks\", body);\n success(`Bookmark created: ${shortId(result?.id)}`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // bookmark update\n cmd\n .command(\"update\")\n .description(\"Update a bookmark\")\n .requiredOption(\"-i, --id <id>\", \"Bookmark ID\")\n .option(\"-c, --command <cmd>\", \"New command\")\n .option(\"--description <desc>\", \"New description\")\n .option(\"--category <cat>\", \"New category\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = {};\n if (options.command) body.command = options.command;\n if (options.description) body.description = options.description;\n if (options.category) body.category = options.category;\n if (Object.keys(body).length === 0) {\n fail(\n \"No fields to update. Provide at least one of --command, --description, or --category.\",\n );\n return;\n }\n await apiPut<any>(url, `/api/bookmarks/${options.id}`, body);\n success(`Bookmark ${shortId(options.id)} updated.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // bookmark delete\n cmd\n .command(\"delete\")\n .description(\"Delete a bookmark\")\n .requiredOption(\"-i, --id <id>\", \"Bookmark ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiDelete<any>(url, `/api/bookmarks/${options.id}`);\n success(`Bookmark ${shortId(options.id)} deleted.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // bookmark execute\n cmd\n .command(\"execute\")\n .description(\"Execute a bookmarked command\")\n .requiredOption(\"-i, --id <id>\", \"Bookmark ID\")\n .option(\"--session <sessionId>\", \"Session ID to execute in\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = {};\n if (options.session) body.sessionId = options.session;\n const result = await apiPost<any>(\n url,\n `/api/bookmarks/${options.id}/execute`,\n body,\n );\n success(`Bookmark ${shortId(options.id)} executed.`);\n if (result?.output) {\n console.log(result.output);\n }\n } catch (err: any) {\n fail(err.message);\n }\n });\n}\n",
|
|
7
|
-
"import type { Command } from \"commander\";\nimport type { HostServices } from \"../../core/plugin-system.js\";\nimport { register as registerBookmark } from \"../../cli/commands/bookmark.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerBookmark(program);\n}\n",
|
|
8
|
-
"import type { VibePlugin } from \"../../core/plugin-system.js\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport { createRoutes } from \"./routes.js\";\nimport { registerCommands } from \"./commands.js\";\n\nexport const vibePlugin: VibePlugin = {\n name: \"bookmark\",\n version: \"2.2.0\",\n description: \"Bookmarked command management — CRUD and execute\",\n tags: [\"backend\", \"cli\"],\n cliCommand: \"bookmark\",\n apiPrefix: \"/api/bookmarks\",\n createRoutes: (deps: PluginRouteDeps) => createRoutes(deps),\n onCliSetup: async (program, hostServices) => {\n registerCommands(program, hostServices);\n },\n};\n"
|
|
9
|
-
],
|
|
10
|
-
"mappings": "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",
|
|
11
|
-
"debugId": "180562EA8CFA2EAC64756E2164756E21",
|
|
12
|
-
"names": []
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/plugins/notification/routes.ts", "../src/cli/commands/notify.cmd.ts", "../src/plugins/notification/commands.ts", "../src/plugins/notification/index.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Notification Plugin — Routes\n *\n * Notification management — CRUD, read/unread status, webhook endpoint.\n *\n * Endpoints (mounted by plugin system at /api/notifications):\n * GET / — List notifications (with filters)\n * GET /unread — Get unread notifications\n * GET /global — Get global notifications\n * GET /project/:projectId — Get notifications by project\n * PUT /read-all — Mark all as read\n * DELETE /clear/old — Clear old notifications\n * GET /:id — Get notification by ID\n * POST / — Create notification\n * PUT /:id/read — Mark as read\n * PUT /:id/unread — Mark as unread\n * DELETE /:id — Delete notification\n * POST /webhook/:sessionId — Webhook for external notifications\n */\n\nimport { Elysia, t } from \"elysia\";\nimport crypto from \"node:crypto\";\n\nimport type { AgentDatabase } from \"../../db/database.js\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\n\n// ── Routes ──────────────────────────────────────────────────────────────\n\nexport function createRoutes(deps: PluginRouteDeps) {\n const { db } = deps;\n\n return (\n new Elysia()\n // List notifications (with optional filters)\n .get(\"/\", ({ query }) => {\n const q = query as Record<string, string>;\n\n if (q.status === \"unread\") {\n return { notifications: db.getUnreadNotifications() };\n }\n if (q.projectId !== undefined) {\n return { notifications: db.getNotificationsByProject(q.projectId) };\n }\n return { notifications: db.getAllNotifications() };\n })\n\n // Get unread notifications\n .get(\"/unread\", () => {\n const notifications = db.getUnreadNotifications();\n return { notifications, count: notifications.length };\n })\n\n // Get global notifications (not tied to a project)\n .get(\"/global\", () => {\n const notifications = db.getGlobalNotifications();\n return { notifications, count: notifications.length };\n })\n\n // Get notifications by project\n .get(\"/project/:projectId\", ({ params }) => {\n const notifications = db.getNotificationsByProject(params.projectId);\n return { notifications };\n })\n\n // Mark all as read — defined before /:id to avoid route conflict\n .put(\"/read-all\", ({ set }) => {\n try {\n const count = db.markAllNotificationsRead();\n return { success: true, markedCount: count };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to mark all notifications as read\",\n details: String(err),\n };\n }\n })\n\n // Clear old notifications — defined before /:id to avoid route conflict\n .delete(\"/clear/old\", ({ query }) => {\n const q = query as Record<string, string>;\n const days = q.days ? parseInt(q.days, 10) : 30;\n const count = db.clearOldNotifications(days);\n return { success: true, deletedCount: count };\n })\n\n // Get notification by ID\n .get(\"/:id\", ({ params, set }) => {\n const notification = db.getNotification(params.id);\n if (!notification) {\n set.status = 404;\n return { error: \"Notification not found\" };\n }\n return { notification };\n })\n\n // Create notification\n .post(\n \"/\",\n ({ body, set }) => {\n try {\n const notification = db.createNotification({\n id: crypto.randomUUID(),\n sessionName: body.sessionName,\n projectId: body.projectId,\n type: body.type || \"info\",\n title: body.title,\n message: body.message,\n status: \"unread\",\n });\n return { notification };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to create notification\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n sessionName: t.Optional(t.String()),\n projectId: t.Optional(t.String()),\n type: t.Optional(\n t.Union([\n t.Literal(\"info\"),\n t.Literal(\"success\"),\n t.Literal(\"warning\"),\n t.Literal(\"error\"),\n ]),\n ),\n title: t.String(),\n message: t.String(),\n }),\n },\n )\n\n // Mark as read\n .put(\"/:id/read\", ({ params, set }) => {\n const notification = db.getNotification(params.id);\n if (!notification) {\n set.status = 404;\n return { error: \"Notification not found\" };\n }\n db.updateNotificationStatus(params.id, \"read\");\n return { success: true };\n })\n\n // Mark as unread\n .put(\"/:id/unread\", ({ params, set }) => {\n const notification = db.getNotification(params.id);\n if (!notification) {\n set.status = 404;\n return { error: \"Notification not found\" };\n }\n db.updateNotificationStatus(params.id, \"unread\");\n return { success: true };\n })\n\n // Delete notification\n .delete(\"/:id\", ({ params, set }) => {\n const notification = db.getNotification(params.id);\n if (!notification) {\n set.status = 404;\n return { error: \"Notification not found\" };\n }\n\n try {\n db.deleteNotification(params.id);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to delete notification\",\n details: String(err),\n };\n }\n })\n\n // Webhook endpoint for external notifications\n .post(\n \"/webhook/:sessionId\",\n ({ params, body, set }) => {\n try {\n // Map type variants to valid DB types\n const typeMap: Record<\n string,\n \"info\" | \"success\" | \"warning\" | \"error\"\n > = {\n task_completed: \"success\",\n info: \"info\",\n success: \"success\",\n warning: \"warning\",\n error: \"error\",\n };\n const mappedType = typeMap[body.type || \"info\"] || \"info\";\n\n const message = body.metadata\n ? `${body.message}\\n\\nMetadata: ${JSON.stringify(body.metadata, null, 2)}`\n : body.message;\n\n const notification = db.createNotification({\n id: crypto.randomUUID(),\n sessionName: body.projectName,\n projectId: params.sessionId,\n type: mappedType,\n title: body.title,\n message,\n status: \"unread\",\n });\n\n return {\n notification,\n webhook: true,\n originalType: body.type || \"info\",\n mappedType,\n };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to create webhook notification\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n type: t.Optional(t.String()),\n title: t.String(),\n message: t.String(),\n metadata: t.Optional(t.Record(t.String(), t.Unknown())),\n projectName: t.Optional(t.String()),\n }),\n },\n )\n );\n}\n",
|
|
6
|
-
"import { Command } from \"commander\";\nimport {\n getAgentUrl,\n apiGet,\n apiPost,\n apiPut,\n apiDelete,\n fail,\n success,\n info,\n header,\n kv,\n blank,\n formatNotificationType,\n timeAgo,\n shortId,\n colors,\n} from \"../utils/index.js\";\n\nconst DEFAULT_AGENT_URL = \"http://localhost:3005\";\n\nexport function register(program: Command): void {\n const cmd = program.command(\"notify\").description(\"Manage notifications\");\n\n // notify list\n cmd\n .command(\"list\")\n .description(\"List notifications\")\n .option(\"--unread\", \"Show only unread notifications\")\n .option(\"--project <id>\", \"Filter by project ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const params = new URLSearchParams();\n if (options.unread) params.set(\"unread\", \"true\");\n if (options.project) params.set(\"project\", options.project);\n const query = params.toString();\n const endpoint = query\n ? `/api/notifications?${query}`\n : \"/api/notifications\";\n const data = await apiGet<{ notifications: any[] }>(url, endpoint);\n const notifications = data.notifications || [];\n if (!notifications || notifications.length === 0) {\n info(\"No notifications found.\");\n return;\n }\n header(\"Notifications\");\n blank();\n for (const n of notifications) {\n const icon = formatNotificationType(n.type);\n const time = n.createdAt ? colors.dim(timeAgo(n.createdAt)) : \"\";\n const title = colors.bold(n.title || \"Untitled\");\n const id = colors.dim(`[${shortId(n.id)}]`);\n console.log(` ${icon} ${title} ${id} ${time}`);\n if (n.message) {\n console.log(` ${n.message}`);\n }\n blank();\n }\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // notify create\n cmd\n .command(\"create\")\n .description(\"Create a notification\")\n .requiredOption(\"--title <title>\", \"Notification title\")\n .requiredOption(\"--message <msg>\", \"Notification message\")\n .option(\"--type <type>\", \"Notification type\", \"info\")\n .option(\"--project <id>\", \"Project ID\")\n .option(\"--session <name>\", \"Session name\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = {\n title: options.title,\n message: options.message,\n type: options.type,\n };\n if (options.project) body.project = options.project;\n if (options.session) body.session = options.session;\n const result = await apiPost<any>(url, \"/api/notifications\", body);\n success(`Notification created: ${shortId(result?.id)}`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // notify delete\n cmd\n .command(\"delete\")\n .description(\"Delete a notification\")\n .requiredOption(\"-i, --id <id>\", \"Notification ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiDelete<any>(url, `/api/notifications/${options.id}`);\n success(`Notification ${shortId(options.id)} deleted.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // notify read-all\n cmd\n .command(\"read-all\")\n .description(\"Mark all notifications as read\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiPut<any>(url, \"/api/notifications/read-all\", {});\n success(\"All notifications marked as read.\");\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // notify clear-old\n cmd\n .command(\"clear-old\")\n .description(\"Clear old notifications\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiDelete<any>(url, \"/api/notifications/clear/old\");\n success(\"Old notifications cleared.\");\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // notify webhook\n cmd\n .command(\"webhook\")\n .description(\"Send a webhook notification to a session\")\n .requiredOption(\"--session <sessionId>\", \"Target session ID\")\n .option(\"--title <title>\", \"Notification title\")\n .option(\"--message <msg>\", \"Notification message\")\n .option(\"--type <type>\", \"Notification type\", \"info\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = {};\n if (options.title) body.title = options.title;\n if (options.message) body.message = options.message;\n if (options.type) body.type = options.type;\n await apiPost<any>(\n url,\n `/api/notifications/webhook/${options.session}`,\n body,\n );\n success(\n `Webhook notification sent to session ${shortId(options.session)}.`,\n );\n } catch (err: any) {\n fail(err.message);\n }\n });\n}\n",
|
|
7
|
-
"import type { Command } from \"commander\";\nimport type { HostServices } from \"../../core/plugin-system.js\";\nimport { register as registerNotify } from \"../../cli/commands/notify.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerNotify(program);\n}\n",
|
|
8
|
-
"import type { VibePlugin } from \"../../core/plugin-system.js\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport { createRoutes } from \"./routes.js\";\nimport { registerCommands } from \"./commands.js\";\n\nexport const vibePlugin: VibePlugin = {\n name: \"notification\",\n version: \"2.2.0\",\n description: \"Notification management — CRUD, read/unread status, webhooks\",\n tags: [\"backend\", \"cli\"],\n cliCommand: \"notify\",\n apiPrefix: \"/api/notifications\",\n createRoutes: (deps: PluginRouteDeps) => createRoutes(deps),\n onCliSetup: async (program, hostServices) => {\n registerCommands(program, hostServices);\n },\n};\n"
|
|
9
|
-
],
|
|
10
|
-
"mappings": "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",
|
|
11
|
-
"debugId": "933C583CBD4F9A8B64756E2164756E21",
|
|
12
|
-
"names": []
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/plugins/git/routes.ts", "../src/cli/commands/git.cmd.ts", "../src/plugins/git/commands.ts", "../src/plugins/git/index.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Git Plugin — Routes\n *\n * Git repository scanning, tracking, and hierarchy management.\n *\n * Endpoints:\n * GET / — List all tracked git repositories\n * GET /:id — Get repository by ID\n * POST /scan — Scan directory for git repositories\n * PUT /:id — Update repository metadata\n * DELETE /:id — Delete repository from tracking\n * POST /fix-hierarchy — Fix parent/child relationships\n */\n\nimport { Elysia, t } from \"elysia\";\nimport crypto from \"node:crypto\";\nimport { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport type { AgentDatabase } from \"../../db/database.js\";\n\n// ── Project Type Detection ──────────────────────────────────────────────\n\nasync function detectProjectType(\n directory: string,\n): Promise<string | undefined> {\n try {\n const entries = await fs.readdir(directory);\n\n if (entries.includes(\"package.json\")) {\n try {\n const packageJson = JSON.parse(\n await fs.readFile(path.join(directory, \"package.json\"), \"utf8\"),\n );\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n if (deps.react || deps[\"@types/react\"]) return \"react\";\n if (deps.vue || deps[\"@vue/cli\"]) return \"vue\";\n if (deps.angular || deps[\"@angular/core\"]) return \"angular\";\n if (deps.next || deps[\"@types/next\"]) return \"nextjs\";\n if (deps.nuxt || deps[\"@nuxt/core\"]) return \"nuxtjs\";\n if (deps.svelte || deps[\"@sveltejs/kit\"]) return \"svelte\";\n if (deps.express || deps.fastify || deps.koa) return \"nodejs-backend\";\n if (deps.electron) return \"electron\";\n if (deps.vite) return \"vite\";\n } catch {\n /* fallback */\n }\n return \"nodejs\";\n }\n\n if (\n entries.includes(\"setup.py\") ||\n entries.includes(\"requirements.txt\") ||\n entries.includes(\"pyproject.toml\") ||\n entries.includes(\"Pipfile\")\n ) {\n if (entries.includes(\"manage.py\")) return \"django\";\n if (entries.includes(\"app.py\")) return \"flask\";\n return \"python\";\n }\n\n if (entries.includes(\"go.mod\")) return \"go\";\n if (entries.includes(\"Cargo.toml\")) return \"rust\";\n if (entries.includes(\"pom.xml\")) return \"maven\";\n if (\n entries.includes(\"build.gradle\") ||\n entries.includes(\"build.gradle.kts\")\n )\n return \"gradle\";\n if (entries.includes(\"Gemfile\")) return \"ruby\";\n if (entries.includes(\"composer.json\")) return \"php\";\n if (entries.some((e) => e.endsWith(\".csproj\") || e.endsWith(\".sln\")))\n return \"dotnet\";\n if (entries.includes(\"CMakeLists.txt\") || entries.includes(\"Makefile\"))\n return \"cpp\";\n if (entries.includes(\"Package.swift\")) return \"swift\";\n if (entries.includes(\"pubspec.yaml\")) return \"flutter\";\n if (entries.some((e) => e.endsWith(\".tf\"))) return \"terraform\";\n if (entries.includes(\"Dockerfile\")) return \"docker\";\n } catch {\n /* ignore */\n }\n\n return undefined;\n}\n\nasync function detectVitePort(directory: string): Promise<number | undefined> {\n try {\n const variants = [\"vite.config.ts\", \"vite.config.js\"];\n for (const name of variants) {\n try {\n const content = await fs.readFile(path.join(directory, name), \"utf-8\");\n const match = content.match(/port:\\s*(\\d+)/);\n if (match) return parseInt(match[1], 10);\n } catch {\n /* next */\n }\n }\n } catch {\n /* ignore */\n }\n return undefined;\n}\n\n// ── Git Repo Scanner ────────────────────────────────────────────────────\n\nconst SKIP_DIRS = new Set([\n \".git\",\n \"node_modules\",\n \"__pycache__\",\n \".venv\",\n \"venv\",\n \"dist\",\n \"build\",\n]);\n\nasync function scanForGitRepositories(\n directory: string,\n includeSubmodules: boolean,\n parentPath?: string,\n): Promise<\n Array<{\n path: string;\n name: string;\n parentPath?: string;\n isSubmodule: boolean;\n projectType?: string;\n vitePort?: number;\n }>\n> {\n const repositories: Array<{\n path: string;\n name: string;\n parentPath?: string;\n isSubmodule: boolean;\n projectType?: string;\n vitePort?: number;\n }> = [];\n\n try {\n const entries = await fs.readdir(directory, { withFileTypes: true });\n const hasGit = entries.some((e) => e.name === \".git\" && e.isDirectory());\n\n if (hasGit) {\n repositories.push({\n path: directory,\n name: path.basename(directory),\n parentPath,\n isSubmodule: !!parentPath,\n projectType: await detectProjectType(directory),\n vitePort: await detectVitePort(directory),\n });\n\n if (!includeSubmodules) return repositories;\n parentPath = directory;\n }\n\n for (const entry of entries) {\n if (\n entry.isDirectory() &&\n !SKIP_DIRS.has(entry.name) &&\n !entry.name.startsWith(\".\")\n ) {\n const subPath = path.join(directory, entry.name);\n const subRepos = await scanForGitRepositories(\n subPath,\n includeSubmodules,\n parentPath,\n );\n repositories.push(...subRepos);\n }\n }\n } catch {\n /* permission errors */\n }\n\n return repositories;\n}\n\n// ── Routes ──────────────────────────────────────────────────────────────\n\nexport function createRoutes(deps: PluginRouteDeps) {\n const { db } = deps;\n\n return (\n new Elysia()\n // List all tracked git repositories\n .get(\"/\", () => {\n const repositories = db.getAllGitRepositories();\n return { repositories };\n })\n\n // Get repository by ID\n .get(\"/:id\", ({ params, set }) => {\n const repository = db.getGitRepository(params.id);\n if (!repository) {\n set.status = 404;\n return { error: \"Repository not found\" };\n }\n return { repository };\n })\n\n // Scan directory for git repositories\n .post(\n \"/scan\",\n async ({ body, set }) => {\n try {\n const stats = await fs.stat(body.directory);\n if (!stats.isDirectory()) {\n set.status = 400;\n return { error: \"Path is not a directory\" };\n }\n\n const repositories = await scanForGitRepositories(\n body.directory,\n body.includeSubmodules ?? true,\n );\n\n const savedRepos = [];\n for (const repo of repositories) {\n const existing = db.getGitRepositoryByPath(repo.path);\n if (existing) {\n db.updateGitRepository(existing.id, repo);\n savedRepos.push({ ...existing, ...repo });\n } else {\n const newRepo = db.createGitRepository({\n id: crypto.randomUUID(),\n ...repo,\n });\n savedRepos.push(newRepo);\n }\n }\n\n return {\n repositories: savedRepos,\n scannedPath: body.directory,\n totalFound: savedRepos.length,\n };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to scan directory\", details: String(err) };\n }\n },\n {\n body: t.Object({\n directory: t.String(),\n includeSubmodules: t.Optional(t.Boolean()),\n }),\n },\n )\n\n // Update repository metadata\n .put(\n \"/:id\",\n ({ params, body, set }) => {\n const repository = db.getGitRepository(params.id);\n if (!repository) {\n set.status = 404;\n return { error: \"Repository not found\" };\n }\n\n try {\n db.updateGitRepository(params.id, body);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to update repository\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n name: t.Optional(t.String()),\n projectType: t.Optional(t.String()),\n vitePort: t.Optional(t.Number()),\n }),\n },\n )\n\n // Delete repository from tracking\n .delete(\"/:id\", ({ params, set }) => {\n const repository = db.getGitRepository(params.id);\n if (!repository) {\n set.status = 404;\n return { error: \"Repository not found\" };\n }\n\n try {\n db.deleteGitRepository(params.id);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to delete repository\", details: String(err) };\n }\n })\n\n // Fix repository hierarchy\n .post(\"/fix-hierarchy\", ({ set }) => {\n try {\n const result = db.fixGitHierarchy();\n const repos = db.getAllGitRepositories();\n return { success: true, fixed: result.fixed, total: repos.length };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to fix hierarchy\", details: String(err) };\n }\n })\n );\n}\n",
|
|
6
|
-
"import { Command } from \"commander\";\nimport {\n getAgentUrl,\n apiGet,\n apiPost,\n apiPut,\n apiDelete,\n fail,\n success,\n info,\n header,\n kv,\n formatTable,\n timeAgo,\n shortId,\n} from \"../utils/index.js\";\n\nconst DEFAULT_AGENT_URL = \"http://localhost:3005\";\n\nexport function register(program: Command): void {\n const cmd = program.command(\"git\").description(\"Manage git repositories\");\n\n // git list\n cmd\n .command(\"list\")\n .description(\"List discovered git repositories\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const data = await apiGet<{ repositories: any[] }>(url, \"/api/git\");\n const repos = data.repositories || [];\n if (!repos || repos.length === 0) {\n info(\"No git repositories found.\");\n return;\n }\n header(\"Git Repositories\");\n formatTable(\n repos.map((r: any) => ({\n ID: shortId(r.id),\n Name: r.name || \"-\",\n Path: r.path || \"-\",\n Type: r.type || r.projectType || \"-\",\n Submodule: r.isSubmodule ? \"Yes\" : \"No\",\n Scanned: r.scannedAt ? timeAgo(r.scannedAt) : \"-\",\n })),\n );\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // git scan\n cmd\n .command(\"scan\")\n .description(\"Scan a directory for git repositories\")\n .requiredOption(\"--dir <directory>\", \"Directory to scan\")\n .option(\"--depth <depth>\", \"Scan depth\", \"3\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const result = await apiPost<any>(url, \"/api/git/scan\", {\n directory: options.dir,\n depth: parseInt(options.depth, 10),\n });\n success(\"Git scan completed.\");\n if (result?.found !== undefined) kv(\"Repositories found\", result.found);\n if (result?.repositories)\n kv(\"Repositories found\", result.repositories.length);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // git update\n cmd\n .command(\"update\")\n .description(\"Update a git repository entry\")\n .requiredOption(\"-i, --id <id>\", \"Repository ID\")\n .option(\"--vite-port <port>\", \"Vite dev server port\")\n .option(\"--project-type <type>\", \"Project type\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = {};\n if (options.vitePort) body.vitePort = parseInt(options.vitePort, 10);\n if (options.projectType) body.projectType = options.projectType;\n await apiPut<any>(url, `/api/git/${options.id}`, body);\n success(`Repository ${shortId(options.id)} updated.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // git delete\n cmd\n .command(\"delete\")\n .description(\"Delete a git repository entry\")\n .requiredOption(\"-i, --id <id>\", \"Repository ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiDelete<any>(url, `/api/git/${options.id}`);\n success(`Repository ${shortId(options.id)} deleted.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // git fix-hierarchy\n cmd\n .command(\"fix-hierarchy\")\n .description(\"Fix repository parent-child hierarchy\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const result = await apiPost<any>(url, \"/api/git/fix-hierarchy\", {});\n success(\"Hierarchy fix completed.\");\n if (result?.fixed !== undefined) kv(\"Fixed\", result.fixed);\n } catch (err: any) {\n fail(err.message);\n }\n });\n}\n",
|
|
7
|
-
"/**\n * Git Plugin — CLI Commands\n *\n * Delegates to the shared git CLI command registration.\n */\n\nimport type { Command } from \"commander\";\nimport type { HostServices } from \"../../core/plugin-system.js\";\nimport { register as registerGit } from \"../../cli/commands/git.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerGit(program);\n}\n",
|
|
8
|
-
"/**\n * Git Plugin — Entry Point\n *\n * Core plugin for git repository scanning, tracking, and hierarchy management.\n */\n\nimport type { VibePlugin } from \"../../core/plugin-system.js\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport { createRoutes } from \"./routes.js\";\nimport { registerCommands } from \"./commands.js\";\n\nexport const vibePlugin: VibePlugin = {\n name: \"git\",\n version: \"2.2.0\",\n description: \"Git repository scanning, tracking, and hierarchy management\",\n tags: [\"backend\", \"cli\"],\n cliCommand: \"git\",\n apiPrefix: \"/api/git\",\n createRoutes: (deps: PluginRouteDeps) => createRoutes(deps),\n onCliSetup: async (program, hostServices) => {\n registerCommands(program, hostServices);\n },\n};\n"
|
|
9
|
-
],
|
|
10
|
-
"mappings": "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",
|
|
11
|
-
"debugId": "7E548635BBB4C3EF64756E2164756E21",
|
|
12
|
-
"names": []
|
|
13
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/core/plugin-system.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Plugin System — Plugin-First Architecture\n *\n * Manages the full lifecycle of VibeControls plugins: discovery, loading,\n * provider registration, lifecycle dispatch, and introspection.\n *\n * Two plugin classes:\n * 1. Core plugins — statically imported from ../plugins/index.js,\n * always available, bundled with the agent.\n * 2. External plugins — npm packages installed globally, loaded via\n * dynamic import, persisted in ~/.vibecontrols/plugins.json.\n *\n * Override rule: An external plugin whose name matches a core plugin\n * replaces the core version. Loading order is core-first, external-second.\n *\n * Plugin registry persisted at ~/.vibecontrols/plugins.json\n *\n * Lifecycle:\n * install - load - onServerStart - onServerReady - ... - onServerStop - remove\n *\n * CLI lifecycle:\n * load - onCliSetup - program.parse() - ...\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport os from \"node:os\";\nimport { execSync } from \"node:child_process\";\nimport type { Command } from \"commander\";\nimport type { Elysia } from \"elysia\";\n\nimport type { TunnelProvider } from \"./providers/tunnel.provider.js\";\nimport type { SessionProvider } from \"./providers/session.provider.js\";\nimport type { StorageProvider } from \"./providers/storage.provider.js\";\nimport type { ServiceRegistry } from \"./service-registry.js\";\nimport type { AgentDatabase } from \"../db/database.js\";\nimport type {\n PluginTag,\n PluginUIConfig,\n PluginRouteDeps,\n PluginEntry,\n PluginInfo,\n LogLevel,\n} from \"./types.js\";\nimport { logger } from \"../services/logger.js\";\n\n// ── Constants ────────────────────────────────────────────────────────────\n\n/** Core plugin names — order matches the static import array */\nconst CORE_PLUGIN_NAMES = [\n \"agent\",\n \"session\",\n \"tunnel\",\n \"task\",\n \"config\",\n \"git\",\n \"file\",\n \"bookmark\",\n \"notification\",\n \"project\",\n \"plugin-mgr\",\n \"state\",\n \"log\",\n] as const;\n\n/** Registry directory and file */\nconst VIBECONTROLS_DIR = join(os.homedir(), \".vibecontrols\");\nconst REGISTRY_FILE = join(VIBECONTROLS_DIR, \"plugins.json\");\n\n/** DB key prefix for default provider settings */\nconst PROVIDER_DEFAULT_PREFIX = \"provider:default:\";\n\n// ── Host Services (passed to plugins) ───────────────────────────────────\n\nexport interface HostServices {\n /** KV storage for plugin data */\n storage: StorageProvider;\n /** Structured logger */\n logger: {\n debug(\n source: string,\n message: string,\n metadata?: Record<string, unknown>,\n ): void;\n info(\n source: string,\n message: string,\n metadata?: Record<string, unknown>,\n ): void;\n warn(\n source: string,\n message: string,\n metadata?: Record<string, unknown>,\n ): void;\n error(\n source: string,\n message: string,\n metadata?: Record<string, unknown>,\n ): void;\n setLevel(level: LogLevel): void;\n };\n /** Service registry for inter-plugin communication */\n serviceRegistry: ServiceRegistry;\n /** Get a registered provider */\n getProvider<T extends TunnelProvider | SessionProvider>(\n type: \"tunnel\" | \"session\",\n ): T | undefined;\n /** Get the agent's base URL (local) */\n getAgentBaseUrl(): string;\n /** Get the agent version */\n getAgentVersion(): string;\n}\n\n// ── Plugin Interface ────────────────────────────────────────────────────\n\nexport interface VibePlugin {\n /** Unique plugin name (e.g., \"tunnel\", \"session\", \"git\") */\n name: string;\n /** Semver version string */\n version: string;\n /** Short description */\n description?: string;\n\n // Discovery metadata\n /** Classification tags for filtering and grouping */\n tags?: PluginTag[];\n /** Base CLI command name (e.g., \"git\" → `vibe git ...`) */\n cliCommand?: string;\n /** Base API route prefix (e.g., \"/api/git\") */\n apiPrefix?: string;\n /** Other plugin names this plugin depends on */\n dependencies?: string[];\n /** Public paths that bypass authentication */\n publicPaths?: string[];\n\n // Provider registration\n providers?: {\n tunnel?: TunnelProvider;\n session?: SessionProvider;\n [key: string]: unknown;\n };\n\n // UI configuration\n ui?: PluginUIConfig;\n\n // Route factory\n /** Create Elysia sub-routes for the plugin */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n createRoutes?: (deps: PluginRouteDeps) => any;\n\n // Lifecycle hooks\n /** Called during CLI setup to register commander commands */\n onCliSetup?: (\n program: Command,\n hostServices: HostServices,\n ) => void | Promise<void>;\n /** Called when the server starts (before listening) */\n onServerStart?: (\n app: Elysia,\n hostServices: HostServices,\n ) => void | Promise<void>;\n /** Called after the server is listening */\n onServerReady?: (\n app: Elysia,\n hostServices: HostServices,\n ) => void | Promise<void>;\n /** Called when the server is stopping */\n onServerStop?: () => void | Promise<void>;\n}\n\n// ── Plugin Manager ──────────────────────────────────────────────────────\n\nexport class PluginManager {\n /** External plugin registry (persisted to JSON) */\n private registry: PluginEntry[] = [];\n\n /** External plugins loaded in memory, keyed by packageName */\n private loaded = new Map<string, VibePlugin>();\n\n /** Core plugins loaded from ../plugins/*, keyed by plugin name */\n private corePlugins = new Map<string, VibePlugin>();\n\n /** Optional database reference for provider defaults */\n private db: AgentDatabase | undefined;\n\n constructor(db?: AgentDatabase) {\n this.db = db;\n this.ensureDir();\n this.loadRegistry();\n }\n\n // ── Registry Persistence ────────────────────────────────────────────\n\n /**\n * Ensure the ~/.vibecontrols directory exists.\n */\n private ensureDir(): void {\n if (!existsSync(VIBECONTROLS_DIR)) {\n mkdirSync(VIBECONTROLS_DIR, { recursive: true });\n }\n }\n\n /**\n * Load the plugin registry from disk.\n */\n private loadRegistry(): void {\n try {\n if (existsSync(REGISTRY_FILE)) {\n const raw = readFileSync(REGISTRY_FILE, \"utf-8\");\n const parsed: unknown = JSON.parse(raw);\n if (Array.isArray(parsed)) {\n this.registry = parsed as PluginEntry[];\n }\n }\n } catch {\n this.registry = [];\n }\n }\n\n /**\n * Persist the plugin registry to disk.\n */\n private saveRegistry(): void {\n this.ensureDir();\n writeFileSync(\n REGISTRY_FILE,\n JSON.stringify(this.registry, null, 2),\n \"utf-8\",\n );\n }\n\n // ── Core Plugin Loading ─────────────────────────────────────────────\n\n /**\n * Load all core plugins via static imports.\n *\n * Uses Promise.allSettled so a single broken plugin does not prevent\n * the rest from loading. Each module is expected to export a default\n * VibePlugin (or a named `vibePlugin` export).\n */\n async loadCorePlugins(): Promise<void> {\n const coreModules = await Promise.allSettled([\n import(\"../plugins/agent/index.js\"),\n import(\"../plugins/session/index.js\"),\n import(\"../plugins/tunnel/index.js\"),\n import(\"../plugins/task/index.js\"),\n import(\"../plugins/config/index.js\"),\n import(\"../plugins/git/index.js\"),\n import(\"../plugins/file/index.js\"),\n import(\"../plugins/bookmark/index.js\"),\n import(\"../plugins/notification/index.js\"),\n import(\"../plugins/project/index.js\"),\n import(\"../plugins/plugin-mgr/index.js\"),\n import(\"../plugins/state/index.js\"),\n import(\"../plugins/log/index.js\"),\n ]);\n\n for (let i = 0; i < coreModules.length; i++) {\n const result = coreModules[i];\n const expectedName = CORE_PLUGIN_NAMES[i];\n\n if (result.status === \"fulfilled\") {\n const mod = result.value as Record<string, unknown>;\n const plugin = this.extractPlugin(mod);\n\n if (plugin?.name) {\n this.corePlugins.set(plugin.name, plugin);\n logger.info(\n \"plugin-manager\",\n `Core plugin loaded: ${plugin.name} v${plugin.version}`,\n );\n } else {\n logger.warn(\n \"plugin-manager\",\n `Core plugin '${expectedName}' did not export a valid VibePlugin`,\n );\n }\n } else {\n logger.warn(\n \"plugin-manager\",\n `Failed to load core plugin '${expectedName}': ${result.reason}`,\n );\n }\n }\n\n logger.info(\n \"plugin-manager\",\n `Core plugins loaded: ${this.corePlugins.size}/${CORE_PLUGIN_NAMES.length}`,\n );\n }\n\n // ── External Plugin Install ─────────────────────────────────────────\n\n /**\n * Install a plugin package globally via npm.\n * Validates the package exports a valid VibePlugin before persisting.\n */\n async install(packageName: string): Promise<PluginEntry> {\n logger.info(\"plugin-manager\", `Installing ${packageName}...`);\n\n // npm install -g\n try {\n execSync(`npm install -g ${packageName}`, {\n timeout: 120_000,\n stdio: \"pipe\",\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Failed to install ${packageName}: ${message}`, {\n cause: err,\n });\n }\n\n // Dynamic import to validate\n const plugin = await this.importPlugin(packageName);\n\n // Log if this overrides a core plugin\n if (this.corePlugins.has(plugin.name)) {\n logger.info(\n \"plugin-manager\",\n `External plugin '${packageName}' overrides core plugin '${plugin.name}'`,\n );\n }\n\n // Save to registry (deduplicate by packageName)\n const entry: PluginEntry = {\n packageName,\n version: plugin.version,\n pluginName: plugin.name,\n installedAt: new Date().toISOString(),\n };\n\n this.registry = this.registry.filter((e) => e.packageName !== packageName);\n this.registry.push(entry);\n this.saveRegistry();\n\n logger.info(\n \"plugin-manager\",\n `Installed ${packageName}@${plugin.version} (${plugin.name})`,\n );\n return entry;\n }\n\n /**\n * Install and immediately load a plugin into a running server.\n * Registers providers and dispatches onServerStart.\n */\n async installAndLoad(\n packageName: string,\n app: Elysia,\n hostServices: HostServices,\n ): Promise<PluginEntry> {\n const entry = await this.install(packageName);\n\n // Load and start\n const plugin = this.loaded.get(entry.packageName);\n if (plugin) {\n this.registerPluginProviders(plugin, hostServices);\n\n if (plugin.onServerStart) {\n await plugin.onServerStart(app, hostServices);\n }\n }\n\n return entry;\n }\n\n // ── External Plugin Remove ──────────────────────────────────────────\n\n /**\n * Remove a plugin package. Stops the plugin, unregisters it,\n * runs npm uninstall -g, and updates the persisted registry.\n */\n async remove(packageName: string): Promise<void> {\n logger.info(\"plugin-manager\", `Removing ${packageName}...`);\n\n // Stop plugin if loaded\n const plugin = this.loaded.get(packageName);\n if (plugin?.onServerStop) {\n try {\n await plugin.onServerStop();\n } catch (err) {\n logger.warn(\"plugin-manager\", `Error stopping ${packageName}: ${err}`);\n }\n }\n\n // Clean up loaded reference\n if (plugin) {\n this.loaded.delete(packageName);\n }\n\n // npm uninstall -g\n try {\n execSync(`npm uninstall -g ${packageName}`, {\n timeout: 60_000,\n stdio: \"pipe\",\n });\n } catch {\n // Package might not be globally installed — that's ok\n }\n\n // Remove from registry\n this.registry = this.registry.filter((e) => e.packageName !== packageName);\n this.saveRegistry();\n\n logger.info(\"plugin-manager\", `Removed ${packageName}`);\n }\n\n // ── External Plugin Load ────────────────────────────────────────────\n\n /**\n * Load all registered external plugins into memory.\n * Does not clear core plugins — only external loaded map.\n */\n async loadAll(): Promise<void> {\n this.loaded.clear();\n\n for (const entry of this.registry) {\n try {\n await this.importPlugin(entry.packageName);\n logger.info(\n \"plugin-manager\",\n `Loaded ${entry.packageName} (${entry.pluginName})`,\n );\n } catch (err) {\n logger.warn(\n \"plugin-manager\",\n `Failed to load ${entry.packageName}: ${err}`,\n );\n }\n }\n }\n\n /**\n * Import a plugin module and extract the VibePlugin export.\n *\n * Supports multiple export patterns:\n * 1. `{ vibePlugin: VibePlugin }`\n * 2. `{ default: { vibePlugin: VibePlugin } }`\n * 3. `{ default: VibePlugin }`\n */\n private async importPlugin(packageName: string): Promise<VibePlugin> {\n const mod = (await import(packageName)) as Record<string, unknown>;\n const plugin = this.extractPlugin(mod);\n\n if (!plugin) {\n throw new Error(`${packageName} does not export a valid VibePlugin`);\n }\n\n this.loaded.set(packageName, plugin);\n return plugin;\n }\n\n /**\n * Extract a VibePlugin from a module object, supporting multiple\n * export patterns (default export, named vibePlugin export, nested).\n */\n private extractPlugin(mod: Record<string, unknown>): VibePlugin | undefined {\n // Pattern 1: named export { vibePlugin }\n if (this.isVibePlugin(mod.vibePlugin)) {\n return mod.vibePlugin;\n }\n\n // Pattern 2: { default: { vibePlugin } }\n const defaultExport = mod.default as Record<string, unknown> | undefined;\n if (defaultExport && this.isVibePlugin(defaultExport.vibePlugin)) {\n return defaultExport.vibePlugin as VibePlugin;\n }\n\n // Pattern 3: { default: VibePlugin }\n if (this.isVibePlugin(defaultExport)) {\n return defaultExport as VibePlugin;\n }\n\n return undefined;\n }\n\n /**\n * Type guard: check if a value looks like a valid VibePlugin.\n */\n private isVibePlugin(value: unknown): value is VibePlugin {\n if (!value || typeof value !== \"object\") return false;\n const candidate = value as Record<string, unknown>;\n return (\n typeof candidate.name === \"string\" &&\n typeof candidate.version === \"string\"\n );\n }\n\n // ── Provider Registration ───────────────────────────────────────────\n\n /**\n * Register tunnel and session providers from a plugin into the\n * service registry.\n */\n private registerPluginProviders(\n plugin: VibePlugin,\n hostServices: HostServices,\n ): void {\n if (plugin.providers?.tunnel) {\n hostServices.serviceRegistry.registerProvider(\n \"tunnel\",\n plugin.providers.tunnel,\n plugin.name,\n );\n }\n if (plugin.providers?.session) {\n hostServices.serviceRegistry.registerProvider(\n \"session\",\n plugin.providers.session,\n plugin.name,\n );\n }\n }\n\n // ── Lifecycle Dispatch ──────────────────────────────────────────────\n\n /**\n * Dispatch onCliSetup to all loaded plugins (core + external).\n */\n async dispatchCliSetup(\n program: Command,\n hostServices: HostServices,\n ): Promise<void> {\n for (const plugin of this.getAllPlugins()) {\n if (plugin.onCliSetup) {\n try {\n await plugin.onCliSetup(program, hostServices);\n } catch (err) {\n logger.warn(\n \"plugin-manager\",\n `onCliSetup failed for ${plugin.name}: ${err}`,\n );\n }\n }\n }\n }\n\n /**\n * Dispatch onServerStart to all plugins (core + external).\n * Sorts by dependencies before dispatching. Registers providers first.\n */\n async dispatchServerStart(\n app: Elysia,\n hostServices: HostServices,\n ): Promise<void> {\n const sorted = this.sortAllByDependencies();\n\n for (const plugin of sorted) {\n // Register providers before calling onServerStart\n this.registerPluginProviders(plugin, hostServices);\n\n if (plugin.onServerStart) {\n try {\n await plugin.onServerStart(app, hostServices);\n } catch (err) {\n logger.error(\n \"plugin-manager\",\n `onServerStart failed for ${plugin.name}: ${err}`,\n );\n }\n }\n }\n }\n\n /**\n * Dispatch onServerReady to all plugins (core + external).\n */\n async dispatchServerReady(\n app: Elysia,\n hostServices: HostServices,\n ): Promise<void> {\n for (const plugin of this.getAllPlugins()) {\n if (plugin.onServerReady) {\n try {\n await plugin.onServerReady(app, hostServices);\n } catch (err) {\n logger.warn(\n \"plugin-manager\",\n `onServerReady failed for ${plugin.name}: ${err}`,\n );\n }\n }\n }\n }\n\n /**\n * Dispatch onServerStop to all plugins (core + external).\n */\n async dispatchServerStop(): Promise<void> {\n for (const plugin of this.getAllPlugins()) {\n if (plugin.onServerStop) {\n try {\n await plugin.onServerStop();\n } catch (err) {\n logger.warn(\n \"plugin-manager\",\n `onServerStop failed for ${plugin.name}: ${err}`,\n );\n }\n }\n }\n }\n\n /**\n * Reload all plugins: stop everything, clear state, reload registry,\n * reload core + external plugins, and restart.\n */\n async reloadAll(app: Elysia, hostServices: HostServices): Promise<void> {\n await this.dispatchServerStop();\n this.loaded.clear();\n this.corePlugins.clear();\n this.loadRegistry();\n await this.loadCorePlugins();\n await this.loadAll();\n await this.dispatchServerStart(app, hostServices);\n await this.dispatchServerReady(app, hostServices);\n }\n\n // ── Dependency Sorting ──────────────────────────────────────────────\n\n /**\n * Topological sort of ALL plugins (core + external, deduplicated)\n * respecting declared dependencies.\n */\n private sortAllByDependencies(): VibePlugin[] {\n const allPlugins = this.getAllPlugins();\n const pluginMap = new Map<string, VibePlugin>();\n for (const plugin of allPlugins) {\n pluginMap.set(plugin.name, plugin);\n }\n\n const visited = new Set<string>();\n const sorted: VibePlugin[] = [];\n\n const visit = (name: string) => {\n if (visited.has(name)) return;\n visited.add(name);\n\n const plugin = pluginMap.get(name);\n if (!plugin) return;\n\n if (plugin.dependencies) {\n for (const dep of plugin.dependencies) {\n if (pluginMap.has(dep)) {\n visit(dep);\n }\n }\n }\n\n sorted.push(plugin);\n };\n\n for (const plugin of allPlugins) {\n visit(plugin.name);\n }\n\n return sorted;\n }\n\n /**\n * Topological sort of external plugins only.\n * Returns [packageName, VibePlugin] pairs in dependency order.\n */\n private sortByDependencies(): Array<[string, VibePlugin]> {\n const entries = Array.from(this.loaded.entries());\n const nameToPackage = new Map<string, string>();\n for (const [pkg, plugin] of entries) {\n nameToPackage.set(plugin.name, pkg);\n }\n\n const visited = new Set<string>();\n const sorted: Array<[string, VibePlugin]> = [];\n\n const visit = (pkg: string) => {\n if (visited.has(pkg)) return;\n visited.add(pkg);\n\n const plugin = this.loaded.get(pkg);\n if (plugin?.dependencies) {\n for (const dep of plugin.dependencies) {\n const depPkg = nameToPackage.get(dep);\n if (depPkg && this.loaded.has(depPkg)) {\n visit(depPkg);\n }\n }\n }\n const loadedPlugin = this.loaded.get(pkg);\n if (loadedPlugin) {\n sorted.push([pkg, loadedPlugin]);\n }\n };\n\n for (const [pkg] of entries) {\n visit(pkg);\n }\n\n return sorted;\n }\n\n // ── Unified Lookup ──────────────────────────────────────────────────\n\n /**\n * Look up a plugin by its name across core and external.\n * External plugins win on conflict (override semantics).\n */\n getPluginByKey(key: string): VibePlugin | undefined {\n // Check external plugins first (they override core)\n for (const [, plugin] of this.loaded) {\n if (plugin.name === key) {\n return plugin;\n }\n }\n\n // Fall back to core plugins\n return this.corePlugins.get(key);\n }\n\n /**\n * Return all plugins (core + external), deduplicated by name.\n * External plugins override core plugins with the same name.\n */\n getAllPlugins(): VibePlugin[] {\n const merged = new Map<string, VibePlugin>();\n\n // Core first\n for (const [key, plugin] of this.corePlugins) {\n merged.set(key, plugin);\n }\n\n // External override core\n for (const [, plugin] of this.loaded) {\n merged.set(plugin.name, plugin);\n }\n\n return Array.from(merged.values());\n }\n\n /**\n * Return all plugins that have the specified tag.\n */\n getAllPluginsByTag(tag: PluginTag): VibePlugin[] {\n return this.getAllPlugins().filter(\n (plugin) => plugin.tags?.includes(tag) ?? false,\n );\n }\n\n // ── Plugin Chain Resolution ─────────────────────────────────────────\n\n /**\n * Walk tokens left-to-right, matching against all known plugin names.\n * First non-matching token (or flag starting with `-`) is treated as\n * the command.\n *\n * Examples:\n * tokens = [\"git\", \"commit\", \"-m\", \"msg\"]\n * → { chain: [\"git\"], command: \"commit\", args: [\"-m\", \"msg\"] }\n *\n * tokens = [\"agent\", \"config\", \"set\", \"key\", \"value\"]\n * → { chain: [\"agent\", \"config\"], command: \"set\", args: [\"key\", \"value\"] }\n *\n * tokens = [\"tunnel\"]\n * → { chain: [\"tunnel\"], command: \"\", args: [] }\n */\n resolvePluginChain(tokens: string[]): {\n chain: string[];\n command: string;\n args: string[];\n } {\n const allKeys = new Set<string>();\n for (const p of this.getAllPlugins()) {\n allKeys.add(p.name);\n }\n\n const chain: string[] = [];\n let commandIdx = -1;\n\n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i].startsWith(\"-\")) {\n // Flag — stop chain resolution\n commandIdx = i;\n break;\n }\n if (allKeys.has(tokens[i])) {\n chain.push(tokens[i]);\n } else {\n commandIdx = i;\n break;\n }\n }\n\n if (commandIdx === -1) {\n // All tokens were plugins, no command\n return { chain, command: \"\", args: [] };\n }\n\n return {\n chain,\n command: tokens[commandIdx],\n args: tokens.slice(commandIdx + 1),\n };\n }\n\n // ── Provider Defaults ───────────────────────────────────────────────\n\n /**\n * Get the default provider plugin name for a given provider type.\n * Reads from `provider:default:<type>` in the agent database.\n * Returns null if no default is set or db is not available.\n */\n getDefaultProvider(type: string): string | null {\n if (!this.db) return null;\n\n const value = this.db.getConfig(`${PROVIDER_DEFAULT_PREFIX}${type}`);\n return value ?? null;\n }\n\n /**\n * Set the default provider plugin name for a given provider type.\n * Writes `provider:default:<type>` to the agent database.\n * Throws if db is not available.\n */\n setDefaultProvider(type: string, pluginName: string): void {\n if (!this.db) {\n throw new Error(\n \"Cannot set default provider: PluginManager was constructed without a database reference\",\n );\n }\n\n // Verify the plugin exists\n const plugin = this.getPluginByKey(pluginName);\n if (!plugin) {\n throw new Error(`Plugin '${pluginName}' not found`);\n }\n\n this.db.setConfig(`${PROVIDER_DEFAULT_PREFIX}${type}`, pluginName);\n logger.info(\n \"plugin-manager\",\n `Set default '${type}' provider to '${pluginName}'`,\n );\n }\n\n // ── Introspection ───────────────────────────────────────────────────\n\n /**\n * Get detailed information about all plugins (core + external).\n * Deduplicated — external overrides core by plugin name.\n */\n getPluginDetails(): PluginInfo[] {\n const coreInfos = this.getCorePluginDetails();\n const externalInfos = this.getExternalPluginDetails();\n\n // Deduplicate: external overrides core by pluginName\n const merged = new Map<string, PluginInfo>();\n for (const info of coreInfos) {\n merged.set(info.pluginName, info);\n }\n for (const info of externalInfos) {\n merged.set(info.pluginName, info);\n }\n\n return Array.from(merged.values());\n }\n\n /**\n * Build PluginInfo entries for all core plugins.\n */\n private getCorePluginDetails(): PluginInfo[] {\n const infos: PluginInfo[] = [];\n\n for (const [name, plugin] of this.corePlugins) {\n infos.push({\n packageName: `@vibecontrols/plugin-${name}`,\n pluginName: name,\n version: plugin.version,\n description: plugin.description,\n tags: plugin.tags,\n cliCommand: plugin.cliCommand,\n apiPrefix: plugin.apiPrefix,\n dependencies: plugin.dependencies,\n installedAt: \"\",\n loaded: true,\n isCore: true,\n hasUI: !!plugin.ui,\n uiUrl: plugin.ui ? `/ui/${name}` : undefined,\n hasCliSetup: !!plugin.onCliSetup,\n hasServerStart: !!plugin.onServerStart,\n hasServerStop: !!plugin.onServerStop,\n hasServerReady: !!plugin.onServerReady,\n hasProviders: !!(plugin.providers?.tunnel || plugin.providers?.session),\n });\n }\n\n return infos;\n }\n\n /**\n * Build PluginInfo entries for all external (installed) plugins.\n */\n private getExternalPluginDetails(): PluginInfo[] {\n return this.registry.map((entry) => {\n const plugin = this.loaded.get(entry.packageName);\n return {\n packageName: entry.packageName,\n pluginName: entry.pluginName,\n version: plugin?.version ?? entry.version,\n description: plugin?.description,\n tags: plugin?.tags,\n cliCommand: plugin?.cliCommand,\n apiPrefix: plugin?.apiPrefix,\n dependencies: plugin?.dependencies,\n installedAt: entry.installedAt,\n loaded: !!plugin,\n isCore: false,\n hasUI: !!plugin?.ui,\n uiUrl: plugin?.ui ? `/ui/${entry.pluginName}` : undefined,\n hasCliSetup: !!plugin?.onCliSetup,\n hasServerStart: !!plugin?.onServerStart,\n hasServerStop: !!plugin?.onServerStop,\n hasServerReady: !!plugin?.onServerReady,\n hasProviders: !!(\n plugin?.providers?.tunnel || plugin?.providers?.session\n ),\n };\n });\n }\n\n /**\n * Get the external plugin registry entries.\n */\n getRegistry(): PluginEntry[] {\n return [...this.registry];\n }\n\n /**\n * Get an external loaded plugin by package name.\n */\n getLoaded(packageName: string): VibePlugin | undefined {\n return this.loaded.get(packageName);\n }\n\n /**\n * Get all externally loaded plugins (Map keyed by packageName).\n */\n getAllLoaded(): Map<string, VibePlugin> {\n return new Map(this.loaded);\n }\n\n /**\n * Check if a package is installed in the external registry.\n */\n isInstalled(packageName: string): boolean {\n return this.registry.some((e) => e.packageName === packageName);\n }\n\n /**\n * Check if a package is loaded in the external plugins map.\n */\n isLoaded(packageName: string): boolean {\n return this.loaded.has(packageName);\n }\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "5AC5602856ACEA6F64756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
File without changes
|