@johpaz/hive 2.0.1 → 2.0.3

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 (3) hide show
  1. package/README.md +16 -16
  2. package/dist/hive.js +457 -205
  3. package/package.json +1 -1
package/dist/hive.js CHANGED
@@ -16589,6 +16589,7 @@ function ensureSchemaSync() {
16589
16589
  if (_db) {
16590
16590
  _db.query(`UPDATE providers SET base_url = 'https://api.groq.com/openai/v1' WHERE id = 'groq' AND base_url = 'https://api.groq.com/v1'`).run();
16591
16591
  _db.query(`UPDATE providers SET base_url = 'https://api.openai.com/v1' WHERE id = 'openai' AND base_url = 'https://api.openai.com'`).run();
16592
+ _db.query(`UPDATE providers SET base_url = NULL WHERE id = 'gemini' AND base_url = 'https://generativelanguage.googleapis.com/v1beta'`).run();
16592
16593
  }
16593
16594
  }
16594
16595
 
@@ -19741,6 +19742,11 @@ function seedAllData() {
19741
19742
  `).run(provider.id, provider.name, provider.baseUrl || null, provider.category || "llm");
19742
19743
  providerCount++;
19743
19744
  }
19745
+ const ollamaHost = process.env.OLLAMA_HOST;
19746
+ if (ollamaHost) {
19747
+ db.query(`UPDATE providers SET base_url = ? WHERE id = 'ollama'`).run(ollamaHost);
19748
+ log.info(`[seed] \u2705 Ollama base_url set to ${ollamaHost} (from OLLAMA_HOST env)`);
19749
+ }
19744
19750
  log.info(`[seed] \u2705 ${providerCount} providers procesados`);
19745
19751
  let modelCount = 0;
19746
19752
  for (const model of SEED_DATA.models) {
@@ -19899,7 +19905,7 @@ var init_seed = __esm(() => {
19899
19905
  providers: [
19900
19906
  { id: "anthropic", name: "Anthropic", baseUrl: "https://api.anthropic.com" },
19901
19907
  { id: "openai", name: "OpenAI", baseUrl: "https://api.openai.com/v1" },
19902
- { id: "gemini", name: "Google Gemini", baseUrl: "https://generativelanguage.googleapis.com/v1beta" },
19908
+ { id: "gemini", name: "Google Gemini" },
19903
19909
  { id: "mistral", name: "Mistral AI", baseUrl: "https://api.mistral.ai/v1" },
19904
19910
  { id: "deepseek", name: "DeepSeek", baseUrl: "https://api.deepseek.com/v1" },
19905
19911
  { id: "kimi", name: "Kimi (Moonshot)", baseUrl: "https://api.moonshot.ai/v1" },
@@ -20711,7 +20717,7 @@ Las 52 herramientas nativas se cargan din\xE1micamente desde la base de datos.
20711
20717
  | \u23F0 CRON | 4 | cron_add, cron_list, cron_edit, cron_remove |
20712
20718
  | \uD83D\uDCBB CLI | 1 | cli_exec |
20713
20719
  | \uD83E\uDDE0 AGENTS | 14 | memory_*, agent_*, task_delegate, bus_*, project_updates |
20714
- | \uD83C\uDFA8 CANVAS | 7 | canvas_show_card, canvas_show_progress, canvas_ask, canvas_confirm |
20720
+ | \uD83C\uDFA8 CANVAS | 7 | canvas_render(chart/table/form/button/alert-dialog/markdown/...), canvas_ask, canvas_confirm, canvas_show_card, canvas_show_progress |
20715
20721
  | \uD83C\uDF09 CODEBRIDGE | 3 | codebridge_launch, codebridge_status, codebridge_cancel |
20716
20722
  | \uD83C\uDF99\uFE0F VOICE | 2 | voice_transcribe, voice_speak |
20717
20723
  | \uD83D\uDD14 CORE | 4 | search_knowledge, notify, save_note, report_progress |
@@ -22417,7 +22423,7 @@ function emitCanvas(type2, data) {
22417
22423
  }
22418
22424
  function getCanvasSnapshot() {
22419
22425
  const db = getDb();
22420
- const agentNodes = db.query("SELECT id, name, description, status FROM agents").all().map((a) => {
22426
+ const agentNodes = db.query("SELECT id, name, description, role, status FROM agents").all().map((a) => {
22421
22427
  const live = agentLiveState.get(a.id);
22422
22428
  return {
22423
22429
  id: a.id,
@@ -22425,7 +22431,7 @@ function getCanvasSnapshot() {
22425
22431
  description: a.description,
22426
22432
  status: live?.status ?? a.status,
22427
22433
  type: "agent",
22428
- data: { currentTool: live?.currentTool ?? null }
22434
+ data: { role: a.role, currentTool: live?.currentTool ?? null }
22429
22435
  };
22430
22436
  });
22431
22437
  const mcpNodes = db.query("SELECT id, name, status FROM mcp_servers WHERE enabled = 1").all().map((m) => ({
@@ -55275,7 +55281,7 @@ class OllamaProvider {
55275
55281
  async call(options2) {
55276
55282
  const { Ollama: Ollama3 } = await Promise.resolve().then(() => (init_dist3(), exports_dist2));
55277
55283
  const modelName = options2.model.replace(/^ollama\//, "");
55278
- const host = options2.baseUrl?.trim() || "http://localhost:11434";
55284
+ const host = options2.baseUrl?.trim() || process.env.OLLAMA_HOST || "http://localhost:11434";
55279
55285
  try {
55280
55286
  const isCloud = host.includes("ollama.com");
55281
55287
  const headers = {};
@@ -313669,6 +313675,7 @@ class BrowserService {
313669
313675
  const puppeteer3 = await Promise.resolve().then(() => (init_puppeteer2(), exports_puppeteer2));
313670
313676
  this.browser = await puppeteer3.launch({
313671
313677
  headless: true,
313678
+ executablePath: process.env.PUPPETEER_EXECUTABLE_PATH,
313672
313679
  args: [
313673
313680
  "--no-sandbox",
313674
313681
  "--disable-setuid-sandbox",
@@ -317924,12 +317931,12 @@ var init_canvas = __esm(() => {
317924
317931
  log57 = logger.child("canvas");
317925
317932
  canvasRenderTool = {
317926
317933
  name: "canvas_render",
317927
- description: "Render a component or visualization on the canvas. Spanish: renderizar, visualizar, gr\xE1fico, diagrama",
317934
+ description: "Render a component or visualization on the canvas. Use specific types instead of always using card+markdown. Key types: chart (bar/line/area/pie graphs), table (tabular data), markdown (rich text), form (interactive form - waits for submit), button (interactive button), alert-dialog (confirm/cancel dialog), progress (progress bars), accordion, tabs, badge, card, bee-loader. Spanish: renderizar, visualizar, gr\xE1fico, diagrama, tabla, formulario",
317928
317935
  parameters: {
317929
317936
  type: "object",
317930
317937
  properties: {
317931
- component: { type: "string", description: "Component type to render. Available: alert, alert-dialog, accordion, avatar, badge, breadcrumb, button, calendar, card, carousel, chart, checkbox, collapsible, command, context-menu, dialog, drawer, dropdown-menu, form, input, input-otp, label, markdown, menubar, navigation-menu, pagination, popover, progress, radio-group, resizable, scroll-area, select, separator, sheet, skeleton, slider, switch, table, tabs, textarea, toggle, toggle-group, tooltip, aspect-ratio, hover-card, bee-loader, custom" },
317932
- data: { type: "object", description: "Data to pass to the component" }
317938
+ component: { type: "string", description: "Component type. Visualization: chart, table, markdown, card, progress, accordion, tabs, badge, separator, bee-loader. Interactive: form, button, alert-dialog. Layout: carousel, collapsible, resizable, scroll-area, tabs. Other: alert, avatar, breadcrumb, calendar, checkbox, dialog, drawer, dropdown-menu, hover-card, input, input-otp, label, menubar, navigation-menu, pagination, popover, radio-group, select, sheet, skeleton, slider, switch, textarea, toggle, toggle-group, tooltip, aspect-ratio, command, context-menu, custom" },
317939
+ data: { type: "object", description: "Props for the component. chart: {type:'bar'|'line'|'area'|'pie', data:[{name,...}], xKey:'name', keys:['value'], title}. table: {title, columns:[{header,key}], data:[{}]}. form: {title, fields:[{name,label,type:'text'|'email'|'number'|'textarea'|'select'|'checkbox',placeholder,options:[{value,label}]}], submitLabel}. alert-dialog: {title, description, confirmLabel, cancelLabel}. button: {label, variant:'default'|'outline'|'secondary'|'destructive'}. markdown: {content}. progress: {value:0-100}." }
317933
317940
  },
317934
317941
  required: ["component", "data"]
317935
317942
  },
@@ -318949,11 +318956,68 @@ ${scratchpadContent}
318949
318956
  ` + `- Playbook (buenas pr\xE1cticas): type="playbook"
318950
318957
  ` + `- Herramientas nativas espec\xEDficas: type="tools"
318951
318958
  ` + `Las herramientas MCP ya est\xE1n disponibles - no necesitas buscarlas.
318959
+ ` + `
318960
+ ## REGLA CR\xCDTICA \u2014 Delegaci\xF3n a workers
318961
+ ` + `Los workers arrancan con herramientas m\xEDnimas (save_note, notify, report_progress, search_knowledge).
318962
+ ` + `**ANTES de crear o delegar a un worker**, SIEMPRE debes:
318963
+ ` + `1. Usar \`search_knowledge(type="tools", query="<tarea del worker>")\` para identificar qu\xE9 herramientas necesita.
318964
+ ` + `2. Incluir esas herramientas en el campo \`tools\` al crear el agente con \`create_agent\`, o
318965
+ ` + ` en el campo \`task_description\` de \`task_delegate\` como instrucci\xF3n expl\xEDcita:
318966
+ ` + ` "Usa las herramientas: web_search, fs_read, ... para completar esta tarea."
318967
+ ` + `3. El worker con esa instrucci\xF3n usar\xE1 \`search_knowledge\` para activar las tools por nombre.
318968
+ ` + `Ejemplo: si el worker debe investigar en internet \u2192 busca "web search herramienta internet" \u2192 obtienes "web_search" \u2192 dile al worker que use web_search.
318969
+ `;
318970
+ systemPrompt += `
318971
+
318972
+ # \uD83C\uDFA8 CANVAS A2UI \u2014 Componentes disponibles para \`canvas_render\`
318973
+ ` + `**REGLA**: Us\xE1 \`canvas_render\` con el tipo espec\xEDfico en vez de siempre usar \`canvas_show_card\` + markdown.
318974
+
318975
+ ` + `## Tipos de visualizaci\xF3n:
318976
+ ` + `- **chart** \u2014 Gr\xE1ficos. Props: \`{type:"bar"|"line"|"area"|"pie", data:[{name,...}], xKey:"name", keys:["valor"], colors:[], title}\`
318977
+ ` + `- **table** \u2014 Tablas de datos. Props: \`{title, columns:[{header,key}], data:[{...}]}\`
318978
+ ` + `- **progress** \u2014 Barras de progreso. Props: \`{bars:[{label,value:0-100}]}\`
318979
+ ` + `- **markdown** \u2014 Texto rich. Props: \`{content:"## t\xEDtulo\\n..."}\`
318980
+ ` + `- **card** \u2014 Tarjeta con items. Props: \`{title, description, items:[{label,value}], footer}\`
318981
+ ` + `- **accordion** \u2014 Secciones colapsables. Props: \`{items:[{value,title,content}]}\`
318982
+ ` + `- **tabs** \u2014 Pesta\xF1as. Props: \`{tabs:[{value,label,content}]}\`
318983
+ ` + `- **badge** \u2014 Etiqueta. Props: \`{label, variant:"default"|"secondary"|"destructive"|"outline"}\`
318984
+ ` + `- **separator** \u2014 L\xEDnea divisora
318985
+ ` + `- **bee-loader** \u2014 Animaci\xF3n de carga. Props: \`{message}\`
318986
+
318987
+ ` + `## Tipos interactivos (bloquean hasta respuesta del usuario):
318988
+ ` + `- **form** \u2014 Formulario. Props: \`{title, fields:[{name,label,type,placeholder,options}], submitLabel}\`
318989
+ ` + ` \u2192 Tipos de campo: \`text\`, \`email\`, \`number\`, \`textarea\`, \`select\`, \`checkbox\`
318990
+ ` + ` \u2192 Al Submit recibir\xE1s: \`{data:{campo:valor,...}}\`
318991
+ ` + `- **button** \u2014 Bot\xF3n clickeable. Props: \`{label, variant:"default"|"outline"|"secondary"|"destructive"}\`
318992
+ ` + ` \u2192 Al click recibir\xE1s: \`{action:"click", data:{label}}\`
318993
+ ` + `- **alert-dialog** \u2014 Confirmaci\xF3n. Props: \`{title, description, confirmLabel, cancelLabel}\`
318994
+ ` + ` \u2192 Al confirmar recibir\xE1s: \`{data:{confirmed:true|false}}\`
318995
+
318996
+ ` + `## Cu\xE1ndo usar cada uno:
318997
+ ` + `- Estad\xEDsticas/datos num\xE9ricos \u2192 **chart** (bar/line/pie)
318998
+ ` + `- Listas de filas/columnas \u2192 **table**
318999
+ ` + `- Texto largo / an\xE1lisis \u2192 **markdown**
319000
+ ` + `- Pedir datos al usuario \u2192 **canvas_ask** o **canvas_render con form**
319001
+ ` + `- Confirmar acci\xF3n peligrosa \u2192 **canvas_confirm** o **canvas_render con alert-dialog**
319002
+ ` + `- Mostrar progreso de tarea \u2192 **canvas_show_progress**
319003
+
319004
+ ` + `## Ejemplos:
319005
+ ` + `\`\`\`
319006
+ ` + `canvas_render(component:"chart", data:{type:"bar", data:[{mes:"Ene",ventas:1200},{mes:"Feb",ventas:1800}], xKey:"mes", keys:["ventas"], title:"Ventas por mes"})
319007
+ ` + `canvas_render(component:"table", data:{title:"Archivos", columns:[{header:"Nombre",key:"name"},{header:"Tama\xF1o",key:"size"}], data:[{name:"app.ts",size:"12KB"}]})
319008
+ ` + `canvas_render(component:"form", data:{title:"Configuraci\xF3n", fields:[{name:"nombre",label:"Nombre",type:"text"},{name:"tipo",label:"Tipo",type:"select",options:[{value:"a",label:"A"},{value:"b",label:"B"}]}], submitLabel:"Guardar"})
319009
+ ` + `\`\`\`
318952
319010
  `;
318953
319011
  }
