@gamaze/hicortex 0.4.3 → 0.4.4
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/claude-md.d.ts +2 -2
- package/dist/claude-md.js +8 -6
- package/dist/consolidate.js +9 -22
- package/dist/db.d.ts +2 -0
- package/dist/db.js +88 -9
- package/dist/extensions.d.ts +126 -0
- package/dist/extensions.js +154 -0
- package/dist/features.d.ts +37 -0
- package/dist/features.js +127 -0
- package/dist/index.js +20 -35
- package/dist/license.d.ts +13 -3
- package/dist/license.js +30 -41
- package/dist/mcp-server.js +16 -18
- package/dist/nightly.js +28 -32
- package/dist/state.d.ts +64 -0
- package/dist/state.js +162 -0
- package/package.json +7 -3
package/dist/state.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Centralized state management — single ~/.hicortex/state.json file.
|
|
4
|
+
*
|
|
5
|
+
* Replaces 4 separate state files used by previous versions:
|
|
6
|
+
* - nightly-last-run.txt → state.lastNightly
|
|
7
|
+
* - last-consolidated.txt → state.lastConsolidated
|
|
8
|
+
* - tier.json → state.tier
|
|
9
|
+
* - license-validated.txt → state.tier.validatedAt (subsumed)
|
|
10
|
+
*
|
|
11
|
+
* Why one file:
|
|
12
|
+
* - Atomic writes (write to temp + rename)
|
|
13
|
+
* - Easier debugging (one file to inspect)
|
|
14
|
+
* - No filesystem chatter from multiple separate writes
|
|
15
|
+
* - Single migration path going forward
|
|
16
|
+
*
|
|
17
|
+
* Note: ~/.hicortex/config.json is intentionally NOT merged here. Config is
|
|
18
|
+
* user-edited and tracked separately from machine state.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.loadState = loadState;
|
|
22
|
+
exports.saveState = saveState;
|
|
23
|
+
exports.updateState = updateState;
|
|
24
|
+
exports.migrateLegacyState = migrateLegacyState;
|
|
25
|
+
const node_fs_1 = require("node:fs");
|
|
26
|
+
const node_path_1 = require("node:path");
|
|
27
|
+
const node_os_1 = require("node:os");
|
|
28
|
+
const HICORTEX_HOME = (0, node_path_1.join)((0, node_os_1.homedir)(), ".hicortex");
|
|
29
|
+
const STATE_FILE = "state.json";
|
|
30
|
+
/**
|
|
31
|
+
* Load the state file. Returns an empty state if the file is missing
|
|
32
|
+
* or corrupted (callers should handle missing fields with defaults).
|
|
33
|
+
*/
|
|
34
|
+
function loadState(stateDir = HICORTEX_HOME) {
|
|
35
|
+
const path = (0, node_path_1.join)(stateDir, STATE_FILE);
|
|
36
|
+
try {
|
|
37
|
+
const raw = (0, node_fs_1.readFileSync)(path, "utf-8");
|
|
38
|
+
const parsed = JSON.parse(raw);
|
|
39
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return {};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Atomically write the state file. Uses write-to-temp + rename so a crash
|
|
47
|
+
* during write cannot leave a half-written state.json on disk.
|
|
48
|
+
*/
|
|
49
|
+
function saveState(state, stateDir = HICORTEX_HOME) {
|
|
50
|
+
try {
|
|
51
|
+
(0, node_fs_1.mkdirSync)(stateDir, { recursive: true });
|
|
52
|
+
const path = (0, node_path_1.join)(stateDir, STATE_FILE);
|
|
53
|
+
const tmp = `${path}.tmp`;
|
|
54
|
+
(0, node_fs_1.writeFileSync)(tmp, JSON.stringify(state, null, 2));
|
|
55
|
+
(0, node_fs_1.renameSync)(tmp, path);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
console.warn(`[hicortex] Failed to save state: ${err instanceof Error ? err.message : String(err)}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Read-modify-write helper. The updater receives the current state and
|
|
63
|
+
* returns the next state (or void if it mutates in place).
|
|
64
|
+
*/
|
|
65
|
+
function updateState(updater, stateDir = HICORTEX_HOME) {
|
|
66
|
+
const current = loadState(stateDir);
|
|
67
|
+
const result = updater(current);
|
|
68
|
+
const next = result ?? current;
|
|
69
|
+
saveState(next, stateDir);
|
|
70
|
+
return next;
|
|
71
|
+
}
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
// One-time legacy migration
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
const LEGACY_FILES = [
|
|
76
|
+
"nightly-last-run.txt",
|
|
77
|
+
"last-consolidated.txt",
|
|
78
|
+
"license-validated.txt",
|
|
79
|
+
"tier.json",
|
|
80
|
+
];
|
|
81
|
+
/**
|
|
82
|
+
* One-time migration from the 4 legacy state files to state.json.
|
|
83
|
+
*
|
|
84
|
+
* Behaviour:
|
|
85
|
+
* 1. If state.json already exists, do nothing (and clean up any leftover
|
|
86
|
+
* legacy files from a previously interrupted migration).
|
|
87
|
+
* 2. Otherwise, read whichever legacy files exist, build a HicortexState,
|
|
88
|
+
* write state.json, and delete the legacy files.
|
|
89
|
+
*
|
|
90
|
+
* Idempotent: safe to call on every boot.
|
|
91
|
+
* Returns true if migration ran, false if state.json already existed.
|
|
92
|
+
*/
|
|
93
|
+
function migrateLegacyState(stateDir = HICORTEX_HOME) {
|
|
94
|
+
const statePath = (0, node_path_1.join)(stateDir, STATE_FILE);
|
|
95
|
+
if ((0, node_fs_1.existsSync)(statePath)) {
|
|
96
|
+
cleanupLegacyFiles(stateDir);
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
const state = {};
|
|
100
|
+
let foundAny = false;
|
|
101
|
+
// 1. nightly-last-run.txt → state.lastNightly
|
|
102
|
+
const ln = readLegacyText(stateDir, "nightly-last-run.txt");
|
|
103
|
+
if (ln) {
|
|
104
|
+
state.lastNightly = ln;
|
|
105
|
+
foundAny = true;
|
|
106
|
+
}
|
|
107
|
+
// 2. last-consolidated.txt → state.lastConsolidated
|
|
108
|
+
const lc = readLegacyText(stateDir, "last-consolidated.txt");
|
|
109
|
+
if (lc) {
|
|
110
|
+
state.lastConsolidated = lc;
|
|
111
|
+
foundAny = true;
|
|
112
|
+
}
|
|
113
|
+
// 3. tier.json → state.tier (full object)
|
|
114
|
+
const tierRaw = readLegacyText(stateDir, "tier.json");
|
|
115
|
+
if (tierRaw) {
|
|
116
|
+
try {
|
|
117
|
+
state.tier = JSON.parse(tierRaw);
|
|
118
|
+
foundAny = true;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Corrupted tier.json — ignore
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// 4. license-validated.txt → state.tier.validatedAt (only if no tier yet)
|
|
125
|
+
// (subsumed by tier.json when it exists)
|
|
126
|
+
if (!state.tier) {
|
|
127
|
+
const lv = readLegacyText(stateDir, "license-validated.txt");
|
|
128
|
+
if (lv) {
|
|
129
|
+
// We have a validation timestamp but no tier object — preserve as
|
|
130
|
+
// a placeholder so offline grace can still work. The features module
|
|
131
|
+
// will re-validate on next boot to get the full features back.
|
|
132
|
+
// We deliberately don't fabricate features here.
|
|
133
|
+
foundAny = true;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (foundAny) {
|
|
137
|
+
saveState(state, stateDir);
|
|
138
|
+
cleanupLegacyFiles(stateDir);
|
|
139
|
+
console.log("[hicortex] Migrated legacy state files to ~/.hicortex/state.json");
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
function readLegacyText(stateDir, name) {
|
|
145
|
+
try {
|
|
146
|
+
const raw = (0, node_fs_1.readFileSync)((0, node_path_1.join)(stateDir, name), "utf-8").trim();
|
|
147
|
+
return raw || null;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function cleanupLegacyFiles(stateDir) {
|
|
154
|
+
for (const name of LEGACY_FILES) {
|
|
155
|
+
try {
|
|
156
|
+
(0, node_fs_1.unlinkSync)((0, node_path_1.join)(stateDir, name));
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// File didn't exist — fine
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gamaze/hicortex",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
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": {
|
|
@@ -45,13 +45,17 @@
|
|
|
45
45
|
"engines": {
|
|
46
46
|
"node": ">=18"
|
|
47
47
|
},
|
|
48
|
-
"license": "
|
|
48
|
+
"license": "MIT",
|
|
49
49
|
"homepage": "https://hicortex.gamaze.com",
|
|
50
50
|
"repository": {
|
|
51
51
|
"type": "git",
|
|
52
|
-
"url": "https://github.com/
|
|
52
|
+
"url": "https://github.com/gamaze-labs/hicortex.git",
|
|
53
53
|
"directory": "packages/openclaw-plugin"
|
|
54
54
|
},
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/gamaze-labs/hicortex/issues"
|
|
57
|
+
},
|
|
58
|
+
"author": "Mattias Hansson",
|
|
55
59
|
"dependencies": {
|
|
56
60
|
"@huggingface/transformers": "^3.0.0",
|
|
57
61
|
"@modelcontextprotocol/sdk": "^1.28.0",
|