@mingxy/cerebro 2.0.1 → 2.0.3
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/package.json +1 -1
- package/src/hooks.ts +9 -5
- package/src/index.ts +19 -24
- package/src/tui.tsx +10 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mingxy/cerebro",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "Cerebro persistent memory plugin for OpenCode — auto-recall, auto-capture, 9 memory tools with clustering, project-scoped memory isolation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
package/src/hooks.ts
CHANGED
|
@@ -120,13 +120,17 @@ async function detectProjectName(rootPath: string): Promise<string | undefined>
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
export function showToast(tui: any, title: string, message: string, variant: string = "info", delayMs?: number) {
|
|
123
|
-
if (!tui)
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
if (!tui?.showToast) {
|
|
124
|
+
logDebug("showToast: tui or tui.showToast unavailable");
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const defaultDelay = 1000;
|
|
128
|
+
const effectiveDelay = delayMs ?? defaultDelay;
|
|
129
|
+
setTimeout(async () => {
|
|
126
130
|
try {
|
|
127
|
-
tui.showToast({ body: { title, message, variant, duration: 5000 } });
|
|
131
|
+
await tui.showToast({ body: { title, message, variant, duration: 5000 } });
|
|
128
132
|
} catch (err) {
|
|
129
|
-
logErr("showToast failed", { error: String(err) });
|
|
133
|
+
logErr("showToast failed", { error: String(err), title });
|
|
130
134
|
}
|
|
131
135
|
}, effectiveDelay);
|
|
132
136
|
}
|
package/src/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { join, dirname } from "node:path";
|
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { CerebroClient } from "./client.js";
|
|
7
|
-
import { chatMessageRecallHook, autocontinueHook, compactingHook, sessionIdleHook, sessionMessages, firstMessages,
|
|
7
|
+
import { chatMessageRecallHook, autocontinueHook, compactingHook, sessionIdleHook, sessionMessages, firstMessages, timeMemorySystemHook } from "./hooks.js";
|
|
8
8
|
import { detectSaveKeyword, detectRecallKeyword, KEYWORD_NUDGE, RECALL_NUDGE } from "./keywords.js";
|
|
9
9
|
import { getUserTag, getProjectTag } from "./tags.js";
|
|
10
10
|
import { buildTools } from "./tools.js";
|
|
@@ -61,7 +61,9 @@ const OmemPlugin: Plugin = async (input) => {
|
|
|
61
61
|
// even if client.tui isn't ready yet at plugin init time
|
|
62
62
|
const tui = new Proxy({} as any, {
|
|
63
63
|
get(_, prop) {
|
|
64
|
-
|
|
64
|
+
const realTui = (client as any)?.tui;
|
|
65
|
+
const val = realTui?.[prop];
|
|
66
|
+
return typeof val === "function" ? val.bind(realTui) : val;
|
|
65
67
|
},
|
|
66
68
|
});
|
|
67
69
|
|
|
@@ -74,37 +76,26 @@ const OmemPlugin: Plugin = async (input) => {
|
|
|
74
76
|
} catch {}
|
|
75
77
|
|
|
76
78
|
const config = loadPluginConfig(overrides as any);
|
|
77
|
-
const STARTUP_DELAY = 2000;
|
|
78
79
|
|
|
79
80
|
setOpencodeClient(client);
|
|
80
81
|
|
|
81
82
|
const cerebroClient = new CerebroClient(config.connection.apiUrl, config.connection.apiKey, config);
|
|
82
83
|
|
|
84
|
+
let connectionStatus: "success" | "error" = "success";
|
|
85
|
+
let statusMessage = "";
|
|
83
86
|
try {
|
|
84
87
|
await cerebroClient.getStats();
|
|
85
88
|
logInfo(`Connected to ${config.connection.apiUrl}`);
|
|
86
89
|
} catch (err) {
|
|
87
90
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
88
91
|
logError(`Connection failed: ${errMsg}`);
|
|
92
|
+
connectionStatus = "error";
|
|
89
93
|
if (errMsg.includes("[cerebro]")) {
|
|
90
|
-
|
|
91
|
-
showToast(
|
|
92
|
-
tui,
|
|
93
|
-
`🧠 Cerebro v${pluginVersion} · Server Error`,
|
|
94
|
-
cleanMsg.substring(0, 150),
|
|
95
|
-
"error",
|
|
96
|
-
STARTUP_DELAY
|
|
97
|
-
);
|
|
94
|
+
statusMessage = errMsg.replace(/^\[cerebro]\s*/, "").substring(0, 150);
|
|
98
95
|
} else {
|
|
99
|
-
|
|
100
|
-
tui,
|
|
101
|
-
`🧠 Cerebro v${pluginVersion} · Connection Failed`,
|
|
102
|
-
`Unable to reach ${config.connection.apiUrl}`,
|
|
103
|
-
"error",
|
|
104
|
-
STARTUP_DELAY
|
|
105
|
-
);
|
|
96
|
+
statusMessage = `Unable to reach ${config.connection.apiUrl}`;
|
|
106
97
|
}
|
|
107
|
-
}
|
|
98
|
+
}
|
|
108
99
|
|
|
109
100
|
const email = process.env.GIT_AUTHOR_EMAIL || process.env.USER || "unknown";
|
|
110
101
|
const cwd = directory || process.cwd();
|
|
@@ -136,11 +127,15 @@ const OmemPlugin: Plugin = async (input) => {
|
|
|
136
127
|
}
|
|
137
128
|
}
|
|
138
129
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
130
|
+
const startupToast = connectionStatus === "error"
|
|
131
|
+
? { variant: "error" as const, title: `🧠 Cerebro v${pluginVersion} · Connection Failed`, message: statusMessage }
|
|
132
|
+
: webPort
|
|
133
|
+
? { variant: "success" as const, title: `🧠 Cerebro Connected · v${pluginVersion}`, message: `🌐 Open in browser http://localhost:${webPort}` }
|
|
134
|
+
: { variant: "success" as const, title: `🧠 Cerebro Connected · v${pluginVersion}`, message: "No web server" };
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
writeFileSync(join(tmpdir(), "cerebro_startup_toast.json"), JSON.stringify(startupToast));
|
|
138
|
+
} catch {}
|
|
144
139
|
|
|
145
140
|
// Auto-update check (fire-and-forget, non-blocking)
|
|
146
141
|
checkAndUpdate(tui, pluginVersion).catch(() => {});
|
package/src/tui.tsx
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/** @jsxImportSource @opentui/solid */
|
|
3
3
|
import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from "@opencode-ai/plugin/tui";
|
|
4
4
|
import { createEffect, createSignal, onCleanup } from "solid-js";
|
|
5
|
-
import { readFileSync } from "node:fs";
|
|
5
|
+
import { readFileSync, unlinkSync } from "node:fs";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
|
|
@@ -83,6 +83,15 @@ const tui: TuiPlugin = async (api) => {
|
|
|
83
83
|
},
|
|
84
84
|
},
|
|
85
85
|
});
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const raw = readFileSync(join(tmpdir(), "cerebro_startup_toast.json"), "utf-8");
|
|
89
|
+
const toast = JSON.parse(raw);
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
try { api.ui.toast(toast); } catch {}
|
|
92
|
+
try { unlinkSync(join(tmpdir(), "cerebro_startup_toast.json")); } catch {}
|
|
93
|
+
}, 2000);
|
|
94
|
+
} catch {}
|
|
86
95
|
};
|
|
87
96
|
|
|
88
97
|
const pluginModule: TuiPluginModule & { id: string } = {
|