318954
319012
  if (isWorker && opts.taskContext) {
318955
319013
  systemPrompt += `
318956
319014
 
319015
+ # HERRAMIENTAS DISPONIBLES
319016
+ ` + `Arrancas con herramientas b\xE1sicas. Si tu tarea requiere herramientas adicionales (web_search, fs_read, browser_navigate, etc.):
319017
+ ` + `1. Us\xE1 \`search_knowledge(type="tools", query="<herramienta o tarea>")\` para encontrarlas.
319018
+ ` + `2. Las herramientas que encuentres estar\xE1n disponibles para usar inmediatamente.
319019
+ ` + `Si el coordinador te indic\xF3 herramientas espec\xEDficas, buscalas primero con search_knowledge antes de ejecutar tu tarea.
319020
+ ` + `
318957
319021
  # CURRENT TASK
318958
319022
  ${opts.taskContext}
318959
319023
 
@@ -555613,7 +555677,7 @@ var init_initializer = __esm(() => {
555613
555677
  });
555614
555678
 
555615
555679
  // packages/core/src/gateway/routes/setup.ts
555616
- import { randomUUID as randomUUID2 } from "crypto";
555680
+ import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync9 } from "fs";
555617
555681
  function isSetupMode() {
555618
555682
  try {
555619
555683
  const count = getDb().query("SELECT COUNT(*) as count FROM users").get().count;
@@ -555679,18 +555743,19 @@ async function handleVerifyProvider(req) {
555679
555743
  let headers = {};
555680
555744
  const testMessages = [{ role: "user", content: "Say 'ok' if you can read this." }];
555681
555745
  if (provider === "ollama") {
555746
+ const ollamaUrl = process.env.OLLAMA_HOST || "http://localhost:11434";
555682
555747
  try {
555683
- const response2 = await fetch("http://localhost:11434/api/tags", {
555748
+ const response2 = await fetch(`${ollamaUrl}/api/tags`, {
555684
555749
  signal: AbortSignal.timeout(5000)
555685
555750
  });
555686
555751
  return Response.json({
555687
555752
  success: response2.ok,
555688
- error: response2.ok ? null : "Could not connect to Ollama"
555753
+ error: response2.ok ? null : `Could not connect to Ollama at ${ollamaUrl}`
555689
555754
  });
555690
555755
  } catch {
555691
555756
  return Response.json({
555692
555757
  success: false,
555693
- error: "Could not connect to Ollama at http://localhost:11434"
555758
+ error: `Could not connect to Ollama at ${ollamaUrl}`
555694
555759
  });
555695
555760
  }
555696
555761
  }
@@ -555813,21 +555878,20 @@ async function handleCompleteSetup(req, config3, addCorsHeaders) {
555813
555878
  const body = await req.json().catch(() => ({}));
555814
555879
  try {
555815
555880
  initOnboardingDb();
555816
- const userId = `user_${randomUUID2().split("-")[0]}`;
555817
- const agentId = `agent_${randomUUID2().split("-")[0]}`;
555818
- const channelUserId = randomUUID2();
555819
- saveUserProfile({
555820
- userId,
555881
+ const userId = saveUserProfile({
555821
555882
  userName: body.userName || "User",
555822
555883
  userLanguage: body.userLanguage || "es",
555823
555884
  userTimezone: body.userTimezone || "UTC",
555824
555885
  userOccupation: body.userOccupation || "",
555825
- userNotes: body.userNotes || "",
555886
+ userNotes: body.userNotes || ""
555887
+ });
555888
+ const agentId = saveAgentConfig({
555889
+ userId,
555826
555890
  agentName: body.agentName || "Bee",
555827
- agentId,
555828
- agentDescription: body.agentDescription || "",
555829
- agentTone: "friendly",
555830
- channelUserId
555891
+ description: body.agentDescription || "",
555892
+ tone: "friendly",
555893
+ providerId: body.provider || "",
555894
+ modelId: body.model || ""
555831
555895
  });
555832
555896
  if (body.provider && body.apiKey) {
555833
555897
  await saveProviderConfig({
@@ -555839,7 +555903,6 @@ async function handleCompleteSetup(req, config3, addCorsHeaders) {
555839
555903
  }
555840
555904
  await activateChannel(userId, {
555841
555905
  channelId: "webchat",
555842
- channelUserId,
555843
555906
  config: {}
555844
555907
  });
555845
555908
  if (body.channels) {
@@ -555869,7 +555932,19 @@ async function handleCompleteSetup(req, config3, addCorsHeaders) {
555869
555932
  } else {
555870
555933
  activateEthics(userId, "default");
555871
555934
  }
555872
- const authToken = randomUUID2().replace(/-/g, "");
555935
+ const authToken = userId;
555936
+ const hiveDir = getHiveDir();
555937
+ const envContent = [
555938
+ "# Hive configuration \u2014 auto-generated during setup",
555939
+ `HIVE_HOST=${process.env.HIVE_HOST || "0.0.0.0"}`,
555940
+ `HIVE_PORT=${process.env.HIVE_PORT || "18790"}`,
555941
+ `HIVE_LOG_LEVEL=${process.env.HIVE_LOG_LEVEL || "info"}`,
555942
+ `HIVE_AUTH_TOKEN=${authToken}`,
555943
+ ""
555944
+ ].join(`
555945
+ `);
555946
+ mkdirSync9(hiveDir, { recursive: true });
555947
+ writeFileSync4(`${hiveDir}/.env`, envContent, { mode: 384 });
555873
555948
  process.env.HIVE_AUTH_TOKEN = authToken;
555874
555949
  setTimeout(() => process.exit(0), 800);
555875
555950
  return addCorsHeaders(Response.json({
@@ -555890,6 +555965,7 @@ var init_setup = __esm(() => {
555890
555965
  init_sqlite();
555891
555966
  init_seed();
555892
555967
  init_onboarding();
555968
+ init_loader();
555893
555969
  });
555894
555970
 
555895
555971
  // packages/core/src/gateway/routes/agents.ts
@@ -556159,7 +556235,7 @@ async function handleSyncProviderModels(req, addCorsHeaders, providerId) {
556159
556235
  if (!providerRow) {
556160
556236
  return addCorsHeaders(new Response("Provider not found", { status: 404 }), req);
556161
556237
  }
556162
- const baseUrl = (providerRow.base_url || "http://localhost:11434").replace(/\/(v1|api)\/?$/, "");
556238
+ const baseUrl = (providerRow.base_url || process.env.OLLAMA_HOST || "http://localhost:11434").replace(/\/(v1|api)\/?$/, "");
556163
556239
  try {
556164
556240
  const res = await fetch(`${baseUrl}/api/tags`);
556165
556241
  if (!res.ok) {
@@ -556382,8 +556458,8 @@ async function handleCreateSkill(req, addCorsHeaders) {
556382
556458
  if (!name) {
556383
556459
  return addCorsHeaders(new Response("Missing name", { status: 400 }), req);
556384
556460
  }
556385
- const { randomUUID: randomUUID3 } = await import("crypto");
556386
- const id = randomUUID3();
556461
+ const { randomUUID: randomUUID2 } = await import("crypto");
556462
+ const id = randomUUID2();
556387
556463
  getDb().query(`INSERT INTO skills(id, name, category, tools, triggers, body, version, active) VALUES(?, ?, ?, ?, ?, ?, 1, 1)`).run(id, name, category || "", tools || "", triggers || "", bodyContent || "", 1);
556388
556464
  return addCorsHeaders(Response.json({ success: true, id }), req);
556389
556465
  }
@@ -556739,8 +556815,8 @@ async function handleCreateChannel(req, addCorsHeaders, channelManager) {
556739
556815
  id = seeded.id;
556740
556816
  getDb().query(`UPDATE channels SET config_encrypted = ?, config_iv = ?, enabled = 1, active = 1, status = 'connecting' WHERE id = ?`).run(encryptedData, configIv, id);
556741
556817
  } else {
556742
- const { randomUUID: randomUUID3 } = await import("crypto");
556743
- id = randomUUID3();
556818
+ const { randomUUID: randomUUID2 } = await import("crypto");
556819
+ id = randomUUID2();
556744
556820
  getDb().query(`
556745
556821
  INSERT INTO channels(id, type, config_encrypted, config_iv, enabled, active, status)
556746
556822
  VALUES(?, ?, ?, ?, 1, 1, 'connecting')
@@ -557321,6 +557397,96 @@ var init_voice3 = __esm(() => {
557321
557397
  init_crypto();
557322
557398
  });
557323
557399
 
557400
+ // packages/core/package.json
557401
+ var package_default;
557402
+ var init_package = __esm(() => {
557403
+ package_default = {
557404
+ name: "@johpaz/hive-core",
557405
+ version: "2.0.3",
557406
+ private: true,
557407
+ description: "Hive Gateway \u2014 Personal AI agent runtime",
557408
+ main: "./src/index.ts",
557409
+ module: "./src/index.ts",
557410
+ types: "./src/index.ts",
557411
+ license: "MIT",
557412
+ files: [
557413
+ "src/"
557414
+ ],
557415
+ scripts: {
557416
+ test: "bun test",
557417
+ typecheck: "tsc --noEmit"
557418
+ },
557419
+ dependencies: {
557420
+ "@ag-ui/core": "^0.0.46",
557421
+ "@johpaz/hive-code-bridge": "^2.0.3",
557422
+ "@johpaz/hive-mcp": "^2.0.3",
557423
+ "@johpaz/hive-skills": "^2.0.3",
557424
+ "@modelcontextprotocol/sdk": "latest",
557425
+ "@sapphire/snowflake": "latest",
557426
+ "@slack/bolt": "latest",
557427
+ "@whiskeysockets/baileys": "latest",
557428
+ croner: "^10.0.1",
557429
+ "discord.js": "latest",
557430
+ grammy: "latest",
557431
+ "js-yaml": "latest",
557432
+ puppeteer: "^24.39.1",
557433
+ "qrcode-terminal": "latest",
557434
+ "toon-format-parser": "1.1.4",
557435
+ zod: "latest"
557436
+ },
557437
+ devDependencies: {
557438
+ typescript: "6.0.1-rc",
557439
+ "@types/bun": "latest"
557440
+ },
557441
+ exports: {
557442
+ ".": "./src/index.ts",
557443
+ "./gateway": "./src/gateway/index.ts",
557444
+ "./agent": "./src/agent/index.ts",
557445
+ "./agent/service": "./src/agent/service.ts",
557446
+ "./agent/agent-loop": "./src/agent/agent-loop.ts",
557447
+ "./agent/context-compiler": "./src/agent/context-compiler.ts",
557448
+ "./agent/prompt-builder": "./src/agent/prompt-builder.ts",
557449
+ "./agent/conversation-store": "./src/agent/conversation-store.ts",
557450
+ "./agent/tool-selector": "./src/agent/tool-selector.ts",
557451
+ "./agent/skill-selector": "./src/agent/skill-selector.ts",
557452
+ "./agent/playbook-selector": "./src/agent/playbook-selector.ts",
557453
+ "./agent/llm-client": "./src/agent/llm-client.ts",
557454
+ "./channels": "./src/channels/index.ts",
557455
+ "./channels/base": "./src/channels/base.ts",
557456
+ "./channels/manager": "./src/channels/manager.ts",
557457
+ "./channels/telegram": "./src/channels/telegram.ts",
557458
+ "./channels/discord": "./src/channels/discord.ts",
557459
+ "./channels/whatsapp": "./src/channels/whatsapp.ts",
557460
+ "./channels/slack": "./src/channels/slack.ts",
557461
+ "./channels/webchat": "./src/channels/webchat.ts",
557462
+ "./config": "./src/config/loader.ts",
557463
+ "./config/loader": "./src/config/loader.ts",
557464
+ "./utils": "./src/utils/logger.ts",
557465
+ "./utils/logger": "./src/utils/logger.ts",
557466
+ "./storage/sqlite": "./src/storage/sqlite.ts",
557467
+ "./storage/onboarding": "./src/storage/onboarding.ts",
557468
+ "./storage/crypto": "./src/storage/crypto.ts",
557469
+ "./storage/schema": "./src/storage/schema.ts",
557470
+ "./storage/seed": "./src/storage/seed.ts",
557471
+ "./tools": "./src/tools/index.ts",
557472
+ "./tools/agents": "./src/tools/agents/index.ts",
557473
+ "./tools/canvas": "./src/tools/canvas/index.ts",
557474
+ "./tools/cli": "./src/tools/cli/index.ts",
557475
+ "./tools/codebridge": "./src/tools/codebridge/index.ts",
557476
+ "./tools/core": "./src/tools/core/index.ts",
557477
+ "./tools/cron": "./src/tools/cron/index.ts",
557478
+ "./tools/filesystem": "./src/tools/filesystem/index.ts",
557479
+ "./tools/projects": "./src/tools/projects/index.ts",
557480
+ "./tools/voice": "./src/tools/voice/index.ts",
557481
+ "./tools/web": "./src/tools/web/index.ts",
557482
+ "./integrations": "./src/integrations/index.ts",
557483
+ "./integrations/catalog": "./src/integrations/catalog.ts",
557484
+ "./integrations/env": "./src/integrations/env.ts",
557485
+ "./voice": "./src/voice/index.ts"
557486
+ }
557487
+ };
557488
+ });
557489
+
557324
557490
  // packages/core/src/gateway/routes/system.ts
557325
557491
  import { cpus } from "os";
557326
557492
  function detectInstallationType() {
@@ -557664,10 +557830,12 @@ async function handleApiReload(req, addCorsHeaders, agent) {
557664
557830
  return addCorsHeaders(Response.json({ success: false, error: error50.message }, { status: 500 }), req);
557665
557831
  }
557666
557832
  }
557667
- var CURRENT_VERSION = "1.7.15";
557833
+ var CURRENT_VERSION;
557668
557834
  var init_system = __esm(() => {
557669
557835
  init_sqlite();
557670
557836
  init_loader();
557837
+ init_package();
557838
+ CURRENT_VERSION = package_default.version;
557671
557839
  });
557672
557840
 
557673
557841
  // packages/core/src/agent/providers.ts
@@ -557867,7 +558035,7 @@ async function handleGetConfig(req, addCorsHeaders, config3) {
557867
558035
  var init_config = () => {};
557868
558036
 
557869
558037
  // packages/core/src/gateway/routes/workspace.ts
557870
- import { mkdirSync as mkdirSync9, existsSync as existsSync17, accessSync as accessSync2, constants as constants2 } from "fs";
558038
+ import { mkdirSync as mkdirSync10, existsSync as existsSync17, accessSync as accessSync2, constants as constants2 } from "fs";
557871
558039
  import * as path28 from "path";
557872
558040
  import { exec as exec2 } from "child_process";
557873
558041
  import { promisify as promisify4 } from "util";
@@ -557946,7 +558114,7 @@ async function handleCreateWorkspace(req, addCorsHeaders) {
557946
558114
  error: "El path debe ser absoluto"
557947
558115
  }), req);
