@nomad-e/bluma-cli 0.26.0 → 0.26.1
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 +84 -106
- package/package.json +1 -3
package/dist/main.js
CHANGED
|
@@ -2616,17 +2616,22 @@ var init_CtxInspectTool = __esm({
|
|
|
2616
2616
|
import path32 from "path";
|
|
2617
2617
|
import { mkdirSync as mkdirSync3 } from "fs";
|
|
2618
2618
|
import { promises as fs27 } from "fs";
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
const nodeRequire = createRequire(import.meta.url);
|
|
2622
|
-
return nodeRequire("better-sqlite3");
|
|
2623
|
-
}
|
|
2624
|
-
function getSessionDbPath(appDir = getPreferredAppDir()) {
|
|
2625
|
-
return path32.join(appDir, BLUMA_SESSION_DB_FILE);
|
|
2619
|
+
function getSessionIndexPath(appDir = getPreferredAppDir()) {
|
|
2620
|
+
return path32.join(appDir, SESSION_INDEX_FILE);
|
|
2626
2621
|
}
|
|
2627
2622
|
function normalizeRelativePath(relativePath) {
|
|
2628
2623
|
return relativePath.split(path32.sep).join("/");
|
|
2629
2624
|
}
|
|
2625
|
+
function emptyStore() {
|
|
2626
|
+
return { version: 1, sessions: {} };
|
|
2627
|
+
}
|
|
2628
|
+
async function persistStore(store2, appDir) {
|
|
2629
|
+
mkdirSync3(appDir, { recursive: true });
|
|
2630
|
+
const filePath = getSessionIndexPath(appDir);
|
|
2631
|
+
const tmp = `${filePath}.${Date.now()}.tmp`;
|
|
2632
|
+
await fs27.writeFile(tmp, JSON.stringify(store2, null, 2), "utf-8");
|
|
2633
|
+
await fs27.rename(tmp, filePath);
|
|
2634
|
+
}
|
|
2630
2635
|
async function walkSessionJsonFiles(dir, onFile) {
|
|
2631
2636
|
let entries;
|
|
2632
2637
|
try {
|
|
@@ -2707,22 +2712,30 @@ async function readSessionMetaFromJson(absPath) {
|
|
|
2707
2712
|
}
|
|
2708
2713
|
}
|
|
2709
2714
|
}
|
|
2710
|
-
|
|
2715
|
+
function upsertIntoStore(store2, row) {
|
|
2716
|
+
const rel = normalizeRelativePath(row.relativePath);
|
|
2717
|
+
const existing = store2.sessions[row.sessionId];
|
|
2718
|
+
if (!existing) {
|
|
2719
|
+
store2.sessions[row.sessionId] = {
|
|
2720
|
+
relativePath: rel,
|
|
2721
|
+
createdAt: row.createdAt,
|
|
2722
|
+
updatedAt: row.updatedAt,
|
|
2723
|
+
preview: row.preview
|
|
2724
|
+
};
|
|
2725
|
+
return;
|
|
2726
|
+
}
|
|
2727
|
+
const existingMs = Date.parse(existing.updatedAt);
|
|
2728
|
+
const incomingMs = Date.parse(row.updatedAt);
|
|
2729
|
+
const incomingIsNewer = Number.isFinite(incomingMs) && incomingMs >= (Number.isFinite(existingMs) ? existingMs : 0);
|
|
2730
|
+
store2.sessions[row.sessionId] = {
|
|
2731
|
+
relativePath: incomingIsNewer ? rel : existing.relativePath,
|
|
2732
|
+
createdAt: existing.createdAt || row.createdAt,
|
|
2733
|
+
updatedAt: incomingIsNewer ? row.updatedAt : existing.updatedAt,
|
|
2734
|
+
preview: incomingIsNewer ? row.preview : existing.preview
|
|
2735
|
+
};
|
|
2736
|
+
}
|
|
2737
|
+
async function migrateLegacyIndex(store2, appDir) {
|
|
2711
2738
|
const jsonl = await loadJsonlEntries(appDir);
|
|
2712
|
-
const upsert = db.prepare(`
|
|
2713
|
-
INSERT INTO agent_sessions (session_id, relative_path, created_at, updated_at, preview)
|
|
2714
|
-
VALUES (@sessionId, @relativePath, @createdAt, @updatedAt, @preview)
|
|
2715
|
-
ON CONFLICT(session_id) DO UPDATE SET
|
|
2716
|
-
relative_path = excluded.relative_path,
|
|
2717
|
-
updated_at = CASE
|
|
2718
|
-
WHEN excluded.updated_at > agent_sessions.updated_at THEN excluded.updated_at
|
|
2719
|
-
ELSE agent_sessions.updated_at
|
|
2720
|
-
END,
|
|
2721
|
-
preview = CASE
|
|
2722
|
-
WHEN excluded.updated_at > agent_sessions.updated_at THEN excluded.preview
|
|
2723
|
-
ELSE agent_sessions.preview
|
|
2724
|
-
END
|
|
2725
|
-
`);
|
|
2726
2739
|
const insertFromPath = async (sessionId, absPath, jsonlUpdatedAt) => {
|
|
2727
2740
|
let rel;
|
|
2728
2741
|
try {
|
|
@@ -2732,7 +2745,7 @@ async function runMigrationV1(db, appDir) {
|
|
|
2732
2745
|
}
|
|
2733
2746
|
const meta = await readSessionMetaFromJson(absPath);
|
|
2734
2747
|
const updatedAt = jsonlUpdatedAt && Date.parse(jsonlUpdatedAt) > Date.parse(meta.updatedAt) ? jsonlUpdatedAt : meta.updatedAt;
|
|
2735
|
-
|
|
2748
|
+
upsertIntoStore(store2, {
|
|
2736
2749
|
sessionId,
|
|
2737
2750
|
relativePath: rel,
|
|
2738
2751
|
createdAt: meta.createdAt,
|
|
@@ -2746,7 +2759,7 @@ async function runMigrationV1(db, appDir) {
|
|
|
2746
2759
|
await fs27.access(full);
|
|
2747
2760
|
await insertFromPath(sessionId, full, entry.updatedAt);
|
|
2748
2761
|
} catch {
|
|
2749
|
-
|
|
2762
|
+
upsertIntoStore(store2, {
|
|
2750
2763
|
sessionId,
|
|
2751
2764
|
relativePath: entry.relativePath,
|
|
2752
2765
|
createdAt: entry.updatedAt,
|
|
@@ -2756,109 +2769,74 @@ async function runMigrationV1(db, appDir) {
|
|
|
2756
2769
|
}
|
|
2757
2770
|
}
|
|
2758
2771
|
const sessionsRoot = path32.join(appDir, "sessions");
|
|
2759
|
-
const existing = db.prepare("SELECT session_id FROM agent_sessions").all();
|
|
2760
|
-
const seen = new Set(existing.map((r) => r.session_id));
|
|
2761
2772
|
await walkSessionJsonFiles(sessionsRoot, async (absPath) => {
|
|
2762
2773
|
const sessionId = path32.basename(absPath, ".json");
|
|
2763
|
-
if (!sessionId ||
|
|
2764
|
-
seen.add(sessionId);
|
|
2774
|
+
if (!sessionId || store2.sessions[sessionId]) return;
|
|
2765
2775
|
await insertFromPath(sessionId, absPath);
|
|
2766
2776
|
});
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
CREATE INDEX IF NOT EXISTS idx_agent_sessions_updated
|
|
2779
|
-
ON agent_sessions(updated_at DESC);
|
|
2780
|
-
`);
|
|
2777
|
+
}
|
|
2778
|
+
async function loadStoreFromDisk(appDir) {
|
|
2779
|
+
try {
|
|
2780
|
+
const raw = await fs27.readFile(getSessionIndexPath(appDir), "utf-8");
|
|
2781
|
+
const parsed = JSON.parse(raw);
|
|
2782
|
+
if (parsed.version === 1 && parsed.sessions && typeof parsed.sessions === "object") {
|
|
2783
|
+
return { version: 1, sessions: { ...parsed.sessions } };
|
|
2784
|
+
}
|
|
2785
|
+
} catch {
|
|
2786
|
+
}
|
|
2787
|
+
return emptyStore();
|
|
2781
2788
|
}
|
|
2782
2789
|
async function ensureSessionIndexDb(appDir = getPreferredAppDir()) {
|
|
2783
|
-
if (
|
|
2784
|
-
return
|
|
2790
|
+
if (storeCache && storeAppDir === appDir) {
|
|
2791
|
+
return;
|
|
2785
2792
|
}
|
|
2786
|
-
if (!
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2793
|
+
if (!loadPromise || storeAppDir !== appDir) {
|
|
2794
|
+
loadPromise = (async () => {
|
|
2795
|
+
const store2 = await loadStoreFromDisk(appDir);
|
|
2796
|
+
if (Object.keys(store2.sessions).length === 0) {
|
|
2797
|
+
await migrateLegacyIndex(store2, appDir);
|
|
2798
|
+
if (Object.keys(store2.sessions).length > 0) {
|
|
2799
|
+
await persistStore(store2, appDir);
|
|
2792
2800
|
}
|
|
2793
|
-
dbInstance = null;
|
|
2794
2801
|
}
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
mkdirSync3(path32.dirname(dbPath), { recursive: true });
|
|
2798
|
-
const db = new BetterSqlite3(dbPath);
|
|
2799
|
-
db.pragma("journal_mode = WAL");
|
|
2800
|
-
applySchema(db);
|
|
2801
|
-
const version = db.pragma("user_version", { simple: true });
|
|
2802
|
-
if (version < SCHEMA_VERSION) {
|
|
2803
|
-
await runMigrationV1(db, appDir);
|
|
2804
|
-
}
|
|
2805
|
-
dbInstance = db;
|
|
2806
|
-
dbAppDir = appDir;
|
|
2802
|
+
storeCache = store2;
|
|
2803
|
+
storeAppDir = appDir;
|
|
2807
2804
|
})();
|
|
2808
2805
|
}
|
|
2809
|
-
await
|
|
2810
|
-
return dbInstance;
|
|
2806
|
+
await loadPromise;
|
|
2811
2807
|
}
|
|
2812
2808
|
async function upsertSessionIndexRow(row, appDir = getPreferredAppDir()) {
|
|
2813
|
-
|
|
2814
|
-
const
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
ON CONFLICT(session_id) DO UPDATE SET
|
|
2818
|
-
relative_path = excluded.relative_path,
|
|
2819
|
-
updated_at = excluded.updated_at,
|
|
2820
|
-
preview = excluded.preview
|
|
2821
|
-
`);
|
|
2822
|
-
stmt.run({
|
|
2823
|
-
sessionId: row.sessionId,
|
|
2824
|
-
relativePath: normalizeRelativePath(row.relativePath),
|
|
2825
|
-
createdAt: row.createdAt,
|
|
2826
|
-
updatedAt: row.updatedAt,
|
|
2827
|
-
preview: row.preview
|
|
2828
|
-
});
|
|
2809
|
+
await ensureSessionIndexDb(appDir);
|
|
2810
|
+
const store2 = storeCache;
|
|
2811
|
+
upsertIntoStore(store2, row);
|
|
2812
|
+
await persistStore(store2, appDir);
|
|
2829
2813
|
}
|
|
2830
2814
|
async function getSessionPathFromIndex(sessionId, appDir = getPreferredAppDir()) {
|
|
2831
|
-
|
|
2832
|
-
const
|
|
2833
|
-
return
|
|
2815
|
+
await ensureSessionIndexDb(appDir);
|
|
2816
|
+
const entry = storeCache?.sessions[sessionId];
|
|
2817
|
+
return entry?.relativePath?.replace(/\//g, path32.sep) ?? null;
|
|
2834
2818
|
}
|
|
2835
2819
|
async function listSessionsFromIndex(limit = 50, appDir = getPreferredAppDir()) {
|
|
2836
|
-
|
|
2837
|
-
const
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
relativePath: r.relative_path.replace(/\//g, path32.sep),
|
|
2846
|
-
createdAt: r.created_at,
|
|
2847
|
-
updatedAt: r.updated_at,
|
|
2848
|
-
preview: r.preview
|
|
2849
|
-
}));
|
|
2820
|
+
await ensureSessionIndexDb(appDir);
|
|
2821
|
+
const sessions = storeCache?.sessions ?? {};
|
|
2822
|
+
return Object.entries(sessions).map(([sessionId, row]) => ({
|
|
2823
|
+
sessionId,
|
|
2824
|
+
relativePath: row.relativePath.replace(/\//g, path32.sep),
|
|
2825
|
+
createdAt: row.createdAt,
|
|
2826
|
+
updatedAt: row.updatedAt,
|
|
2827
|
+
preview: row.preview
|
|
2828
|
+
})).sort((a, b) => Date.parse(b.updatedAt) - Date.parse(a.updatedAt)).slice(0, limit);
|
|
2850
2829
|
}
|
|
2851
|
-
var AGENT_SESSION_PATHS_JSONL,
|
|
2830
|
+
var AGENT_SESSION_PATHS_JSONL, SESSION_INDEX_FILE, storeCache, storeAppDir, loadPromise;
|
|
2852
2831
|
var init_session_index_db = __esm({
|
|
2853
2832
|
"src/app/agent/session_manager/session_index_db.ts"() {
|
|
2854
2833
|
"use strict";
|
|
2855
2834
|
init_bluma_app_dir();
|
|
2856
2835
|
AGENT_SESSION_PATHS_JSONL = "agent_session_paths.jsonl";
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
migratePromise = null;
|
|
2836
|
+
SESSION_INDEX_FILE = "session_index.json";
|
|
2837
|
+
storeCache = null;
|
|
2838
|
+
storeAppDir = null;
|
|
2839
|
+
loadPromise = null;
|
|
2862
2840
|
}
|
|
2863
2841
|
});
|
|
2864
2842
|
|
|
@@ -39031,7 +39009,7 @@ import { promisify as promisify2 } from "util";
|
|
|
39031
39009
|
|
|
39032
39010
|
// src/app/utils/clipboardNative.ts
|
|
39033
39011
|
import { existsSync as existsSync7 } from "fs";
|
|
39034
|
-
import { createRequire
|
|
39012
|
+
import { createRequire } from "module";
|
|
39035
39013
|
import { dirname as dirname4, join as join13 } from "path";
|
|
39036
39014
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
39037
39015
|
var __dirname;
|
|
@@ -39079,7 +39057,7 @@ function getNativeModule() {
|
|
|
39079
39057
|
throw loadError;
|
|
39080
39058
|
}
|
|
39081
39059
|
try {
|
|
39082
|
-
const require2 =
|
|
39060
|
+
const require2 = createRequire(import.meta.url);
|
|
39083
39061
|
const mod = require2(nativePath);
|
|
39084
39062
|
nativeModule = mod;
|
|
39085
39063
|
return nativeModule;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomad-e/bluma-cli",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.1",
|
|
4
4
|
"description": "BluMa independent agent for automation and advanced software engineering.",
|
|
5
5
|
"author": "Alex Fonseca",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"@babel/preset-env": "^7.28.0",
|
|
12
12
|
"@babel/preset-react": "^7.27.1",
|
|
13
13
|
"@babel/preset-typescript": "^7.27.1",
|
|
14
|
-
"@types/better-sqlite3": "^7.6.13",
|
|
15
14
|
"@types/diff": "^7.0.2",
|
|
16
15
|
"@types/glob": "^8.1.0",
|
|
17
16
|
"@types/jest": "^30.0.0",
|
|
@@ -75,7 +74,6 @@
|
|
|
75
74
|
"@types/react-dom": "^19.2.3",
|
|
76
75
|
"auto-bind": "^5.0.1",
|
|
77
76
|
"axios": "^1.16.0",
|
|
78
|
-
"better-sqlite3": "^11.10.0",
|
|
79
77
|
"bidi-js": "^1.0.3",
|
|
80
78
|
"chalk": "^5.5.0",
|
|
81
79
|
"class-variance-authority": "^0.7.1",
|