@nomad-e/bluma-cli 0.6.1 → 0.6.2

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/main.js +157 -92
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -396,6 +396,118 @@ var init_sandbox_policy = __esm({
396
396
  }
397
397
  });
398
398
 
399
+ // src/app/agent/runtime/task_store.ts
400
+ import fs12 from "fs";
401
+ import path10 from "path";
402
+ function getStorePath() {
403
+ const policy = getSandboxPolicy();
404
+ return path10.join(policy.workspaceRoot, ".bluma", "task_state.json");
405
+ }
406
+ function getDefaultState() {
407
+ return {
408
+ tasks: [],
409
+ nextId: 1,
410
+ activeTask: null,
411
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
412
+ };
413
+ }
414
+ function ensureLoaded() {
415
+ const storePath = getStorePath();
416
+ if (cache2 && cachePath === storePath) {
417
+ return cache2;
418
+ }
419
+ try {
420
+ if (fs12.existsSync(storePath)) {
421
+ const raw = fs12.readFileSync(storePath, "utf-8");
422
+ const parsed = JSON.parse(raw);
423
+ cache2 = {
424
+ tasks: Array.isArray(parsed.tasks) ? parsed.tasks : [],
425
+ nextId: typeof parsed.nextId === "number" ? parsed.nextId : 1,
426
+ activeTask: parsed.activeTask ?? null,
427
+ updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : (/* @__PURE__ */ new Date()).toISOString()
428
+ };
429
+ cachePath = storePath;
430
+ return cache2;
431
+ }
432
+ } catch {
433
+ }
434
+ cache2 = getDefaultState();
435
+ cachePath = storePath;
436
+ return cache2;
437
+ }
438
+ function persist(state2) {
439
+ const storePath = getStorePath();
440
+ fs12.mkdirSync(path10.dirname(storePath), { recursive: true });
441
+ state2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
442
+ fs12.writeFileSync(storePath, JSON.stringify(state2, null, 2), "utf-8");
443
+ cache2 = state2;
444
+ cachePath = storePath;
445
+ }
446
+ function updateTaskStore(mutator) {
447
+ const current = ensureLoaded();
448
+ const clone = {
449
+ tasks: current.tasks.map((task) => ({ ...task })),
450
+ nextId: current.nextId,
451
+ activeTask: current.activeTask ? { ...current.activeTask } : null,
452
+ updatedAt: current.updatedAt
453
+ };
454
+ mutator(clone);
455
+ persist(clone);
456
+ return clone;
457
+ }
458
+ function calculateTaskStats(tasks) {
459
+ const total = tasks.length;
460
+ const pending = tasks.filter((t) => t.status === "pending").length;
461
+ const inProgress = tasks.filter((t) => t.status === "in_progress").length;
462
+ const completed = tasks.filter((t) => t.status === "completed").length;
463
+ const progress = total > 0 ? Math.round(completed / total * 100) : 0;
464
+ return { total, pending, inProgress, completed, progress };
465
+ }
466
+ function buildTaskSnapshot() {
467
+ const state2 = ensureLoaded();
468
+ return {
469
+ tasks: state2.tasks.map((task) => ({ ...task })),
470
+ activeTask: state2.activeTask ? { ...state2.activeTask } : null,
471
+ stats: calculateTaskStats(state2.tasks),
472
+ updatedAt: state2.updatedAt
473
+ };
474
+ }
475
+ function registerWorker(worker) {
476
+ activeWorkers.set(worker.id, worker);
477
+ }
478
+ function completeWorker(workerId) {
479
+ const worker = activeWorkers.get(workerId);
480
+ if (worker) {
481
+ worker.status = "completed";
482
+ worker.endTime = Date.now();
483
+ worker.progress = {
484
+ ...worker.progress,
485
+ completed: true,
486
+ statusText: "Done"
487
+ };
488
+ worker.evictAfter = Date.now() + 3e4;
489
+ }
490
+ }
491
+ function evictWorkerTask(workerId) {
492
+ activeWorkers.delete(workerId);
493
+ }
494
+ function getVisibleWorkers() {
495
+ const now2 = Date.now();
496
+ return Array.from(activeWorkers.values()).filter(
497
+ (w) => (w.evictAfter ?? Infinity) > now2
498
+ );
499
+ }
500
+ var cache2, cachePath, activeWorkers;
501
+ var init_task_store = __esm({
502
+ "src/app/agent/runtime/task_store.ts"() {
503
+ "use strict";
504
+ init_sandbox_policy();
505
+ cache2 = null;
506
+ cachePath = null;
507
+ activeWorkers = /* @__PURE__ */ new Map();
508
+ }
509
+ });
510
+
399
511
  // src/app/agent/tools/CommandStatusTool/CommandStatusTool.ts