557948
558116
  }
557949
- mkdirSync9(workspacePath, { recursive: true });
558117
+ mkdirSync10(workspacePath, { recursive: true });
557950
558118
  return addCorsHeaders(Response.json({
557951
558119
  ok: true,
557952
558120
  path: workspacePath,
@@ -558022,7 +558190,7 @@ Define ethical guidelines here.`
558022
558190
  async function handleUpdateWorkspace(req, addCorsHeaders, workspacePath, wsType, reloadFn) {
558023
558191
  const content = await req.text();
558024
558192
  const filePath = path28.join(workspacePath, `${wsType.toUpperCase()}.md`);
558025
- mkdirSync9(workspacePath, { recursive: true });
558193
+ mkdirSync10(workspacePath, { recursive: true });
558026
558194
  await Bun.write(filePath, content);
558027
558195
  if (reloadFn) {
558028
558196
  await reloadFn(wsType);
@@ -558129,32 +558297,56 @@ var init_helpers2 = __esm(() => {
558129
558297
  init_cors();
558130
558298
  });
558131
558299
 
558300
+ // packages/core/src/tools/cron/index.ts
558301
+ function resolveBestChannel(userId, notifyChannelId) {
558302
+ if (notifyChannelId)
558303
+ return notifyChannelId;
558304
+ try {
558305
+ const db = getDb();
558306
+ const identities = db.query("SELECT channel FROM user_identities WHERE user_id = ? ORDER BY channel ASC LIMIT 5").all(userId);
558307
+ const preferred = ["telegram", "discord", "slack", "whatsapp"];
558308
+ for (const p2 of preferred) {
558309
+ if (identities.some((i2) => i2.channel === p2))
558310
+ return p2;
558311
+ }
558312
+ } catch {}
558313
+ return "webchat";
558314
+ }
558315
+ var log67, activeJobs;
558316
+ var init_cron2 = __esm(() => {
558317
+ init_sqlite();
558318
+ init_logger();
558319
+ init_croner();
558320
+ log67 = logger.child("cron");
558321
+ activeJobs = new Map;
558322
+ });
558323
+
558132
558324
  // packages/core/src/scheduler/integration.ts
558133
558325
  function setSchedulerForCleanup(scheduler) {
558134
558326
  _scheduler2 = scheduler;
558135
558327
  }
558136
558328
  async function executeScheduledTask(task) {
558137
- log67.info(`[execute] Processing task "${task.name}" (${task.id})`);
558329
+ log68.info(`[execute] Processing task "${task.name}" (${task.id})`);
558138
558330
  try {
558139
558331
  let payload;
558140
558332
  try {
558141
558333
  payload = JSON.parse(task.payload);
558142
558334
  } catch (err) {
558143
- log67.error(`[execute] Invalid payload JSON for task "${task.id}": ${err.message}`);
558335
+ log68.error(`[execute] Invalid payload JSON for task "${task.id}": ${err.message}`);
558144
558336
  return { success: false, error: "Invalid payload JSON" };
558145
558337
  }
558146
558338
  const prompt = payload.prompt || payload.message;
558147
558339
  if (!prompt && !payload._internal) {
558148
- log67.error(`[execute] Task "${task.id}" has no prompt or message in payload`);
558340
+ log68.error(`[execute] Task "${task.id}" has no prompt or message in payload`);
558149
558341
  return { success: false, error: "Missing prompt or message in payload" };
558150
558342
  }
558151
558343
  if (payload._internal === true && payload.action === "cleanup") {
558152
558344
  if (_scheduler2) {
558153
558345
  _scheduler2.runCleanup();
558154
558346
  } else {
558155
- log67.warn("[execute] Cleanup task fired but scheduler instance not available");
558347
+ log68.warn("[execute] Cleanup task fired but scheduler instance not available");
558156
558348
  }
558157
- log67.info("[execute] Cleanup task executed");
558349
+ log68.info("[execute] Cleanup task executed");
558158
558350
  return { success: true, response: "Cleanup completed" };
558159
558351
  }
558160
558352
  const metadata = {
@@ -558168,7 +558360,7 @@ async function executeScheduledTask(task) {
558168
558360
  let targetAgentId = task.agent_id || null;
558169
558361
  if (!targetAgentId) {
558170
558362
  targetAgentId = resolveAgentId(null);
558171
- log67.debug(`[execute] No agent specified, routing to Coordinator: ${targetAgentId}`);
558363
+ log68.debug(`[execute] No agent specified, routing to Coordinator: ${targetAgentId}`);
558172
558364
  }
558173
558365
  const db = getDb();
558174
558366
  const user = db.query("SELECT id, timezone, language FROM users LIMIT 1").get();
@@ -558197,16 +558389,17 @@ Type: ${task.task_type}
558197
558389
  Triggered at: ${hora_usuario} on ${fecha_usuario} (${userTimezone})
558198
558390
 
558199
558391
  ${prompt || `Execute tool: ${task.tool_name}`}`;
558200
- log67.debug(`[execute] Sending to agent ${targetAgentId}: "${contextPrompt.slice(0, 100)}..."`);
558392
+ log68.debug(`[execute] Sending to agent ${targetAgentId}: "${contextPrompt.slice(0, 100)}..."`);
558201
558393
  try {
558202
558394
  const agentLoop = buildAgentLoop({ mcpManager: undefined });
558203
558395
  const sessionId = `sched_${task.id}_${Date.now()}`;
558396
+ const agentChannel = task.channel && task.channel !== "system" ? task.channel : resolveBestChannel(user?.id || "");
558204
558397
  const messages2 = [{ role: "user", content: contextPrompt }];
558205
558398
  const stream = agentLoop.stream({ messages: messages2 }, {
558206
558399
  configurable: {
558207
558400
  thread_id: sessionId,
558208
558401
  agent_id: targetAgentId || undefined,
558209
- channel: task.channel,
558402
+ channel: agentChannel,
558210
558403
  user_id: user?.id || "",
558211
558404
  system_prompt: undefined,
558212
558405
  raw_user_message: contextPrompt
@@ -558233,20 +558426,20 @@ ${prompt || `Execute tool: ${task.tool_name}`}`;
558233
558426
  if (hasError && !response) {
558234
558427
  throw new Error("Agent execution returned errors");
558235
558428
  }
558236
- log67.info(`[execute] Agent response received for task "${task.name}"`);
558429
+ log68.info(`[execute] Agent response received for task "${task.name}"`);
558237
558430
  return {
558238
558431
  success: true,
558239
558432
  response: response || "Task executed successfully"
558240
558433
  };
558241
558434
  } catch (agentErr) {
558242
- log67.error(`[execute] Agent execution failed: ${agentErr.message}`);
558435
+ log68.error(`[execute] Agent execution failed: ${agentErr.message}`);
558243
558436
  return {
558244
558437
  success: false,
558245
558438
  error: `Agent execution failed: ${agentErr.message}`
558246
558439
  };
558247
558440
  }
558248
558441
  } catch (err) {
558249
- log67.error(`[execute] Task execution failed: ${err.message}`);
558442
+ log68.error(`[execute] Task execution failed: ${err.message}`);
558250
558443
  return {
558251
558444
  success: false,
558252
558445
  error: err.message
@@ -558257,19 +558450,20 @@ async function notifyTaskCompletion(taskId, taskName, success2, response, error5
558257
558450
  const db = getDb();
558258
558451
  const task = db.query("SELECT channel, agent_id FROM scheduled_tasks WHERE id = ?").get(taskId);
558259
558452
  if (!task) {
558260
- log67.warn(`[notify] Task "${taskId}" not found`);
558261
- return;
558262
- }
558263
- if (task.channel === "system") {
558264
- log67.debug(`[notify] Skipping notification for system channel`);
558453
+ log68.warn(`[notify] Task "${taskId}" not found`);
558265
558454
  return;
558266
558455
  }
558267
558456
  const userRow = db.query("SELECT id FROM users LIMIT 1").get();
558268
558457
  const userId = userRow?.id || "";
558269
- const identities = db.query("SELECT channel FROM user_identities WHERE user_id = ? ORDER BY channel").all(userId);
558270
- let notifyChannel = task.channel;
558271
- if (!identities.some((i2) => i2.channel === notifyChannel)) {
558272
- const preferred = ["telegram", "discord", "slack", "whatsapp", "webchat"];
558458
+ const activeChannels = db.query(`
558459
+ SELECT ui.channel FROM user_identities ui
558460
+ JOIN channels c ON c.id = ui.channel
558461
+ WHERE ui.user_id = ? AND c.active = 1 AND c.status = 'connected'
558462
+ `).all(userId);
558463
+ const identities = activeChannels.length > 0 ? activeChannels : db.query("SELECT channel FROM user_identities WHERE user_id = ?").all(userId);
558464
+ const preferred = ["telegram", "discord", "slack", "whatsapp", "webchat"];
558465
+ let notifyChannel = task.channel && task.channel !== "system" ? task.channel : "";
558466
+ if (!notifyChannel || !identities.some((i2) => i2.channel === notifyChannel)) {
558273
558467
  for (const p2 of preferred) {
558274
558468
  if (identities.some((i2) => i2.channel === p2)) {
558275
558469
  notifyChannel = p2;
@@ -558277,25 +558471,34 @@ async function notifyTaskCompletion(taskId, taskName, success2, response, error5
558277
558471
  }
558278
558472
  }
558279
558473
  }
558474
+ if (!notifyChannel || notifyChannel === "system")
558475
+ notifyChannel = "webchat";
558280
558476
  const status = success2 ? "\u2705" : "\u274C";
558281
558477
  const message = success2 ? `${status} Scheduled task "${taskName}" completed
558282
558478
  ${response || ""}` : `${status} Scheduled task "${taskName}" failed
558283
558479
  ${error50 || ""}`;
558284
- log67.info(`[notify] Sending notification to ${notifyChannel}: "${message.slice(0, 50)}..."`);
558480
+ log68.info(`[notify] Sending notification to ${notifyChannel}: "${message.slice(0, 50)}..."`);
558481
+ try {
558482
+ addMessage(userId, "assistant", message, { channel: notifyChannel });
558483
+ } catch (e) {
558484
+ log68.warn(`[notify] Failed to persist notification to DB: ${e.message}`);
558485
+ }
558285
558486
  await sendToUserChannel(notifyChannel, userId, message);
558286
- log67.info(`[notify] Notification sent to ${notifyChannel}`);
558487
+ log68.info(`[notify] Notification sent to ${notifyChannel}`);
558287
558488
  }
558288
558489
  function createTaskHandler() {
558289
558490
  return executeScheduledTask;
558290
558491
  }
558291
- var log67, _scheduler2 = null;
558492
+ var log68, _scheduler2 = null;
558292
558493
  var init_integration = __esm(() => {
558293
558494
  init_logger();
558294
558495
  init_sqlite();
558295
558496
  init_agent_loop();
558296
558497
  init_onboarding();
558297
558498
  init_channel_notify();
558298
- log67 = logger.child("SchedulerIntegration");
558499
+ init_conversation_store();
558500
+ init_cron2();
558501
+ log68 = logger.child("SchedulerIntegration");
558299
558502
  });
558300
558503
 
558301
558504
  // packages/core/src/scheduler/CronScheduler.ts
@@ -558315,7 +558518,7 @@ class CronScheduler {
558315
558518
  for (const task of tasks) {
558316
558519
  this.activate(task);
558317
558520
  }
558318
- log68.info(`[boot] Loaded ${tasks.length} active task(s)`);
558521
+ log69.info(`[boot] Loaded ${tasks.length} active task(s)`);
558319
558522
  this.ensureCleanupTask();
558320
558523
  }
558321
558524
  activate(task) {
@@ -558323,23 +558526,23 @@ class CronScheduler {
558323
558526
  if (existingJob) {
558324
558527
  existingJob.stop();
558325
558528
  this.jobs.delete(task.id);
558326
- log68.debug(`[activate] Stopped existing job for task "${task.name}" (${task.id})`);
558529
+ log69.debug(`[activate] Stopped existing job for task "${task.name}" (${task.id})`);
558327
558530
  }
558328
558531
  if (task.status === "paused" || task.status === "completed" || task.status === "cancelled") {
558329
- log68.debug(`[activate] Skipping task "${task.name}" (${task.id}) - status: ${task.status}`);
558532
+ log69.debug(`[activate] Skipping task "${task.name}" (${task.id}) - status: ${task.status}`);
558330
558533
  return;
558331
558534
  }
558332
558535
  try {
558333
558536
  let pattern;
558334
558537
  if (task.task_type === "recurring") {
558335
558538
  if (!task.cron_expression) {
558336
- log68.error(`[activate] Task "${task.name}" (${task.id}) is recurring but has no cron_expression`);
558539
+ log69.error(`[activate] Task "${task.name}" (${task.id}) is recurring but has no cron_expression`);
558337
558540
  return;
558338
558541
  }
558339
558542
  pattern = task.cron_expression;
558340
558543
  } else {
558341
558544
  if (!task.fire_at) {
558342
- log68.error(`[activate] Task "${task.name}" (${task.id}) is one_shot but has no fire_at`);
558545
+ log69.error(`[activate] Task "${task.name}" (${task.id}) is one_shot but has no fire_at`);
558343
558546
  return;
558344
558547
  }
558345
558548
  pattern = task.fire_at;
@@ -558347,7 +558550,7 @@ class CronScheduler {
558347
558550
  try {
558348
558551
  new E(pattern);
558349
558552
  } catch (err) {
558350
- log68.error(`[activate] Invalid cron pattern "${pattern}" for task "${task.name}": ${err.message}`);
558553
+ log69.error(`[activate] Invalid cron pattern "${pattern}" for task "${task.name}": ${err.message}`);
558351
558554
  return;
558352
558555
  }
558353
558556
  const options2 = {
@@ -558368,26 +558571,26 @@ class CronScheduler {
558368
558571
  if (nextRun) {
558369
558572
  const nextRunIso = nextRun.toISOString();
558370
558573
  this.db.query("UPDATE scheduled_tasks SET next_run_at = ? WHERE id = ?").run(nextRunIso, task.id);
558371
- log68.info(`[activate] Task "${task.name}" (${task.id}) scheduled - next: ${nextRunIso}`);
558574
+ log69.info(`[activate] Task "${task.name}" (${task.id}) scheduled - next: ${nextRunIso}`);
558372
558575
  } else {
558373
- log68.warn(`[activate] Task "${task.name}" (${task.id}) has no next run date`);
558576
+ log69.warn(`[activate] Task "${task.name}" (${task.id}) has no next run date`);
558374
558577
  }
558375
558578
  } catch (err) {
558376
- log68.error(`[activate] Failed to activate task "${task.name}" (${task.id}): ${err.message}`);
558579
+ log69.error(`[activate] Failed to activate task "${task.name}" (${task.id}): ${err.message}`);
558377
558580
  }
558378
558581
  }
558379
558582
  async execute(task) {
558380
558583
  const runId = crypto.randomUUID().replace(/-/g, "").slice(0, 16);
558381
558584
  const startedAt = new Date().toISOString();
558382
558585
  const startTime2 = performance.now();
558383
- log68.info(`[execute] Starting task "${task.name}" (${task.id}) run #${runId}`);
558586
+ log69.info(`[execute] Starting task "${task.name}" (${task.id}) run #${runId}`);
558384
558587
  try {
558385
558588
  this.db.query(`
558386
558589
  INSERT INTO task_runs (id, task_id, status, started_at, payload_snapshot)
558387
558590
  VALUES (?, ?, 'running', ?, ?)
558388
558591
  `).run(runId, task.id, startedAt, task.payload);
558389
558592
  } catch (err) {
558390
- log68.error(`[execute] Failed to create task_run record: ${err.message}`);
558593
+ log69.error(`[execute] Failed to create task_run record: ${err.message}`);
558391
558594
  }
558392
558595
  try {
558393
558596
  const result2 = await this.handler(task);
@@ -558419,9 +558622,9 @@ class CronScheduler {
558419
558622
  WHERE id = ?
558420
558623
  `).run(finishedAt, task.id);
558421
558624
  this.deactivate(task.id);
558422
- log68.info(`[execute] One-shot task "${task.name}" (${task.id}) completed`);
558625
+ log69.info(`[execute] One-shot task "${task.name}" (${task.id}) completed`);
558423
558626
  } else {
558424
- log68.info(`[execute] Task "${task.name}" (${task.id}) completed in ${Math.round(duration3)}ms`);
558627
+ log69.info(`[execute] Task "${task.name}" (${task.id}) completed in ${Math.round(duration3)}ms`);
558425
558628
  }
558426
558629
  } else {
558427
558630
  throw new Error(result2.error || "Handler reported failure");
@@ -558440,12 +558643,12 @@ class CronScheduler {
558440
558643
  SET error_count = error_count + 1, last_error = ?
558441
558644
  WHERE id = ?
558442
558645
  `).run(errorMessage, task.id);
558443
- log68.error(`[execute] Task "${task.name}" (${task.id}) failed: ${errorMessage}`);
558646
+ log69.error(`[execute] Task "${task.name}" (${task.id}) failed: ${errorMessage}`);
558444
558647
  await notifyTaskCompletion(task.id, task.name, false, undefined, errorMessage);
558445
558648
  }
558446
558649
  }
558447
558650
  handleError(task, error50) {
558448
- log68.error(`[error] Task "${task.name}" (${task.id}) error: ${error50.message}`);
558651
+ log69.error(`[error] Task "${task.name}" (${task.id}) error: ${error50.message}`);
558449
558652
  this.db.query(`
558450
558653
  UPDATE scheduled_tasks
558451
558654
  SET error_count = error_count + 1, last_error = ?
@@ -558459,21 +558662,21 @@ class CronScheduler {
558459
558662
  }
558460
558663
  const result2 = this.db.query("UPDATE scheduled_tasks SET status = 'paused' WHERE id = ?").run(taskId);
558461
558664
  if (result2.changes > 0) {
558462
- log68.info(`[pause] Task "${taskId}" paused`);
558665
+ log69.info(`[pause] Task "${taskId}" paused`);
558463
558666
  return true;
558464
558667
  }
558465
- log68.warn(`[pause] Task "${taskId}" not found`);
558668
+ log69.warn(`[pause] Task "${taskId}" not found`);
558466
558669
  return false;
558467
558670
  }
558468
558671
  resume(taskId) {
558469
558672
  const task = this.db.query("SELECT * FROM scheduled_tasks WHERE id = ?").get(taskId);
558470
558673
  if (!task) {
558471
- log68.warn(`[resume] Task "${taskId}" not found`);
558674
+ log69.warn(`[resume] Task "${taskId}" not found`);
558472
558675
  return false;
558473
558676
  }
558474
558677
  this.db.query("UPDATE scheduled_tasks SET status = 'active' WHERE id = ?").run(taskId);
558475
558678
  this.activate(task);
558476
- log68.info(`[resume] Task "${taskId}" resumed`);
558679
+ log69.info(`[resume] Task "${taskId}" resumed`);
558477
558680
  return true;
558478
558681
  }
558479
558682
  deactivate(taskId) {
@@ -558481,17 +558684,17 @@ class CronScheduler {
558481
558684
  if (job) {
558482
558685
  job.stop();
558483
558686
  this.jobs.delete(taskId);
558484
- log68.debug(`[deactivate] Task "${taskId}" deactivated`);
558687
+ log69.debug(`[deactivate] Task "${taskId}" deactivated`);
558485
558688
  }
558486
558689
  }
558487
558690
  delete(taskId) {
558488
558691
  this.deactivate(taskId);
558489
558692
  const result2 = this.db.query("DELETE FROM scheduled_tasks WHERE id = ?").run(taskId);
558490
558693
  if (result2.changes > 0) {
558491
- log68.info(`[delete] Task "${taskId}" deleted`);
558694
+ log69.info(`[delete] Task "${taskId}" deleted`);
558492
558695
  return true;
558493
558696
  }
558494
- log68.warn(`[delete] Task "${taskId}" not found`);
558697
+ log69.warn(`[delete] Task "${taskId}" not found`);
558495
558698
  return false;
558496
558699
  }
558497
558700
  create(input2) {
@@ -558538,13 +558741,13 @@ class CronScheduler {
558538
558741
  this.activate(task);
558539
558742
  const job = this.jobs.get(id);
558540
558743
  const nextRun = job?.nextRun()?.toISOString();
558541
- log68.info(`[create] Task "${input2.name}" (${id}) created`);
558744
+ log69.info(`[create] Task "${input2.name}" (${id}) created`);
558542
558745
  return { id, nextRun };
558543
558746
  }
558544
558747
  update(taskId, changes) {
558545
558748
  const task = this.db.query("SELECT * FROM scheduled_tasks WHERE id = ?").get(taskId);
558546
558749
  if (!task) {
558547
- log68.warn(`[update] Task "${taskId}" not found`);
558750
+ log69.warn(`[update] Task "${taskId}" not found`);
558548
558751
  return false;
558549
558752
  }
558550
558753
  const fields = [];
@@ -558612,7 +558815,7 @@ class CronScheduler {
558612
558815
  this.db.query(`UPDATE scheduled_tasks SET ${fields.join(", ")} WHERE id = ?`).run(...values2);
558613
558816
  const updatedTask = this.db.query("SELECT * FROM scheduled_tasks WHERE id = ?").get(taskId);
558614
558817
  this.activate(updatedTask);
558615
- log68.info(`[update] Task "${taskId}" updated`);
558818
+ log69.info(`[update] Task "${taskId}" updated`);
558616
558819
  return true;
558617
558820
  }
558618
558821
  getStatus() {
@@ -558631,16 +558834,16 @@ class CronScheduler {
558631
558834
  trigger(taskId) {
558632
558835
  const task = this.db.query("SELECT * FROM scheduled_tasks WHERE id = ?").get(taskId);
558633
558836
  if (!task) {
558634
- log68.warn(`[trigger] Task "${taskId}" not found`);
558837
+ log69.warn(`[trigger] Task "${taskId}" not found`);
558635
558838
  return false;
558636
558839
  }
558637
558840
  const job = this.jobs.get(taskId);
558638
558841
  if (!job) {
558639
- log68.warn(`[trigger] Task "${taskId}" has no active job`);
558842
+ log69.warn(`[trigger] Task "${taskId}" has no active job`);
558640
558843
  return false;
558641
558844
  }
558642
558845
  job.trigger();
558643
- log68.info(`[trigger] Task "${taskId}" manually triggered`);
558846
+ log69.info(`[trigger] Task "${taskId}" manually triggered`);
558644
558847
  return true;
558645
558848
  }
558646
558849
  shutdown() {
@@ -558648,13 +558851,13 @@ class CronScheduler {
558648
558851
  job.stop();
558649
558852
  }
558650
558853
  this.jobs.clear();
558651
- log68.info("[shutdown] All jobs stopped");
558854
+ log69.info("[shutdown] All jobs stopped");
558652
558855
  }
558653
558856
  ensureCleanupTask() {
558654
558857
  const existing = this.db.query("SELECT id FROM scheduled_tasks WHERE name = '_hive_cleanup_runs'").get();
558655
558858
  if (existing) {
558656
558859
  this.cleanupTaskId = existing.id;
558657
- log68.debug("[ensureCleanupTask] Cleanup task already exists");
558860
+ log69.debug("[ensureCleanupTask] Cleanup task already exists");
558658
558861
  return;
558659
558862
  }
558660
558863
  try {
@@ -558668,9 +558871,9 @@ class CronScheduler {
558668
558871
  protect: true
558669
558872
  });
558670
558873
  this.cleanupTaskId = result2.id;
558671
- log68.info("[ensureCleanupTask] Cleanup task created");
558874
+ log69.info("[ensureCleanupTask] Cleanup task created");
558672
558875
  } catch (err) {
558673
- log68.error(`[ensureCleanupTask] Failed to create cleanup task: ${err.message}`);
558876
+ log69.error(`[ensureCleanupTask] Failed to create cleanup task: ${err.message}`);
558674
558877
  }
558675
558878
  }
558676
558879
  runCleanup() {
@@ -558700,7 +558903,7 @@ class CronScheduler {
558700
558903
  )
558701
558904
  `).run(task_id, task_id);
558702
558905
  }
558703
- log68.info("[runCleanup] Cleanup completed");
558906
+ log69.info("[runCleanup] Cleanup completed");
558704
558907
  }
558705
558908
  getHistory(taskId, limit2 = 50) {
558706
558909
  return this.db.query(`
@@ -558720,12 +558923,12 @@ class CronScheduler {
558720
558923
  return this.db.query("SELECT * FROM scheduled_tasks ORDER BY next_run_at").all();
558721
558924
  }
558722
558925
  }
558723
- var log68;
558926
+ var log69;
558724
558927
  var init_CronScheduler = __esm(() => {
558725
558928
  init_croner();
558726
558929
  init_logger();
558727
558930
  init_integration();
558728
- log68 = logger.child("CronScheduler");
558931
+ log69 = logger.child("CronScheduler");
558729
558932
  });
558730
558933
 
558731
558934
  // packages/core/src/gateway/routes/scheduled-tasks.ts
@@ -559013,10 +559216,10 @@ var init_scheduled_tasks = __esm(() => {
559013
559216
  });
559014
559217
 
559015
559218
  // packages/core/src/gateway/server.ts
559016
- import { unlinkSync as unlinkSync4, existsSync as existsSync18 } from "fs";
559219
+ import { mkdirSync as mkdirSync11, unlinkSync as unlinkSync4, existsSync as existsSync18, writeFileSync as writeFileSync5, readFileSync as readFileSync9 } from "fs";
559017
559220
  import * as path30 from "path";
559018
559221
  import { cpus as osCpus } from "os";
559019
- import { randomUUID as randomUUID3 } from "crypto";
559222
+ import { randomUUID as randomUUID2 } from "crypto";
559020
559223
  async function startGateway(config3) {
559021
559224
  const host = config3.gateway?.host ?? "127.0.0.1";
559022
559225
  const port = config3.gateway?.port ?? 18790;
@@ -559025,9 +559228,25 @@ async function startGateway(config3) {
559025
559228
  const numCores = osCpus().length || 1;
559026
559229
  let lastCpuSample = process.cpuUsage();
559027
559230
  let lastCpuSampleTime = Date.now();
559028
- const log69 = logger.child("gateway");
559231
+ const log70 = logger.child("gateway");
559029
559232
  const mcpLog2 = logger.child("mcp:api");
559030
- log69.info(`Starting gateway on ${host}:${port}`);
559233
+ log70.info(`Starting gateway on ${host}:${port}`);
559234
+ const tokenFile = path30.join(getHiveDir(), ".auth_token");
559235
+ if (!process.env.HIVE_AUTH_TOKEN) {
559236
+ if (existsSync18(tokenFile)) {
559237
+ process.env.HIVE_AUTH_TOKEN = readFileSync9(tokenFile, "utf-8").trim();
559238
+ log70.info("\uD83D\uDD11 Auth token loaded from persistent storage");
559239
+ } else {
559240
+ const generated = randomUUID2().replace(/-/g, "");
559241
+ process.env.HIVE_AUTH_TOKEN = generated;
559242
+ mkdirSync11(path30.dirname(tokenFile), { recursive: true });
559243
+ writeFileSync5(tokenFile, generated, { mode: 384 });
559244
+ log70.info("\uD83D\uDD11 Auth token auto-generated and persisted");
559245
+ }
559246
+ } else {
559247
+ writeFileSync5(tokenFile, process.env.HIVE_AUTH_TOKEN, { mode: 384 });
559248
+ log70.info("\uD83D\uDD11 Auth token loaded from environment variable");
559249
+ }
559031
559250
  let agent;
559032
559251
  let runner;
559033
559252
  let channelManager;
@@ -559056,7 +559275,7 @@ async function startGateway(config3) {
559056
559275
  },
559057
559276
  websocket: { open() {}, message() {}, close() {} }
559058
559277
  });
559059
- log69.info(`Port ${port} bound (initializing gateway...)`);
559278
+ log70.info(`Port ${port} bound (initializing gateway...)`);
559060
559279
  try {
559061
559280
  initializeDatabase();
559062
559281
  seedAllData();
@@ -559079,9 +559298,9 @@ async function startGateway(config3) {
559079
559298
  await channelManager.send(channel, sessionId, { content, type: "progress" });
559080
559299
  });
559081
559300
  if (gatewaySetupMode) {
559082
- log69.info("\uD83C\uDF89 Setup mode: gateway running \u2014 open http://localhost:" + port + "/setup to configure");
559301
+ log70.info("\uD83C\uDF89 Setup mode: gateway running \u2014 open http://localhost:" + port + "/setup to configure");
559083
559302
  } else {
559084
- log69.info("\u2705 Gateway initialization completed successfully");
559303
+ log70.info("\u2705 Gateway initialization completed successfully");
559085
559304
  try {
559086
559305
  const db = getDb();
559087
559306
  db.query(`
@@ -559095,18 +559314,18 @@ async function startGateway(config3) {
559095
559314
  setSchedulerInstance(scheduler);
559096
559315
  setSchedulerInstance2(scheduler);
559097
559316
  setSchedulerForCleanup(scheduler);
559098
- log69.info(`\uD83D\uDCC5 CronScheduler initialized with ${scheduler.getStatus().length} task(s)`);
559317
+ log70.info(`\uD83D\uDCC5 CronScheduler initialized with ${scheduler.getStatus().length} task(s)`);
559099
559318
  } catch (err) {
559100
- log69.error(`\u274C CronScheduler initialization failed: ${err.message}`);
559319
+ log70.error(`\u274C CronScheduler initialization failed: ${err.message}`);
559101
559320
  }
559102
559321
  }
559103
559322
  } catch (error50) {
559104
- log69.error(`\u274C Gateway initialization failed: ${error50.message}`);
559105
- log69.error("Stack trace:", error50.stack);
559323
+ log70.error(`\u274C Gateway initialization failed: ${error50.message}`);
559324
+ log70.error("Stack trace:", error50.stack);
559106
559325
  process.exit(1);
559107
559326
  }
559108
559327
  if (host === "0.0.0.0" && config3.security?.warnOnInsecureConfig !== false) {
559109
- log69.warn("Gateway binding to 0.0.0.0 exposes server to all network interfaces!");
559328
+ log70.warn("Gateway binding to 0.0.0.0 exposes server to all network interfaces!");
559110
559329
  }
559111
559330
  function prepareTools(agentInstance, sessionId) {
559112
559331
  return;
@@ -559114,17 +559333,17 @@ async function startGateway(config3) {
559114
559333
  const watchers = [];
559115
559334
  if (!gatewaySetupMode)
559116
559335
  channelManager.onMessage(async (message) => {
559117
- log69.info(`\uD83D\uDCE5 Message from ${message.channel}:${message.accountId}`);
559118
- log69.info(` Session: ${message.sessionId}`);
559336
+ log70.info(`\uD83D\uDCE5 Message from ${message.channel}:${message.accountId}`);
559337
+ log70.info(` Session: ${message.sessionId}`);
559119
559338
  const voiceConfig = voiceService.getChannelVoiceConfig(message.channel);
559120
559339
  let messageContent = message.content;
559121
559340
  let preferAudioResponse = false;
559122
559341
  let inputType = "text";
559123
559342
  let sttProviderUsed = null;
559124
559343
  if (voiceConfig.voiceEnabled && message.audio) {
559125
- log69.info(`\uD83C\uDF99\uFE0F Voice enabled, processing audio...`);
559344
+ log70.info(`\uD83C\uDF99\uFE0F Voice enabled, processing audio...`);
559126
559345
  if (!voiceConfig.sttProvider) {
559127
- log69.warn(`\u26A0\uFE0F STT provider not configured for channel ${message.channel}`);
559346
+ log70.warn(`\u26A0\uFE0F STT provider not configured for channel ${message.channel}`);
559128
559347
  await channelManager.send(message.channel, message.sessionId, {
559129
559348
  content: `\uD83C\uDF99\uFE0F Para usar notas de voz, necesitas configurar el proveedor STT en la configuraci\xF3n del canal. Ve a Configuraci\xF3n > Canales > [Tu canal] y configura "Prov. STT" (ej: groq-whisper o openai)`
559130
559349
  });
@@ -559134,7 +559353,7 @@ async function startGateway(config3) {
559134
559353
  const audioInput = voiceService.normalizeAudioFromChannel(message.channel, message.audio);
559135
559354
  sttProviderUsed = voiceConfig.sttProvider || "groq-whisper";
559136
559355
  messageContent = await voiceService.transcribe(audioInput, sttProviderUsed);
559137
- log69.info(`\uD83D\uDCDD Transcribed: ${messageContent.substring(0, 100)}...`);
559356
+ log70.info(`\uD83D\uDCDD Transcribed: ${messageContent.substring(0, 100)}...`);
559138
559357
  inputType = "audio_transcribed";
559139
559358
  preferAudioResponse = !!voiceConfig.ttsProvider;
559140
559359
  await channelManager.send(message.channel, message.sessionId, {
@@ -559142,14 +559361,14 @@ async function startGateway(config3) {
559142
559361
  type: "message"
559143
559362
  });
559144
559363
  } catch (error50) {
559145
- log69.error(`\u274C Transcription failed: ${error50.message}`);
559364
+ log70.error(`\u274C Transcription failed: ${error50.message}`);
559146
559365
  await channelManager.send(message.channel, message.sessionId, {
559147
559366
  content: `Error al transcribir audio: ${error50.message}`
559148
559367
  });
559149
559368
  return;
559150
559369
  }
559151
559370
  }
559152
- log69.info(` Content: ${messageContent.substring(0, 150)}${messageContent.length > 150 ? "..." : ""}`);
559371
+ log70.info(` Content: ${messageContent.substring(0, 150)}${messageContent.length > 150 ? "..." : ""}`);
559153
559372
  const { userId } = resolveContext({
559154
559373
  channel: message.channel,
559155
559374
  channelUserId: message.sessionId
@@ -559180,7 +559399,7 @@ async function startGateway(config3) {
559180
559399
  ${messageContent}`;
559181
559400
  const messages2 = [{ role: "user", content: messageContentWithTime }];
559182
559401
  try {
559183
- log69.info(`\uD83E\uDD16 Routing to agent loop...`);
559402
+ log70.info(`\uD83E\uDD16 Routing to agent loop...`);
559184
559403
  const response = await runner.generate({
559185
559404
  provider: dbProvider,
559186
559405
  messages: messages2,
@@ -559195,7 +559414,7 @@ ${messageContent}`;
559195
559414
  if (step.type === "text" && step.message) {
559196
559415
  const trimmedMessage = (typeof step.message === "string" ? step.message : "").trim();
559197
559416
  if (trimmedMessage) {
559198
- log69.debug(`[NARRATION] ${trimmedMessage.substring(0, 100)}`);
559417
+ log70.debug(`[NARRATION] ${trimmedMessage.substring(0, 100)}`);
559199
559418
  await channelManager.send(message.channel, routingSessionId, {
559200
559419
  content: trimmedMessage,
559201
559420
  type: "progress"
@@ -559205,7 +559424,7 @@ ${messageContent}`;
559205
559424
  }
559206
559425
  if (step.type === "tool_call" && step.toolName) {
559207
559426
  const narration = getNarration(step.toolName);
559208
- log69.debug(`[TOOL] ${step.toolName} \u2192 "${narration}"`);
559427
+ log70.debug(`[TOOL] ${step.toolName} \u2192 "${narration}"`);
559209
559428
  await channelManager.send(message.channel, routingSessionId, {
559210
559429
  content: narration,
559211
559430
  type: "progress"
@@ -559229,10 +559448,10 @@ ${messageContent}`;
559229
559448
  });
559230
559449
  const responseContent = response.content?.trim() || "";
559231
559450
  if (!responseContent) {
559232
- log69.warn(`\uD83D\uDCE4 LLM response: empty \u2014 skipping send`);
559451
+ log70.warn(`\uD83D\uDCE4 LLM response: empty \u2014 skipping send`);
559233
559452
  return;
559234
559453
  }
559235
- log69.info(`\uD83D\uDCE4 LLM response: ${responseContent.substring(0, 100)}${responseContent.length > 100 ? "..." : ""}`);
559454
+ log70.info(`\uD83D\uDCE4 LLM response: ${responseContent.substring(0, 100)}${responseContent.length > 100 ? "..." : ""}`);
559236
559455
  const shouldSpeak = preferAudioResponse;
559237
559456
  let responseType = "text";
559238
559457
  let ttsProviderUsed = null;
@@ -559240,7 +559459,7 @@ ${messageContent}`;
559240
559459
  if (responseContent) {
559241
559460
  if (shouldSpeak) {
559242
559461
  if (!voiceConfig.ttsProvider) {
559243
- log69.warn(`\u26A0\uFE0F TTS provider not configured, user requested audio`);
559462
+ log70.warn(`\u26A0\uFE0F TTS provider not configured, user requested audio`);
559244
559463
  await channelManager.send(message.channel, routingSessionId, {
559245
559464
  content: `${responseContent}
559246
559465
 
@@ -559248,7 +559467,7 @@ ${messageContent}`;
559248
559467
  });
559249
559468
  } else {
559250
559469
  try {
559251
- log69.info(`\uD83D\uDD0A TTS enabled, synthesizing audio...`);
559470
+ log70.info(`\uD83D\uDD0A TTS enabled, synthesizing audio...`);
559252
559471
  const audioOutput = await voiceService.speak(responseContent, voiceConfig.ttsProvider, voiceConfig.ttsVoiceId || undefined);
559253
559472
  ttsProviderUsed = voiceConfig.ttsProvider;
559254
559473
  ttsMimeType = audioOutput.mimeType;
@@ -559257,17 +559476,17 @@ ${messageContent}`;
559257
559476
  const channel = channelManager.getChannel(message.channel);
559258
559477
  if (channel?.sendAudio) {
559259
559478
  await channel.sendAudio(routingSessionId, audioOutput.data, audioOutput.mimeType);
559260
- log69.info(`\u2705 Audio sent to ${routingSessionId}`);
559479
+ log70.info(`\u2705 Audio sent to ${routingSessionId}`);
559261
559480
  } else {
559262
- log69.warn(`Channel ${message.channel} does not support audio, sending text`);
559481
+ log70.warn(`Channel ${message.channel} does not support audio, sending text`);
559263
559482
  await channelManager.send(message.channel, routingSessionId, { content: responseContent });
559264
559483
  }
559265
559484
  } catch (audioError) {
559266
- log69.error(`\u274C Audio send failed: ${audioError.message}, sending text instead`);
559485
+ log70.error(`\u274C Audio send failed: ${audioError.message}, sending text instead`);
559267
559486
  await channelManager.send(message.channel, routingSessionId, { content: responseContent });
559268
559487
  }
559269
559488
  } catch (ttsError) {
559270
- log69.error(`\u274C TTS failed: ${ttsError.message}, sending text instead`);
559489
+ log70.error(`\u274C TTS failed: ${ttsError.message}, sending text instead`);
559271
559490
  await channelManager.send(message.channel, routingSessionId, { content: responseContent });
559272
559491
  }
559273
559492
  }
@@ -559282,10 +559501,10 @@ ${messageContent}`;
559282
559501
  channel: message.channel
559283
559502
  };
559284
559503
  await channelManager.stopTyping(message.channel, routingSessionId);
559285
- log69.info(`\u2705 Response sent to ${routingSessionId} via ${message.channel}`);
559504
+ log70.info(`\u2705 Response sent to ${routingSessionId} via ${message.channel}`);
559286
559505
  } catch (error50) {
559287
559506
  await channelManager.stopTyping(message.channel, routingSessionId);
559288
- log69.error(`\u274C Error: ${error50.message} `);
559507
+ log70.error(`\u274C Error: ${error50.message} `);
559289
559508
  await channelManager.send(message.channel, routingSessionId, {
559290
559509
  content: `Error: ${error50.message} `
559291
559510
  });
@@ -559295,6 +559514,8 @@ ${messageContent}`;
559295
559514
  function checkAuth(req, url3) {
559296
559515
  if (isDev)
559297
559516
  return true;
559517
+ if (url3.pathname.startsWith("/api/setup/"))
559518
+ return true;
559298
559519
  const activeToken = process.env.HIVE_AUTH_TOKEN;
559299
559520
  if (!activeToken)
559300
559521
  return true;
@@ -559309,9 +559530,9 @@ ${messageContent}`;
559309
559530
  const method = req.method;
559310
559531
  const logRequest = (status, duration3) => {
559311
559532
  if (url3.pathname === "/health" || url3.pathname === "/health/") {
559312
- log69.debug(`${method} ${url3.pathname} - ${status} (${duration3}ms)`);
559533
+ log70.debug(`${method} ${url3.pathname} - ${status} (${duration3}ms)`);
559313
559534
  } else {
559314
- log69.info(`${method} ${url3.pathname} - ${status} (${duration3}ms)`);
559535
+ log70.info(`${method} ${url3.pathname} - ${status} (${duration3}ms)`);
559315
559536
  }
559316
559537
  };
559317
559538
  const handleRequest = async () => {
@@ -559332,10 +559553,24 @@ ${messageContent}`;
559332
559553
  return new Response(null, { status: 204 });
559333
559554
  }
559334
559555
  if (url3.pathname === "/ws" || url3.pathname === "/ws/") {
559335
- if (!isDev && !checkAuth(req, url3)) {
559336
- return new Response("Unauthorized", { status: 401 });
559556
+ let sessionId = url3.searchParams.get("session") || resolveUserId({}) || "default";
559557
+ if (!isDev) {
559558
+ const tokenParam = url3.searchParams.get("token");
559559
+ const activeToken = process.env.HIVE_AUTH_TOKEN;
559560
+ if (tokenParam && activeToken && tokenParam === activeToken) {
559561
+ const user = getDb().query("SELECT id FROM users LIMIT 1").get();
559562
+ if (user)
559563
+ sessionId = user.id;
559564
+ }
559565
+ try {
559566
+ const userExists = getDb().query("SELECT 1 FROM users WHERE id = ? LIMIT 1").get(sessionId);
559567
+ if (!userExists) {
559568
+ return new Response("Unauthorized", { status: 401 });
559569
+ }
559570
+ } catch {
559571
+ return new Response("Unauthorized", { status: 401 });
559572
+ }
559337
559573
  }
559338
- const sessionId = url3.searchParams.get("session") || resolveUserId({}) || "default";
559339
559574
  if (!sessionId) {
559340
559575
  return new Response("Missing session or user ID", { status: 400 });
559341
559576
  }
@@ -559428,8 +559663,8 @@ ${messageContent}`;
559428
559663
  return Response.redirect(`/ ui${tokenParam} `, 301);
559429
559664
  }
559430
559665
  if (!checkAuth(req, url3)) {
559431
- log69.warn(`[AUTH] Unauthorized request to ${url3.pathname} from ${req.headers.get("origin")} `);
559432
- return new Response("Unauthorized", { status: 401 });
559666
+ log70.warn(`[AUTH] Unauthorized request to ${url3.pathname} from ${req.headers.get("origin")} `);
559667
+ return addCorsHeaders(new Response("Unauthorized", { status: 401 }), req);
559433
559668
  }
559434
559669
  if (url3.pathname === "/api/setup/status" || url3.pathname === "/api/setup/status/") {
559435
559670
  return addCorsHeaders(await handleSetupStatus(), req);
@@ -559627,7 +559862,7 @@ ${messageContent}`;
559627
559862
  return await handleApiReload(req, addCorsHeaders, agent);
559628
559863
  }
559629
559864
  if (url3.pathname === "/api/user/channels" && req.method === "POST") {
559630
- return await handleLinkUserChannel(req, addCorsHeaders, config3, log69);
559865
+ return await handleLinkUserChannel(req, addCorsHeaders, config3, log70);
559631
559866
  }
559632
559867
  if (url3.pathname === "/api/user/channels" && req.method === "GET") {
559633
559868
  return await handleGetUserChannels(req, addCorsHeaders, config3);
@@ -559685,7 +559920,7 @@ ${messageContent}`;
559685
559920
  const { name, category, tools, triggers, body: bodyContent } = body;
559686
559921
  if (!name)
559687
559922
  return addCorsHeaders(new Response("Missing name", { status: 400 }), req);
559688
- const id = randomUUID3();
559923
+ const id = randomUUID2();
559689
559924
  getDb().query(`INSERT INTO skills(id, name, category, tools, triggers, body, version, active) VALUES(?, ?, ?, ?, ?, ?, 1, 1)`).run(id, name, category || "", tools || "", triggers || "", bodyContent || "");
559690
559925
  return addCorsHeaders(Response.json({ success: true, id }), req);
559691
559926
  }
@@ -559715,7 +559950,7 @@ ${messageContent}`;
559715
559950
  const { name, description, content, is_default: is_default2 } = body;
559716
559951
  if (!name || !content)
559717
559952
  return addCorsHeaders(Response.json({ success: false, error: "Missing name or content" }, { status: 400 }), req);
559718
- const id = randomUUID3();
559953
+ const id = randomUUID2();
559719
559954
  getDb().query(`INSERT INTO ethics(id, name, description, content, is_default, enabled, active) VALUES(?, ?, ?, ?, ?, 1, 1)`).run(id, name, description || "", content, is_default2 ? 1 : 0);
559720
559955
  return addCorsHeaders(Response.json({ success: true, id }), req);
559721
559956
  }
@@ -559757,16 +559992,16 @@ ${messageContent}`;
559757
559992
  if (active === undefined) {
559758
559993
  return addCorsHeaders(Response.json({ success: false, error: "Missing active field" }, { status: 400 }), req);
559759
559994
  }
559760
- log69.info(`[MCP] Toggle connection for ${mcpName}, active=${active}`);
559995
+ log70.info(`[MCP] Toggle connection for ${mcpName}, active=${active}`);
559761
559996
  getDb().query(`UPDATE mcp_servers SET active = ?, enabled = ? WHERE id = ? OR name = ?`).run(active ? 1 : 0, active ? 1 : 0, mcpName, mcpName);
559762
559997
  try {
559763
559998
  const mcp = agent?.getMCPManager() ?? null;
559764
559999
  if (mcp) {
559765
- log69.info(`[MCP] Manager found, connecting ${mcpName}...`);
560000
+ log70.info(`[MCP] Manager found, connecting ${mcpName}...`);
559766
560001
  if (active) {
559767
560002
  const server4 = getDb().query(`SELECT * FROM mcp_servers WHERE id = ? OR name = ?`).get(mcpName, mcpName);
559768
560003
  if (server4) {
559769
- log69.info(`[MCP] Server config: transport=${server4.transport}, url=${server4.url}`);
560004
+ log70.info(`[MCP] Server config: transport=${server4.transport}, url=${server4.url}`);
559770
560005
  const mcpServerConfig = {
559771
560006
  transport: server4.transport,
559772
560007
  command: server4.command,
@@ -559778,7 +560013,7 @@ ${messageContent}`;
559778
560013
  try {
559779
560014
  mcpServerConfig.headers = decryptConfig(server4.headers_encrypted, server4.headers_iv);
559780
560015
  } catch (e) {
559781
- log69.warn(`Failed to decrypt headers for ${mcpName}`);
560016
+ log70.warn(`Failed to decrypt headers for ${mcpName}`);
559782
560017
  }
559783
560018
  }
559784
560019
  const currentConfig = mcp.config || { servers: {} };
@@ -559788,22 +560023,22 @@ ${messageContent}`;
559788
560023
  ...currentConfig,
559789
560024
  servers: newServersConfig
559790
560025
  });
559791
- log69.info(`[MCP] Server registered in MCP Manager`);
560026
+ log70.info(`[MCP] Server registered in MCP Manager`);
559792
560027
  const tools = mcp.getServerTools(mcpName) || [];
559793
- log69.info(`[MCP] Connected! Tools: ${tools.length}`);
560028
+ log70.info(`[MCP] Connected! Tools: ${tools.length}`);
559794
560029
  getDb().query(`UPDATE mcp_servers SET status = ?, tools_count = ? WHERE id = ? OR name = ?`).run("connected", tools.length, mcpName, mcpName);
559795
560030
  } else {
559796
- log69.error(`[MCP] Server not found in DB: ${mcpName}`);
560031
+ log70.error(`[MCP] Server not found in DB: ${mcpName}`);
559797
560032
  }
559798
560033
  } else {
559799
560034
  await mcp.disconnectServer(mcpName);
559800
560035
  getDb().query(`UPDATE mcp_servers SET status = ? WHERE id = ? OR name = ?`).run("disconnected", mcpName, mcpName);
559801
560036
  }
559802
560037
  } else {
559803
- log69.error(`[MCP] No MCP Manager found`);
560038
+ log70.error(`[MCP] No MCP Manager found`);
559804
560039
  }
559805
560040
  } catch (error50) {
559806
- log69.error(`[MCP] Failed to connect ${mcpName}: ${error50.message}`);
560041
+ log70.error(`[MCP] Failed to connect ${mcpName}: ${error50.message}`);
559807
560042
  }
559808
560043
  return addCorsHeaders(Response.json({ success: true, active, message: active ? "Servidor MCP conectado" : "Servidor MCP desconectado" }), req);
559809
560044
  }
@@ -559830,7 +560065,7 @@ ${messageContent}`;
559830
560065
  if (active) {
559831
560066
  const server4 = getDb().query(`SELECT * FROM mcp_servers WHERE id = ? OR name = ?`).get(mcpName, mcpName);
559832
560067
  if (server4) {
559833
- log69.info(`[MCP] Server config: transport=${server4.transport}, url=${server4.url}`);
560068
+ log70.info(`[MCP] Server config: transport=${server4.transport}, url=${server4.url}`);
559834
560069
  const mcpServerConfig = {
559835
560070
  transport: server4.transport,
559836
560071
  command: server4.command,
@@ -559842,7 +560077,7 @@ ${messageContent}`;
559842
560077
  try {
559843
560078
  mcpServerConfig.headers = decryptConfig(server4.headers_encrypted, server4.headers_iv);
559844
560079
  } catch (e) {
559845
- log69.warn(`Failed to decrypt headers for ${mcpName}`);
560080
+ log70.warn(`Failed to decrypt headers for ${mcpName}`);
559846
560081
  }
559847
560082
  }
559848
560083
  const currentConfig = mcp.config || { servers: {} };
@@ -559852,12 +560087,12 @@ ${messageContent}`;
559852
560087
  ...currentConfig,
559853
560088
  servers: newServersConfig
559854
560089
  });
559855
- log69.info(`[MCP] Server registered in MCP Manager`);
560090
+ log70.info(`[MCP] Server registered in MCP Manager`);
559856
560091
  const tools = mcp.getServerTools(mcpName) || [];
559857
- log69.info(`[MCP] Connected! Tools: ${tools.length}`);
560092
+ log70.info(`[MCP] Connected! Tools: ${tools.length}`);
559858
560093
  getDb().query(`UPDATE mcp_servers SET status = ?, tools_count = ? WHERE id = ? OR name = ?`).run("connected", tools.length, mcpName, mcpName);
559859
560094
  } else {
559860
- log69.error(`[MCP] Server not found in DB: ${mcpName}`);
560095
+ log70.error(`[MCP] Server not found in DB: ${mcpName}`);
559861
560096
  }
559862
560097
  } else {
559863
560098
  await mcp.disconnectServer(mcpName);
@@ -559865,7 +560100,7 @@ ${messageContent}`;
559865
560100
  }
559866
560101
  }
559867
560102
  } catch (error50) {
559868
- log69.error(`[MCP] Failed to connect ${mcpName}: ${error50.message}`);
560103
+ log70.error(`[MCP] Failed to connect ${mcpName}: ${error50.message}`);
559869
560104
  }
559870
560105
  return addCorsHeaders(Response.json({ success: true, active, message: active ? "Servidor MCP conectado" : "Servidor MCP desconectado" }), req);
559871
560106
  }
@@ -559985,12 +560220,12 @@ ${messageContent}`;
559985
560220
  if (response) {
559986
560221
  logRequest(response.status, duration3);
559987
560222
  } else {
559988
- log69.info(`${method} ${url3.pathname} - 101 Switching Protocols(${duration3}ms)`);
560223
+ log70.info(`${method} ${url3.pathname} - 101 Switching Protocols(${duration3}ms)`);
559989
560224
  }
559990
560225
  return response;
559991
560226
  } catch (error50) {
559992
560227
  const duration3 = Date.now() - start;
559993
- log69.error(`${method} ${url3.pathname} - Internal Error(${duration3}ms): ${error50.message} `);
560228
+ log70.error(`${method} ${url3.pathname} - Internal Error(${duration3}ms): ${error50.message} `);
559994
560229
  return addCorsHeaders(Response.json({ success: false, error: error50.message, message: "Error interno del servidor" }, { status: 500 }), req);
559995
560230
  }
559996
560231
  },
@@ -560000,20 +560235,20 @@ ${messageContent}`;
560000
560235
  const isCanvas = data.sessionId.startsWith("canvas:");
560001
560236
  const isBridge = data.sessionId.startsWith("bridge:");
560002
560237
  if (isBridge) {
560003
- log69.info(`Bridge events client connected: ${data.sessionId}`);
560238
+ log70.info(`Bridge events client connected: ${data.sessionId}`);
560004
560239
  subscribeBridge(ws);
560005
560240
  ws.send(JSON.stringify({ type: "bridge:connected", sessionId: data.sessionId }));
560006
560241
  return;
560007
560242
  }
560008
560243
  if (isCanvas) {
560009
- log69.info(`Canvas session connected: ${data.sessionId} `);
560244
+ log70.info(`Canvas session connected: ${data.sessionId} `);
560010
560245
  canvasManager.registerSession(data.sessionId, ws);
560011
560246
  subscribeCanvas(ws);
560012
560247
  ws.send(JSON.stringify({ type: "canvas:connected", sessionId: data.sessionId }));
560013
560248
  ws.send(JSON.stringify({ type: "canvas:snapshot", data: getCanvasSnapshot() }));
560014
560249
  return;
560015
560250
  }
560016
- log69.debug(`WebSocket connected: ${data.sessionId} `);
560251
+ log70.debug(`WebSocket connected: ${data.sessionId} `);
560017
560252
  sessionManager.create(data.sessionId, ws);
560018
560253
  const channel = channelManager?.getChannel("webchat");
560019
560254
  if (channel?.registerConnection)
@@ -560044,13 +560279,19 @@ ${messageContent}`;
560044
560279
  codeBridge: codeBridge.map((cb) => cb.id)
560045
560280
  }));
560046
560281
  } catch (err) {
560047
- log69.error("Error sending welcome message:", err);
560282
+ log70.error("Error sending welcome message:", err);
560048
560283
  }
560049
560284
  },
560050
560285
  async message(ws, message) {
560051
560286
  const data = ws.data;
560052
- if (data.sessionId.startsWith("bridge:"))
560287
+ if (data.sessionId.startsWith("bridge:")) {
560288
+ try {
560289
+ const m2 = JSON.parse(message.toString());
560290
+ if (m2?.type === "ping")
560291
+ ws.send(JSON.stringify({ type: "pong" }));
560292
+ } catch {}
560053
560293
  return;
560294
+ }
560054
560295
  let msg;
560055
560296
  try {
560056
560297
  msg = JSON.parse(message.toString());
@@ -560093,17 +560334,17 @@ ${messageContent}`;
560093
560334
  }
560094
560335
  if (msg.type === "logs_subscribe") {
560095
560336
  logSubscribers.add(data.sessionId);
560096
- log69.debug(`Session ${data.sessionId} subscribed to logs`);
560337
+ log70.debug(`Session ${data.sessionId} subscribed to logs`);
560097
560338
  return;
560098
560339
  }
560099
560340
  if (msg.type === "logs_unsubscribe") {
560100
560341
  logSubscribers.delete(data.sessionId);
560101
- log69.debug(`Session ${data.sessionId} unsubscribed from logs`);
560342
+ log70.debug(`Session ${data.sessionId} unsubscribed from logs`);
560102
560343
  return;
560103
560344
  }
560104
560345
  let webchatPreferAudio = false;
560105
560346
  if (msg.type === "audio" && msg.audio) {
560106
- log69.info(`WebChat audio from session ${msg.sessionId}`);
560347
+ log70.info(`WebChat audio from session ${msg.sessionId}`);
560107
560348
  const voiceConfig = voiceService.getChannelVoiceConfig("webchat");
560108
560349
  if (!voiceConfig.voiceEnabled) {
560109
560350
  ws.send(JSON.stringify({
@@ -560130,7 +560371,7 @@ ${messageContent}`;
560130
560371
  const audioInput = { type: "base64", data: msg.audio, mimeType: "audio/webm" };
560131
560372
  const sttProvider = voiceConfig.sttProvider || "groq-whisper";
560132
560373
  const messageContent = await voiceService.transcribe(audioInput, sttProvider);
560133
- log69.info(`\uD83D\uDCDD Transcribed: ${messageContent.substring(0, 100)}...`);
560374
+ log70.info(`\uD83D\uDCDD Transcribed: ${messageContent.substring(0, 100)}...`);
560134
560375
  webchatPreferAudio = true;
560135
560376
  ws.send(JSON.stringify({
560136
560377
  type: "message",
@@ -560151,7 +560392,7 @@ ${messageContent}`;
560151
560392
  try {
560152
560393
  const unifiedSessionId = msg.sessionId;
560153
560394
  const messages2 = [{ role: "user", content: messageContent }];
560154
- log69.info(`Generating response for session ${unifiedSessionId}...`);
560395
+ log70.info(`Generating response for session ${unifiedSessionId}...`);
560155
560396
  const { userId } = resolveContext({
560156
560397
  channel: "webchat",
560157
560398
  channelUserId: msg.sessionId
@@ -560197,11 +560438,11 @@ ${messageContent}`;
560197
560438
  }
560198
560439
  } catch {}
560199
560440
  }
560200
- log69.debug(`[TOOL] ${step.type}: ${step.toolName || ""}`);
560441
+ log70.debug(`[TOOL] ${step.type}: ${step.toolName || ""}`);
560201
560442
  }
560202
560443
  });
560203
560444
  const content = streamedContent || response.content?.trim() || "";
560204
- log69.info(`Response sent to session ${unifiedSessionId} (${content.length} chars)`);
560445
+ log70.info(`Response sent to session ${unifiedSessionId} (${content.length} chars)`);
560205
560446
  const voiceCfg = voiceService.getChannelVoiceConfig("webchat");
560206
560447
  const shouldSpeak = webchatPreferAudio;
560207
560448
  let responseType = "text";
@@ -560222,7 +560463,7 @@ ${messageContent}`;
560222
560463
  }));
560223
560464
  } else {
560224
560465
  try {
560225
- log69.info(`\uD83D\uDD0A TTS enabled, synthesizing audio for WebChat...`);
560466
+ log70.info(`\uD83D\uDD0A TTS enabled, synthesizing audio for WebChat...`);
560226
560467
  const audioOutput = await voiceService.speak(content, voiceCfg.ttsProvider, voiceCfg.ttsVoiceId || undefined);
560227
560468
  ttsProviderUsed = voiceCfg.ttsProvider;
560228
560469
  ttsMimeType = audioOutput.mimeType;
@@ -560236,7 +560477,7 @@ ${messageContent}`;
560236
560477
  mimeType: audioOutput.mimeType
560237
560478
  }));
560238
560479
  } catch (ttsError) {
560239
- log69.error(`TTS failed: ${ttsError.message}), sending text instead`);
560480
+ log70.error(`TTS failed: ${ttsError.message}), sending text instead`);
560240
560481
  ws.send(JSON.stringify({ type: "message", sessionId: unifiedSessionId, content, isStep: false }));
560241
560482
  }
560242
560483
  }
