@gamaze/hicortex 0.2.1 → 0.3.0

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/README.md CHANGED
@@ -2,51 +2,68 @@
2
2
 
3
3
  Upgrade your agents with Hicortex for automatic capturing of experiences, feedback, and decisions across all your connected agents. They start learning from every session, self-reflect, avoid past mistakes, and improve on their own — overnight, automatically. No configuration needed.
4
4
 
5
+ Works with **OpenClaw** (in-process plugin) and **Claude Code** (HTTP/SSE MCP server).
6
+
5
7
  ## Requirements
6
8
 
7
- - OpenClaw gateway (Node.js 18+)
8
- - LLM provider configured in OpenClaw (auto-detected, 20+ providers supported)
9
+ - Node.js 18+
10
+ - LLM provider (auto-detected from OC config or `ANTHROPIC_API_KEY` for CC)
9
11
  - ~500MB disk for database + embedding model
10
12
 
11
- ## Install
13
+ ## Install — OpenClaw
12
14
 
13
15
  ```bash
14
16
  openclaw plugins install @gamaze/hicortex
17
+ openclaw gateway restart
15
18
  ```
16
19
 
17
- ## Configure
20
+ No configuration needed. The plugin auto-detects your LLM provider from OpenClaw settings on first startup.
21
+
22
+ ## Install — Claude Code
18
23
 
19
- No configuration needed for most users. The plugin auto-detects your LLM provider from OpenClaw settings on first startup.
24
+ ```bash
25
+ npx @gamaze/hicortex init
26
+ ```
20
27
 
21
- Optional config (add to plugin entry in `~/.openclaw/openclaw.json`):
28
+ This detects your environment, installs a persistent MCP server daemon, registers it with Claude Code, and adds `/learn` and `/hicortex-activate` commands. Restart CC after setup.
29
+
30
+ Or manually:
31
+
32
+ ```bash
33
+ # Start server
34
+ npx @gamaze/hicortex server
35
+
36
+ # Register with CC
37
+ claude mcp add hicortex --transport http http://localhost:8787/sse
38
+ ```
39
+
40
+ ## Configure
41
+
42
+ Optional config for OC (add to plugin entry in `~/.openclaw/openclaw.json`):
22
43
 
23
44
  | Field | Default | Description |
24
45
  |-------|---------|-------------|
25
46
  | `licenseKey` | _(none)_ | License key. Free tier (250 memories) without key. |
26
- | `llmBaseUrl` | _(auto)_ | Override LLM base URL (auto-detected from OC config) |
27
- | `llmApiKey` | _(auto)_ | Override LLM API key (auto-detected from OC auth) |
47
+ | `llmBaseUrl` | _(auto)_ | Override LLM base URL |
48
+ | `llmApiKey` | _(auto)_ | Override LLM API key |
28
49
  | `llmModel` | _(auto)_ | Override model for scoring and distillation |
29
50
  | `reflectModel` | _(auto)_ | Override model for nightly reflection |
30
51
  | `consolidateHour` | `2` | Hour (0-23, local time) for nightly consolidation |
31
52
  | `dbPath` | _(auto)_ | Custom database path |
32
53
 
33
- Restart the gateway after config changes:
34
-
35
- ```bash
36
- openclaw gateway restart
37
- ```
54
+ For CC, set environment variables: `ANTHROPIC_API_KEY` (auto-detected), or `HICORTEX_LLM_BASE_URL` + `HICORTEX_LLM_API_KEY` + `HICORTEX_LLM_MODEL` for custom providers.
38
55
 
39
56
  ## What Happens Automatically
40
57
 
41
58
  | When | What | How |
42
59
  |------|------|-----|
43
- | Agent start | Recent lessons injected into context | `before_agent_start` hook |
44
- | Agent end | Conversation captured and distilled | `agent_end` hook + LLM |
60
+ | Agent start | Recent lessons injected into context | OC: `before_agent_start` hook / CC: CLAUDE.md block |
61
+ | Agent end | Conversation captured and distilled | OC: `agent_end` hook / CC: nightly transcript scan |
45
62
  | Nightly | Score importance, reflect, link, decay | In-process consolidation pipeline |
