@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 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
+ }
@@ -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.1",
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.1",
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": {