@gamaze/hicortex 0.10.1 → 0.11.1
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 +42 -0
- package/THIRD_PARTY_NOTICES.md +108 -0
- package/assets/vendor/3d-force-graph.min.js +5 -0
- package/assets/vendor/force-graph.min.js +5 -0
- package/assets/vendor/three.core.min.js +6 -0
- package/assets/vendor/three.module.min.js +6 -0
- package/assets/viz.html +1128 -0
- package/dist/classify-domains.d.ts +98 -0
- package/dist/classify-domains.js +340 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +63 -0
- package/dist/consolidate.d.ts +139 -2
- package/dist/consolidate.js +302 -87
- package/dist/db.js +70 -0
- package/dist/domain-classify.d.ts +164 -0
- package/dist/domain-classify.js +300 -0
- package/dist/extensions.d.ts +12 -0
- package/dist/graph.d.ts +56 -0
- package/dist/graph.js +145 -0
- package/dist/index.js +1 -1
- package/dist/init.d.ts +25 -0
- package/dist/init.js +54 -0
- package/dist/lesson-selection.js +12 -5
- package/dist/lessons-context.js +2 -1
- package/dist/llm.d.ts +67 -0
- package/dist/llm.js +122 -0
- package/dist/mcp-server.js +86 -28
- package/dist/nightly-status.js +9 -28
- package/dist/nightly.js +42 -32
- package/dist/nofit.d.ts +111 -0
- package/dist/nofit.js +176 -0
- package/dist/prompts.d.ts +0 -5
- package/dist/prompts.js +5 -29
- package/dist/relink.d.ts +100 -0
- package/dist/relink.js +277 -0
- package/dist/retrieval.d.ts +16 -1
- package/dist/retrieval.js +34 -2
- package/dist/schema-prototypes.d.ts +149 -0
- package/dist/schema-prototypes.js +329 -0
- package/dist/state.d.ts +32 -0
- package/dist/state.js +29 -0
- package/dist/status.js +12 -19
- package/dist/storage.d.ts +44 -1
- package/dist/storage.js +70 -1
- package/dist/types.d.ts +90 -0
- package/dist/viz.d.ts +69 -0
- package/dist/viz.js +180 -0
- package/domains.example.json +36 -0
- package/package.json +6 -3
package/dist/types.d.ts
CHANGED
|
@@ -72,6 +72,24 @@ export interface ConsolidationReport {
|
|
|
72
72
|
domain_curation?: {
|
|
73
73
|
curated: boolean;
|
|
74
74
|
domains: number;
|
|
75
|
+
/** Content-based path only: memories (re)filed this run. */
|
|
76
|
+
classified?: number;
|
|
77
|
+
/** Graded-schema pass: domains with a stored prototype after the run. */
|
|
78
|
+
prototypes?: number;
|
|
79
|
+
/** Graded-schema pass: memory_tags rows whose weight was recomputed. */
|
|
80
|
+
weights_recomputed?: number;
|
|
81
|
+
/** Graded-schema pass: memories whose derived primary changed. */
|
|
82
|
+
primaries_updated?: number;
|
|
83
|
+
/**
|
|
84
|
+
* No-fit path: memories that earned a WEAK primary (argmax prototype
|
|
85
|
+
* cosine >= weakPrimaryFloor) after the LLM found no fitting domain.
|
|
86
|
+
*/
|
|
87
|
+
weak_primary?: number;
|
|
88
|
+
/**
|
|
89
|
+
* No-fit path: memories below the weak-primary floor — untagged,
|
|
90
|
+
* base_strength halved (accelerated decay toward prune).
|
|
91
|
+
*/
|
|
92
|
+
no_association_decayed?: number;
|
|
75
93
|
reason?: string;
|
|
76
94
|
};
|
|
77
95
|
hub_boost?: {
|
|
@@ -112,10 +130,65 @@ export interface HicortexConfig {
|
|
|
112
130
|
llmModel?: string;
|
|
113
131
|
/** @deprecated Use the Hicortex server for distillation and consolidation. */
|
|
114
132
|
reflectModel?: string;
|
|
133
|
+
/**
|
|
134
|
+
* Optional dedicated model for memory tag classification (server-side
|
|
135
|
+
* nightly + `hicortex classify-domains`). When unset, classification uses
|
|
136
|
+
* the reflect tier exactly as before.
|
|
137
|
+
*/
|
|
138
|
+
classifyModel?: string;
|
|
139
|
+
/**
|
|
140
|
+
* Optional dedicated endpoint for classification. When only classifyModel
|
|
141
|
+
* is set, it runs on the reflect endpoint (else the base endpoint).
|
|
142
|
+
*/
|
|
143
|
+
classifyBaseUrl?: string;
|
|
144
|
+
/** Optional API key for the classify endpoint (defaults to the base apiKey). */
|
|
145
|
+
classifyApiKey?: string;
|
|
146
|
+
/** Optional provider for the classify endpoint (defaults to the base provider). */
|
|
147
|
+
classifyProvider?: string;
|
|
115
148
|
/** @deprecated Consolidation is owned by the server nightly. */
|
|
116
149
|
consolidateHour?: number;
|
|
117
150
|
/** @deprecated The OC plugin no longer opens its own database. */
|
|
118
151
|
dbPath?: string;
|
|
152
|
+
/**
|
|
153
|
+
* Optional config-owned domain list — the user's top-level memory spheres
|
|
154
|
+
* (life areas OR project/topic areas). When present, the nightly multi-tag
|
|
155
|
+
* classifies each memory by CONTENT against this vocabulary (classify tier,
|
|
156
|
+
* falling back to the reflect tier) instead of grouping projects into
|
|
157
|
+
* LLM-invented domains. When ABSENT, the legacy project-grouping
|
|
158
|
+
* moduleIndex behaviour is unchanged.
|
|
159
|
+
*
|
|
160
|
+
* Server-mode `init` scaffolds a generic 5-domain default (Work, Personal,
|
|
161
|
+
* People, Health, Finance — see GENERIC_DEFAULT_DOMAINS in init.ts) when
|
|
162
|
+
* this key is absent, and NEVER touches an existing list. A power-user
|
|
163
|
+
* example (compartment flag, custom weakPrimaryFloor) ships as
|
|
164
|
+
* domains.example.json in the package root.
|
|
165
|
+
*
|
|
166
|
+
* NO fallback bucket is needed or special-cased (owner amendment 07.07):
|
|
167
|
+
* a genuine no-fit memory gets a WEAK primary from prototype cosines when
|
|
168
|
+
* possible, else it decays toward pruning (see nofit.ts). A domain named
|
|
169
|
+
* "Unsorted" — if configured — is just a normal domain.
|
|
170
|
+
*/
|
|
171
|
+
domains?: DomainDef[];
|
|
172
|
+
/**
|
|
173
|
+
* Minimum cosine(memory embedding, best domain prototype) for a no-fit
|
|
174
|
+
* memory to earn a WEAK primary instead of decaying (see nofit.ts).
|
|
175
|
+
* Number in (0, 1); default 0.45. Tune from the corpus weight distribution
|
|
176
|
+
* (the memory_tags.weight histogram of LLM-tagged rows — set the floor
|
|
177
|
+
* near its lower tail). See domains.example.json for a worked example.
|
|
178
|
+
*/
|
|
179
|
+
weakPrimaryFloor?: number;
|
|
180
|
+
}
|
|
181
|
+
/** A config-owned life-sphere domain (see HicortexConfig.domains). */
|
|
182
|
+
export interface DomainDef {
|
|
183
|
+
name: string;
|
|
184
|
+
description: string;
|
|
185
|
+
/**
|
|
186
|
+
* Deliberate compartmentalization (graded-schema spec, 07.07.2026): when
|
|
187
|
+
* true, this domain becomes the PRIMARY (memories.domain) whenever it is
|
|
188
|
+
* tagged, overriding the argmax-weight rule. The owner's config flags only
|
|
189
|
+
* Work — a work/life firewall. Optional; absent = false.
|
|
190
|
+
*/
|
|
191
|
+
compartment?: boolean;
|
|
119
192
|
}
|
|
120
193
|
/** Response from license validation API. */
|
|
121
194
|
export interface LicenseInfo {
|
|
@@ -138,14 +211,31 @@ export interface ModuleDomain {
|
|
|
138
211
|
memoryCount: number;
|
|
139
212
|
lessonCount: number;
|
|
140
213
|
keywords: string[];
|
|
214
|
+
/**
|
|
215
|
+
* One-line description — only populated for content-based (config-owned)
|
|
216
|
+
* domains. Empty for project-grouping domains.
|
|
217
|
+
*/
|
|
218
|
+
description?: string;
|
|
141
219
|
}
|
|
142
220
|
/** Auto-generated knowledge routing index, cached in state.json. */
|
|
143
221
|
export interface ModuleIndex {
|
|
144
222
|
domains: ModuleDomain[];
|
|
223
|
+
/**
|
|
224
|
+
* Cache-invalidation key.
|
|
225
|
+
* - Project-grouping mode: sha256 of the sorted PROJECT name set.
|
|
226
|
+
* - Content-based mode: sha256 of the sorted configured DOMAIN name set.
|
|
227
|
+
* A single field keeps the state shape stable; `mode` disambiguates.
|
|
228
|
+
*/
|
|
145
229
|
projectSetHash: string;
|
|
146
230
|
curatedAt: string;
|
|
147
231
|
totalMemories: number;
|
|
148
232
|
totalLessons: number;
|
|
233
|
+
/**
|
|
234
|
+
* How this index was built. Absent = legacy project-grouping (backward
|
|
235
|
+
* compatible). "content" = per-memory content classification from the
|
|
236
|
+
* config-owned `domains` list.
|
|
237
|
+
*/
|
|
238
|
+
mode?: "project" | "content";
|
|
149
239
|
}
|
|
150
240
|
/** Options for inserting a memory. */
|
|
151
241
|
export interface InsertMemoryOptions {
|
package/dist/viz.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /viz support (#124) — knowledge-graph visualization page.
|
|
3
|
+
*
|
|
4
|
+
* Two concerns live here so they can be unit-tested without booting the full
|
|
5
|
+
* MCP daemon (mcp-server.ts pulls in the embedder + MCP SDK):
|
|
6
|
+
*
|
|
7
|
+
* 1. createAuthMiddleware — the bearer-token auth middleware used by the whole
|
|
8
|
+
* REST surface. Extracted verbatim from mcp-server.ts, plus ONE change for
|
|
9
|
+
* /viz: the page SHELL is exempt like /health (it carries no data or
|
|
10
|
+
* secrets — it ships verbatim in the public npm tarball). Browsers cannot
|
|
11
|
+
* attach an Authorization header on plain navigation; the page collects
|
|
12
|
+
* the token client-side and uses it on its /graph data fetch, which stays
|
|
13
|
+
* bearer-only like every other data route.
|
|
14
|
+
*
|
|
15
|
+
* 2. readVizHtml — loads the self-contained visualization page from
|
|
16
|
+
* assets/viz.html at request time. The asset sits next to src/ and dist/
|
|
17
|
+
* (siblings), so `../assets/viz.html` resolves from both the compiled
|
|
18
|
+
* output (dist/viz.js) and the TypeScript source (tests/tsx).
|
|
19
|
+
*
|
|
20
|
+
* 3. vendorHandler — serves the pinned renderer bundles from assets/vendor/
|
|
21
|
+
* (#139: three.js / 3d-force-graph / force-graph, see
|
|
22
|
+
* THIRD_PARTY_NOTICES.md). STRICT allowlist of exact filenames — the
|
|
23
|
+
* request path is never joined into the filesystem path; the served path
|
|
24
|
+
* comes from a fixed lookup table, so traversal is impossible by
|
|
25
|
+
* construction. Public like the /viz shell (static public code, no data).
|
|
26
|
+
*/
|
|
27
|
+
import type express from "express";
|
|
28
|
+
/**
|
|
29
|
+
* Exact filenames servable from assets/vendor/ — nothing else. Pinned bundles
|
|
30
|
+
* documented in THIRD_PARTY_NOTICES.md. Keep this list in lockstep with the
|
|
31
|
+
* <script src="/viz/vendor/…"> references in assets/viz.html.
|
|
32
|
+
*/
|
|
33
|
+
export declare const VIZ_VENDOR_FILES: ReadonlySet<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Bearer token auth — ALWAYS installed, fail-closed. /health, the /viz page
|
|
36
|
+
* shell, and localhost bypass (OPTIONS is short-circuited by the CORS
|
|
37
|
+
* middleware before this runs). With no token configured, remote requests are
|
|
38
|
+
* REJECTED (not open): the default bind is 0.0.0.0, so "no token = no auth"
|
|
39
|
+
* would expose the whole memory store to the network.
|
|
40
|
+
*/
|
|
41
|
+
export declare function createAuthMiddleware(authToken: string | undefined): express.RequestHandler;
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the on-disk path of the viz page. Throws (fail explicitly) when the
|
|
44
|
+
* asset is missing — a broken install should surface, not degrade silently.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveVizHtmlPath(): string;
|
|
47
|
+
/** Read the viz page. Read at request time so a reinstall is picked up live. */
|
|
48
|
+
export declare function readVizHtml(): string;
|
|
49
|
+
/**
|
|
50
|
+
* Express handler for GET /viz. 503 with the endpoint's usual {error} shape
|
|
51
|
+
* when the asset cannot be read.
|
|
52
|
+
*/
|
|
53
|
+
export declare function vizHandler(): express.RequestHandler;
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the on-disk path of an allowlisted vendor bundle, or null when the
|
|
56
|
+
* requested name is not on the allowlist. The filesystem path is built ONLY
|
|
57
|
+
* from the allowlist literal (never from request input), so no traversal is
|
|
58
|
+
* possible by construction.
|
|
59
|
+
*/
|
|
60
|
+
export declare function resolveVizVendorPath(file: string): string | null;
|
|
61
|
+
/**
|
|
62
|
+
* Express handler for GET /viz/vendor/:file (#139).
|
|
63
|
+
*
|
|
64
|
+
* - Not on the allowlist (unknown name, traversal attempts, anything) → 404.
|
|
65
|
+
* - Allowlisted but missing on disk → 503 (broken install — fail explicitly,
|
|
66
|
+
* same contract as vizHandler).
|
|
67
|
+
* - Long immutable cache: the files only ever change with a package version.
|
|
68
|
+
*/
|
|
69
|
+
export declare function vizVendorHandler(): express.RequestHandler;
|
package/dist/viz.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* /viz support (#124) — knowledge-graph visualization page.
|
|
4
|
+
*
|
|
5
|
+
* Two concerns live here so they can be unit-tested without booting the full
|
|
6
|
+
* MCP daemon (mcp-server.ts pulls in the embedder + MCP SDK):
|
|
7
|
+
*
|
|
8
|
+
* 1. createAuthMiddleware — the bearer-token auth middleware used by the whole
|
|
9
|
+
* REST surface. Extracted verbatim from mcp-server.ts, plus ONE change for
|
|
10
|
+
* /viz: the page SHELL is exempt like /health (it carries no data or
|
|
11
|
+
* secrets — it ships verbatim in the public npm tarball). Browsers cannot
|
|
12
|
+
* attach an Authorization header on plain navigation; the page collects
|
|
13
|
+
* the token client-side and uses it on its /graph data fetch, which stays
|
|
14
|
+
* bearer-only like every other data route.
|
|
15
|
+
*
|
|
16
|
+
* 2. readVizHtml — loads the self-contained visualization page from
|
|
17
|
+
* assets/viz.html at request time. The asset sits next to src/ and dist/
|
|
18
|
+
* (siblings), so `../assets/viz.html` resolves from both the compiled
|
|
19
|
+
* output (dist/viz.js) and the TypeScript source (tests/tsx).
|
|
20
|
+
*
|
|
21
|
+
* 3. vendorHandler — serves the pinned renderer bundles from assets/vendor/
|
|
22
|
+
* (#139: three.js / 3d-force-graph / force-graph, see
|
|
23
|
+
* THIRD_PARTY_NOTICES.md). STRICT allowlist of exact filenames — the
|
|
24
|
+
* request path is never joined into the filesystem path; the served path
|
|
25
|
+
* comes from a fixed lookup table, so traversal is impossible by
|
|
26
|
+
* construction. Public like the /viz shell (static public code, no data).
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.VIZ_VENDOR_FILES = void 0;
|
|
30
|
+
exports.createAuthMiddleware = createAuthMiddleware;
|
|
31
|
+
exports.resolveVizHtmlPath = resolveVizHtmlPath;
|
|
32
|
+
exports.readVizHtml = readVizHtml;
|
|
33
|
+
exports.vizHandler = vizHandler;
|
|
34
|
+
exports.resolveVizVendorPath = resolveVizVendorPath;
|
|
35
|
+
exports.vizVendorHandler = vizVendorHandler;
|
|
36
|
+
const node_fs_1 = require("node:fs");
|
|
37
|
+
const node_path_1 = require("node:path");
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Vendored renderer assets (#139)
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
/**
|
|
42
|
+
* Exact filenames servable from assets/vendor/ — nothing else. Pinned bundles
|
|
43
|
+
* documented in THIRD_PARTY_NOTICES.md. Keep this list in lockstep with the
|
|
44
|
+
* <script src="/viz/vendor/…"> references in assets/viz.html.
|
|
45
|
+
*/
|
|
46
|
+
exports.VIZ_VENDOR_FILES = new Set([
|
|
47
|
+
"three.module.min.js",
|
|
48
|
+
"three.core.min.js",
|
|
49
|
+
"3d-force-graph.min.js",
|
|
50
|
+
"force-graph.min.js",
|
|
51
|
+
]);
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Auth middleware
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
/**
|
|
56
|
+
* Bearer token auth — ALWAYS installed, fail-closed. /health, the /viz page
|
|
57
|
+
* shell, and localhost bypass (OPTIONS is short-circuited by the CORS
|
|
58
|
+
* middleware before this runs). With no token configured, remote requests are
|
|
59
|
+
* REJECTED (not open): the default bind is 0.0.0.0, so "no token = no auth"
|
|
60
|
+
* would expose the whole memory store to the network.
|
|
61
|
+
*/
|
|
62
|
+
function createAuthMiddleware(authToken) {
|
|
63
|
+
return (req, res, next) => {
|
|
64
|
+
if (req.path === "/health")
|
|
65
|
+
return next();
|
|
66
|
+
// The /viz page SHELL is public like /health — it contains no data and no
|
|
67
|
+
// secrets (it ships verbatim in the npm tarball). All memory content comes
|
|
68
|
+
// from /graph, which stays bearer-only; the page collects the token
|
|
69
|
+
// client-side (URL ?token= handoff or in-page prompt) and sends it as a
|
|
70
|
+
// normal Authorization header on its data fetches.
|
|
71
|
+
if (req.method === "GET" && req.path === "/viz")
|
|
72
|
+
return next();
|
|
73
|
+
// The pinned renderer bundles the /viz page loads (#139) are public for
|
|
74
|
+
// the same reason as the shell: static third-party code shipped verbatim
|
|
75
|
+
// in the npm tarball, zero data. Kept tight: GET only, and ONLY names on
|
|
76
|
+
// the allowlist. The name is percent-DECODED before the lookup so this
|
|
77
|
+
// check and vizVendorHandler (which sees Express's decoded req.params)
|
|
78
|
+
// agree on one canonical form — traversal sequences decode to strings
|
|
79
|
+
// containing "/" or "..", which are never on the allowlist.
|
|
80
|
+
if (req.method === "GET" && req.path.startsWith("/viz/vendor/")) {
|
|
81
|
+
let file = "";
|
|
82
|
+
try {
|
|
83
|
+
file = decodeURIComponent(req.path.slice("/viz/vendor/".length));
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// malformed percent-encoding — not a vendor file, fall through to auth
|
|
87
|
+
}
|
|
88
|
+
if (exports.VIZ_VENDOR_FILES.has(file))
|
|
89
|
+
return next();
|
|
90
|
+
}
|
|
91
|
+
const ip = req.ip ?? req.socket.remoteAddress ?? "";
|
|
92
|
+
if (ip === "127.0.0.1" || ip === "::1" || ip === "::ffff:127.0.0.1")
|
|
93
|
+
return next();
|
|
94
|
+
if (authToken && req.headers.authorization === `Bearer ${authToken}`)
|
|
95
|
+
return next();
|
|
96
|
+
res.status(401).json({
|
|
97
|
+
error: authToken
|
|
98
|
+
? "Unauthorized"
|
|
99
|
+
: "No auth token configured on this server — run `npx @gamaze/hicortex init` on the server, then connect with its token.",
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Asset loading
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
/**
|
|
107
|
+
* Resolve the on-disk path of the viz page. Throws (fail explicitly) when the
|
|
108
|
+
* asset is missing — a broken install should surface, not degrade silently.
|
|
109
|
+
*/
|
|
110
|
+
function resolveVizHtmlPath() {
|
|
111
|
+
// dist/viz.js → ../assets/viz.html
|
|
112
|
+
// src/viz.ts → ../assets/viz.html (tests / tsx — same sibling layout)
|
|
113
|
+
const candidates = [(0, node_path_1.join)(__dirname, "..", "assets", "viz.html")];
|
|
114
|
+
for (const candidate of candidates) {
|
|
115
|
+
if ((0, node_fs_1.existsSync)(candidate))
|
|
116
|
+
return candidate;
|
|
117
|
+
}
|
|
118
|
+
throw new Error(`viz.html asset not found — looked in: ${candidates.join(", ")}. ` +
|
|
119
|
+
`The package install is incomplete (assets/ missing).`);
|
|
120
|
+
}
|
|
121
|
+
/** Read the viz page. Read at request time so a reinstall is picked up live. */
|
|
122
|
+
function readVizHtml() {
|
|
123
|
+
return (0, node_fs_1.readFileSync)(resolveVizHtmlPath(), "utf-8");
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Express handler for GET /viz. 503 with the endpoint's usual {error} shape
|
|
127
|
+
* when the asset cannot be read.
|
|
128
|
+
*/
|
|
129
|
+
function vizHandler() {
|
|
130
|
+
return (_req, res) => {
|
|
131
|
+
try {
|
|
132
|
+
res.type("html").send(readVizHtml());
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
res.status(503).json({ error: err instanceof Error ? err.message : String(err) });
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Resolve the on-disk path of an allowlisted vendor bundle, or null when the
|
|
141
|
+
* requested name is not on the allowlist. The filesystem path is built ONLY
|
|
142
|
+
* from the allowlist literal (never from request input), so no traversal is
|
|
143
|
+
* possible by construction.
|
|
144
|
+
*/
|
|
145
|
+
function resolveVizVendorPath(file) {
|
|
146
|
+
if (!exports.VIZ_VENDOR_FILES.has(file))
|
|
147
|
+
return null;
|
|
148
|
+
// dist/viz.js → ../assets/vendor/<file>; src/viz.ts → same sibling layout.
|
|
149
|
+
return (0, node_path_1.join)(__dirname, "..", "assets", "vendor", file);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Express handler for GET /viz/vendor/:file (#139).
|
|
153
|
+
*
|
|
154
|
+
* - Not on the allowlist (unknown name, traversal attempts, anything) → 404.
|
|
155
|
+
* - Allowlisted but missing on disk → 503 (broken install — fail explicitly,
|
|
156
|
+
* same contract as vizHandler).
|
|
157
|
+
* - Long immutable cache: the files only ever change with a package version.
|
|
158
|
+
*/
|
|
159
|
+
function vizVendorHandler() {
|
|
160
|
+
return (req, res) => {
|
|
161
|
+
const file = typeof req.params.file === "string" ? req.params.file : "";
|
|
162
|
+
const path = resolveVizVendorPath(file);
|
|
163
|
+
if (!path) {
|
|
164
|
+
res.status(404).json({ error: "Not found" });
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
const body = (0, node_fs_1.readFileSync)(path);
|
|
169
|
+
res.setHeader("Content-Type", "application/javascript; charset=utf-8");
|
|
170
|
+
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
|
|
171
|
+
res.send(body);
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
res.status(503).json({
|
|
175
|
+
error: `Vendor asset ${file} is missing — the package install is incomplete ` +
|
|
176
|
+
`(assets/vendor/ missing): ${err instanceof Error ? err.message : String(err)}`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_readme": [
|
|
3
|
+
"Hicortex memory domains — example config.",
|
|
4
|
+
"Copy the `domains` key (and optionally `weakPrimaryFloor`) into ~/.hicortex/config.json on the SERVER machine.",
|
|
5
|
+
"Domains are your top-level memory spheres. Each memory gets multiple weighted tags plus a derived primary.",
|
|
6
|
+
"They can be life areas OR project/topic areas — edit to match how YOU think.",
|
|
7
|
+
"The `domains` list below is the generic default that `hicortex init` scaffolds automatically.",
|
|
8
|
+
"There is NO fallback category: memories that fit nothing are handled automatically (weak-primary floor + decay).",
|
|
9
|
+
"Backfill an existing corpus with: hicortex classify-domains"
|
|
10
|
+
],
|
|
11
|
+
"domains": [
|
|
12
|
+
{ "name": "Work", "description": "Your job and professional life — employer, clients, workstreams" },
|
|
13
|
+
{ "name": "Personal", "description": "Private life — home, hobbies, everyday matters" },
|
|
14
|
+
{ "name": "People", "description": "Relationships — family, friends, social life, network" },
|
|
15
|
+
{ "name": "Health", "description": "Fitness, wellbeing, medical" },
|
|
16
|
+
{ "name": "Finance", "description": "Money — budgeting, spending, investing" }
|
|
17
|
+
],
|
|
18
|
+
"_powerUserExample": {
|
|
19
|
+
"_readme": [
|
|
20
|
+
"A narrower life-sphere set for users who want tighter buckets.",
|
|
21
|
+
"`compartment: true` makes a domain the PRIMARY whenever it is tagged — a deliberate work/life firewall.",
|
|
22
|
+
"`weakPrimaryFloor` (default 0.45) is the minimum embedding similarity for a no-fit memory to earn a weak primary; tune it from your corpus."
|
|
23
|
+
],
|
|
24
|
+
"domains": [
|
|
25
|
+
{ "name": "Work", "description": "Employer, day job, client projects, workstreams", "compartment": true },
|
|
26
|
+
{ "name": "Personal", "description": "Private life — home, hobbies, everyday matters" },
|
|
27
|
+
{ "name": "People", "description": "Relationships — family, friends, social life, network" },
|
|
28
|
+
{ "name": "Health", "description": "Fitness, wellbeing, medical" },
|
|
29
|
+
{ "name": "Finance", "description": "Money — budgeting, spending, investing" },
|
|
30
|
+
{ "name": "Boating", "description": "Boats — maintenance, gear, trips, harbour life" },
|
|
31
|
+
{ "name": "Property", "description": "House and land — renovation, upkeep, garden" },
|
|
32
|
+
{ "name": "Vehicles", "description": "Cars and other vehicles — service, repairs, purchases" }
|
|
33
|
+
],
|
|
34
|
+
"weakPrimaryFloor": 0.5
|
|
35
|
+
}
|
|
36
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gamaze/hicortex",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Self-learning memory for AI agents
|
|
3
|
+
"version": "0.11.1",
|
|
4
|
+
"description": "Self-learning memory for AI agents — experience captured automatically, distilled into lessons overnight, shared across your whole fleet. Works with Hermes, OpenClaw, Claude Code, and Pi.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"hicortex": "dist/cli.js"
|
|
@@ -25,10 +25,13 @@
|
|
|
25
25
|
"types": "dist/index.d.ts",
|
|
26
26
|
"files": [
|
|
27
27
|
"dist/",
|
|
28
|
+
"assets/",
|
|
28
29
|
"skills/",
|
|
29
30
|
"hermes-plugin/",
|
|
30
31
|
"openclaw.plugin.json",
|
|
31
|
-
"
|
|
32
|
+
"domains.example.json",
|
|
33
|
+
"README.md",
|
|
34
|
+
"THIRD_PARTY_NOTICES.md"
|
|
32
35
|
],
|
|
33
36
|
"scripts": {
|
|
34
37
|
"build": "rm -rf dist && tsc",
|