46
63
 
47
64
  ## Agent Tools
48
65
 
49
- The plugin registers these tools for agents to use:
66
+ Available via MCP (both OC and CC):
50
67
 
51
68
  - **hicortex_search** — Semantic search across all stored knowledge
52
69
  - **hicortex_context** — Get recent decisions and project state
@@ -55,22 +72,41 @@ The plugin registers these tools for agents to use:
55
72
 
56
73
  Skills: `/learn` to save explicit learnings.
57
74
 
75
+ ## CLI Commands
76
+
77
+ ```bash
78
+ npx @gamaze/hicortex server # Start MCP HTTP/SSE server (port 8787)
79
+ npx @gamaze/hicortex init # Set up for Claude Code
80
+ npx @gamaze/hicortex nightly # Run distill + consolidate + inject
81
+ npx @gamaze/hicortex status # Show config, DB stats, adapters
82
+ npx @gamaze/hicortex uninstall # Remove CC integration (keeps DB)
83
+ ```
84
+
58
85
  ## Architecture
59
86
 
60
87
  ```
61
- OpenClaw Gateway (Node.js)
62
- └── @gamaze/hicortex plugin (TypeScript, in-process)
63
- ├── before_agent_start → inject lessons into agent context
64
- ├── agent_end → capture conversation, distill via LLM
65
- ├── session_endcheck if consolidation overdue
66
- ├── registerTool → hicortex_search, hicortex_context, hicortex_ingest, hicortex_lessons
67
- └── registerService DB init, LLM auto-config, nightly consolidation
68
- ├── SQLite + sqlite-vec + FTS5 (single file, in-process)
69
- ├── bge-small-en-v1.5 embeddings (ONNX, local CPU)
70
- └── BM25 + vector search with RRF fusion
88
+ @gamaze/hicortex (single npm package, dual mode)
89
+ ├── OpenClaw mode (in-process plugin)
90
+ ├── before_agent_start → inject lessons
91
+ ├── agent_end → capture + distill
92
+ │ └── registerServiceDB, LLM, consolidation timer
93
+
94
+ └── Claude Code mode (persistent HTTP/SSE server)
95
+ ├── MCP tools hicortex_search, hicortex_context, hicortex_ingest, hicortex_lessons
96
+ ├── /health endpoint monitoring
97
+ ├── Nightly scan CC transcripts, distill, consolidate, inject CLAUDE.md
98
+ └── Shared DB at ~/.hicortex/hicortex.db
99
+
100
+ Shared core:
101
+ ├── SQLite + sqlite-vec + FTS5 (single file)
102
+ ├── bge-small-en-v1.5 embeddings (ONNX, local CPU)
103
+ ├── BM25 + vector search with RRF fusion
104
+ └── Multi-provider LLM (20+ providers)
71
105
  ```
72
106
 
73
- No sidecar, no HTTP server, no separate process. Everything runs inside the gateway.
107
+ ## Database
108
+
109
+ Canonical location: `~/.hicortex/hicortex.db`. Existing OC installations at `~/.openclaw/data/hicortex.db` are automatically migrated on upgrade.
74
110
 
75
111
  ## Pricing
76
112
 