400
512
  var CommandStatusTool_exports = {};
401
513
  __export(CommandStatusTool_exports, {
@@ -1364,12 +1476,33 @@ async function spawnAgent(args) {
1364
1476
  );
1365
1477
  child.unref();
1366
1478
  updateSession(sessionId, { pid: child.pid });
1367
- spawnLog.info("Worker spawned successfully", {
1479
+ const workerTask = {
1480
+ id: sessionId,
1481
+ title,
1482
+ description: args.task,
1483
+ status: "running",
1484
+ task: args.task,
1485
+ progress: {
1486
+ step: 1,
1487
+ totalSteps: 10,
1488
+ currentTask: args.task?.slice(0, 100) || "Initializing...",
1489
+ statusText: "Running",
1490
+ lastActivity: Date.now()
1491
+ },
1492
+ startTime: Date.now(),
1493
+ endTime: void 0,
1494
+ evictAfter: void 0,
1495
+ agentType: args.agent_type || "general",
1496
+ parentSessionId: parentSessionId || void 0
1497
+ };
1498
+ registerWorker(workerTask);
1499
+ spawnLog.info("Worker spawned and registered", {
1368
1500
  sessionId,
1369
1501
  pid: child.pid,
1370
1502
  title,
1371
1503
  timeoutMs,
1372
- sandbox: true
1504
+ sandbox: true,
1505
+ workerTaskId: sessionId
1373
1506
  });
1374
1507
  return {
1375
1508
  success: true,
@@ -1411,6 +1544,19 @@ async function waitAgent(args) {
1411
1544
  }
1412
1545
  if (session.status !== "running") {
1413
1546
  waitLog.info("Agent completed", { sessionId, status: session.status });
1547
+ if (session.status === "completed") {
1548
+ completeWorker(sessionId);
1549
+ } else if (session.status === "cancelled") {
1550
+ const workerTask = {
1551
+ id: sessionId,
1552
+ title: session.title,
1553
+ description: session.title,
1554
+ status: "killed",
1555
+ startTime: Date.now(),
1556
+ endTime: Date.now()
1557
+ };
1558
+ registerWorker(workerTask);
1559
+ }
1414
1560
  return {
1415
1561
  success: true,
1416
1562
  completed: true,
@@ -1501,6 +1647,7 @@ var init_AgentCoordinationTool = __esm({
1501
1647
  "src/app/agent/tools/AgentCoordinationTool/AgentCoordinationTool.ts"() {
1502
1648
  "use strict";
1503
1649
  init_session_registry();
1650
+ init_task_store();
1504
1651
  init_logger();
1505
1652
  init_errors();
1506
1653
  init_worker_context();
@@ -15596,97 +15743,8 @@ async function countLines(args) {
15596
15743
  }
15597
15744
  }
15598
15745
 
15599
- // src/app/agent/runtime/task_store.ts
15600
- init_sandbox_policy();
15601
- import fs12 from "fs";
15602
- import path10 from "path";
15603
- var cache2 = null;
15604
- var cachePath = null;
15605
- function getStorePath() {
15606
- const policy = getSandboxPolicy();
15607
- return path10.join(policy.workspaceRoot, ".bluma", "task_state.json");
15608
- }
15609
- function getDefaultState() {
15610
- return {
15611
- tasks: [],
15612
- nextId: 1,
15613
- activeTask: null,
15614
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
15615
- };
15616
- }
15617
- function ensureLoaded() {
15618
- const storePath = getStorePath();
15619
- if (cache2 && cachePath === storePath) {
15620
- return cache2;
15621
- }
15622
- try {
15623
- if (fs12.existsSync(storePath)) {
15624
- const raw = fs12.readFileSync(storePath, "utf-8");
15625
- const parsed = JSON.parse(raw);
15626
- cache2 = {
15627
- tasks: Array.isArray(parsed.tasks) ? parsed.tasks : [],
15628
- nextId: typeof parsed.nextId === "number" ? parsed.nextId : 1,
15629
- activeTask: parsed.activeTask ?? null,
15630
- updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : (/* @__PURE__ */ new Date()).toISOString()
15631
- };
15632
- cachePath = storePath;
15633
- return cache2;
15634
- }
15635
- } catch {
15636
- }
15637
- cache2 = getDefaultState();
15638
- cachePath = storePath;
15639
- return cache2;
15640
- }
15641
- function persist(state2) {
15642
- const storePath = getStorePath();
15643
- fs12.mkdirSync(path10.dirname(storePath), { recursive: true });
15644
- state2.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
15645
- fs12.writeFileSync(storePath, JSON.stringify(state2, null, 2), "utf-8");
15646
- cache2 = state2;
15647
- cachePath = storePath;
15648
- }
15649
- function updateTaskStore(mutator) {
15650
- const current = ensureLoaded();
15651
- const clone = {
15652
- tasks: current.tasks.map((task) => ({ ...task })),
15653
- nextId: current.nextId,
15654
- activeTask: current.activeTask ? { ...current.activeTask } : null,
15655
- updatedAt: current.updatedAt
15656
- };
15657
- mutator(clone);
15658
- persist(clone);
15659
- return clone;
15660
- }
15661
- function calculateTaskStats(tasks) {
15662
- const total = tasks.length;
15663
- const pending = tasks.filter((t) => t.status === "pending").length;
15664
- const inProgress = tasks.filter((t) => t.status === "in_progress").length;
15665
- const completed = tasks.filter((t) => t.status === "completed").length;
15666
- const progress = total > 0 ? Math.round(completed / total * 100) : 0;
15667
- return { total, pending, inProgress, completed, progress };
15668
- }
15669
- function buildTaskSnapshot() {
15670
- const state2 = ensureLoaded();
15671
- return {
15672
- tasks: state2.tasks.map((task) => ({ ...task })),
15673
- activeTask: state2.activeTask ? { ...state2.activeTask } : null,
15674
- stats: calculateTaskStats(state2.tasks),
15675
- updatedAt: state2.updatedAt
15676
- };
15677
- }
15678
- var activeWorkers = /* @__PURE__ */ new Map();
15679
- function evictWorkerTask(workerId) {
15680
- activeWorkers.delete(workerId);
15681
- }
15682
- function getVisibleWorkers() {
15683
- const now2 = Date.now();
15684
- return Array.from(activeWorkers.values()).filter(
15685
- (w) => (w.evictAfter ?? Infinity) > now2
15686
- );
15687
- }
15688
-
15689
15746
  // src/app/agent/tools/TodoTool/TodoTool.ts
15747
+ init_task_store();
15690
15748
  function validateDescription(desc) {
15691
15749
  if (!desc || typeof desc !== "string") return "Description is required";
15692
15750
  if (desc.trim().length === 0) return "Description cannot be empty";
@@ -16527,6 +16585,7 @@ init_CommandStatusTool();
16527
16585
 
16528
16586
  // src/app/agent/tools/TaskBoundaryTool/TaskBoundaryTool.ts
16529
16587
  init_sandbox_policy();
16588
+ init_task_store();
16530
16589
  import path14 from "path";
16531
16590
  import { promises as fs13 } from "fs";
16532
16591
  var artifactsDir = null;
@@ -35533,6 +35592,9 @@ function useTerminalSize() {
35533
35592
  return size;
35534
35593
  }
35535
35594
 
35595
+ // src/app/ui/components/CoordinatorTaskPanel.tsx
35596
+ init_task_store();
35597
+
35536
35598
  // src/utils/format.ts
35537
35599
  function formatDuration2(ms, options) {
35538
35600
  if (ms < 6e4) {
@@ -36110,6 +36172,7 @@ var renderBridgePanel = () => {
36110
36172
  };
36111
36173
 
36112
36174
  // src/app/ui/components/slash-commands/renderers/taskRenderers.tsx
36175
+ init_task_store();
36113
36176
  import { Fragment as Fragment13, jsx as jsx87, jsxs as jsxs72 } from "react/jsx-runtime";
36114
36177
  var renderMasonSnapshot = () => {
36115
36178
  const snapshot = buildTaskSnapshot();
@@ -36227,6 +36290,7 @@ var runTasksClear = (agentRef) => {
36227
36290
  init_runtime_config();
36228
36291
  init_sessionPermissionState();
36229
36292
  init_sandbox_policy();
36293
+ init_task_store();
36230
36294
  import { Fragment as Fragment14, jsx as jsx88, jsxs as jsxs73 } from "react/jsx-runtime";
36231
36295
  var renderStatusline = () => {
36232
36296
  const cfg = getRuntimeConfig();
@@ -36474,6 +36538,7 @@ var renderPermissionsSnapshot = (sessionId) => {
36474
36538
  };
36475
36539
 
36476
36540
  // src/app/agent/runtime/diagnostics.ts
36541
+ init_task_store();
36477
36542
  init_runtime_config();
36478
36543
  init_sandbox_policy();
36479
36544
  init_session_registry();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomad-e/bluma-cli",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "BluMa independent agent for automation and advanced software engineering.",
5
5
  "author": "Alex Fonseca",
6
6
  "license": "Apache-2.0",