@nomad-e/bluma-cli 0.6.0 → 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.
- package/dist/main.js +157 -92
- package/package.json +2 -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
|
-
|
|
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.
|
|
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",
|
|
@@ -94,6 +94,7 @@
|
|
|
94
94
|
"latest-version": "^9.0.0",
|
|
95
95
|
"lodash-es": "^4.18.1",
|
|
96
96
|
"marked": "^16.1.2",
|
|
97
|
+
"minimatch": "^10.2.5",
|
|
97
98
|
"next": "^16.2.6",
|
|
98
99
|
"openai": "^4.47.3",
|
|
99
100
|
"react": "^19.2.5",
|