nexo-brain 5.3.18 → 5.3.19
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/.claude-plugin/plugin.json +1 -1
- package/bin/nexo-brain.js +109 -7
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.19",
|
|
4
4
|
"description": "Local cognitive runtime for Claude Code \u2014 persistent memory, overnight learning, doctor diagnostics, personal scripts, recovery-aware jobs, startup preflight, and optional dashboard/power helper.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "NEXO Brain",
|
package/bin/nexo-brain.js
CHANGED
|
@@ -2511,6 +2511,9 @@ I am ${operatorName}, a cognitive co-operator. Not an assistant — an operation
|
|
|
2511
2511
|
calendar: {},
|
|
2512
2512
|
contacts: [],
|
|
2513
2513
|
documents: {},
|
|
2514
|
+
notes: { count: 0, folders: [] },
|
|
2515
|
+
reminders: { count: 0, lists: [] },
|
|
2516
|
+
photos: { count: 0 },
|
|
2514
2517
|
messaging: [],
|
|
2515
2518
|
interests: [],
|
|
2516
2519
|
summary: {},
|
|
@@ -2747,16 +2750,27 @@ I am ${operatorName}, a cognitive co-operator. Not an assistant — an operation
|
|
|
2747
2750
|
// --- Email accounts ---
|
|
2748
2751
|
process.stdout.write(" \u280B Email accounts...\r");
|
|
2749
2752
|
if (platform === "darwin") {
|
|
2750
|
-
// macOS Mail.app accounts
|
|
2751
|
-
|
|
2753
|
+
// macOS Mail.app accounts — try multiple detection methods
|
|
2754
|
+
// Method 1: sandboxed container (modern macOS)
|
|
2755
|
+
let mailAccounts = run("defaults read ~/Library/Containers/com.apple.mail/Data/Library/Preferences/com.apple.mail MailAccounts 2>/dev/null | grep -E 'AccountName|EmailAddresses' | head -30");
|
|
2756
|
+
// Method 2: legacy plist (older macOS)
|
|
2757
|
+
if (!mailAccounts) mailAccounts = run("defaults read com.apple.mail MailAccounts 2>/dev/null | grep -E 'AccountName|EmailAddresses' | head -30");
|
|
2758
|
+
// Method 3: Internet Accounts (covers Mail, Calendar, Contacts, etc.)
|
|
2759
|
+
if (!mailAccounts) mailAccounts = run("defaults read com.apple.internetaccounts Accounts 2>/dev/null | grep -E 'AccountDescription|Username' | head -30");
|
|
2760
|
+
// Method 4: scan Mail directory for account folders
|
|
2761
|
+
if (!mailAccounts) {
|
|
2762
|
+
const mailDir = run("ls -1 ~/Library/Mail/V*/ 2>/dev/null | grep -v '^$' | head -20");
|
|
2763
|
+
if (mailDir) mailAccounts = mailDir;
|
|
2764
|
+
}
|
|
2752
2765
|
if (mailAccounts) {
|
|
2753
2766
|
profileData.email = mailAccounts.split("\n")
|
|
2754
|
-
.map(l => l.replace(/.*=\s*"?/, "").replace(/"?\s*;?\s*$/, "").trim())
|
|
2755
|
-
.filter(
|
|
2767
|
+
.map(l => l.replace(/.*=\s*"?/, "").replace(/"?\s*;?\s*$/, "").replace(/\/$/, "").trim())
|
|
2768
|
+
.filter(l => l && l.length > 1 && !l.startsWith("(") && !l.startsWith(")") && !l.includes("{") && !l.includes("}"))
|
|
2769
|
+
.filter((v, i, a) => a.indexOf(v) === i); // dedupe
|
|
2756
2770
|
}
|
|
2757
2771
|
}
|
|
2758
2772
|
if (profileData.email.length > 0) {
|
|
2759
|
-
log(`\u2713 ${profileData.email.length} email accounts
|
|
2773
|
+
log(`\u2713 ${profileData.email.length} email accounts detected`);
|
|
2760
2774
|
}
|
|
2761
2775
|
|
|
2762
2776
|
// --- Calendar (macOS) ---
|
|
@@ -2815,6 +2829,76 @@ I am ${operatorName}, a cognitive co-operator. Not an assistant — an operation
|
|
|
2815
2829
|
log(`\u2713 ${totalDocs} recent documents (${typesSummary})`);
|
|
2816
2830
|
}
|
|
2817
2831
|
|
|
2832
|
+
// --- Notes ---
|
|
2833
|
+
process.stdout.write(" \u280B Notes...\r");
|
|
2834
|
+
profileData.notes = { count: 0, folders: [] };
|
|
2835
|
+
if (platform === "linux") {
|
|
2836
|
+
// GNOME Notes / Tomboy / Obsidian vaults
|
|
2837
|
+
const obsidianVaults = run(`find "${home}" -maxdepth 3 -name ".obsidian" -type d 2>/dev/null | head -5`);
|
|
2838
|
+
if (obsidianVaults) {
|
|
2839
|
+
const vaults = obsidianVaults.split("\n").filter(Boolean);
|
|
2840
|
+
let totalNotes = 0;
|
|
2841
|
+
for (const v of vaults) {
|
|
2842
|
+
const vaultDir = path.dirname(v);
|
|
2843
|
+
const count = run(`find "${vaultDir}" -name "*.md" -type f 2>/dev/null | wc -l`);
|
|
2844
|
+
totalNotes += parseInt((count || "0").trim());
|
|
2845
|
+
}
|
|
2846
|
+
profileData.notes.count = totalNotes;
|
|
2847
|
+
profileData.notes.folders = vaults.map(v => path.basename(path.dirname(v)));
|
|
2848
|
+
}
|
|
2849
|
+
} else if (platform === "darwin") {
|
|
2850
|
+
const notesDb = path.join(home, "Library", "Group Containers", "group.com.apple.notes", "NoteStore.sqlite");
|
|
2851
|
+
if (fs.existsSync(notesDb)) {
|
|
2852
|
+
const noteCount = run(`sqlite3 "${notesDb}" "SELECT COUNT(*) FROM ZICCLOUDSYNCINGOBJECT WHERE ZTITLE IS NOT NULL AND ZMARKEDFORDELETION != 1" 2>/dev/null`);
|
|
2853
|
+
profileData.notes.count = parseInt((noteCount || "0").trim());
|
|
2854
|
+
const folders = run(`sqlite3 "${notesDb}" "SELECT DISTINCT ZTITLE2 FROM ZICCLOUDSYNCINGOBJECT WHERE ZTITLE2 IS NOT NULL AND ZMARKEDFORDELETION != 1 LIMIT 15" 2>/dev/null`);
|
|
2855
|
+
if (folders) profileData.notes.folders = folders.split("\n").filter(Boolean);
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
if (profileData.notes.count > 0) {
|
|
2859
|
+
log(`\u2713 ${profileData.notes.count} notes${profileData.notes.folders.length ? ` in ${profileData.notes.folders.length} folders` : ""}`);
|
|
2860
|
+
}
|
|
2861
|
+
|
|
2862
|
+
// --- Reminders ---
|
|
2863
|
+
process.stdout.write(" \u280B Reminders...\r");
|
|
2864
|
+
profileData.reminders = { count: 0, lists: [] };
|
|
2865
|
+
if (platform === "linux") {
|
|
2866
|
+
// GNOME Reminders / Todoist / task files
|
|
2867
|
+
const todoFiles = run(`find "${home}" -maxdepth 2 -name "todo.txt" -o -name "TODO.md" -o -name "tasks.md" 2>/dev/null | head -5`);
|
|
2868
|
+
if (todoFiles) {
|
|
2869
|
+
let count = 0;
|
|
2870
|
+
todoFiles.split("\n").filter(Boolean).forEach(f => {
|
|
2871
|
+
const lines = run(`wc -l < "${f}" 2>/dev/null`);
|
|
2872
|
+
count += parseInt((lines || "0").trim());
|
|
2873
|
+
});
|
|
2874
|
+
profileData.reminders.count = count;
|
|
2875
|
+
profileData.reminders.lists = todoFiles.split("\n").filter(Boolean).map(f => path.basename(f));
|
|
2876
|
+
}
|
|
2877
|
+
} else if (platform === "darwin") {
|
|
2878
|
+
// Reminders uses EventKit, but we can count via the Calendars directory or osascript
|
|
2879
|
+
const reminderCount = run('osascript -e \'tell application "Reminders" to count of (every reminder whose completed is false)\' 2>/dev/null');
|
|
2880
|
+
if (reminderCount) profileData.reminders.count = parseInt(reminderCount.trim()) || 0;
|
|
2881
|
+
const reminderLists = run('osascript -e \'tell application "Reminders" to get name of every list\' 2>/dev/null');
|
|
2882
|
+
if (reminderLists) profileData.reminders.lists = reminderLists.split(", ").filter(Boolean);
|
|
2883
|
+
}
|
|
2884
|
+
if (profileData.reminders.count > 0) {
|
|
2885
|
+
log(`\u2713 ${profileData.reminders.count} active reminders across ${profileData.reminders.lists.length} lists`);
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2888
|
+
// --- Photos library size (macOS) ---
|
|
2889
|
+
process.stdout.write(" \u280B Photos...\r");
|
|
2890
|
+
profileData.photos = { count: 0 };
|
|
2891
|
+
if (platform === "darwin") {
|
|
2892
|
+
const photosDb = path.join(home, "Pictures", "Photos Library.photoslibrary", "database", "Photos.sqlite");
|
|
2893
|
+
if (fs.existsSync(photosDb)) {
|
|
2894
|
+
const photoCount = run(`sqlite3 "${photosDb}" "SELECT COUNT(*) FROM ZASSET WHERE ZTRASHEDSTATE = 0" 2>/dev/null`);
|
|
2895
|
+
if (photoCount) profileData.photos.count = parseInt(photoCount.trim()) || 0;
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
if (profileData.photos.count > 0) {
|
|
2899
|
+
log(`\u2713 ${profileData.photos.count.toLocaleString()} photos in library`);
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2818
2902
|
// --- Messaging apps ---
|
|
2819
2903
|
process.stdout.write(" \u280B Messaging...\r");
|
|
2820
2904
|
const msgApps = { "WhatsApp": "WhatsApp.app", "Telegram": "Telegram.app", "Slack": "Slack.app", "Discord": "Discord.app", "Signal": "Signal.app", "Teams": "Microsoft Teams.app", "Zoom": "zoom.us.app" };
|
|
@@ -2839,6 +2923,11 @@ I am ${operatorName}, a cognitive co-operator. Not an assistant — an operation
|
|
|
2839
2923
|
repos: repos.length,
|
|
2840
2924
|
servers: profileData.ssh.length,
|
|
2841
2925
|
email_accounts: profileData.email.length,
|
|
2926
|
+
notes: profileData.notes.count,
|
|
2927
|
+
reminders: profileData.reminders.count,
|
|
2928
|
+
photos: profileData.photos.count,
|
|
2929
|
+
recent_documents: profileData.documents.recent_count || 0,
|
|
2930
|
+
contacts: profileData.contacts.count || 0,
|
|
2842
2931
|
key_tools: topApps.slice(0, 8),
|
|
2843
2932
|
work_hours: profileData.terminal.peak_hours || [],
|
|
2844
2933
|
peak_days: profileData.terminal.peak_days || [],
|
|
@@ -2855,12 +2944,24 @@ I am ${operatorName}, a cognitive co-operator. Not an assistant — an operation
|
|
|
2855
2944
|
line(`${t.profileTitle}: ${userName || profileData.git.name || "User"}`);
|
|
2856
2945
|
line("");
|
|
2857
2946
|
if (topLangs.length) line(`Stack: ${topLangs.join(", ")}`);
|
|
2858
|
-
|
|
2947
|
+
// Life data
|
|
2948
|
+
const lifeParts = [];
|
|
2949
|
+
if (profileData.email.length) lifeParts.push(`${profileData.email.length} email`);
|
|
2950
|
+
if (profileData.notes.count) lifeParts.push(`${profileData.notes.count} notes`);
|
|
2951
|
+
if (profileData.reminders.count) lifeParts.push(`${profileData.reminders.count} reminders`);
|
|
2952
|
+
if (profileData.contacts.count) lifeParts.push(`${profileData.contacts.count} contacts`);
|
|
2953
|
+
if (profileData.photos.count) lifeParts.push(`${profileData.photos.count.toLocaleString()} photos`);
|
|
2954
|
+
if (profileData.documents.recent_count) lifeParts.push(`${profileData.documents.recent_count} docs`);
|
|
2955
|
+
if (lifeParts.length) line(lifeParts.join(" \u00B7 "));
|
|
2956
|
+
// Dev data
|
|
2957
|
+
if (repos.length || profileData.ssh.length) {
|
|
2958
|
+
line(`${repos.length} repos \u00B7 ${profileData.ssh.length} servers`);
|
|
2959
|
+
}
|
|
2960
|
+
if (topLangs.length) line(`Stack: ${topLangs.join(", ")}`);
|
|
2859
2961
|
if (topApps.length) line(`Tools: ${topApps.slice(0, 6).join(", ")}`);
|
|
2860
2962
|
if (totalCommits) line(`${totalCommits.toLocaleString()} commits/year`);
|
|
2861
2963
|
if (profileData.terminal.peak_hours) {
|
|
2862
2964
|
const hours = profileData.terminal.peak_hours;
|
|
2863
|
-
// Group consecutive hours into ranges
|
|
2864
2965
|
const ranges = [];
|
|
2865
2966
|
let start = hours[0], prev = hours[0];
|
|
2866
2967
|
for (let i = 1; i <= hours.length; i++) {
|
|
@@ -2871,6 +2972,7 @@ I am ${operatorName}, a cognitive co-operator. Not an assistant — an operation
|
|
|
2871
2972
|
line(`Hours: ${ranges.join(", ")}${profileData.terminal.peak_days ? ` \u00B7 Peak: ${profileData.terminal.peak_days.join(", ")}` : ""}`);
|
|
2872
2973
|
}
|
|
2873
2974
|
if (profileData.messaging.length) line(`Messaging: ${profileData.messaging.join(", ")}`);
|
|
2975
|
+
if (profileData.calendar.events) line(`Calendar: ${profileData.calendar.events} events`);
|
|
2874
2976
|
line(`Timezone: ${profileData.system.timezone}`);
|
|
2875
2977
|
line("");
|
|
2876
2978
|
line(lang === "es" ? "Ya te conozco. Vamos a trabajar." : lang === "fr" ? "Je te connais. Au travail." : lang === "de" ? "Ich kenne dich. Los geht's." : lang === "it" ? "Ti conosco. Al lavoro." : lang === "pt" ? "J\u00E1 te conhe\u00E7o. Ao trabalho." : "I know you now. Let's work.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.19",
|
|
4
4
|
"mcpName": "io.github.wazionapps/nexo",
|
|
5
5
|
"description": "NEXO Brain — Shared brain for AI agents. Persistent memory, semantic RAG, natural forgetting, metacognitive guard, trust scoring, 150+ MCP tools. Works with Claude Code, Codex, Claude Desktop & any MCP client. 100% local, free.",
|
|
6
6
|
"homepage": "https://nexo-brain.com",
|