@@ -85,33 +121,37 @@ Get a license key at [hicortex.gamaze.com](https://hicortex.gamaze.com).
85
121
 
86
122
  ## Uninstall
87
123
 
124
+ **OpenClaw:**
88
125
  ```bash
89
126
  openclaw plugins uninstall hicortex
90
127
  ```
91
128
 
92
- Your memory database is preserved by default. To remove it: delete `~/.openclaw/data/hicortex.db`.
129
+ **Claude Code:**
130
+ ```bash
131
+ npx @gamaze/hicortex uninstall
132
+ ```
133
+
134
+ Your memory database is preserved by default. To remove all data: `rm -rf ~/.hicortex`
93
135
 
94
136
  ## Development
95
137
 
96
138
  ```bash
97
- # Local dev install
98
- openclaw plugins install -l ./packages/openclaw-plugin
99
-
100
- # Build
101
139
  cd packages/openclaw-plugin
102
140
  npm install
103
141
  npm run build
104
-
105
- # Test
106
142
  npm test
107
143
  ```
108
144
 
109
145
  ## Troubleshooting
110
146
 
111
- **Tools not visible to agent:** The plugin auto-adds tools to `tools.allow` on startup. If tools still don't appear, check that the gateway was restarted after install.
147
+ **Tools not visible to agent (OC):** The plugin auto-adds tools to `tools.allow` on startup. Restart the gateway after install.
112
148
 
113
- **LLM auto-config failed:** Check the gateway log for `[hicortex] WARNING`. You may need to add `llmBaseUrl` to the plugin config manually for non-standard providers.
149
+ **LLM auto-config failed:** Check logs for `[hicortex] WARNING`. Add `llmBaseUrl` to plugin config or set `HICORTEX_LLM_BASE_URL` env var.
114
150
 
115
- **No lessons generated:** Reflection requires an LLM. Check that your LLM provider is accessible and has sufficient quota.
151
+ **No lessons generated:** Reflection requires an LLM. Check that your provider is accessible and has sufficient quota.
116
152
 
117
153
  **First startup slow:** The embedding model (~130MB) downloads on first run. Allow up to 2 minutes.
154
+
155
+ **Server won't start (CC):** Check `~/.hicortex/server.log` for errors. Verify port 8787 is free: `lsof -i :8787`.
156
+
157
+ **Multiple CC sessions:** The HTTP server handles multiple concurrent sessions. Do not use stdio transport — it spawns separate processes per session.
@@ -0,0 +1,28 @@
1
+ /**
2
+ * CLAUDE.md lesson injection — manages the Hicortex Learnings block.
3
+ *
4
+ * Writes a delimited block into ~/.claude/CLAUDE.md containing:
5
+ * - Agent guidance for proactive tool use
6
+ * - Active lessons from the DB
7
+ *
8
+ * Idempotent: calling twice with the same lessons produces the same file.
9
+ */
10
+ import type Database from "better-sqlite3";
11
+ /**
12
+ * Inject lessons from the DB into CLAUDE.md.
13
+ * Creates the file if it doesn't exist.
14
+ * Replaces existing block if present, appends if not.
15
+ */
16
+ export declare function injectLessons(db: Database.Database, options?: {
17
+ claudeMdPath?: string;
18
+ stateDir?: string;
19
+ project?: string;
20
+ }): {
21
+ lessonsCount: number;
22
+ path: string;
23
+ };
24
+ /**
25
+ * Remove the Hicortex Learnings block from CLAUDE.md.
26
+ * Used by the uninstall command.
27
+ */
28
+ export declare function removeLessonsBlock(claudeMdPath?: string): boolean;
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ /**
3
+ * CLAUDE.md lesson injection — manages the Hicortex Learnings block.
4
+ *
5
+ * Writes a delimited block into ~/.claude/CLAUDE.md containing:
6
+ * - Agent guidance for proactive tool use
7
+ * - Active lessons from the DB
8
+ *
9
+ * Idempotent: calling twice with the same lessons produces the same file.
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.injectLessons = injectLessons;
46
+ exports.removeLessonsBlock = removeLessonsBlock;
47
+ const node_fs_1 = require("node:fs");
48
+ const node_path_1 = require("node:path");
49
+ const node_path_2 = require("node:path");
50
+ const node_os_1 = require("node:os");
51
+ const storage = __importStar(require("./storage.js"));
52
+ const license_js_1 = require("./license.js");
53
+ const START_MARKER = "<!-- HICORTEX-LEARNINGS:START -->";
54
+ const END_MARKER = "<!-- HICORTEX-LEARNINGS:END -->";
55
+ const DEFAULT_CLAUDE_MD = (0, node_path_2.join)((0, node_os_1.homedir)(), ".claude", "CLAUDE.md");
56
+ const AGENT_GUIDANCE = `You have access to long-term memory via Hicortex MCP tools. Use \`hicortex_search\` when you need context from past sessions, decisions, or prior work. Use \`hicortex_context\` at session start to recall recent project state. Use \`hicortex_ingest\` to save important decisions or learnings. Sessions are auto-captured nightly.`;
57
+ /**
58
+ * Inject lessons from the DB into CLAUDE.md.
59
+ * Creates the file if it doesn't exist.
60
+ * Replaces existing block if present, appends if not.
61
+ */
62
+ function injectLessons(db, options = {}) {
63
+ const claudeMdPath = options.claudeMdPath ?? DEFAULT_CLAUDE_MD;
64
+ const stateDir = options.stateDir ?? (0, node_path_2.join)((0, node_os_1.homedir)(), ".hicortex");
65
+ // Determine lesson limit based on license
66
+ const features = (0, license_js_1.getFeatures)(stateDir);
67
+ const maxLessons = features.maxMemories === -1 ? 15 : 7;
68
+ // Load lessons
69
+ const lessons = storage.getLessons(db, 30, options.project);
70
+ const selected = lessons.slice(0, maxLessons);
71
+ // Format lesson lines
72
+ const lessonLines = selected.map((l) => {
73
+ const match = l.content.match(/## Lesson: (.+)/);
74
+ return match ? `- ${match[1]}` : `- ${l.content.slice(0, 200)}`;
75
+ });
76
+ // Build the block
77
+ const blockParts = [START_MARKER, "## Hicortex Learnings", "", AGENT_GUIDANCE];
78
+ if (lessonLines.length > 0) {
79
+ blockParts.push("", "### Active Lessons");
80
+ blockParts.push(...lessonLines);
81
+ }
82
+ blockParts.push(END_MARKER);
83
+ const block = blockParts.join("\n");
84
+ // Read existing file or start empty
85
+ let content = "";
86
+ try {
87
+ content = (0, node_fs_1.readFileSync)(claudeMdPath, "utf-8");
88
+ }
89
+ catch {
90
+ // File doesn't exist — will create it
91
+ }
92
+ // Replace or append
93
+ const startIdx = content.indexOf(START_MARKER);
94
+ const endIdx = content.indexOf(END_MARKER);
95
+ if (startIdx !== -1 && endIdx !== -1) {
96
+ // Replace existing block
97
+ content =
98
+ content.slice(0, startIdx) +
99
+ block +
100
+ content.slice(endIdx + END_MARKER.length);
101
+ }
102
+ else {
103
+ // Append with blank line separator
104
+ if (content.length > 0 && !content.endsWith("\n")) {
105
+ content += "\n";
106
+ }
107
+ if (content.length > 0) {
108
+ content += "\n";
109
+ }
110
+ content += block + "\n";
111
+ }
112
+ // Write
113
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(claudeMdPath), { recursive: true });
114
+ (0, node_fs_1.writeFileSync)(claudeMdPath, content);
115
+ return { lessonsCount: selected.length, path: claudeMdPath };
116
+ }
117
+ /**
118
+ * Remove the Hicortex Learnings block from CLAUDE.md.
119
+ * Used by the uninstall command.
120
+ */
121
+ function removeLessonsBlock(claudeMdPath = DEFAULT_CLAUDE_MD) {
122
+ let content;
123
+ try {
124
+ content = (0, node_fs_1.readFileSync)(claudeMdPath, "utf-8");
125
+ }
126
+ catch {
127
+ return false; // File doesn't exist
128
+ }
129
+ const startIdx = content.indexOf(START_MARKER);
130
+ const endIdx = content.indexOf(END_MARKER);
131
+ if (startIdx === -1 || endIdx === -1)
132
+ return false;
133
+ // Remove block and any trailing blank line
134
+ let newContent = content.slice(0, startIdx) +
135
+ content.slice(endIdx + END_MARKER.length);
136
+ // Clean up double blank lines left by removal
137
+ newContent = newContent.replace(/\n{3,}/g, "\n\n").trim();
138
+ if (newContent.length > 0)
139
+ newContent += "\n";
140
+ (0, node_fs_1.writeFileSync)(claudeMdPath, newContent);
141
+ return true;
142
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Hicortex CLI — entry point for `npx @gamaze/hicortex <command>`.
4
+ *
5
+ * Commands:
6
+ * server Start the MCP HTTP/SSE server (persistent daemon)
7
+ * init Detect existing setup and configure for CC/OC
8
+ * nightly Run distill + consolidate + inject lessons (manual trigger)
9
+ * status Show config, DB stats, adapter status
10
+ * uninstall Clean removal of CC integration
11
+ */
12
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * Hicortex CLI — entry point for `npx @gamaze/hicortex <command>`.
5
+ *
6
+ * Commands:
7
+ * server Start the MCP HTTP/SSE server (persistent daemon)
8
+ * init Detect existing setup and configure for CC/OC
9
+ * nightly Run distill + consolidate + inject lessons (manual trigger)
10
+ * status Show config, DB stats, adapter status
11
+ * uninstall Clean removal of CC integration
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ const command = process.argv[2];
15
+ switch (command) {
16
+ case "server": {
17
+ const portArg = process.argv.indexOf("--port");
18
+ const port = portArg !== -1 ? parseInt(process.argv[portArg + 1], 10) : undefined;
19
+ const hostArg = process.argv.indexOf("--host");
20
+ const host = hostArg !== -1 ? process.argv[hostArg + 1] : undefined;
21
+ import("./mcp-server.js").then(({ startServer }) => {
22
+ startServer({ port, host }).catch((err) => {
23
+ console.error("[hicortex] Server failed to start:", err);
24
+ process.exit(1);
25
+ });
26
+ });
27
+ break;
28
+ }
29
+ case "init":
30
+ import("./init.js").then(({ runInit }) => {
31
+ runInit().catch((err) => {
32
+ console.error("[hicortex] Init failed:", err);
33
+ process.exit(1);
34
+ });
35
+ });
36
+ break;
37
+ case "nightly": {
38
+ const dryRun = process.argv.includes("--dry-run");
39
+ import("./nightly.js").then(({ runNightly }) => {
40
+ runNightly({ dryRun }).catch((err) => {
41
+ console.error("[hicortex] Nightly pipeline failed:", err);
42
+ process.exit(1);
43
+ });
44
+ });
45
+ break;
46
+ }
47
+ case "status":
48
+ import("./status.js").then(({ runStatus }) => {
49
+ runStatus().catch((err) => {
50
+ console.error("[hicortex] Status failed:", err);
51
+ process.exit(1);
52
+ });
53
+ });
54
+ break;
55
+ case "uninstall":
56
+ import("./uninstall.js").then(({ runUninstall }) => {
57
+ runUninstall().catch((err) => {
58
+ console.error("[hicortex] Uninstall failed:", err);
59
+ process.exit(1);
60
+ });
61
+ });
62
+ break;
63
+ default:
64
+ console.log(`Hicortex — Human-like memory for self-improving AI agents
65
+
66
+ Usage: hicortex <command> [options]
67
+
68
+ Commands:
69
+ server Start the MCP HTTP/SSE server
70
+ init Set up Hicortex for Claude Code
71
+ nightly Run nightly distill + consolidate + inject
72
+ status Show current configuration and stats
73
+ uninstall Remove CC integration (preserves DB)
74
+
75
+ Options:
76
+ server --port <n> Port (default: 8787)
77
+ server --host <h> Host (default: 127.0.0.1)
78
+
79
+ Examples:
80
+ npx @gamaze/hicortex server
81
+ npx @gamaze/hicortex init
82
+ npx @gamaze/hicortex status`);
83
+ process.exit(command ? 1 : 0);
84
+ }
@@ -49,7 +49,7 @@ const node_os_1 = require("node:os");
49
49
  const retrieval_js_1 = require("./retrieval.js");
50
50
  const storage = __importStar(require("./storage.js"));
51
51
  const prompts_js_1 = require("./prompts.js");
52
- const LAST_CONSOLIDATED_PATH = (0, node_path_1.join)((0, node_os_1.homedir)(), ".claude", "memory", "last-consolidated.txt");
52
+ const LAST_CONSOLIDATED_PATH = (0, node_path_1.join)((0, node_os_1.homedir)(), ".hicortex", "last-consolidated.txt");
53
53
  // Default config constants (matching Python config.py)
54
54
  const CONSOLIDATE_MAX_LLM_CALLS = 200;
55
55
  const CONSOLIDATE_PRUNE_MIN_AGE_DAYS = 90;
package/dist/db.d.ts CHANGED
@@ -3,6 +3,16 @@
3
3
  * Ported from hicortex/db.py — same schema for migration compatibility.
4
4
  */
5
5
  import Database from "better-sqlite3";
6
+ /**
7
+ * Resolve the database path. Handles migration from legacy OC location.
8
+ *
9
+ * Priority:
10
+ * 1. Explicit override (env var or config)
11
+ * 2. Canonical ~/.hicortex/hicortex.db (if exists)
12
+ * 3. Legacy ~/.openclaw/data/hicortex.db (migrate to canonical, leave symlink)
13
+ * 4. Default: create ~/.hicortex/hicortex.db
14
+ */
15
+ export declare function resolveDbPath(override?: string): string;
6
16
  /**
7
17
  * Initialize the database: load sqlite-vec, enable WAL, create all tables.
8
18
  * Returns the open Database instance (caller manages lifetime).
package/dist/db.js CHANGED
@@ -7,11 +7,85 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
7
7
  return (mod && mod.__esModule) ? mod : { "default": mod };
8
8
  };
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.resolveDbPath = resolveDbPath;
10
11
  exports.initDb = initDb;
11
12
  exports.getStats = getStats;
12
13
  const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
13
14
  const node_fs_1 = require("node:fs");
15
+ const node_path_1 = require("node:path");
16
+ const node_os_1 = require("node:os");
14
17
  const EMBEDDING_DIMENSIONS = 384;
18
+ /** Canonical Hicortex home directory. */
19
+ const HICORTEX_HOME = (0, node_path_1.join)((0, node_os_1.homedir)(), ".hicortex");
20
+ /** Legacy OC plugin DB path (pre-v0.3 installations). */
21
+ const LEGACY_OC_DB = (0, node_path_1.join)((0, node_os_1.homedir)(), ".openclaw", "data", "hicortex.db");
22
+ /**
23
+ * Resolve the database path. Handles migration from legacy OC location.
24
+ *
25
+ * Priority:
26
+ * 1. Explicit override (env var or config)
27
+ * 2. Canonical ~/.hicortex/hicortex.db (if exists)
28
+ * 3. Legacy ~/.openclaw/data/hicortex.db (migrate to canonical, leave symlink)
29
+ * 4. Default: create ~/.hicortex/hicortex.db
30
+ */
31
+ function resolveDbPath(override) {
32
+ // 1. Explicit override
33
+ if (override)
34
+ return override;
35
+ const envOverride = process.env.HICORTEX_DB_PATH;
36
+ if (envOverride)
37
+ return envOverride;
38
+ const canonicalPath = (0, node_path_1.join)(HICORTEX_HOME, "hicortex.db");
39
+ // 2. Canonical path exists — use it
40
+ if ((0, node_fs_1.existsSync)(canonicalPath)) {
41
+ if ((0, node_fs_1.existsSync)(LEGACY_OC_DB) && !isSymlink(LEGACY_OC_DB)) {
42
+ console.warn(`[hicortex] WARNING: DB exists at both ${canonicalPath} and ${LEGACY_OC_DB}. ` +
43
+ `Using canonical path. Remove the legacy file if it is stale.`);
44
+ }
45
+ return canonicalPath;
46
+ }
47
+ // 3. Legacy OC path exists — migrate
48
+ if ((0, node_fs_1.existsSync)(LEGACY_OC_DB)) {
49
+ return migrateDb(LEGACY_OC_DB, canonicalPath);
50
+ }
51
+ // 4. Fresh install — ensure directory exists
52
+ (0, node_fs_1.mkdirSync)(HICORTEX_HOME, { recursive: true });
53
+ return canonicalPath;
54
+ }
55
+ /**
56
+ * Migrate DB from legacy path to canonical ~/.hicortex/.
57
+ * Moves the main DB file plus WAL/SHM if present.
58
+ * Leaves a symlink at the old path for backward compatibility.
59
+ */
60
+ function migrateDb(legacyPath, canonicalPath) {
61
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(canonicalPath), { recursive: true });
62
+ // Move main DB file
63
+ (0, node_fs_1.renameSync)(legacyPath, canonicalPath);
64
+ // Move WAL and SHM files if present
65
+ for (const suffix of ["-wal", "-shm"]) {
66
+ const legacySuffix = legacyPath + suffix;
67
+ if ((0, node_fs_1.existsSync)(legacySuffix)) {
68
+ (0, node_fs_1.renameSync)(legacySuffix, canonicalPath + suffix);
69
+ }
70
+ }
71
+ // Leave symlink at old path for backward compat
72
+ try {
73
+ (0, node_fs_1.symlinkSync)(canonicalPath, legacyPath);
74
+ }
75
+ catch {
76
+ // Non-fatal — symlink may fail on some filesystems
77
+ }
78
+ console.log(`[hicortex] Migrated database to ${canonicalPath}`);
79
+ return canonicalPath;
80
+ }
81
+ function isSymlink(path) {
82
+ try {
83
+ return (0, node_fs_1.lstatSync)(path).isSymbolicLink();
84
+ }
85
+ catch {
86
+ return false;
87
+ }
88
+ }
15
89
  const SCHEMA = `
16
90
  CREATE TABLE IF NOT EXISTS memories (
17
91
  id TEXT PRIMARY KEY,
package/dist/index.js CHANGED
@@ -41,11 +41,10 @@ var __importStar = (this && this.__importStar) || (function () {
41
41
  })();
42
42
  Object.defineProperty(exports, "__esModule", { value: true });
43
43
  const node_path_1 = require("node:path");
44
- const node_fs_1 = require("node:fs");
45
44
  const db_js_1 = require("./db.js");
46
45
  const license_js_1 = require("./license.js");
47
46
  const llm_js_1 = require("./llm.js");
48
- const node_fs_2 = require("node:fs");
47
+ const node_fs_1 = require("node:fs");
49
48
  const node_os_1 = require("node:os");
50
49
  const embedder_js_1 = require("./embedder.js");
51
50
  const storage = __importStar(require("./storage.js"));
@@ -78,11 +77,8 @@ exports.default = {
78
77
  const log = ctx.logger
79
78
  ? (msg) => ctx.logger.info(msg)
80
79
  : console.log;
81
- // Ensure data directory exists
82
- const dataDir = (0, node_path_1.join)(stateDir, "data");
83
- (0, node_fs_1.mkdirSync)(dataDir, { recursive: true });
84
- // Initialize database
85
- const dbPath = config.dbPath ?? (0, node_path_1.join)(dataDir, "hicortex.db");
80
+ // Resolve database path (handles migration from legacy OC location)
81
+ const dbPath = (0, db_js_1.resolveDbPath)(config.dbPath);
86
82
  log(`[hicortex] Initializing database at ${dbPath}`);
87
83
  db = (0, db_js_1.initDb)(dbPath);
88
84
  // Auto-configure LLM: resolve → test → persist
@@ -213,7 +209,7 @@ exports.default = {
213
209
  const { readFileSync: readFs } = await import("node:fs");
214
210
  const { join: joinPath } = await import("node:path");
215
211
  const { homedir: homeDir } = await import("node:os");
216
- const lastPath = joinPath(homeDir(), ".claude", "memory", "last-consolidated.txt");
212
+ const lastPath = joinPath(homeDir(), ".hicortex", "last-consolidated.txt");
217
213
  const lastTs = readFs(lastPath, "utf-8").trim();
218
214
  const lastDate = new Date(lastTs);
219
215
  const hoursSince = (Date.now() - lastDate.getTime()) / (1000 * 60 * 60);
@@ -422,7 +418,7 @@ async function autoConfigureLlm(pluginConfig, log) {
422
418
  function persistProviderConfig(llmConfig, log) {
423
419
  try {
424
420
  const configPath = (0, node_path_1.join)((0, node_os_1.homedir)(), ".openclaw", "openclaw.json");
425
- const raw = (0, node_fs_2.readFileSync)(configPath, "utf-8");
421
+ const raw = (0, node_fs_1.readFileSync)(configPath, "utf-8");
426
422
  const config = JSON.parse(raw);
427
423
  // Check if baseUrl already stored for this provider
428
424
  const existing = config?.models?.providers?.[llmConfig.provider]?.baseUrl;
@@ -448,7 +444,7 @@ function persistProviderConfig(llmConfig, log) {
448
444
  maxTokens: 8192,
449
445
  }];
450
446
  }
451
- (0, node_fs_2.writeFileSync)(configPath, JSON.stringify(config, null, 2));
447
+ (0, node_fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2));
452
448
  log(`[hicortex] Persisted LLM config: ${llmConfig.provider} → ${llmConfig.baseUrl}`);
453
449
  }
454
450
  catch {
@@ -462,14 +458,14 @@ function persistProviderConfig(llmConfig, log) {
462
458
  function getDaysSinceCapHit(dir) {
463
459
  const capFile = (0, node_path_1.join)(dir, "cap-hit.txt");
464
460
  try {
465
- const ts = (0, node_fs_2.readFileSync)(capFile, "utf-8").trim();
461
+ const ts = (0, node_fs_1.readFileSync)(capFile, "utf-8").trim();
466
462
  const hitDate = new Date(ts);
467
463
  return Math.floor((Date.now() - hitDate.getTime()) / (1000 * 60 * 60 * 24));
468
464
  }
469
465
  catch {
470
466
  // First time hitting cap — record it
471
467
  try {
472
- (0, node_fs_2.writeFileSync)(capFile, new Date().toISOString());
468
+ (0, node_fs_1.writeFileSync)(capFile, new Date().toISOString());
473
469
  }
474
470
  catch { /* non-fatal */ }
475
471
  return 0;
@@ -488,7 +484,7 @@ const HICORTEX_TOOLS = [
488
484
  function ensureToolsAllowed(log) {
489
485
  try {
490
486
  const configPath = (0, node_path_1.join)((0, node_os_1.homedir)(), ".openclaw", "openclaw.json");
491
- const raw = (0, node_fs_2.readFileSync)(configPath, "utf-8");
487
+ const raw = (0, node_fs_1.readFileSync)(configPath, "utf-8");
492
488
  const config = JSON.parse(raw);
493
489
  if (!config.tools)
494
490
  config.tools = {};
@@ -498,7 +494,7 @@ function ensureToolsAllowed(log) {
498
494
  if (missing.length === 0)
499
495
  return;
500
496
  config.tools.allow.push(...missing);
501
- (0, node_fs_2.writeFileSync)(configPath, JSON.stringify(config, null, 2));
497
+ (0, node_fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2));
502
498
  log(`[hicortex] Added tools to allow list: ${missing.join(", ")}`);
503
499
  }
504
500
  catch {
package/dist/init.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Hicortex init — detect existing setup and configure for CC.
3
+ *
4
+ * Detection:
5
+ * 1. Local HC server running (localhost:8787)
6
+ * 2. Remote HC server (HICORTEX_SERVER_URL or bedrock:8787)
7
+ * 3. OC plugin installed (~/.openclaw/openclaw.json)
8
+ * 4. CC MCP already registered (~/.claude/settings.json)
9
+ * 5. Existing DB (~/.hicortex/ or ~/.openclaw/data/)
10
+ *
11
+ * Actions:
12
+ * - Install persistent daemon (launchd/systemd)
13
+ * - Register MCP server in CC settings
14
+ * - Inject CLAUDE.md learnings block
15
+ * - Install CC custom commands (/learn, /hicortex-activate)
16
+ */
17
+ export declare function runInit(): Promise<void>;