@gamaze/hicortex 0.3.7 → 0.3.8
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/init.js +54 -0
- package/dist/mcp-server.js +52 -10
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/init.js
CHANGED
|
@@ -228,6 +228,58 @@ Tell them: "Get a license key at https://hicortex.gamaze.com/ — after purchase
|
|
|
228
228
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(CC_COMMANDS_DIR, "hicortex-activate.md"), activateContent);
|
|
229
229
|
console.log(` ✓ Installed /learn and /hicortex-activate commands in ${CC_COMMANDS_DIR}`);
|
|
230
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* Detect LLM API key from current shell environment and persist to
|
|
233
|
+
* ~/.hicortex/config.json so the daemon can use it (launchd/systemd
|
|
234
|
+
* don't inherit shell env vars).
|
|
235
|
+
*/
|
|
236
|
+
function persistLlmConfig() {
|
|
237
|
+
const configPath = (0, node_path_1.join)(HICORTEX_HOME, "config.json");
|
|
238
|
+
// Read existing config (may have licenseKey)
|
|
239
|
+
let config = {};
|
|
240
|
+
try {
|
|
241
|
+
config = JSON.parse((0, node_fs_1.readFileSync)(configPath, "utf-8"));
|
|
242
|
+
}
|
|
243
|
+
catch { /* new file */ }
|
|
244
|
+
// Don't overwrite if LLM config already persisted
|
|
245
|
+
if (config.llmApiKey && config.llmBaseUrl) {
|
|
246
|
+
console.log(` ✓ LLM config already in ${configPath}`);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
// Detect from environment (same priority as resolveLlmConfigForCC)
|
|
250
|
+
const hcKey = process.env.HICORTEX_LLM_API_KEY;
|
|
251
|
+
const hcUrl = process.env.HICORTEX_LLM_BASE_URL;
|
|
252
|
+
const hcModel = process.env.HICORTEX_LLM_MODEL;
|
|
253
|
+
if (hcKey && hcUrl) {
|
|
254
|
+
config.llmApiKey = hcKey;
|
|
255
|
+
config.llmBaseUrl = hcUrl;
|
|
256
|
+
if (hcModel)
|
|
257
|
+
config.llmModel = hcModel;
|
|
258
|
+
}
|
|
259
|
+
else if (process.env.ANTHROPIC_API_KEY) {
|
|
260
|
+
config.llmApiKey = process.env.ANTHROPIC_API_KEY;
|
|
261
|
+
config.llmBaseUrl = process.env.ANTHROPIC_BASE_URL ?? "https://api.anthropic.com";
|
|
262
|
+
config.llmProvider = "anthropic";
|
|
263
|
+
}
|
|
264
|
+
else if (process.env.OPENAI_API_KEY) {
|
|
265
|
+
config.llmApiKey = process.env.OPENAI_API_KEY;
|
|
266
|
+
config.llmBaseUrl = process.env.OPENAI_BASE_URL ?? "https://api.openai.com";
|
|
267
|
+
config.llmProvider = "openai";
|
|
268
|
+
}
|
|
269
|
+
else if (process.env.GOOGLE_API_KEY) {
|
|
270
|
+
config.llmApiKey = process.env.GOOGLE_API_KEY;
|
|
271
|
+
config.llmBaseUrl = "https://generativelanguage.googleapis.com/v1beta";
|
|
272
|
+
config.llmProvider = "google";
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
console.log(" ⚠ No LLM API key found in environment. Server will use Ollama fallback.");
|
|
276
|
+
console.log(" Set ANTHROPIC_API_KEY and re-run init, or edit ~/.hicortex/config.json");
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
(0, node_fs_1.mkdirSync)(HICORTEX_HOME, { recursive: true });
|
|
280
|
+
(0, node_fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2));
|
|
281
|
+
console.log(` ✓ LLM config saved to ${configPath}`);
|
|
282
|
+
}
|
|
231
283
|
/**
|
|
232
284
|
* Determine the npm package specifier for the daemon.
|
|
233
285
|
* Uses tag-based resolution so restarts pick up new versions automatically.
|
|
@@ -428,6 +480,8 @@ async function runInit() {
|
|
|
428
480
|
}
|
|
429
481
|
console.log();
|
|
430
482
|
// Phase 3: Execute
|
|
483
|
+
// Persist LLM config from current environment for the daemon
|
|
484
|
+
persistLlmConfig();
|
|
431
485
|
// Install daemon if needed
|
|
432
486
|
if (!d.localServer && !d.remoteServer) {
|
|
433
487
|
installDaemon();
|
package/dist/mcp-server.js
CHANGED
|
@@ -179,13 +179,18 @@ async function startServer(options = {}) {
|
|
|
179
179
|
console.log(`[hicortex] Initializing database at ${dbPath}`);
|
|
180
180
|
db = (0, db_js_1.initDb)(dbPath);
|
|
181
181
|
stateDir = dbPath.replace(/\/hicortex\.db$/, "");
|
|
182
|
-
// LLM config
|
|
183
|
-
const
|
|
182
|
+
// LLM config: read from config.json first (persisted by init), then env vars
|
|
183
|
+
const savedConfig = readConfigFile(stateDir);
|
|
184
|
+
const llmConfig = (0, llm_js_1.resolveLlmConfigForCC)({
|
|
185
|
+
llmBaseUrl: savedConfig?.llmBaseUrl,
|
|
186
|
+
llmApiKey: savedConfig?.llmApiKey,
|
|
187
|
+
llmModel: savedConfig?.llmModel,
|
|
188
|
+
});
|
|
184
189
|
llm = new llm_js_1.LlmClient(llmConfig);
|
|
185
190
|
console.log(`[hicortex] LLM: ${llmConfig.provider}/${llmConfig.model} (reflect: ${llmConfig.reflectModel})`);
|
|
186
191
|
// License: read from options, config file, or env var
|
|
187
192
|
const licenseKey = options.licenseKey
|
|
188
|
-
??
|
|
193
|
+
?? savedConfig?.licenseKey
|
|
189
194
|
?? process.env.HICORTEX_LICENSE_KEY;
|
|
190
195
|
(0, license_js_1.validateLicense)(licenseKey, stateDir).catch((err) => console.log(`[hicortex] License validation failed: ${err}`));
|
|
191
196
|
if (licenseKey) {
|
|
@@ -196,6 +201,8 @@ async function startServer(options = {}) {
|
|
|
196
201
|
cancelConsolidation = (0, consolidate_js_1.scheduleConsolidation)(db, llm, embedder_js_1.embed, consolidateHour);
|
|
197
202
|
// Seed lesson on first run
|
|
198
203
|
await (0, seed_lesson_js_1.injectSeedLesson)(db);
|
|
204
|
+
// Self-heal: fix pinned version in daemon config
|
|
205
|
+
fixDaemonVersionPin();
|
|
199
206
|
// Stats
|
|
200
207
|
const stats = (0, db_js_1.getStats)(db, dbPath);
|
|
201
208
|
console.log(`[hicortex] Ready: ${stats.memories} memories, ${stats.links} links, ` +
|
|
@@ -281,20 +288,55 @@ async function startServer(options = {}) {
|
|
|
281
288
|
// Helpers
|
|
282
289
|
// ---------------------------------------------------------------------------
|
|
283
290
|
/**
|
|
284
|
-
* Read
|
|
285
|
-
* Written by /hicortex-activate CC command.
|
|
291
|
+
* Read ~/.hicortex/config.json (persisted by init with LLM and license config).
|
|
286
292
|
*/
|
|
287
|
-
function
|
|
293
|
+
function readConfigFile(stateDir) {
|
|
288
294
|
try {
|
|
289
295
|
const { readFileSync } = require("node:fs");
|
|
290
296
|
const { join } = require("node:path");
|
|
291
297
|
const configPath = join(stateDir, "config.json");
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
298
|
+
return JSON.parse(readFileSync(configPath, "utf-8"));
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Self-heal: if the daemon plist/systemd unit has a pinned version
|
|
306
|
+
* (e.g. @gamaze/hicortex@0.3.4), rewrite it to use the bare package
|
|
307
|
+
* name so future restarts pick up the latest version automatically.
|
|
308
|
+
*/
|
|
309
|
+
function fixDaemonVersionPin() {
|
|
310
|
+
try {
|
|
311
|
+
const os = require("node:os");
|
|
312
|
+
const fs = require("node:fs");
|
|
313
|
+
const path = require("node:path");
|
|
314
|
+
if (os.platform() === "darwin") {
|
|
315
|
+
const plistPath = path.join(os.homedir(), "Library", "LaunchAgents", "com.gamaze.hicortex.plist");
|
|
316
|
+
if (!fs.existsSync(plistPath))
|
|
317
|
+
return;
|
|
318
|
+
const content = fs.readFileSync(plistPath, "utf-8");
|
|
319
|
+
// Match @gamaze/hicortex@X.Y.Z (pinned to specific version)
|
|
320
|
+
if (/@gamaze\/hicortex@\d+\.\d+\.\d+/.test(content)) {
|
|
321
|
+
const fixed = content.replace(/@gamaze\/hicortex@\d+\.\d+\.\d+/, "@gamaze/hicortex");
|
|
322
|
+
fs.writeFileSync(plistPath, fixed);
|
|
323
|
+
console.log("[hicortex] Fixed daemon config: removed pinned version (will use latest on next restart)");
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
else if (os.platform() === "linux") {
|
|
327
|
+
const servicePath = path.join(os.homedir(), ".config", "systemd", "user", "hicortex.service");
|
|
328
|
+
if (!fs.existsSync(servicePath))
|
|
329
|
+
return;
|
|
330
|
+
const content = fs.readFileSync(servicePath, "utf-8");
|
|
331
|
+
if (/@gamaze\/hicortex@\d+\.\d+\.\d+/.test(content)) {
|
|
332
|
+
const fixed = content.replace(/@gamaze\/hicortex@\d+\.\d+\.\d+/, "@gamaze/hicortex");
|
|
333
|
+
fs.writeFileSync(servicePath, fixed);
|
|
334
|
+
console.log("[hicortex] Fixed daemon config: removed pinned version");
|
|
335
|
+
}
|
|
336
|
+
}
|
|
295
337
|
}
|
|
296
338
|
catch {
|
|
297
|
-
|
|
339
|
+
// Non-fatal
|
|
298
340
|
}
|
|
299
341
|
}
|
|
300
342
|
function formatResults(results) {
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "hicortex",
|
|
3
3
|
"name": "Hicortex — Long-term Memory That Learns",
|
|
4
4
|
"description": "Your agents remember past decisions, avoid repeated mistakes, and get smarter every day. Nightly reflection generates actionable lessons that automatically update agent behavior.",
|
|
5
|
-
"version": "0.3.
|
|
5
|
+
"version": "0.3.8",
|
|
6
6
|
"kind": "lifecycle",
|
|
7
7
|
"skills": ["./skills/hicortex-memory", "./skills/hicortex-learn", "./skills/hicortex-activate"],
|
|
8
8
|
"configSchema": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gamaze/hicortex",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "Human-like memory for self-improving AI agents. Automatic capturing, nightly reflection, and cross-agent learning. Works with Claude Code and OpenClaw.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|