@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.
Files changed (30) hide show
  1. package/dist/{app-6mmbmske.js → app-8dgv7s3y.js} +13 -14
  2. package/dist/{app-6mmbmske.js.map → app-8dgv7s3y.js.map} +3 -3
  3. package/dist/cli.js +28 -27
  4. package/dist/cli.js.map +5 -5
  5. package/dist/{index-41m1exz7.js → index-3rjnbp97.js} +3 -4
  6. package/dist/index-3rjnbp97.js.map +13 -0
  7. package/dist/{index-q4ytrfx7.js → index-6vry08rz.js} +4 -5
  8. package/dist/index-6vry08rz.js.map +13 -0
  9. package/dist/{index-wdtxbebz.js → index-fm6gqenc.js} +3 -4
  10. package/dist/index-fm6gqenc.js.map +13 -0
  11. package/dist/{index-3v78e2cn.js → index-s7ff1fj1.js} +88 -46
  12. package/dist/index-s7ff1fj1.js.map +11 -0
  13. package/dist/{index-9tgyd3ep.js → index-wjsms9jw.js} +11 -9
  14. package/dist/{index-9tgyd3ep.js.map → index-wjsms9jw.js.map} +3 -3
  15. package/dist/{index-qthbtg9n.js → index-wmvkjcjj.js} +4 -5
  16. package/dist/index-wmvkjcjj.js.map +13 -0
  17. package/dist/{index-xn4tarcd.js → index-x82yjxw7.js} +4 -4
  18. package/dist/index.js +2 -2
  19. package/dist/{package-ywexp6sg.js → package-04nkt49b.js} +5 -3
  20. package/dist/{package-ywexp6sg.js.map → package-04nkt49b.js.map} +1 -1
  21. package/dist/{plugin-system-v7a7xnhk.js → plugin-system-bc4rvt1c.js} +46 -14
  22. package/dist/plugin-system-bc4rvt1c.js.map +10 -0
  23. package/package.json +3 -1
  24. package/dist/index-3v78e2cn.js.map +0 -11
  25. package/dist/index-41m1exz7.js.map +0 -13
  26. package/dist/index-q4ytrfx7.js.map +0 -13
  27. package/dist/index-qthbtg9n.js.map +0 -13
  28. package/dist/index-wdtxbebz.js.map +0 -13
  29. package/dist/plugin-system-v7a7xnhk.js.map +0 -10
  30. /package/dist/{index-xn4tarcd.js.map → index-x82yjxw7.js.map} +0 -0
