codebolt 1.11.5 → 1.11.7

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 (2) hide show
  1. package/dist/index.js +73 -36
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -463674,6 +463674,9 @@ exports.toolCliService = {
463674
463674
  const configFilePath = path_1.default.join(getGlobalCodeboltPath(), 'mcp_servers.json');
463675
463675
  const serverName = finalMessage.mcpName;
463676
463676
  const config = finalMessage.config;
463677
+ if (!fs.existsSync(configFilePath)) {
463678
+ fs.writeFileSync(configFilePath, JSON.stringify({ mcpServers: {}, enabled: [] }, null, 2));
463679
+ }
463677
463680
  const data = fs.readFileSync(configFilePath, 'utf8');
463678
463681
  const configData = JSON.parse(data);
463679
463682
  if (configData.mcpServers.hasOwnProperty(serverName)) {
@@ -490672,6 +490675,9 @@ async function toggleMcpServer(req, res) {
490672
490675
  try {
490673
490676
  const { serverName, enabled } = req.body;
490674
490677
  const configFilePath = path_1.default.join((0, serverPaths_1.getGlobalCodeboltPath)(), 'mcp_servers.json');
490678
+ if (!fs_1.default.existsSync(configFilePath)) {
490679
+ fs_1.default.writeFileSync(configFilePath, JSON.stringify({ mcpServers: {}, enabled: [] }, null, 2));
490680
+ }
490675
490681
  const data = fs_1.default.readFileSync(configFilePath, 'utf8');
490676
490682
  const mcpServer = JSON.parse(data);
490677
490683
  if (!mcpServer.enabled) {
@@ -516487,8 +516493,8 @@ class AgentProcessManager extends events_1.EventEmitter {
516487
516493
  super();
516488
516494
  this.processes = new Map();
516489
516495
  this.SPAWN_TIMEOUT = 500000; // 10 seconds
516490
- this.SHUTDOWN_TIMEOUT = 5000; // 5 seconds
516491
- this.FORCE_KILL_TIMEOUT = 3000; // 3 seconds
516496
+ this.FORCE_KILL_TIMEOUT = 3000; // 3 seconds after SIGTERM, send SIGKILL
516497
+ this.SHUTDOWN_TIMEOUT = 8000; // 8 seconds total — enough time for SIGTERM (3s) + SIGKILL (5s)
516492
516498
  this.STDOUT_THROTTLE_MS = 100;
516493
516499
  this.STDERR_THROTTLE_MS = 100;
516494
516500
  this.isShuttingDown = false;
@@ -516850,24 +516856,31 @@ class AgentProcessManager extends events_1.EventEmitter {
516850
516856
  // Force kill after timeout using tree-kill to ensure all child processes are killed
516851
516857
  setTimeout(() => {
516852
516858
  if (!resolved && this.processes.has(processId)) {
516853
- appLogger_1.default.warn(`[${processType} STOP] Forcing SIGKILL for process tree: ${processId} (pid: ${utilityProcess.pid})`);
516854
- // Send notification to UI
516855
- // sendNotificationToUi({
516856
- // type: 'agentProcessUpdate',
516857
- // actionType: WebSocketMessageType.AgentEvent,
516858
- // content: `Forcing SIGKILL for ${metadata.type}: ${metadata.name}`,
516859
- // templateType: TemplateEnum.AGENT,
516860
- // data: { text: `Forcing SIGKILL for ${metadata.type}: ${metadata.name}` },
516861
- // messageId: `agent_force_kill_${processId}_${Date.now()}`,
516862
- // threadId: metadata.threadId || ''
516863
- // });
516859
+ const pid = utilityProcess.pid;
516860
+ appLogger_1.default.warn(`[${processType} STOP] Forcing SIGKILL for process tree: ${processId} (pid: ${pid})`);
516864
516861
  try {
516865
- if (utilityProcess.pid) {
516862
+ if (pid) {
516866
516863
  // Use tree-kill with SIGKILL to forcefully terminate entire process tree
516867
- (0, tree_kill_1.default)(utilityProcess.pid, 'SIGKILL', (err) => {
516864
+ (0, tree_kill_1.default)(pid, 'SIGKILL', (err) => {
516868
516865
  if (err) {
516869
516866
  appLogger_1.default.warn(`[${processType} STOP] tree-kill SIGKILL warning: ${err.message}`);
516870
516867
  }
516868
+ // Verify the process is actually dead after a short delay
516869
+ setTimeout(() => {
516870
+ if (!resolved) {
516871
+ try {
516872
+ // process.kill(pid, 0) throws if process doesn't exist
516873
+ process.kill(pid, 0);
516874
+ appLogger_1.default.error(`[${processType} STOP] Process ${pid} still alive after SIGKILL, forcing cleanup`);
516875
+ }
516876
+ catch {
516877
+ // Process is dead — good
516878
+ appLogger_1.default.debug(`[${processType} STOP] Process ${pid} confirmed dead after SIGKILL`);
516879
+ }
516880
+ // Either way, trigger close to resolve the promise
516881
+ onClose(-1);
516882
+ }
516883
+ }, 1000);
516871
516884
  });
516872
516885
  }
516873
516886
  else {
@@ -516876,16 +516889,6 @@ class AgentProcessManager extends events_1.EventEmitter {
516876
516889
  }
516877
516890
  catch (error) {
516878
516891
  appLogger_1.default.error(`[${processType} STOP] Error sending SIGKILL: ${error.message}`);
516879
- // Send notification to UI
516880
- // sendNotificationToUi({
516881
- // type: 'agentProcessUpdate',
516882
- // actionType: WebSocketMessageType.AgentEvent,
516883
- // content: `Error sending SIGKILL to ${metadata.type}: ${metadata.name}. Error: ${(error as Error).message}`,
516884
- // templateType: TemplateEnum.AGENT,
516885
- // data: { text: `Error sending SIGKILL to ${metadata.type}: ${metadata.name}. Error: ${(error as Error).message}` },
516886
- // messageId: `agent_kill_error_${processId}_${Date.now()}`,
516887
- // threadId: metadata.threadId || ''
516888
- // });
516889
516892
  onClose(-1);
516890
516893
  }
516891
516894
  }
@@ -531016,6 +531019,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
531016
531019
  };
531017
531020
  Object.defineProperty(exports, "__esModule", ({ value: true }));
531018
531021
  exports.getLocalProjectAgents = exports.getInstalled = exports.getIntalledAgent = exports.updateAgent = exports.install = exports.installLocal = exports.getAgentFromLocal = exports.changeAgent = exports.stopAgent = exports.startAgent = exports.updateAgentIndex = exports.refreshAgentIndexFromServer = exports.initializeAgentIndex = void 0;
531022
+ exports.fetchAgents = fetchAgents;
531019
531023
  exports.getInstalledAgentsAction = getInstalledAgentsAction;
531020
531024
  exports.getAgentConfig = getAgentConfig;
531021
531025
  exports.getAgentConfigs = getAgentConfigs;
@@ -531076,11 +531080,9 @@ async function fetchAgents() {
531076
531080
  try {
531077
531081
  const response = await axios_1.default.get('https://api.codebolt.ai/api/agents/list');
531078
531082
  const agents = response.data;
531079
- // Save agents to assets directory which gets bundled with the app
531080
- const assetsDir = path_1.default.join(process.cwd(), 'assets');
531081
- await fs_extra_1.default.ensureDir(assetsDir);
531082
- // Save agents to a JSON file in assets
531083
- const agentsFilePath = path_1.default.join(assetsDir, 'agents.json');
531083
+ // Save agents to the codebolt config directory
531084
+ ensureAgentCodeboltPath();
531085
+ const agentsFilePath = path_1.default.join(codeboltPath, 'agents.json');
531084
531086
  await fs_extra_1.default.writeJson(agentsFilePath, agents, { spaces: 2 });
531085
531087
  logger.info(`Successfully fetched ${agents.length} agents and saved to ${agentsFilePath}`);
531086
531088
  return agents;
@@ -560429,15 +560431,29 @@ const getLocalAgentService = async (agentName) => {
560429
560431
  };
560430
560432
  };
560431
560433
  exports.getLocalAgentService = getLocalAgentService;
560432
- const getLLMPricingFromLocal = () => {
560433
- // const destinationFolder = path.join(__dirname, './../../../../.codebolt');
560434
- const llmpricing = path_1.default.join(ensureLlmConfigPath(), 'llmpricing.json');
560434
+ const getLLMPricingFromLocal = async () => {
560435
+ const configPath = ensureLlmConfigPath();
560436
+ const llmpricing = path_1.default.join(configPath, 'llmpricing.json');
560435
560437
  if (fs_1.default.existsSync(llmpricing)) {
560436
560438
  return JSON.parse(fs_1.default.readFileSync(llmpricing, 'utf-8'));
560437
560439
  }
560438
- else {
560439
- throw new Error(`Agent not file not found in ${ensureLlmConfigPath()}`);
560440
+ // File not found locally — fetch from API and cache
560441
+ logger.info(`[getLLMPricingFromLocal] llmpricing.json not found, fetching from API`);
560442
+ try {
560443
+ const pricingData = await (0, llmHelper_1.getLLMPricingFromApi)();
560444
+ if (pricingData) {
560445
+ if (!fs_1.default.existsSync(configPath)) {
560446
+ fs_1.default.mkdirSync(configPath, { recursive: true });
560447
+ }
560448
+ fs_1.default.writeFileSync(llmpricing, JSON.stringify(pricingData, null, 2));
560449
+ logger.info(`[getLLMPricingFromLocal] Fetched and cached llmpricing.json`);
560450
+ return pricingData;
560451
+ }
560452
+ }
560453
+ catch (error) {
560454
+ logger.error(`[getLLMPricingFromLocal] Failed to fetch LLM pricing from API: ${error}`);
560440
560455
  }
560456
+ return [];
560441
560457
  };
560442
560458
  exports.getLLMPricingFromLocal = getLLMPricingFromLocal;
560443
560459
  const updateLLMPricingIndex = async () => {
@@ -563914,6 +563930,9 @@ exports.testTool = testTool;
563914
563930
  const configugeServer = async (updatedConfig, serverName) => {
563915
563931
  try {
563916
563932
  const configFilePath = path.join(ensureMcpCodeboltPath(), 'mcp_servers.json');
563933
+ if (!fs.existsSync(configFilePath)) {
563934
+ fs.writeFileSync(configFilePath, JSON.stringify({ mcpServers: {}, enabled: [] }, null, 2));
563935
+ }
563917
563936
  const data = fs.readFileSync(configFilePath, 'utf8');
563918
563937
  const mcpServer = JSON.parse(data);
563919
563938
  if (!serverName) {
@@ -605421,7 +605440,25 @@ async function findAgentById(agentId) {
605421
605440
  appLogger_1.default.debug(`[findAgentById] Found agent in local project agents: ${agent.agent_id || agent.agentId || agent.id}`);
605422
605441
  }
605423
605442
  else {
605424
- appLogger_1.default.warn(`[findAgentById] Agent ${agentId} not found in any location`);
605443
+ // Fallback: fetch agents from remote API
605444
+ appLogger_1.default.info(`[findAgentById] Agent ${agentId} not found locally, fetching from remote API`);
605445
+ try {
605446
+ const remoteAgents = await (0, agentService_1.fetchAgents)();
605447
+ if (remoteAgents && remoteAgents.length > 0) {
605448
+ appLogger_1.default.info(`[findAgentById] Fetched ${remoteAgents.length} agents from remote API`);
605449
+ agent = remoteAgents.find(a => a.agent_id === agentId || a.id === agentId || a.unique_id === agentId);
605450
+ if (agent) {
605451
+ agent.isLocal = false;
605452
+ appLogger_1.default.info(`[findAgentById] Found agent ${agentId} from remote API`);
605453
+ }
605454
+ else {
605455
+ appLogger_1.default.warn(`[findAgentById] Agent ${agentId} not found in remote API either`);
605456
+ }
605457
+ }
605458
+ }
605459
+ catch (remoteError) {
605460
+ appLogger_1.default.error(`[findAgentById] Failed to fetch agents from remote API: ${remoteError}`);
605461
+ }
605425
605462
  }
605426
605463
  }
605427
605464
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebolt",
3
- "version": "1.11.5",
3
+ "version": "1.11.7",
4
4
  "description": "CodeBolt headless server CLI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",