@@ -560251,7 +560492,7 @@ ${messageContent}`;
560251
560492
  sessionId: msg.sessionId,
560252
560493
  error: error50.message
560253
560494
  }));
560254
- log69.error(`Error for session ${msg.sessionId}: ${error50.message}`);
560495
+ log70.error(`Error for session ${msg.sessionId}: ${error50.message}`);
560255
560496
  }
560256
560497
  });
560257
560498
  } catch (error50) {
@@ -560269,7 +560510,7 @@ ${messageContent}`;
560269
560510
  return;
560270
560511
  }
560271
560512
  if (msg.type === "message" && msg.content) {
560272
- log69.info(`WebChat message from session ${msg.sessionId}: ${msg.content.substring(0, 100)}`);
560513
+ log70.info(`WebChat message from session ${msg.sessionId}: ${msg.content.substring(0, 100)}`);
560273
560514
  ws.send(JSON.stringify({
560274
560515
  type: "typing",
560275
560516
  isTyping: true,
@@ -560284,7 +560525,7 @@ ${messageContent}`;
560284
560525
  try {
560285
560526
  const unifiedSessionId = msg.sessionId;
560286
560527
  const messages2 = [{ role: "user", content: msg.content }];
560287
- log69.info(`Generating response for session ${unifiedSessionId}...`);
560528
+ log70.info(`Generating response for session ${unifiedSessionId}...`);
560288
560529
  const { userId } = resolveContext({
560289
560530
  channel: "webchat",
560290
560531
  channelUserId: msg.sessionId
@@ -560330,11 +560571,11 @@ ${messageContent}`;
560330
560571
  }
560331
560572
  } catch {}
560332
560573
  }
560333
- log69.debug(`[TOOL] ${step.type}: ${step.toolName || ""}`);
560574
+ log70.debug(`[TOOL] ${step.type}: ${step.toolName || ""}`);
560334
560575
  }