@@ -20,7 +20,6 @@ import {
20
20
  import"./index-g8dczzvv.js";
21
21
 
22
22
  // src/plugins/task/routes.ts
23
- import crypto from "crypto";
24
23
  import { promises as fs } from "fs";
25
24
  import path from "path";
26
25
  import os from "os";
@@ -138,7 +137,7 @@ function createRoutes(deps) {
138
137
  }).post("/", async ({ body, set }) => {
139
138
  try {
140
139
  const task = db.createTask({
141
- id: crypto.randomUUID(),
140
+ id: globalThis.crypto.randomUUID(),
142
141
  type: body.type,
143
142
  status: "pending",
144
143
  payload: JSON.stringify(body.payload)
@@ -265,5 +264,5 @@ export {
265
264
  vibePlugin
266
265
  };
267
266
 
268
- //# debugId=84A2CB11789A3BBD64756E2164756E21
269
- //# sourceMappingURL=index-41m1exz7.js.map
267
+ //# debugId=BC2EA895432C9ECA64756E2164756E21
268
+ //# sourceMappingURL=index-3rjnbp97.js.map
@@ -0,0 +1,13 @@
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 { 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: globalThis.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": ";;;;;;;;;;;;;;;;;;;;;;AAaA,qBAAS;AACT;AACA;AAOA,eAAe,cAAc,CAAC,SAIkB;AAAA,EAC9C,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,MAAM,QAAQ,OAAO,GAAG;AAAA,IACpD,KAAK,QAAQ;AAAA,IACb,KAAK,KAAK,QAAQ,QAAQ,QAAQ,IAAI;AAAA,IACtC,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AAAA,EAED,OAAO,QAAQ,UAAU,MAAM,QAAQ,IAAI;AAAA,IACzC,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK;AAAA,IAC/B,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK;AAAA,EACjC,CAAC;AAAA,EAED,MAAM,KAAK;AAAA,EACX,OAAO,EAAE,QAAQ,OAAO;AAAA;AAG1B,eAAe,aAAa,CAAC,SAImB;AAAA,EAC9C,MAAM,cAAc,QAAQ,eAAe;AAAA,EAC3C,MAAM,SAAS,GAAG,OAAO;AAAA,EACzB,MAAM,aAAa,KAAK,KAAK,QAAQ,uBAAuB,KAAK,IAAI,MAAM;AAAA,EAE3E,MAAM,GAAG,UAAU,YAAY,QAAQ,QAAQ,EAAE,MAAM,IAAM,CAAC;AAAA,EAE9D,IAAI;AAAA,IACF,MAAM,OAAO,IAAI,MAAM,CAAC,aAAa,UAAU,GAAG;AAAA,MAChD,KAAK,QAAQ;AAAA,MACb,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV,CAAC;AAAA,IAED,OAAO,QAAQ,UAAU,MAAM,QAAQ,IAAI;AAAA,MACzC,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK;AAAA,MAC/B,IAAI,SAAS,KAAK,MAAM,EAAE,KAAK;AAAA,IACjC,CAAC;AAAA,IAED,MAAM,KAAK;AAAA,IACX,OAAO,EAAE,QAAQ,OAAO;AAAA,YACxB;AAAA,IACA,MAAM,GAAG,OAAO,UAAU,EAAE,MAAM,MAAM,EAAE;AAAA;AAAA;AAI9C,eAAe,oBAAoB,CAAC,SAIC;AAAA,EACnC,QAAQ,QAAQ;AAAA,SACT,QAAQ;AAAA,MACX,MAAM,OAAO,MAAM,GAAG,SAAS,QAAQ,MAAM,OAAO;AAAA,MACpD,OAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAAA,SACK,SAAS;AAAA,MACZ,IAAI,CAAC,QAAQ;AAAA,QACX,MAAM,IAAI,MAAM,yCAAyC;AAAA,MAC3D,MAAM,GAAG,UAAU,QAAQ,MAAM,QAAQ,OAAO;AAAA,MAChD,OAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAAA,SACK,UAAU;AAAA,MACb,MAAM,GAAG,OAAO,QAAQ,IAAI;AAAA,MAC5B,OAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAAA,SACK,UAAU;AAAA,MACb,IAAI;AAAA,QACF,MAAM,GAAG,OAAO,QAAQ,IAAI;AAAA,QAC5B,OAAO,EAAE,QAAQ,KAAK;AAAA,QACtB,MAAM;AAAA,QACN,OAAO,EAAE,QAAQ,MAAM;AAAA;AAAA,IAE3B;AAAA,SACK,QAAQ;AAAA,MACX,MAAM,QAAQ,MAAM,GAAG,QAAQ,QAAQ,IAAI;AAAA,MAC3C,OAAO,EAAE,MAAM;AAAA,IACjB;AAAA;AAAA,MAEE,MAAM,IAAI,MAAM,2BAA2B,QAAQ,WAAW;AAAA;AAAA;AAIpE,eAAe,WAAW,CAAC,IAAmB,MAA2B;AAAA,EACvE,IAAI;AAAA,IACF,GAAG,WAAW,KAAK,IAAI,EAAE,QAAQ,UAAU,CAAC;AAAA,IAE5C,MAAM,UAAU,KAAK,MAAM,KAAK,OAAO;AAAA,IACvC,IAAI;AAAA,IAEJ,QAAQ,KAAK;AAAA,WACN;AAAA,QACH,SAAS,MAAM,eAAe,OAAO;AAAA,QACrC;AAAA,WACG;AAAA,QACH,SAAS,MAAM,cAAc,OAAO;AAAA,QACpC;AAAA,WACG;AAAA,QACH,SAAS,MAAM,qBAAqB,OAAO;AAAA,QAC3C;AAAA;AAAA,QAEA,MAAM,IAAI,MAAM,sBAAsB,KAAK,MAAM;AAAA;AAAA,IAGrD,GAAG,WAAW,KAAK,IAAI;AAAA,MACrB,QAAQ;AAAA,MACR,QAAQ,KAAK,UAAU,MAAM;AAAA,IAC/B,CAAC;AAAA,IACD,OAAO,KAAK;AAAA,IACZ,GAAG,WAAW,KAAK,IAAI;AAAA,MACrB,QAAQ;AAAA,MACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACxD,CAAC;AAAA;AAAA;AAME,SAAS,YAAY,CAAC,MAAuB;AAAA,EAClD,QAAQ,OAAO;AAAA,EAEf,OACE,IAAI,OAAO,EAER,IAAI,KAAK,GAAG,YAAY;AAAA,IACvB,MAAM,SAAU,MAAiC;AAAA,IACjD,IAAI,WAAW,WAAW;AAAA,MACxB,OAAO,EAAE,OAAO,GAAG,gBAAgB,EAAE;AAAA,IACvC;AAAA,IACA,OAAO,EAAE,OAAO,GAAG,YAAY,EAAE;AAAA,GAClC,EAGA,IAAI,QAAQ,GAAG,QAAQ,UAAU;AAAA,IAChC,MAAM,OAAO,GAAG,QAAQ,OAAO,EAAE;AAAA,IACjC,IAAI,CAAC,MAAM;AAAA,MACT,IAAI,SAAS;AAAA,MACb,OAAO,EAAE,OAAO,iBAAiB;AAAA,IACnC;AAAA,IACA,OAAO,EAAE,KAAK;AAAA,GACf,EAGA,KACC,KACA,SAAS,MAAM,UAAU;AAAA,IACvB,IAAI;AAAA,MACF,MAAM,OAAO,GAAG,WAAW;AAAA,QACzB,IAAI,WAAW,OAAO,WAAW;AAAA,QACjC,MAAM,KAAK;AAAA,QACX,QAAQ;AAAA,QACR,SAAS,KAAK,UAAU,KAAK,OAAO;AAAA,MACtC,CAAC;AAAA,MAGD,YAAY,IAAI,IAAI;AAAA,MAEpB,OAAO,EAAE,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,MACZ,IAAI,SAAS;AAAA,MACb,OAAO,EAAE,OAAO,yBAAyB,SAAS,OAAO,GAAG,EAAE;AAAA;AAAA,KAGlE;AAAA,IACE,MAAM,EAAE,OAAO;AAAA,MACb,MAAM,EAAE,MAAM;AAAA,QACZ,EAAE,QAAQ,SAAS;AAAA,QACnB,EAAE,QAAQ,QAAQ;AAAA,QAClB,EAAE,QAAQ,gBAAgB;AAAA,MAC5B,CAAC;AAAA,MACD,SAAS,EAAE,OAAO;AAAA,QAChB,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,QAC9B,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,QAC1B,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,QAChD,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,QAC7B,aAAa,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,QAClC,WAAW,EAAE,SACX,EAAE,MAAM;AAAA,UACN,EAAE,QAAQ,MAAM;AAAA,UAChB,EAAE,QAAQ,OAAO;AAAA,UACjB,EAAE,QAAQ,QAAQ;AAAA,UAClB,EAAE,QAAQ,QAAQ;AAAA,UAClB,EAAE,QAAQ,MAAM;AAAA,QAClB,CAAC,CACH;AAAA,QACA,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,QAC3B,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC;AAAA,MAChC,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CACF,EAGC,KAAK,eAAe,GAAG,QAAQ,UAAU;AAAA,IACxC,MAAM,OAAO,GAAG,QAAQ,OAAO,EAAE;AAAA,IACjC,IAAI,CAAC,MAAM;AAAA,MACT,IAAI,SAAS;AAAA,MACb,OAAO,EAAE,OAAO,iBAAiB;AAAA,IACnC;AAAA,IAEA,IAAI,KAAK,WAAW,WAAW;AAAA,MAC7B,IAAI,SAAS;AAAA,MACb,OAAO,EAAE,OAAO,sCAAsC;AAAA,IACxD;AAAA,IAEA,GAAG,WAAW,OAAO,IAAI;AAAA,MACvB,QAAQ;AAAA,MACR,OAAO;AAAA,IACT,CAAC;AAAA,IAED,OAAO,EAAE,SAAS,KAAK;AAAA,GACxB;AAAA;;;AC9NP,IAAM,oBAAoB;AAEnB,SAAS,QAAQ,CAAC,SAAwB;AAAA,EAC/C,MAAM,MAAM,QAAQ,QAAQ,MAAM,EAAE,YAAY,yBAAyB;AAAA,EAGzE,IACG,QAAQ,MAAM,EACd,YAAY,YAAY,EACxB,OAAO,qBAAqB,kBAAkB,EAC9C,OAAO,qBAAqB,aAAa,iBAAiB,EAC1D,OAAO,OAAO,YAAY;AAAA,IACzB,IAAI;AAAA,MACF,MAAM,MAAM,YAAY,OAAO;AAAA,MAC/B,MAAM,QAAQ,QAAQ,SAClB,sBAAsB,mBAAmB,QAAQ,MAAM,MACvD;AAAA,MACJ,MAAM,OAAO,MAAM,OAAyB,KAAK,KAAK;AAAA,MACtD,MAAM,QAAQ,KAAK,SAAS,CAAC;AAAA,MAC7B,IAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAAA,QAChC,KAAK,iBAAiB;AAAA,QACtB;AAAA,MACF;AAAA,MACA,OAAO,OAAO;AAAA,MACd,YACE,MAAM,IAAI,CAAC,QAAY;AAAA,QACrB,IAAI,QAAQ,GAAE,EAAE;AAAA,QAChB,MAAM,GAAE,QAAQ;AAAA,QAChB,QAAQ,aAAa,GAAE,MAAM;AAAA,QAC7B,SAAS,GAAE,YAAY,QAAQ,GAAE,SAAS,IAAI;AAAA,MAChD,EAAE,CACJ;AAAA,MACA,OAAO,KAAU;AAAA,MACjB,KAAK,IAAI,OAAO;AAAA;AAAA,GAEnB;AAAA,EAGH,IACG,QAAQ,KAAK,EACb,YAAY,gBAAgB,EAC5B,eAAe,uBAAuB,gBAAgB,EACtD,OAAO,eAAe,mBAAmB,EACzC,OAAO,qBAAqB,aAAa,iBAAiB,EAC1D,OAAO,OAAO,YAAY;AAAA,IACzB,IAAI;AAAA,MACF,MAAM,MAAM,YAAY,OAAO;AAAA,MAC/B,MAAM,UAA+B,EAAE,SAAS,QAAQ,QAAQ;AAAA,MAChE,IAAI,QAAQ;AAAA,QAAK,QAAQ,MAAM,QAAQ;AAAA,MACvC,MAAM,OAAO;AAAA,QACX,MAAM;AAAA,QACN,SAAS,KAAK,UAAU,OAAO;AAAA,MACjC;AAAA,MACA,MAAM,SAAS,MAAM,QAAa,KAAK,eAAe,IAAI;AAAA,MAC1D,QAAQ,iBAAiB,QAAQ,QAAQ,MAAM,QAAQ,MAAM,GAAG;AAAA,MAChE,OAAO,KAAU;AAAA,MACjB,KAAK,IAAI,OAAO;AAAA;AAAA,GAEnB;AAAA,EAGH,IACG,QAAQ,QAAQ,EAChB,YAAY,uBAAuB,EACnC,eAAe,iBAAiB,SAAS,EACzC,OAAO,qBAAqB,aAAa,iBAAiB,EAC1D,OAAO,OAAO,YAAY;AAAA,IACzB,IAAI;AAAA,MACF,MAAM,MAAM,YAAY,OAAO;AAAA,MAC/B,MAAM,OAAY,KAAK,cAAc,QAAQ,aAAa,CAAC,CAAC;AAAA,MAC5D,QAAQ,QAAQ,QAAQ,QAAQ,EAAE,cAAc;AAAA,MAChD,OAAO,KAAU;AAAA,MACjB,KAAK,IAAI,OAAO;AAAA;AAAA,GAEnB;AAAA;;;ACtFE,SAAS,gBAAgB,CAC9B,SACA,eACM;AAAA,EACN,SAAa,OAAO;AAAA;;;ACHf,IAAM,aAAyB;AAAA,EACpC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,MAAM,CAAC,WAAW,KAAK;AAAA,EACvB,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,cAAc,CAAC,SAA0B,aAAa,IAAI;AAAA,EAC1D,YAAY,OAAO,SAAS,iBAAiB;AAAA,IAC3C,iBAAiB,SAAS,YAAY;AAAA;AAE1C;",
11
+ "debugId": "BC2EA895432C9ECA64756E2164756E21",
12
+ "names": []
13
+ }
@@ -19,7 +19,6 @@ import {
19
19
  import"./index-g8dczzvv.js";
20
20
 
21
21
  // src/plugins/bookmark/routes.ts
22
- import crypto from "crypto";
23
22
  function createRoutes(deps) {
24
23
  const { db, serviceRegistry } = deps;
25
24
  return new Elysia().get("/", ({ query }) => {
@@ -45,7 +44,7 @@ function createRoutes(deps) {
45
44
  }).post("/", ({ body, set }) => {
46
45
  try {
47
46
  const bookmark = db.createBookmarkedCommand({
48
- id: crypto.randomUUID(),
47
+ id: globalThis.crypto.randomUUID(),
49
48
  projectId: body.projectId,
50
49
  command: body.command,
51
50
  description: body.description,
@@ -138,7 +137,7 @@ function createRoutes(deps) {
138
137
  };
139
138
  }
140
139
  const task = db.createTask({
141
- id: crypto.randomUUID(),
140
+ id: globalThis.crypto.randomUUID(),
142
141
  type: "command",
143
142
  status: "pending",
144
143
  payload: JSON.stringify({
@@ -282,5 +281,5 @@ export {
282
281
  vibePlugin
283
282
  };
284
283
 
285
- //# debugId=180562EA8CFA2EAC64756E2164756E21
286
- //# sourceMappingURL=index-q4ytrfx7.js.map
284
+ //# debugId=E29820E5E0F6A45164756E2164756E21
285
+ //# sourceMappingURL=index-6vry08rz.js.map
@@ -0,0 +1,13 @@
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\";\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: globalThis.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: globalThis.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": "E29820E5E0F6A45164756E2164756E21",
12
+ "names": []
13
+ }
@@ -21,7 +21,6 @@ import {
21
21
  import"./index-g8dczzvv.js";
22
22
 
23
23
  // src/plugins/git/routes.ts
24
- import crypto from "crypto";
25
24
  import { promises as fs } from "fs";
26
25
  import path from "path";
27
26
  async function detectProjectType(directory) {
@@ -168,7 +167,7 @@ function createRoutes(deps) {
168
167
  savedRepos.push({ ...existing, ...repo });
169
168
  } else {
170
169
  const newRepo = db.createGitRepository({
171
- id: crypto.randomUUID(),
170
+ id: globalThis.crypto.randomUUID(),
172
171
  ...repo
173
172
  });
174
173
  savedRepos.push(newRepo);
@@ -335,5 +334,5 @@ export {
335
334
  vibePlugin
336
335
  };
337
336
 
338
- //# debugId=7E548635BBB4C3EF64756E2164756E21
339
- //# sourceMappingURL=index-wdtxbebz.js.map
337
+ //# debugId=7833782DA41E97E464756E2164756E21
338
+ //# sourceMappingURL=index-fm6gqenc.js.map
@@ -0,0 +1,13 @@
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 { 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: globalThis.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": "7833782DA41E97E464756E2164756E21",
12
+ "names": []
13
+ }
@@ -4,16 +4,30 @@ import {
4
4
  } from "./index-88ym10cs.js";
5
5
 
6
6
  // src/services/bootstrap.service.ts
7
- import { execSync } from "child_process";
8
7
  import os from "os";
9
8
  function checkCommand(cmd) {
10
9
  try {
11
- const version = execSync(`${cmd} --version 2>&1 || ${cmd} -v 2>&1`, {
10
+ const result = Bun.spawnSync([cmd, "--version"], {
12
11
  timeout: 5000,
13
- stdio: "pipe"
14
- }).toString().trim().split(`
12
+ stdout: "pipe",
13
+ stderr: "pipe"
14
+ });
15
+ if (result.exitCode === 0) {
16
+ const version = result.stdout.toString().trim().split(`
17
+ `)[0];
18
+ return { installed: true, version };
19
+ }
20
+ const result2 = Bun.spawnSync([cmd, "-v"], {
21
+ timeout: 5000,
22
+ stdout: "pipe",
23
+ stderr: "pipe"
24
+ });
25
+ if (result2.exitCode === 0) {
26
+ const version = result2.stdout.toString().trim().split(`
15
27
  `)[0];
16
- return { installed: true, version };
28
+ return { installed: true, version };
29
+ }
30
+ return { installed: false };
17
31
  } catch {
18
32
  return { installed: false };
19
33
  }
@@ -83,15 +97,27 @@ async function installDependencies(deps) {
83
97
  }
84
98
  async function installTmux(platform) {
85
99
  if (platform === "darwin") {
86
- execSync("brew install tmux", { timeout: 120000, stdio: "pipe" });
100
+ const r = Bun.spawnSync(["brew", "install", "tmux"], {
101
+ timeout: 120000,
102
+ stdout: "pipe",
103
+ stderr: "pipe"
104
+ });
105
+ if (r.exitCode !== 0)
106
+ throw new Error(r.stderr.toString());
87
107
  } else if (platform === "linux") {
88
- try {
89
- execSync("sudo apt-get install -y tmux", {
108
+ const apt = Bun.spawnSync(["sudo", "apt-get", "install", "-y", "tmux"], {
109
+ timeout: 120000,
110
+ stdout: "pipe",
111
+ stderr: "pipe"
112
+ });
113
+ if (apt.exitCode !== 0) {
114
+ const yum = Bun.spawnSync(["sudo", "yum", "install", "-y", "tmux"], {
90
115
  timeout: 120000,
91
- stdio: "pipe"
116
+ stdout: "pipe",
117
+ stderr: "pipe"
92
118
  });
93
- } catch {
94
- execSync("sudo yum install -y tmux", { timeout: 120000, stdio: "pipe" });
119
+ if (yum.exitCode !== 0)
120
+ throw new Error(yum.stderr.toString());
95
121
  }
96
122
  } else {
97
123
  throw new Error(`Unsupported platform for tmux: ${platform}`);
@@ -99,16 +125,24 @@ async function installTmux(platform) {
99
125
  }
100
126
  async function installTtyd(platform) {
101
127
  if (platform === "darwin") {
102
- execSync("brew install ttyd", { timeout: 120000, stdio: "pipe" });
128
+ const r = Bun.spawnSync(["brew", "install", "ttyd"], {
129
+ timeout: 120000,
130
+ stdout: "pipe",
131
+ stderr: "pipe"
132
+ });
133
+ if (r.exitCode !== 0)
134
+ throw new Error(r.stderr.toString());
103
135
  } else if (platform === "linux") {
104
- try {
105
- execSync("sudo snap install ttyd --classic", {
106
- timeout: 120000,
107
- stdio: "pipe"
108
- });
109
- } catch {
136
+ const snap = Bun.spawnSync(["sudo", "snap", "install", "ttyd", "--classic"], { timeout: 120000, stdout: "pipe", stderr: "pipe" });
137
+ if (snap.exitCode !== 0) {
110
138
  const arch = os.arch() === "x64" ? "x86_64" : os.arch();
111
- execSync(`curl -sLo /tmp/ttyd https://github.com/tsl0922/ttyd/releases/latest/download/ttyd.${arch} && sudo install /tmp/ttyd /usr/local/bin/ttyd`, { timeout: 120000, stdio: "pipe" });
139
+ const curl = Bun.spawnSync([
140
+ "sh",
141
+ "-c",
142
+ `curl -sLo /tmp/ttyd https://github.com/tsl0922/ttyd/releases/latest/download/ttyd.${arch} && sudo install /tmp/ttyd /usr/local/bin/ttyd`
143
+ ], { timeout: 120000, stdout: "pipe", stderr: "pipe" });
144
+ if (curl.exitCode !== 0)
145
+ throw new Error(curl.stderr.toString());
112
146
  }
113
147
  } else {
114
148
  throw new Error(`Unsupported platform for ttyd: ${platform}`);
@@ -116,7 +150,13 @@ async function installTtyd(platform) {
116
150
  }
117
151
  async function installCloudflared(platform) {
118
152
  if (platform === "darwin") {
119
- execSync("brew install cloudflared", { timeout: 120000, stdio: "pipe" });
153
+ const r = Bun.spawnSync(["brew", "install", "cloudflared"], {
154
+ timeout: 120000,
155
+ stdout: "pipe",
156
+ stderr: "pipe"
157
+ });
158
+ if (r.exitCode !== 0)
159
+ throw new Error(r.stderr.toString());
120
160
  } else if (platform === "linux") {
121
161
  const arch = os.arch();
122
162
  let archStr = "amd64";
@@ -124,15 +164,19 @@ async function installCloudflared(platform) {
124
164
  archStr = "arm64";
125
165
  else if (arch === "arm")
126
166
  archStr = "arm";
127
- execSync(`curl -sLo /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${archStr} && sudo install /tmp/cloudflared /usr/local/bin/cloudflared`, { timeout: 120000, stdio: "pipe" });
167
+ const r = Bun.spawnSync([
168
+ "sh",
169
+ "-c",
170
+ `curl -sLo /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-${archStr} && sudo install /tmp/cloudflared /usr/local/bin/cloudflared`
171
+ ], { timeout: 120000, stdout: "pipe", stderr: "pipe" });
172
+ if (r.exitCode !== 0)
173
+ throw new Error(r.stderr.toString());
128
174
  } else {
129
175
  throw new Error(`Unsupported platform for cloudflared: ${platform}`);
130
176
  }
131
177
  }
132
178
 
133
179
  // src/services/service-manager.ts
134
- import { spawn } from "child_process";
135
- import { promisify } from "util";
136
180
  import {
137
181
  existsSync,
138
182
  readFileSync,
@@ -141,13 +185,8 @@ import {
141
185
  openSync,
142
186
  closeSync
143
187
  } from "fs";
144
- import { join, dirname } from "path";
145
- import { fileURLToPath } from "url";
188
+ import { join } from "path";
146
189
  import { homedir } from "os";
147
- import { exec } from "child_process";
148
- var execAsync = promisify(exec);
149
- var __filename2 = fileURLToPath(import.meta.url);
150
- var __dirname2 = dirname(__filename2);
151
190
 
152
191
  class ServiceManager {
153
192
  registryPath;
@@ -167,10 +206,11 @@ class ServiceManager {
167
206
  }
168
207
  const logFile = join(this.logsDir, `${config.name}.log`);
169
208
  const logFd = openSync(logFile, "a");
170
- const indexPath = join(__dirname2, "..", "index.js");
171
- const child = spawn("bun", ["run", indexPath], {
172
- detached: true,
173
- stdio: ["ignore", logFd, logFd],
209
+ const indexPath = join(import.meta.dir, "..", "index.js");
210
+ const child = Bun.spawn(["bun", "run", indexPath], {
211
+ stdin: "ignore",
212
+ stdout: logFd,
213
+ stderr: logFd,
174
214
  env: {
175
215
  ...process.env,
176
216
  PORT: config.port.toString(),
@@ -179,7 +219,6 @@ class ServiceManager {
179
219
  }
180
220
  });
181
221
  closeSync(logFd);
182
- child.unref();
183
222
  await new Promise((resolve) => setTimeout(resolve, 2000));
184
223
  const isRunning = await this.isProcessRunning(child.pid);
185
224
  if (!isRunning) {
@@ -250,22 +289,25 @@ class ServiceManager {
250
289
  return;
251
290
  }
252
291
  if (options.follow) {
253
- const tail = spawn("tail", [
254
- "-f",
255
- "-n",
256
- options.tail.toString(),
257
- logFile
258
- ]);
259
- tail.stdout?.on("data", (data) => process.stdout.write(data));
260
- tail.stderr?.on("data", (data) => process.stderr.write(data));
292
+ const tail = Bun.spawn(["tail", "-f", "-n", options.tail.toString(), logFile], { stdout: "pipe", stderr: "pipe" });
293
+ (async () => {
294
+ for await (const chunk of tail.stdout) {
295
+ process.stdout.write(chunk);
296
+ }
297
+ })();
298
+ (async () => {
299
+ for await (const chunk of tail.stderr) {
300
+ process.stderr.write(chunk);
301
+ }
302
+ })();
261
303
  process.on("SIGINT", () => {
262
304
  tail.kill();
263
305
  process.exit(0);
264
306
  });
265
307
  } else {
266
308
  try {
267
- const { stdout } = await execAsync(`tail -n ${options.tail} "${logFile}"`);
268
- console.log(stdout);
309
+ const proc = Bun.spawnSync(["tail", "-n", options.tail.toString(), logFile], { stdout: "pipe", stderr: "pipe" });
310
+ console.log(proc.stdout.toString());
269
311
  } catch (err) {
270
312
  console.error("Failed to read logs:", err);
271
313
  }
@@ -369,5 +411,5 @@ class ServiceManager {
369
411
 
370
412
  export { checkDependencies, installDependencies, ServiceManager };
371
413
 
372
- //# debugId=1F2B497AC857BCC064756E2164756E21
373
- //# sourceMappingURL=index-3v78e2cn.js.map
414
+ //# debugId=6E0629A41BAEEB3564756E2164756E21
415
+ //# sourceMappingURL=index-s7ff1fj1.js.map
@@ -0,0 +1,11 @@
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 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 result = Bun.spawnSync([cmd, \"--version\"], {\n timeout: 5000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (result.exitCode === 0) {\n const version = result.stdout.toString().trim().split(\"\\n\")[0];\n return { installed: true, version };\n }\n // Try -v fallback\n const result2 = Bun.spawnSync([cmd, \"-v\"], {\n timeout: 5000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (result2.exitCode === 0) {\n const version = result2.stdout.toString().trim().split(\"\\n\")[0];\n return { installed: true, version };\n }\n return { installed: false };\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 const r = Bun.spawnSync([\"brew\", \"install\", \"tmux\"], {\n timeout: 120_000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (r.exitCode !== 0) throw new Error(r.stderr.toString());\n } else if (platform === \"linux\") {\n const apt = Bun.spawnSync([\"sudo\", \"apt-get\", \"install\", \"-y\", \"tmux\"], {\n timeout: 120_000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (apt.exitCode !== 0) {\n const yum = Bun.spawnSync([\"sudo\", \"yum\", \"install\", \"-y\", \"tmux\"], {\n timeout: 120_000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (yum.exitCode !== 0) throw new Error(yum.stderr.toString());\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 const r = Bun.spawnSync([\"brew\", \"install\", \"ttyd\"], {\n timeout: 120_000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (r.exitCode !== 0) throw new Error(r.stderr.toString());\n } else if (platform === \"linux\") {\n const snap = Bun.spawnSync(\n [\"sudo\", \"snap\", \"install\", \"ttyd\", \"--classic\"],\n { timeout: 120_000, stdout: \"pipe\", stderr: \"pipe\" },\n );\n if (snap.exitCode !== 0) {\n // Try direct download\n const arch = os.arch() === \"x64\" ? \"x86_64\" : os.arch();\n const curl = Bun.spawnSync(\n [\n \"sh\",\n \"-c\",\n `curl -sLo /tmp/ttyd https://github.com/tsl0922/ttyd/releases/latest/download/ttyd.${arch} && sudo install /tmp/ttyd /usr/local/bin/ttyd`,\n ],\n { timeout: 120_000, stdout: \"pipe\", stderr: \"pipe\" },\n );\n if (curl.exitCode !== 0) throw new Error(curl.stderr.toString());\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 const r = Bun.spawnSync([\"brew\", \"install\", \"cloudflared\"], {\n timeout: 120_000,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n if (r.exitCode !== 0) throw new Error(r.stderr.toString());\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 const r = Bun.spawnSync(\n [\n \"sh\",\n \"-c\",\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 ],\n { timeout: 120_000, stdout: \"pipe\", stderr: \"pipe\" },\n );\n if (r.exitCode !== 0) throw new Error(r.stderr.toString());\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 {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n openSync,\n closeSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nimport type { AgentConfig } from \"./agent.service.js\";\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(import.meta.dir, \"..\", \"index.js\");\n const child = Bun.spawn([\"bun\", \"run\", indexPath], {\n stdin: \"ignore\",\n stdout: logFd,\n stderr: 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\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 = Bun.spawn(\n [\"tail\", \"-f\", \"-n\", options.tail.toString(), logFile],\n { stdout: \"pipe\", stderr: \"pipe\" },\n );\n\n // Pipe stdout and stderr to process\n (async () => {\n for await (const chunk of tail.stdout as ReadableStream) {\n process.stdout.write(chunk);\n }\n })();\n (async () => {\n for await (const chunk of tail.stderr as ReadableStream) {\n process.stderr.write(chunk);\n }\n })();\n\n process.on(\"SIGINT\", () => {\n tail.kill();\n process.exit(0);\n });\n } else {\n try {\n const proc = Bun.spawnSync(\n [\"tail\", \"-n\", options.tail.toString(), logFile],\n { stdout: \"pipe\", stderr: \"pipe\" },\n );\n console.log(proc.stdout.toString());\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": "6E0629A41BAEEB3564756E2164756E21",
10
+ "names": []
11
+ }
@@ -6,7 +6,7 @@ import {
6
6
  ServiceManager,
7
7
  checkDependencies,
8
8
  installDependencies
9
- } from "./index-3v78e2cn.js";
9
+ } from "./index-s7ff1fj1.js";
10
10
  import"./index-88ym10cs.js";
11
11
  import {
12
12
  Elysia,
@@ -34,18 +34,20 @@ import"./index-g8dczzvv.js";
34
34
 
35
35
  // src/plugins/agent/routes.ts
36
36
  import os from "os";
37
- import crypto from "crypto";
37
+ import { join } from "path";
38
38
  import { readFileSync } from "fs";
39
39
  function getMachineId() {
40
40
  const hostname = os.hostname();
41
41
  const platform = os.platform();
42
42
  const arch = os.arch();
43
- return crypto.createHash("sha256").update(`${hostname}-${platform}-${arch}`).digest("hex").substring(0, 16);
43
+ const hasher = new Bun.CryptoHasher("sha256");
44
+ hasher.update(`${hostname}-${platform}-${arch}`);
45
+ return hasher.digest("hex").substring(0, 16);
44
46
  }
45
47
  function getAgentVersion() {
46
48
  try {
47
- const pkgPath = new URL("../../../package.json", import.meta.url);
48
- const pkg = JSON.parse(readFileSync(new URL(pkgPath), "utf8"));
49
+ const pkgPath = join(import.meta.dir, "..", "..", "package.json");
50
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
49
51
  return pkg.version || "0.0.0";
50
52
  } catch {
51
53
  return "0.0.0";
@@ -62,8 +64,8 @@ function createRoutes(deps) {
62
64
  arch: os.arch(),
63
65
  version,
64
66
  uptime: process.uptime()
65
- })).get("/api-key", ({ store }) => ({
66
- apiKey: store.apiKey ?? "unknown"
67
+ })).get("/api-key", (ctx) => ({
68
+ apiKey: ctx.apiKey ?? ctx.store.apiKey ?? "unknown"
67
69
  })).get("/tunnel", async () => {
68
70
  const tunnelProvider = serviceRegistry.getProvider("tunnel");
69
71
  if (!tunnelProvider) {
@@ -509,5 +511,5 @@ export {
509
511
  vibePlugin
510
512
  };
511
513
 
512
- //# debugId=05E8A24F9D5A583B64756E2164756E21
513
- //# sourceMappingURL=index-9tgyd3ep.js.map
514
+ //# debugId=9AE6B13FD3CF2B6664756E2164756E21
515
+ //# sourceMappingURL=index-wjsms9jw.js.map