clementine-agent 1.0.36 → 1.0.39
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/cli/dashboard.js +16 -5
- package/dist/cli/index.js +59 -42
- package/package.json +1 -1
package/dist/cli/dashboard.js
CHANGED
|
@@ -1159,6 +1159,17 @@ function writeCronFileAt(cronFile, parsed, jobs) {
|
|
|
1159
1159
|
}
|
|
1160
1160
|
// ── Express app ──────────────────────────────────────────────────────
|
|
1161
1161
|
export async function cmdDashboard(opts) {
|
|
1162
|
+
// Ensure BASE_DIR exists before any dashboard-local files (PID file, auth
|
|
1163
|
+
// token) are written. Other CLI commands route through ensureDataHome() in
|
|
1164
|
+
// index.ts, but the dashboard command doesn't — on a truly fresh install
|
|
1165
|
+
// where someone runs `clementine dashboard` before `clementine launch` or
|
|
1166
|
+
// `config setup`, the parent-process writeFileSync(DASHBOARD_PID_FILE)
|
|
1167
|
+
// would ENOENT and the dashboard would die before the browser could see
|
|
1168
|
+
// it. Idempotent, so safe for every invocation.
|
|
1169
|
+
try {
|
|
1170
|
+
mkdirSync(BASE_DIR, { recursive: true });
|
|
1171
|
+
}
|
|
1172
|
+
catch { /* ignore */ }
|
|
1162
1173
|
// Child process skips the kill step — parent already handled it
|
|
1163
1174
|
if (!process.env.__CLEM_DASHBOARD_CHILD) {
|
|
1164
1175
|
const killed = killExistingDashboards();
|
|
@@ -9328,7 +9339,7 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
9328
9339
|
const wmHtml = a.workingMemorySnippet
|
|
9329
9340
|
? '<div style="margin-top:8px;padding:8px;background:var(--bg-input);border-radius:6px;font-size:11px;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + a.workingMemorySnippet + '</div>'
|
|
9330
9341
|
: '';
|
|
9331
|
-
return '<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:16px;cursor:pointer" onclick="showPage(
|
|
9342
|
+
return '<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:16px;cursor:pointer" onclick="showPage(\\'team\\');setTimeout(()=>selectAgent(\\''+a.slug+'\\'),100)">' +
|
|
9332
9343
|
'<div style="display:flex;align-items:center;gap:10px;margin-bottom:10px">' +
|
|
9333
9344
|
'<div style="width:40px;height:40px;border-radius:50%;background:var(--clementine);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:18px">' + avatarLetter + '</div>' +
|
|
9334
9345
|
'<div><div style="font-weight:600">' + (a.name || a.slug) + '</div>' +
|
|
@@ -16480,11 +16491,11 @@ async function applyBrokenJobFix(jobName) {
|
|
|
16480
16491
|
return;
|
|
16481
16492
|
}
|
|
16482
16493
|
var diffPreview = (dryRes.diff || '(no diff)').slice(0, 1200);
|
|
16483
|
-
var msg = 'Apply this fix to ' + jobName + '
|
|
16484
|
-
+ 'File: ' + (dryRes.file || 'unknown') + '
|
|
16485
|
-
+ 'Operations: ' + (dryRes.appliedOps || []).length + '
|
|
16494
|
+
var msg = 'Apply this fix to ' + jobName + '?\\n\\n'
|
|
16495
|
+
+ 'File: ' + (dryRes.file || 'unknown') + '\\n'
|
|
16496
|
+
+ 'Operations: ' + (dryRes.appliedOps || []).length + '\\n\\n'
|
|
16486
16497
|
+ diffPreview
|
|
16487
|
-
+ '
|
|
16498
|
+
+ '\\n\\nA .bak will be written. The daemon auto-reloads; the next run will be fix-verified.';
|
|
16488
16499
|
if (!confirm(msg)) return;
|
|
16489
16500
|
|
|
16490
16501
|
var res = await apiJson('POST', '/api/cron/broken-jobs/' + encodeURIComponent(jobName) + '/apply-fix', {});
|
package/dist/cli/index.js
CHANGED
|
@@ -480,11 +480,10 @@ function cmdDoctor(opts = {}) {
|
|
|
480
480
|
console.log(` ${DIM}Running health checks...${fix ? ` (auto-fix enabled)` : ''}${RESET}`);
|
|
481
481
|
console.log();
|
|
482
482
|
let issues = 0;
|
|
483
|
-
let warnings = 0;
|
|
484
483
|
let fixed = 0;
|
|
485
484
|
const isMac = process.platform === 'darwin';
|
|
486
485
|
const isLinux = process.platform === 'linux';
|
|
487
|
-
|
|
486
|
+
let hasBrew = isMac && (() => { try {
|
|
488
487
|
execSync('which brew', { stdio: 'pipe' });
|
|
489
488
|
return true;
|
|
490
489
|
}
|
|
@@ -498,9 +497,19 @@ function cmdDoctor(opts = {}) {
|
|
|
498
497
|
catch {
|
|
499
498
|
return false;
|
|
500
499
|
} })();
|
|
501
|
-
//
|
|
502
|
-
//
|
|
500
|
+
// Homebrew official installer. Honors NONINTERACTIVE=1 (set by tryFix) so
|
|
501
|
+
// it won't block on sudo or "Press Return" prompts, though it still needs
|
|
502
|
+
// the password cached or sudoless access. Surfaced as copy-paste guidance
|
|
503
|
+
// when --fix is off.
|
|
503
504
|
const BREW_INSTALL_CMD = '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"';
|
|
505
|
+
/** Resolve the current brew binary path after a fresh install. */
|
|
506
|
+
const brewBin = () => {
|
|
507
|
+
for (const p of ['/opt/homebrew/bin/brew', '/usr/local/bin/brew']) {
|
|
508
|
+
if (existsSync(p))
|
|
509
|
+
return p;
|
|
510
|
+
}
|
|
511
|
+
return 'brew';
|
|
512
|
+
};
|
|
504
513
|
/** Attempt a fix command, return true on success. */
|
|
505
514
|
function tryFix(label, cmd, opts) {
|
|
506
515
|
if (!fix)
|
|
@@ -575,33 +584,51 @@ function cmdDoctor(opts = {}) {
|
|
|
575
584
|
issues++;
|
|
576
585
|
}
|
|
577
586
|
}
|
|
587
|
+
// macOS: if Homebrew is missing and --fix is on, install it up front so
|
|
588
|
+
// the subsequent redis-server / libomp checks can auto-resolve. Brew's
|
|
589
|
+
// installer honors NONINTERACTIVE=1 (which tryFix sets), but still needs
|
|
590
|
+
// sudo access — fails gracefully and falls back to copy-paste guidance
|
|
591
|
+
// if sudo isn't available.
|
|
592
|
+
if (isMac && !hasBrew && fix) {
|
|
593
|
+
console.log(` ${RED}FAIL${RESET} Homebrew not installed (required to install graph-memory deps)`);
|
|
594
|
+
if (tryFix('Homebrew', BREW_INSTALL_CMD, { timeout: 600000 })) {
|
|
595
|
+
hasBrew = existsSync('/opt/homebrew/bin/brew') || existsSync('/usr/local/bin/brew');
|
|
596
|
+
}
|
|
597
|
+
if (!hasBrew) {
|
|
598
|
+
console.log(` Install manually, then re-run ${CYAN}clementine doctor --fix${RESET}:`);
|
|
599
|
+
console.log(` ${BREW_INSTALL_CMD}`);
|
|
600
|
+
issues++;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
else if (isMac && !hasBrew) {
|
|
604
|
+
console.log(` ${RED}FAIL${RESET} Homebrew not installed (required to install graph-memory deps)`);
|
|
605
|
+
console.log(` Install it, then run ${CYAN}clementine doctor --fix${RESET}:`);
|
|
606
|
+
console.log(` ${BREW_INSTALL_CMD}`);
|
|
607
|
+
issues++;
|
|
608
|
+
}
|
|
578
609
|
// FalkorDB graph engine — system dependencies: redis
|
|
579
|
-
//
|
|
580
|
-
//
|
|
581
|
-
//
|
|
610
|
+
// The knowledge-graph layer is a core memory feature. Missing deps are
|
|
611
|
+
// a blocking issue: the daemon technically launches (graph-store.ts has
|
|
612
|
+
// a no-op degradation path), but memory features the framework depends
|
|
613
|
+
// on are silently absent. Surface it loudly.
|
|
582
614
|
try {
|
|
583
615
|
execSync('which redis-server', { stdio: 'pipe' });
|
|
584
616
|
console.log(` ${GREEN}OK${RESET} redis-server found`);
|
|
585
617
|
}
|
|
586
618
|
catch {
|
|
587
|
-
console.log(` ${
|
|
588
|
-
const fixCmd = hasBrew ?
|
|
619
|
+
console.log(` ${RED}FAIL${RESET} redis-server not found (required for graph memory)`);
|
|
620
|
+
const fixCmd = hasBrew ? `${brewBin()} install redis` : hasApt ? 'sudo apt-get install -y redis-server' : null;
|
|
589
621
|
if (fixCmd && tryFix('redis-server', fixCmd)) {
|
|
590
622
|
// fixed
|
|
591
623
|
}
|
|
592
|
-
else
|
|
593
|
-
if (isMac) {
|
|
594
|
-
console.log(`
|
|
595
|
-
console.log(` ${BREW_INSTALL_CMD}`);
|
|
624
|
+
else {
|
|
625
|
+
if (isMac && !hasBrew) {
|
|
626
|
+
console.log(` Install Homebrew first (see above), then ${CYAN}clementine doctor --fix${RESET}`);
|
|
596
627
|
}
|
|
597
628
|
else {
|
|
598
|
-
console.log(`
|
|
629
|
+
console.log(` Fix: brew install redis (macOS) or sudo apt install redis-server (Linux)`);
|
|
599
630
|
}
|
|
600
|
-
|
|
601
|
-
}
|
|
602
|
-
else {
|
|
603
|
-
console.log(` Fix: brew install redis (macOS) or sudo apt install redis-server (Linux)`);
|
|
604
|
-
warnings++;
|
|
631
|
+
issues++;
|
|
605
632
|
}
|
|
606
633
|
}
|
|
607
634
|
// FalkorDB graph engine — system dependencies: libomp
|
|
@@ -615,25 +642,19 @@ function cmdDoctor(opts = {}) {
|
|
|
615
642
|
console.log(` ${GREEN}OK${RESET} libomp (OpenMP runtime) found`);
|
|
616
643
|
}
|
|
617
644
|
catch {
|
|
618
|
-
console.log(` ${
|
|
619
|
-
const fixCmd = hasBrew ?
|
|
645
|
+
console.log(` ${RED}FAIL${RESET} libomp (OpenMP runtime) not found (required for graph memory)`);
|
|
646
|
+
const fixCmd = hasBrew ? `${brewBin()} install libomp` : hasApt ? 'sudo apt-get install -y libomp-dev' : null;
|
|
620
647
|
if (fixCmd && tryFix('libomp', fixCmd)) {
|
|
621
648
|
// fixed
|
|
622
649
|
}
|
|
623
|
-
else
|
|
624
|
-
if (isMac) {
|
|
625
|
-
|
|
626
|
-
// avoid spamming it twice by just pointing back to that guidance.
|
|
627
|
-
console.log(` Install Homebrew (see redis-server WARN above), then ${CYAN}brew install libomp${RESET}`);
|
|
650
|
+
else {
|
|
651
|
+
if (isMac && !hasBrew) {
|
|
652
|
+
console.log(` Install Homebrew first (see above), then ${CYAN}clementine doctor --fix${RESET}`);
|
|
628
653
|
}
|
|
629
654
|
else {
|
|
630
|
-
console.log(`
|
|
655
|
+
console.log(` Fix: brew install libomp (macOS) or sudo apt install libomp-dev (Linux)`);
|
|
631
656
|
}
|
|
632
|
-
|
|
633
|
-
}
|
|
634
|
-
else {
|
|
635
|
-
console.log(` Fix: brew install libomp (macOS) or sudo apt install libomp-dev (Linux)`);
|
|
636
|
-
warnings++;
|
|
657
|
+
issues++;
|
|
637
658
|
}
|
|
638
659
|
}
|
|
639
660
|
// FalkorDB graph engine — module binaries
|
|
@@ -642,11 +663,11 @@ function cmdDoctor(opts = {}) {
|
|
|
642
663
|
console.log(` ${GREEN}OK${RESET} FalkorDB graph engine binaries installed`);
|
|
643
664
|
}
|
|
644
665
|
catch {
|
|
645
|
-
console.log(` ${
|
|
666
|
+
console.log(` ${RED}FAIL${RESET} FalkorDB graph engine binaries not available`);
|
|
646
667
|
if (!tryFix('FalkorDB binaries', `node node_modules/falkordblite/scripts/postinstall.js`, { cwd: PACKAGE_ROOT, timeout: 180000 })) {
|
|
647
668
|
console.log(` Fix: cd ${PACKAGE_ROOT} && node node_modules/falkordblite/scripts/postinstall.js`);
|
|
648
669
|
console.log(` ${DIM}(Usually self-heals once redis-server + libomp are installed)${RESET}`);
|
|
649
|
-
|
|
670
|
+
issues++;
|
|
650
671
|
}
|
|
651
672
|
}
|
|
652
673
|
// Data home
|
|
@@ -848,21 +869,17 @@ function cmdDoctor(opts = {}) {
|
|
|
848
869
|
}
|
|
849
870
|
}
|
|
850
871
|
console.log();
|
|
851
|
-
|
|
852
|
-
if (issues === 0 && fixed === 0 && warnings === 0) {
|
|
872
|
+
if (issues === 0 && fixed === 0) {
|
|
853
873
|
console.log(` ${GREEN}All checks passed.${RESET}`);
|
|
854
874
|
}
|
|
855
|
-
else if (issues === 0 && fixed === 0 && warnings > 0) {
|
|
856
|
-
console.log(` ${GREEN}Ready to launch.${RESET} ${warnings} optional dependency warning(s) — safe to ignore or install for full experience.`);
|
|
857
|
-
}
|
|
858
875
|
else if (issues === 0 && fixed > 0) {
|
|
859
|
-
console.log(` ${GREEN}All issues fixed!${RESET} (${fixed} auto-fixed
|
|
876
|
+
console.log(` ${GREEN}All issues fixed!${RESET} (${fixed} auto-fixed)`);
|
|
860
877
|
}
|
|
861
878
|
else if (fixed > 0) {
|
|
862
|
-
console.log(` ${YELLOW}${issues} issue(s) remaining${RESET} (${fixed} auto-fixed
|
|
879
|
+
console.log(` ${YELLOW}${issues} issue(s) remaining${RESET} (${fixed} auto-fixed)`);
|
|
863
880
|
}
|
|
864
881
|
else {
|
|
865
|
-
console.log(` ${YELLOW}${issues} issue(s) found
|
|
882
|
+
console.log(` ${YELLOW}${issues} issue(s) found.${RESET}${!fix ? ` Run ${CYAN}clementine doctor --fix${RESET} to auto-install dependencies.` : ''}`);
|
|
866
883
|
}
|
|
867
884
|
console.log();
|
|
868
885
|
}
|