560335
560576
  });
560336
560577
  const content = streamedContent || response.content?.trim() || "";
560337
- log69.info(`Response sent to session ${unifiedSessionId} (${content.length} chars)`);
560578
+ log70.info(`Response sent to session ${unifiedSessionId} (${content.length} chars)`);
560338
560579
  const voiceConfig = voiceService.getChannelVoiceConfig("webchat");
560339
560580
  const shouldSpeak = webchatPreferAudio;
560340
560581
  let responseType = "text";
@@ -560355,7 +560596,7 @@ ${messageContent}`;
560355
560596
  }));
560356
560597
  } else {
560357
560598
  try {
560358
- log69.info(`\uD83D\uDD0A TTS enabled, synthesizing audio for WebChat...`);
560599
+ log70.info(`\uD83D\uDD0A TTS enabled, synthesizing audio for WebChat...`);
560359
560600
  const audioOutput = await voiceService.speak(content, voiceConfig.ttsProvider, voiceConfig.ttsVoiceId || undefined);
560360
560601
  ttsProviderUsed = voiceConfig.ttsProvider;
560361
560602
  ttsMimeType = audioOutput.mimeType;
@@ -560369,7 +560610,7 @@ ${messageContent}`;
560369
560610
  mimeType: audioOutput.mimeType
