@gamaze/hicortex 0.5.1 → 0.5.2
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/nightly.js +35 -0
- package/dist/state.d.ts +2 -0
- package/dist/telemetry.d.ts +48 -0
- package/dist/telemetry.js +77 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/nightly.js
CHANGED
|
@@ -47,6 +47,11 @@ exports.runNightly = runNightly;
|
|
|
47
47
|
const node_fs_1 = require("node:fs");
|
|
48
48
|
const node_path_1 = require("node:path");
|
|
49
49
|
const node_os_1 = require("node:os");
|
|
50
|
+
let VERSION = "0.0.0";
|
|
51
|
+
try {
|
|
52
|
+
VERSION = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(__dirname, "..", "package.json"), "utf-8")).version;
|
|
53
|
+
}
|
|
54
|
+
catch { }
|
|
50
55
|
const db_js_1 = require("./db.js");
|
|
51
56
|
const llm_js_1 = require("./llm.js");
|
|
52
57
|
const embedder_js_1 = require("./embedder.js");
|
|
@@ -59,6 +64,7 @@ const claude_md_js_1 = require("./claude-md.js");
|
|
|
59
64
|
const features_js_1 = require("./features.js");
|
|
60
65
|
const extensions_js_1 = require("./extensions.js");
|
|
61
66
|
const state_js_1 = require("./state.js");
|
|
67
|
+
const telemetry_js_1 = require("./telemetry.js");
|
|
62
68
|
const HICORTEX_HOME = (0, node_path_1.join)((0, node_os_1.homedir)(), ".hicortex");
|
|
63
69
|
function readNightlyConfig(stateDir) {
|
|
64
70
|
try {
|
|
@@ -315,6 +321,22 @@ async function runNightly(options = {}) {
|
|
|
315
321
|
}
|
|
316
322
|
}
|
|
317
323
|
console.log(`[hicortex] Nightly pipeline complete.`);
|
|
324
|
+
// Step 6: Anonymous telemetry (fire-and-forget, opt-out via config)
|
|
325
|
+
if (!dryRun && (0, telemetry_js_1.isTelemetryEnabled)(savedConfig)) {
|
|
326
|
+
const agentType = piBatches.length > 0 && ccBatches.length > 0 ? "mixed"
|
|
327
|
+
: piBatches.length > 0 ? "pi"
|
|
328
|
+
: "cc";
|
|
329
|
+
await (0, telemetry_js_1.sendTelemetry)({
|
|
330
|
+
id: (0, telemetry_js_1.getTelemetryId)(stateDir),
|
|
331
|
+
v: VERSION,
|
|
332
|
+
mode: "server",
|
|
333
|
+
agent: agentType,
|
|
334
|
+
mem: storage.countMemories(db),
|
|
335
|
+
lessons: storage.getLessons(db, 365).length,
|
|
336
|
+
sessions: batches.length,
|
|
337
|
+
ok: !hadTransientFailure,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
318
340
|
}
|
|
319
341
|
finally {
|
|
320
342
|
db.close();
|
|
@@ -508,6 +530,19 @@ async function runClientNightly(config, dryRun) {
|
|
|
508
530
|
}
|
|
509
531
|
}
|
|
510
532
|
console.log(`[hicortex] Client nightly complete: ${memoriesIngested} memories from ${sessionsSent} sessions → ${serverUrl}`);
|
|
533
|
+
// Anonymous telemetry (fire-and-forget, opt-out via config)
|
|
534
|
+
if (!dryRun && (0, telemetry_js_1.isTelemetryEnabled)(config)) {
|
|
535
|
+
await (0, telemetry_js_1.sendTelemetry)({
|
|
536
|
+
id: (0, telemetry_js_1.getTelemetryId)(HICORTEX_HOME),
|
|
537
|
+
v: VERSION,
|
|
538
|
+
mode: "client",
|
|
539
|
+
agent: "cc", // client mode is always CC-originated currently
|
|
540
|
+
mem: memoriesIngested,
|
|
541
|
+
lessons: 0, // client doesn't know lesson count
|
|
542
|
+
sessions: batches.length,
|
|
543
|
+
ok: !hadTransientFailure,
|
|
544
|
+
});
|
|
545
|
+
}
|
|
511
546
|
}
|
|
512
547
|
/**
|
|
513
548
|
* Fetch lessons + memory index from server and inject into CLAUDE.md.
|
package/dist/state.d.ts
CHANGED
|
@@ -33,6 +33,8 @@ export interface HicortexState {
|
|
|
33
33
|
lastConsolidated?: string;
|
|
34
34
|
/** Last-known license tier (replaces tier.json + license-validated.txt). */
|
|
35
35
|
tier?: PersistedTier;
|
|
36
|
+
/** Anonymous telemetry UUID — generated once, never linked to personal info. */
|
|
37
|
+
telemetryId?: string;
|
|
36
38
|
}
|
|
37
39
|
/**
|
|
38
40
|
* Load the state file. Returns an empty state if the file is missing
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anonymous telemetry — sends aggregate stats after each nightly run.
|
|
3
|
+
*
|
|
4
|
+
* What's sent (8 fields, all aggregate):
|
|
5
|
+
* id — random UUID, generated once on first run, stored in state.json
|
|
6
|
+
* v — package version
|
|
7
|
+
* mode — server or client
|
|
8
|
+
* agent — cc, pi, oc, or mixed (detected from session sources)
|
|
9
|
+
* mem — total memory count
|
|
10
|
+
* lessons — total lesson count
|
|
11
|
+
* sessions — sessions distilled this run
|
|
12
|
+
* ok — nightly succeeded (true/false)
|
|
13
|
+
*
|
|
14
|
+
* What's NOT sent:
|
|
15
|
+
* No personal data, no session content, no file paths, no IPs stored.
|
|
16
|
+
*
|
|
17
|
+
* Opt-out:
|
|
18
|
+
* Set "telemetry": false in ~/.hicortex/config.json
|
|
19
|
+
* OR set HICORTEX_TELEMETRY=off in the environment
|
|
20
|
+
*
|
|
21
|
+
* The ping is fire-and-forget with a 5s timeout. If it fails, nothing
|
|
22
|
+
* happens — the nightly result is unaffected.
|
|
23
|
+
*/
|
|
24
|
+
export interface TelemetryPayload {
|
|
25
|
+
id: string;
|
|
26
|
+
v: string;
|
|
27
|
+
mode: string;
|
|
28
|
+
agent: string;
|
|
29
|
+
mem: number;
|
|
30
|
+
lessons: number;
|
|
31
|
+
sessions: number;
|
|
32
|
+
ok: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if telemetry is enabled. Disabled by:
|
|
36
|
+
* - config.telemetry === false
|
|
37
|
+
* - HICORTEX_TELEMETRY env var set to "off", "false", or "0"
|
|
38
|
+
*/
|
|
39
|
+
export declare function isTelemetryEnabled(config: Record<string, unknown> | null): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Get or create the anonymous telemetry ID.
|
|
42
|
+
* Generated once, stored in state.json, never linked to any personal info.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getTelemetryId(stateDir: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Send anonymous telemetry. Fire-and-forget — failures are silently ignored.
|
|
47
|
+
*/
|
|
48
|
+
export declare function sendTelemetry(payload: TelemetryPayload, serverUrl?: string): Promise<void>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Anonymous telemetry — sends aggregate stats after each nightly run.
|
|
4
|
+
*
|
|
5
|
+
* What's sent (8 fields, all aggregate):
|
|
6
|
+
* id — random UUID, generated once on first run, stored in state.json
|
|
7
|
+
* v — package version
|
|
8
|
+
* mode — server or client
|
|
9
|
+
* agent — cc, pi, oc, or mixed (detected from session sources)
|
|
10
|
+
* mem — total memory count
|
|
11
|
+
* lessons — total lesson count
|
|
12
|
+
* sessions — sessions distilled this run
|
|
13
|
+
* ok — nightly succeeded (true/false)
|
|
14
|
+
*
|
|
15
|
+
* What's NOT sent:
|
|
16
|
+
* No personal data, no session content, no file paths, no IPs stored.
|
|
17
|
+
*
|
|
18
|
+
* Opt-out:
|
|
19
|
+
* Set "telemetry": false in ~/.hicortex/config.json
|
|
20
|
+
* OR set HICORTEX_TELEMETRY=off in the environment
|
|
21
|
+
*
|
|
22
|
+
* The ping is fire-and-forget with a 5s timeout. If it fails, nothing
|
|
23
|
+
* happens — the nightly result is unaffected.
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.isTelemetryEnabled = isTelemetryEnabled;
|
|
27
|
+
exports.getTelemetryId = getTelemetryId;
|
|
28
|
+
exports.sendTelemetry = sendTelemetry;
|
|
29
|
+
const node_crypto_1 = require("node:crypto");
|
|
30
|
+
const state_js_1 = require("./state.js");
|
|
31
|
+
const TELEMETRY_URL = "https://hicortex.gamaze.com/api/telemetry";
|
|
32
|
+
/**
|
|
33
|
+
* Check if telemetry is enabled. Disabled by:
|
|
34
|
+
* - config.telemetry === false
|
|
35
|
+
* - HICORTEX_TELEMETRY env var set to "off", "false", or "0"
|
|
36
|
+
*/
|
|
37
|
+
function isTelemetryEnabled(config) {
|
|
38
|
+
// Config override
|
|
39
|
+
if (config?.telemetry === false)
|
|
40
|
+
return false;
|
|
41
|
+
// Env var override
|
|
42
|
+
const env = process.env.HICORTEX_TELEMETRY?.toLowerCase();
|
|
43
|
+
if (env === "off" || env === "false" || env === "0")
|
|
44
|
+
return false;
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get or create the anonymous telemetry ID.
|
|
49
|
+
* Generated once, stored in state.json, never linked to any personal info.
|
|
50
|
+
*/
|
|
51
|
+
function getTelemetryId(stateDir) {
|
|
52
|
+
const state = (0, state_js_1.loadState)(stateDir);
|
|
53
|
+
if (state.telemetryId)
|
|
54
|
+
return state.telemetryId;
|
|
55
|
+
const id = (0, node_crypto_1.randomUUID)();
|
|
56
|
+
(0, state_js_1.updateState)((s) => {
|
|
57
|
+
s.telemetryId = id;
|
|
58
|
+
return s;
|
|
59
|
+
}, stateDir);
|
|
60
|
+
return id;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Send anonymous telemetry. Fire-and-forget — failures are silently ignored.
|
|
64
|
+
*/
|
|
65
|
+
async function sendTelemetry(payload, serverUrl = TELEMETRY_URL) {
|
|
66
|
+
try {
|
|
67
|
+
await fetch(serverUrl, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: { "Content-Type": "application/json" },
|
|
70
|
+
body: JSON.stringify(payload),
|
|
71
|
+
signal: AbortSignal.timeout(5_000),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Silently ignore — telemetry must never affect the nightly result
|
|
76
|
+
}
|
|
77
|
+
}
|
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.5.
|
|
5
|
+
"version": "0.5.2",
|
|
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.5.
|
|
3
|
+
"version": "0.5.2",
|
|
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": {
|