560370
560611
  }));
560371
560612
  } catch (ttsError) {
560372
- log69.error(`TTS failed: ${ttsError.message}), sending text instead`);
560613
+ log70.error(`TTS failed: ${ttsError.message}), sending text instead`);
560373
560614
  ws.send(JSON.stringify({ type: "message", sessionId: unifiedSessionId, content, isStep: false }));
560374
560615
  }
560375
560616
  }
@@ -560385,7 +560626,7 @@ ${messageContent}`;
560385
560626
  sessionId: unifiedSessionId,
560386
560627
  error: error50.message
560387
560628
  }));
560388
- log69.error(`Error for session ${unifiedSessionId}: ${error50.message}`);
560629
+ log70.error(`Error for session ${unifiedSessionId}: ${error50.message}`);
560389
560630
  }
560390
560631
  });
560391
560632
  return;
@@ -560409,7 +560650,7 @@ ${messageContent}`;
560409
560650
  unsubscribeCanvas(ws);
560410
560651
  return;
560411
560652
  }
560412
- log69.debug(`WebSocket disconnected: ${data.sessionId}`);
560653
+ log70.debug(`WebSocket disconnected: ${data.sessionId}`);
560413
560654
  logSubscribers.delete(data.sessionId);
560414
560655
  sessionManager.delete(data.sessionId);
560415
560656
  laneQueue.cancel(data.sessionId);
@@ -560440,25 +560681,25 @@ ${messageContent}`;
560440
560681
  }
560441
560682
  }
560442
560683
  });
560443
- log69.info(`Gateway started successfully`);
560684
+ log70.info(`Gateway started successfully`);
560444
560685
  const isGatewayChild = process.env.HIVE_GATEWAY_CHILD === "1";
560445
560686
  if (isDev) {
560446
- log69.info(`[gateway] API: http://${host}:${port}`);
560447
- log69.info(`[gateway] WebSocket: ws://${host}:${port}/ws`);
560448
- log69.info(`[gateway] Canvas: ws://${host}:${port}/canvas`);
560449
- log69.info(`[gateway] Modo: desarrollo`);
560687
+ log70.info(`[gateway] API: http://${host}:${port}`);
560688
+ log70.info(`[gateway] WebSocket: ws://${host}:${port}/ws`);
560689
+ log70.info(`[gateway] Canvas: ws://${host}:${port}/canvas`);
560690
+ log70.info(`[gateway] Modo: desarrollo`);
560450
560691
  if (!isGatewayChild) {
560451
- log69.info(`\uD83D\uDC1D Administra tu Hive aqu\xED: http://localhost:5173`);
560692
+ log70.info(`\uD83D\uDC1D Administra tu Hive aqu\xED: http://localhost:5173`);
560452
560693
  }
560453
560694
  } else {
560454
560695
  const isSetupMode2 = gatewaySetupMode;
560455
560696
  const baseUrl = `http://${host}:${port}`;
560456
560697
  const uiUrl = isSetupMode2 ? `${baseUrl}/setup` : `${baseUrl}/ui`;
560457
- log69.info(`[gateway] UI: ${uiUrl}`);
560458
- log69.info(`[gateway] API: http://${host}:${port}`);
560459
- log69.info(`[gateway] WebSocket: ws://${host}:${port}/ws`);
560460
- log69.info(`[gateway] Canvas: ws://${host}:${port}/canvas`);
560461
- log69.info(isSetupMode2 ? `\uD83C\uDF89 Primer arranque \u2014 abriendo wizard de configuraci\xF3n...` : `\uD83D\uDC1D Administra tu Hive aqu\xED: ${uiUrl}`);
560698
+ log70.info(`[gateway] UI: ${uiUrl}`);
560699
+ log70.info(`[gateway] API: http://${host}:${port}`);
560700
+ log70.info(`[gateway] WebSocket: ws://${host}:${port}/ws`);
560701
+ log70.info(`[gateway] Canvas: ws://${host}:${port}/canvas`);
560702
+ log70.info(isSetupMode2 ? `\uD83C\uDF89 Primer arranque \u2014 abriendo wizard de configuraci\xF3n...` : `\uD83D\uDC1D Administra tu Hive aqu\xED: ${uiUrl}`);
560462
560703
  if (!process.env.NO_BROWSER) {
560463
560704
  try {
560464
560705
  const platform2 = process.platform;
@@ -560479,18 +560720,18 @@ ${messageContent}`;
560479
560720
  });
560480
560721
  proc.unref();
560481
560722
  } catch (err) {
560482
- log69.warn(`Could not open browser: ${err.message}`);
560723
+ log70.warn(`Could not open browser: ${err.message}`);
560483
560724
  }
560484
560725
  }
560485
560726
  }
560486
560727
  if (!gatewaySetupMode)
560487
- log69.info(`Channels: ${channelManager.listChannels().map((c3) => c3.name).join(", ") || "none"}`);
560728
+ log70.info(`Channels: ${channelManager.listChannels().map((c3) => c3.name).join(", ") || "none"}`);
560488
560729
  process.on("SIGTERM", async () => {
560489
- log69.info("Received SIGTERM, shutting down gracefully...");
560730
+ log70.info("Received SIGTERM, shutting down gracefully...");
560490
560731
  watchers.forEach((close) => close());
560491
560732
  const mcp = agent?.getMCPManager();
560492
560733
  if (mcp) {
560493
- log69.info("Disconnecting MCP servers...");
560734
+ log70.info("Disconnecting MCP servers...");
560494
560735
  await mcp.disconnectAll().catch(() => {});
560495
560736
  }
560496
560737
  if (channelManager)
@@ -560502,14 +560743,14 @@ ${messageContent}`;
560502
560743
  process.exit(0);
560503
560744
  });
560504
560745
  process.on("SIGHUP", async () => {
560505
- log69.info("Received SIGHUP, reloading configuration...");
560746
+ log70.info("Received SIGHUP, reloading configuration...");
560506
560747
  try {
560507
560748
  const newConfig = await loadConfig();
560508
560749
  await agent.updateConfig(newConfig);
560509
560750
  await agent.reload();
560510
- log69.info("Configuration reloaded successfully");
560751
+ log70.info("Configuration reloaded successfully");
560511
560752
  } catch (error50) {
560512
- log69.error(`Failed to reload configuration: ${error50.message}`);
560753
+ log70.error(`Failed to reload configuration: ${error50.message}`);
560513
560754
  }
560514
560755
  });
560515
560756
  }
@@ -561992,7 +562233,7 @@ var init_circuit_breaker = __esm(() => {
561992
562233
  circuitBreakerRegistry = new CircuitBreakerRegistry;
561993
562234
  });
561994
562235
  // packages/core/src/plugins/loader.ts
561995
- import { mkdirSync as mkdirSync11, readdirSync as readdirSync5, existsSync as existsSync19 } from "fs";
562236
+ import { mkdirSync as mkdirSync12, readdirSync as readdirSync5, existsSync as existsSync19 } from "fs";
561996
562237
  import * as path31 from "path";
561997
562238
 
561998
562239
  class PluginLoader {
@@ -562007,7 +562248,7 @@ class PluginLoader {
562007
562248
  constructor(options2) {
562008
562249
  this.options = options2;
562009
562250
  if (!existsSync19(options2.pluginDir)) {
562010
- mkdirSync11(options2.pluginDir, { recursive: true });
562251
+ mkdirSync12(options2.pluginDir, { recursive: true });
562011
562252
  }
562012
562253
  }
562013
562254
  async discover() {
@@ -562607,7 +562848,8 @@ var init_schemas4 = __esm(() => {
562607
562848
  prompt: exports_external.string()
562608
562849
  }),
562609
562850
  exports_external.object({ cmd: exports_external.literal("cancel"), taskId: exports_external.string() }),
562610
- exports_external.object({ cmd: exports_external.literal("status") })
562851
+ exports_external.object({ cmd: exports_external.literal("status") }),
562852
+ exports_external.object({ cmd: exports_external.literal("ping") })
562611
562853
  ]);
562612
562854
  });
562613
562855
 
@@ -562679,6 +562921,10 @@ var init_src4 = __esm(() => {
562679
562921
  ws.send(JSON.stringify(manager4.status()));
562680
562922
  break;
562681
562923
  }
562924
+ case "ping": {
562925
+ ws.send(JSON.stringify({ type: "pong" }));
562926
+ break;
562927
+ }
562682
562928
  }
562683
562929
  },
562684
562930
  close(ws) {
@@ -562697,7 +562943,7 @@ __export(exports_gateway, {
562697
562943
  start: () => start,
562698
562944
  reload: () => reload
562699
562945
  });
562700
- import { existsSync as existsSync20, mkdirSync as mkdirSync12, writeFileSync as writeFileSync4, readFileSync as readFileSync9, unlinkSync as unlinkSync5, openSync } from "fs";
562946
+ import { existsSync as existsSync20, mkdirSync as mkdirSync13, writeFileSync as writeFileSync6, readFileSync as readFileSync10, unlinkSync as unlinkSync5, openSync } from "fs";
562701
562947
  import * as path32 from "path";
562702
562948
  import { spawn as spawn5 } from "child_process";
562703
562949
  function cleanup() {
@@ -562732,7 +562978,7 @@ async function getPidFile() {
562732
562978
  function ensureLogDir() {
562733
562979
  const logDir = path32.dirname(getLogFile());
562734
562980
  if (!existsSync20(logDir)) {
562735
- mkdirSync12(logDir, { recursive: true });
562981
+ mkdirSync13(logDir, { recursive: true });
562736
562982
  }
562737
562983
  }
562738
562984
  function openBrowser(url3) {
@@ -562770,7 +563016,7 @@ async function isRunning() {
562770
563016
  const pidFile = await getPidFile();
562771
563017
  if (!existsSync20(pidFile))
562772
563018
  return false;
562773
- const pid = parseInt(readFileSync9(pidFile, "utf-8").trim(), 10);
563019
+ const pid = parseInt(readFileSync10(pidFile, "utf-8").trim(), 10);
562774
563020
  if (isNaN(pid))
562775
563021
  return false;
562776
563022
  try {
@@ -562843,7 +563089,7 @@ async function start(flags) {
562843
563089
  \u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2551
562844
563090
  \u2551 \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u2551
562845
563091
  \u2551 \u2551
562846
- \u2551 Personal Swarm AI Gateway \u2014 v2.0.1 \u2551
563092
+ \u2551 Personal Swarm AI Gateway \u2014 v2.0.3 \u2551
562847
563093
  \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
562848
563094
  `);
562849
563095
  }
@@ -562855,7 +563101,7 @@ async function start(flags) {
562855
563101
  stdio: ["ignore", openSync(logFile, "a"), openSync(logFile, "a")]
562856
563102
  });
562857
563103
  child.unref();
562858
- writeFileSync4(await getPidFile(), child.pid?.toString() || "");
563104
+ writeFileSync6(await getPidFile(), child.pid?.toString() || "");
562859
563105
  console.log(`\u2705 Hive Gateway iniciado en modo daemon (PID: ${child.pid})`);
562860
563106
  console.log(` Logs: ${logFile}`);
562861
563107
  return;
@@ -562969,6 +563215,12 @@ async function start(flags) {
562969
563215
  }
562970
563216
  return;
562971
563217
  }
563218
+ try {
563219
+ await Promise.resolve().then(() => (init_src4(), exports_src));
563220
+ console.log("\uD83C\uDF09 Code Bridge iniciado en puerto 18791");
563221
+ } catch (error50) {
563222
+ console.warn(`\u26A0\uFE0F No se pudo iniciar el Code Bridge: ${error50.message}`);
563223
+ }
562972
563224
  if (!daemon && !isGatewayChild) {
562973
563225
  const port = config4.gateway?.port || 18790;
562974
563226
  waitForPort(port, 30000).then(() => {
@@ -562988,7 +563240,7 @@ async function stop() {
562988
563240
  return;
562989
563241
  }
562990
563242
  const pidFile = await getPidFile();
562991
- const pid = parseInt(readFileSync9(pidFile, "utf-8").trim(), 10);
563243
+ const pid = parseInt(readFileSync10(pidFile, "utf-8").trim(), 10);
562992
563244
  try {
562993
563245
  process.kill(pid, "SIGTERM");
562994
563246
  unlinkSync5(pidFile);
@@ -563006,7 +563258,7 @@ async function status(flags) {
563006
563258
  const pidFile = await getPidFile();
563007
563259
  console.log(`Estado: ${running ? "\u2705 Corriendo" : "\u23F9\uFE0F Detenido"}`);
563008
563260
  if (running) {
563009
- const pid = readFileSync9(pidFile, "utf-8").trim();
563261
+ const pid = readFileSync10(pidFile, "utf-8").trim();
563010
563262
  console.log(`PID: ${pid}`);
563011
563263
  }
563012
563264
  console.log(`Puerto: ${config4.gateway?.port || 18790}`);
@@ -563018,7 +563270,7 @@ async function status(flags) {
563018
563270
  console.log(`Logs: ${getLogFile()}`);
563019
563271
  if (flags.includes("--json")) {
563020
563272
  console.log(`
563021
- ` + JSON.stringify({ running, pid: running ? readFileSync9(pidFile, "utf-8").trim() : null, config: config4 }, null, 2));
563273
+ ` + JSON.stringify({ running, pid: running ? readFileSync10(pidFile, "utf-8").trim() : null, config: config4 }, null, 2));
563022
563274
  }
563023
563275
  }
563024
563276
  async function reload() {
@@ -563026,7 +563278,7 @@ async function reload() {
563026
563278
  console.log("\u26A0\uFE0F Hive Gateway no est\xE1 corriendo");
563027
563279
  return;
563028
563280
  }
563029
- const pid = parseInt(readFileSync9(await getPidFile(), "utf-8").trim(), 10);
563281
+ const pid = parseInt(readFileSync10(await getPidFile(), "utf-8").trim(), 10);
563030
563282
  try {
563031
563283
  process.kill(pid, "SIGHUP");
563032
563284
  console.log("\u2705 Configuraci\xF3n recargada");
@@ -565053,7 +565305,7 @@ async function executeAsync(gatewayUrl, payload, spinner) {
565053
565305
  }
565054
565306
 
565055
565307
  // packages/cli/src/index.ts
565056
- var VERSION4 = "2.0.1";
565308
+ var VERSION4 = "2.0.3";
565057
565309
  var HELP = `
565058
565310
  \uD83D\uDC1D Hive \u2014 Personal Swarm AI Gateway v${VERSION4}
565059
565311