@gamaze/hicortex 0.7.1 → 0.10.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 +72 -39
- package/dist/claude-md.d.ts +9 -21
- package/dist/claude-md.js +9 -241
- package/dist/cli.d.ts +3 -2
- package/dist/cli.js +29 -11
- package/dist/consolidate.js +0 -7
- package/dist/db.js +24 -0
- package/dist/embedder.d.ts +11 -0
- package/dist/embedder.js +27 -0
- package/dist/extensions.d.ts +41 -88
- package/dist/extensions.js +36 -61
- package/dist/features.d.ts +21 -25
- package/dist/features.js +47 -83
- package/dist/hermes-transcript-reader.d.ts +27 -0
- package/dist/hermes-transcript-reader.js +134 -0
- package/dist/index.d.ts +16 -4
- package/dist/index.js +252 -344
- package/dist/init.d.ts +41 -1
- package/dist/init.js +545 -190
- package/dist/lesson-selection.d.ts +62 -0
- package/dist/lesson-selection.js +159 -0
- package/dist/lessons-context.d.ts +17 -0
- package/dist/lessons-context.js +96 -0
- package/dist/llm.d.ts +42 -29
- package/dist/llm.js +89 -270
- package/dist/mcp-server.d.ts +0 -1
- package/dist/mcp-server.js +404 -86
- package/dist/nightly.d.ts +9 -6
- package/dist/nightly.js +197 -357
- package/dist/oc-transcript-reader.d.ts +20 -0
- package/dist/oc-transcript-reader.js +61 -0
- package/dist/pi-transcript-reader.d.ts +1 -0
- package/dist/status.js +22 -2
- package/dist/storage.d.ts +7 -1
- package/dist/storage.js +28 -7
- package/dist/transcript-reader.d.ts +19 -0
- package/dist/transcript-reader.js +17 -3
- package/dist/types.d.ts +10 -0
- package/dist/uninstall.js +31 -1
- package/hermes-plugin/hicortex/README.md +77 -0
- package/hermes-plugin/hicortex/__init__.py +17 -0
- package/hermes-plugin/hicortex/client.py +162 -0
- package/hermes-plugin/hicortex/config.py +105 -0
- package/hermes-plugin/hicortex/plugin.yaml +12 -0
- package/hermes-plugin/hicortex/provider.py +432 -0
- package/openclaw.plugin.json +17 -44
- package/package.json +7 -5
- package/dist/pro-loader.d.ts +0 -33
- package/dist/pro-loader.js +0 -187
package/dist/embedder.d.ts
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
* installed. The model is lazy-loaded on first call.
|
|
7
7
|
*/
|
|
8
8
|
export declare const EMBEDDING_DIMENSIONS = 384;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve the directory where @huggingface/transformers caches model weights.
|
|
11
|
+
*
|
|
12
|
+
* Exported as a pure function so it can be unit-tested without mocking the
|
|
13
|
+
* dynamic import. The default (`~/.hicortex/models`) is stable across package
|
|
14
|
+
* upgrades and writable by the installing user even under global npm installs
|
|
15
|
+
* (where the package dir is root-owned).
|
|
16
|
+
*
|
|
17
|
+
* @param home Override for the user home directory (used in tests).
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveModelCacheDir(home?: string): string;
|
|
9
20
|
/**
|
|
10
21
|
* Embed a single text string. Returns a Float32Array of 384 dimensions.
|
|
11
22
|
*/
|
package/dist/embedder.js
CHANGED
|
@@ -8,14 +8,31 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.EMBEDDING_DIMENSIONS = void 0;
|
|
11
|
+
exports.resolveModelCacheDir = resolveModelCacheDir;
|
|
11
12
|
exports.embed = embed;
|
|
12
13
|
exports.embedBatch = embedBatch;
|
|
13
14
|
exports.dimensions = dimensions;
|
|
15
|
+
const node_fs_1 = require("node:fs");
|
|
16
|
+
const node_path_1 = require("node:path");
|
|
17
|
+
const node_os_1 = require("node:os");
|
|
14
18
|
exports.EMBEDDING_DIMENSIONS = 384;
|
|
15
19
|
const MODEL_NAME = "Xenova/bge-small-en-v1.5";
|
|
16
20
|
// Pipeline is lazy-loaded on first use
|
|
17
21
|
let pipeline = null;
|
|
18
22
|
let initPromise = null;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the directory where @huggingface/transformers caches model weights.
|
|
25
|
+
*
|
|
26
|
+
* Exported as a pure function so it can be unit-tested without mocking the
|
|
27
|
+
* dynamic import. The default (`~/.hicortex/models`) is stable across package
|
|
28
|
+
* upgrades and writable by the installing user even under global npm installs
|
|
29
|
+
* (where the package dir is root-owned).
|
|
30
|
+
*
|
|
31
|
+
* @param home Override for the user home directory (used in tests).
|
|
32
|
+
*/
|
|
33
|
+
function resolveModelCacheDir(home) {
|
|
34
|
+
return (0, node_path_1.join)(home ?? (0, node_os_1.homedir)(), ".hicortex", "models");
|
|
35
|
+
}
|
|
19
36
|
/**
|
|
20
37
|
* Initialize the embedding pipeline (called lazily on first embed call).
|
|
21
38
|
* Throws with a clear error if @huggingface/transformers is not available.
|
|
@@ -32,6 +49,16 @@ async function ensureInit() {
|
|
|
32
49
|
// Dynamic import — package may not be installed (it's optional)
|
|
33
50
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
34
51
|
const transformers = await Function('return import("@huggingface/transformers")')();
|
|
52
|
+
// Point the model cache at a stable user-writable directory so the
|
|
53
|
+
// ~130 MB weights survive package upgrades and work under global installs
|
|
54
|
+
// (the package dir is root-owned; defaulting to it causes EACCES).
|
|
55
|
+
const cacheDir = resolveModelCacheDir();
|
|
56
|
+
(0, node_fs_1.mkdirSync)(cacheDir, { recursive: true });
|
|
57
|
+
const env = transformers.env ?? transformers.default?.env;
|
|
58
|
+
if (env) {
|
|
59
|
+
env.cacheDir = cacheDir;
|
|
60
|
+
}
|
|
61
|
+
console.log(`[hicortex] Model cache: ${cacheDir}`);
|
|
35
62
|
const pipelineFn = transformers.pipeline ?? transformers.default?.pipeline;
|
|
36
63
|
if (!pipelineFn) {
|
|
37
64
|
throw new Error("Could not find pipeline function in @huggingface/transformers");
|
package/dist/extensions.d.ts
CHANGED
|
@@ -1,39 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Extension interfaces
|
|
2
|
+
* Extension interfaces + default implementations.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Originally the seam for the OSS/Pro split (Pro retired in #122 — the
|
|
5
|
+
* product is fully featured for everyone). The interfaces and the
|
|
6
|
+
* setExtensions() override hook remain so alternative implementations can
|
|
7
|
+
* still be swapped in (tests, future experiments).
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* LessonSelector — lesson selection sites:
|
|
10
|
+
* lessons-context.ts:fetchLessonsContext (CC SessionStart hook),
|
|
11
|
+
* index.ts:before_agent_start (OC in-process plugin).
|
|
12
|
+
* The default is the domain-aware scoring selector (lesson-selection.ts):
|
|
13
|
+
* ranks lessons by project match + domain affinity + recency +
|
|
14
|
+
* base_strength + access affinity, with prefix-based dedup. Restored
|
|
15
|
+
* into core in #123 after being deleted with the Pro loader in #122.
|
|
10
16
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* selector ranks lessons against project context, recency, and
|
|
16
|
-
* effectiveness scores instead of dumb-truncating.
|
|
17
|
-
*
|
|
18
|
-
* PromptStrategy — the current prompts.ts exports three pure functions
|
|
19
|
-
* (distillation, reflection, importanceScoring). The Pro variant has
|
|
20
|
-
* prescriptive prompts (`when X do Y` format) and re-trained reflection
|
|
21
|
-
* that produces a richer schema. The strategy bundles the prompt WITH
|
|
22
|
-
* its parser so a Pro prompt with a different output schema cannot
|
|
23
|
-
* silently fail when the OSS consumer parses it with the wrong shape.
|
|
17
|
+
* PromptStrategy — prompts.ts exports three pure functions
|
|
18
|
+
* (distillation, reflection, importanceScoring). The strategy bundles
|
|
19
|
+
* the prompt WITH its parser so a prompt with a different output schema
|
|
20
|
+
* cannot silently fail when the consumer parses it with the wrong shape.
|
|
24
21
|
*
|
|
25
22
|
* NOT in this file (deliberately deferred):
|
|
26
23
|
* - ContextAssembler — over-abstracted; the real seam is buildProjectContext
|
|
27
24
|
* in claude-md.ts, not the whole assembler. Will add when needed.
|
|
28
|
-
* - LessonValidator — speculative; no validation exists today.
|
|
29
|
-
* when the first Pro use case demands it.
|
|
25
|
+
* - LessonValidator — speculative; no validation exists today.
|
|
30
26
|
*/
|
|
31
27
|
import type { ModuleIndex } from "./types.js";
|
|
32
28
|
/**
|
|
33
29
|
* Minimum fields a lesson must have for the selector to work.
|
|
34
30
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
31
|
+
* Only `content` is required. The default (domain-aware) selector uses the
|
|
32
|
+
* optional fields when present — project for in-project/domain weighting,
|
|
33
|
+
* created_at for recency, base_strength for importance, access_count for
|
|
34
|
+
* proven-usefulness — and falls back to neutral scores when absent.
|
|
37
35
|
*
|
|
38
36
|
* Memory satisfies this interface (it's a structural subset), and the
|
|
39
37
|
* client-mode HTTP shape `{content, created_at, base_strength, access_count}`
|
|
@@ -52,20 +50,21 @@ export interface SelectableLesson {
|
|
|
52
50
|
export interface LessonSelectorContext {
|
|
53
51
|
/** Maximum number of lessons to return. Caller decides this from features.lessonsLimit(). */
|
|
54
52
|
maxLessons: number;
|
|
55
|
-
/** Current project, if known.
|
|
53
|
+
/** Current project, if known. The default selector weights in-project lessons higher. */
|
|
56
54
|
project?: string | null;
|
|
57
|
-
/** Optional: agent id, for cross-agent learning context
|
|
55
|
+
/** Optional: agent id, for cross-agent learning context. */
|
|
58
56
|
agentId?: string;
|
|
59
|
-
/** Optional: current task description, for relevance scoring
|
|
57
|
+
/** Optional: current task description, for relevance scoring. */
|
|
60
58
|
currentTask?: string;
|
|
61
|
-
/** MODULE_INDEX for domain-aware lesson selection (
|
|
59
|
+
/** MODULE_INDEX for domain-aware lesson selection (same-domain projects score 0.5). */
|
|
62
60
|
moduleIndex?: ModuleIndex;
|
|
63
61
|
}
|
|
64
62
|
export interface LessonSelector {
|
|
65
63
|
/**
|
|
66
64
|
* Pick `ctx.maxLessons` lessons from the candidate pool.
|
|
67
|
-
* Default impl:
|
|
68
|
-
*
|
|
65
|
+
* Default impl: domain-aware scoring (lesson-selection.ts) — ranks by
|
|
66
|
+
* project match, domain affinity, recency, base_strength, and access
|
|
67
|
+
* affinity, with prefix-based dedup.
|
|
69
68
|
*
|
|
70
69
|
* Generic so the output type matches the input type — Memory[] in returns
|
|
71
70
|
* Memory[] out, partial-shape in returns partial-shape out.
|
|
@@ -73,8 +72,13 @@ export interface LessonSelector {
|
|
|
73
72
|
select<T extends SelectableLesson>(lessons: T[], ctx: LessonSelectorContext): T[] | Promise<T[]>;
|
|
74
73
|
}
|
|
75
74
|
/**
|
|
76
|
-
* Default LessonSelector —
|
|
77
|
-
*
|
|
75
|
+
* Default LessonSelector — the domain-aware scoring selector.
|
|
76
|
+
*
|
|
77
|
+
* Ranks lessons by project match (1.0 exact / 0.5 same-domain via moduleIndex
|
|
78
|
+
* / 0.3 global), recency (30-day half-life), base_strength, and access
|
|
79
|
+
* affinity; dedups near-identical lessons by normalized prefix. When lessons
|
|
80
|
+
* carry no metadata, all scores tie and stable sort preserves input order
|
|
81
|
+
* (equivalent to the old slice(0, N) behaviour).
|
|
78
82
|
*/
|
|
79
83
|
export declare const defaultLessonSelector: LessonSelector;
|
|
80
84
|
/** Output schema produced by the reflection prompt and consumed by consolidate.ts. */
|
|
@@ -108,69 +112,18 @@ export interface PromptStrategy {
|
|
|
108
112
|
}
|
|
109
113
|
export declare const defaultPromptStrategy: PromptStrategy;
|
|
110
114
|
/**
|
|
111
|
-
* Holder for the active extension implementations.
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* Wiring will happen via setExtensions() called from src/pro/ after license
|
|
116
|
-
* validation (not yet implemented in OSS). Until Pro code exists and is loaded,
|
|
117
|
-
* every call site uses the defaults — zero behavioural change for OSS users.
|
|
115
|
+
* Holder for the active extension implementations. Every install uses the
|
|
116
|
+
* defaults; setExtensions() remains as an override hook for tests and future
|
|
117
|
+
* alternative implementations.
|
|
118
118
|
*/
|
|
119
119
|
declare let activeExtensions: {
|
|
120
120
|
selector: LessonSelector;
|
|
121
121
|
prompts: PromptStrategy;
|
|
122
122
|
};
|
|
123
|
-
/** Replace the active extensions (
|
|
123
|
+
/** Replace the active extensions (override hook — tests, experiments). */
|
|
124
124
|
export declare function setExtensions(ext: Partial<typeof activeExtensions>): void;
|
|
125
|
-
/** Get the active LessonSelector
|
|
125
|
+
/** Get the active LessonSelector. */
|
|
126
126
|
export declare function getLessonSelector(): LessonSelector;
|
|
127
|
-
/** Get the active PromptStrategy
|
|
127
|
+
/** Get the active PromptStrategy. */
|
|
128
128
|
export declare function getPromptStrategy(): PromptStrategy;
|
|
129
|
-
/**
|
|
130
|
-
* The object passed to a Pro package's `activate()` function at boot.
|
|
131
|
-
* Pro packages receive this to register their extensions and access OSS
|
|
132
|
-
* runtime APIs they need.
|
|
133
|
-
*
|
|
134
|
-
* Design rationale: Pro code never STATICALLY imports from the OSS client.
|
|
135
|
-
* All runtime access is through this context object. This has two benefits:
|
|
136
|
-
* 1. Pro bundles are self-contained — they don't have `require("../...")`
|
|
137
|
-
* calls that would break when the tarball is installed to
|
|
138
|
-
* ~/.hicortex/pro/ at runtime.
|
|
139
|
-
* 2. Pro code can only access what the OSS client exposes here, so the
|
|
140
|
-
* blast radius of a malicious/buggy Pro release is contained.
|
|
141
|
-
*
|
|
142
|
-
* Type-only imports of `LessonSelector`, `PromptStrategy` etc. in Pro code
|
|
143
|
-
* are fine — they're erased at compile time and produce no runtime imports.
|
|
144
|
-
*/
|
|
145
|
-
export interface ProActivationContext {
|
|
146
|
-
/** Register a lesson selector implementation. */
|
|
147
|
-
setSelector(selector: LessonSelector): void;
|
|
148
|
-
/** Register a prompt strategy implementation. */
|
|
149
|
-
setPrompts(prompts: PromptStrategy): void;
|
|
150
|
-
/** The version of the OSS host (from package.json). Pro can use this
|
|
151
|
-
* to gate features against host compatibility. */
|
|
152
|
-
hostVersion: string;
|
|
153
|
-
/** Log through the OSS logging surface so Pro logs get the [hicortex]
|
|
154
|
-
* prefix and unified formatting. */
|
|
155
|
-
log(message: string): void;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* The shape Pro packages must export as their default export.
|
|
159
|
-
* See `packages/hicortex/src/pro/index.ts` for the reference impl.
|
|
160
|
-
*/
|
|
161
|
-
export interface ProPackage {
|
|
162
|
-
/** Called once at OSS boot if a Pro license is valid and the Pro
|
|
163
|
-
* tarball has been downloaded + extracted. Should register extensions
|
|
164
|
-
* via the context and return. Errors abort Pro activation but do not
|
|
165
|
-
* abort the OSS host. */
|
|
166
|
-
activate(ctx: ProActivationContext): void | Promise<void>;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Build an activation context for a Pro package. Called from the Pro
|
|
170
|
-
* loader in features.ts / pro-loader.ts.
|
|
171
|
-
*
|
|
172
|
-
* Keep this function small — it's the ONLY surface a Pro package gets.
|
|
173
|
-
* Expanding it expands the attack surface, so add fields deliberately.
|
|
174
|
-
*/
|
|
175
|
-
export declare function createProActivationContext(hostVersion: string): ProActivationContext;
|
|
176
129
|
export {};
|
package/dist/extensions.js
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Extension interfaces
|
|
3
|
+
* Extension interfaces + default implementations.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Originally the seam for the OSS/Pro split (Pro retired in #122 — the
|
|
6
|
+
* product is fully featured for everyone). The interfaces and the
|
|
7
|
+
* setExtensions() override hook remain so alternative implementations can
|
|
8
|
+
* still be swapped in (tests, future experiments).
|
|
9
9
|
*
|
|
10
|
-
*
|
|
10
|
+
* LessonSelector — lesson selection sites:
|
|
11
|
+
* lessons-context.ts:fetchLessonsContext (CC SessionStart hook),
|
|
12
|
+
* index.ts:before_agent_start (OC in-process plugin).
|
|
13
|
+
* The default is the domain-aware scoring selector (lesson-selection.ts):
|
|
14
|
+
* ranks lessons by project match + domain affinity + recency +
|
|
15
|
+
* base_strength + access affinity, with prefix-based dedup. Restored
|
|
16
|
+
* into core in #123 after being deleted with the Pro loader in #122.
|
|
11
17
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* selector ranks lessons against project context, recency, and
|
|
17
|
-
* effectiveness scores instead of dumb-truncating.
|
|
18
|
-
*
|
|
19
|
-
* PromptStrategy — the current prompts.ts exports three pure functions
|
|
20
|
-
* (distillation, reflection, importanceScoring). The Pro variant has
|
|
21
|
-
* prescriptive prompts (`when X do Y` format) and re-trained reflection
|
|
22
|
-
* that produces a richer schema. The strategy bundles the prompt WITH
|
|
23
|
-
* its parser so a Pro prompt with a different output schema cannot
|
|
24
|
-
* silently fail when the OSS consumer parses it with the wrong shape.
|
|
18
|
+
* PromptStrategy — prompts.ts exports three pure functions
|
|
19
|
+
* (distillation, reflection, importanceScoring). The strategy bundles
|
|
20
|
+
* the prompt WITH its parser so a prompt with a different output schema
|
|
21
|
+
* cannot silently fail when the consumer parses it with the wrong shape.
|
|
25
22
|
*
|
|
26
23
|
* NOT in this file (deliberately deferred):
|
|
27
24
|
* - ContextAssembler — over-abstracted; the real seam is buildProjectContext
|
|
28
25
|
* in claude-md.ts, not the whole assembler. Will add when needed.
|
|
29
|
-
* - LessonValidator — speculative; no validation exists today.
|
|
30
|
-
* when the first Pro use case demands it.
|
|
26
|
+
* - LessonValidator — speculative; no validation exists today.
|
|
31
27
|
*/
|
|
32
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
29
|
exports.defaultPromptStrategy = exports.defaultLessonSelector = void 0;
|
|
34
30
|
exports.setExtensions = setExtensions;
|
|
35
31
|
exports.getLessonSelector = getLessonSelector;
|
|
36
32
|
exports.getPromptStrategy = getPromptStrategy;
|
|
37
|
-
|
|
33
|
+
// The domain-aware scoring selector is THE default for every install.
|
|
34
|
+
// (lesson-selection.ts only imports types from this file, so there is no
|
|
35
|
+
// runtime import cycle — `import type` is erased at compile time.)
|
|
36
|
+
const lesson_selection_js_1 = require("./lesson-selection.js");
|
|
38
37
|
/**
|
|
39
|
-
* Default LessonSelector —
|
|
40
|
-
*
|
|
38
|
+
* Default LessonSelector — the domain-aware scoring selector.
|
|
39
|
+
*
|
|
40
|
+
* Ranks lessons by project match (1.0 exact / 0.5 same-domain via moduleIndex
|
|
41
|
+
* / 0.3 global), recency (30-day half-life), base_strength, and access
|
|
42
|
+
* affinity; dedups near-identical lessons by normalized prefix. When lessons
|
|
43
|
+
* carry no metadata, all scores tie and stable sort preserves input order
|
|
44
|
+
* (equivalent to the old slice(0, N) behaviour).
|
|
41
45
|
*/
|
|
42
|
-
exports.defaultLessonSelector =
|
|
43
|
-
select(lessons, ctx) {
|
|
44
|
-
return lessons.slice(0, ctx.maxLessons);
|
|
45
|
-
},
|
|
46
|
-
};
|
|
46
|
+
exports.defaultLessonSelector = lesson_selection_js_1.domainAwareLessonSelector;
|
|
47
47
|
// ---------------------------------------------------------------------------
|
|
48
48
|
// Default PromptStrategy — wraps the current prompts.ts and the lenient JSON
|
|
49
49
|
// parser from consolidate.ts. Preserves current OSS behaviour exactly.
|
|
@@ -126,51 +126,26 @@ exports.defaultPromptStrategy = {
|
|
|
126
126
|
},
|
|
127
127
|
};
|
|
128
128
|
// ---------------------------------------------------------------------------
|
|
129
|
-
// Loader — used by call sites to get
|
|
129
|
+
// Loader — used by call sites to get the active implementations
|
|
130
130
|
// ---------------------------------------------------------------------------
|
|
131
131
|
/**
|
|
132
|
-
* Holder for the active extension implementations.
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* Wiring will happen via setExtensions() called from src/pro/ after license
|
|
137
|
-
* validation (not yet implemented in OSS). Until Pro code exists and is loaded,
|
|
138
|
-
* every call site uses the defaults — zero behavioural change for OSS users.
|
|
132
|
+
* Holder for the active extension implementations. Every install uses the
|
|
133
|
+
* defaults; setExtensions() remains as an override hook for tests and future
|
|
134
|
+
* alternative implementations.
|
|
139
135
|
*/
|
|
140
136
|
let activeExtensions = {
|
|
141
137
|
selector: exports.defaultLessonSelector,
|
|
142
138
|
prompts: exports.defaultPromptStrategy,
|
|
143
139
|
};
|
|
144
|
-
/** Replace the active extensions (
|
|
140
|
+
/** Replace the active extensions (override hook — tests, experiments). */
|
|
145
141
|
function setExtensions(ext) {
|
|
146
142
|
activeExtensions = { ...activeExtensions, ...ext };
|
|
147
143
|
}
|
|
148
|
-
/** Get the active LessonSelector
|
|
144
|
+
/** Get the active LessonSelector. */
|
|
149
145
|
function getLessonSelector() {
|
|
150
146
|
return activeExtensions.selector;
|
|
151
147
|
}
|
|
152
|
-
/** Get the active PromptStrategy
|
|
148
|
+
/** Get the active PromptStrategy. */
|
|
153
149
|
function getPromptStrategy() {
|
|
154
150
|
return activeExtensions.prompts;
|
|
155
151
|
}
|
|
156
|
-
/**
|
|
157
|
-
* Build an activation context for a Pro package. Called from the Pro
|
|
158
|
-
* loader in features.ts / pro-loader.ts.
|
|
159
|
-
*
|
|
160
|
-
* Keep this function small — it's the ONLY surface a Pro package gets.
|
|
161
|
-
* Expanding it expands the attack surface, so add fields deliberately.
|
|
162
|
-
*/
|
|
163
|
-
function createProActivationContext(hostVersion) {
|
|
164
|
-
return {
|
|
165
|
-
setSelector(selector) {
|
|
166
|
-
activeExtensions = { ...activeExtensions, selector };
|
|
167
|
-
},
|
|
168
|
-
setPrompts(prompts) {
|
|
169
|
-
activeExtensions = { ...activeExtensions, prompts };
|
|
170
|
-
},
|
|
171
|
-
hostVersion,
|
|
172
|
-
log(message) {
|
|
173
|
-
console.log(`[hicortex][pro] ${message}`);
|
|
174
|
-
},
|
|
175
|
-
};
|
|
176
|
-
}
|
package/dist/features.d.ts
CHANGED
|
@@ -1,37 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Feature gating — all gates removed as of 0.10.0.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* dodge a circular import).
|
|
4
|
+
* Personal and noncommercial use is fully featured under the
|
|
5
|
+
* PolyForm Noncommercial License. Commercial use requires a per-seat
|
|
6
|
+
* license (see COMMERCIAL.md). There is no technical feature gating;
|
|
7
|
+
* the license key's only remaining role is the "licensed to <org>"
|
|
8
|
+
* display in `hicortex status`.
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* The functions below are kept as trivial wrappers so call sites
|
|
11
|
+
* compile without churn. They will be removed entirely in a future
|
|
12
|
+
* cleanup pass once callers have been audited.
|
|
13
13
|
*/
|
|
14
14
|
import type { LicenseInfo } from "./types.js";
|
|
15
15
|
/**
|
|
16
|
-
* Initialize
|
|
17
|
-
*
|
|
18
|
-
* 1. Synchronously load persisted tier from disk (instant, deterministic)
|
|
19
|
-
* 2. If no persisted tier and we have a key, AWAIT first validation
|
|
20
|
-
* 3. If persisted tier exists, kick off background re-validation
|
|
21
|
-
*
|
|
22
|
-
* After this returns, sync getters (isPro, lessonsLimit, etc.) are deterministic
|
|
23
|
-
* and reflect the user's actual tier — no more "free during validation window".
|
|
16
|
+
* Initialize license display. Call ONCE at process boot.
|
|
17
|
+
* No feature gates are applied regardless of the validation result.
|
|
24
18
|
*/
|
|
25
|
-
export declare function initFeatures(licenseKey: string | undefined, stateDir?: string,
|
|
26
|
-
/**
|
|
19
|
+
export declare function initFeatures(licenseKey: string | undefined, stateDir?: string, _hostVersion?: string): Promise<void>;
|
|
20
|
+
/** Returns the validated license info if a key was supplied and validated. */
|
|
21
|
+
export declare function getValidatedLicense(): LicenseInfo | null;
|
|
22
|
+
/** Always false — no memory cap. */
|
|
27
23
|
export declare function isPro(): boolean;
|
|
28
|
-
/**
|
|
24
|
+
/** Always -1 (unlimited). */
|
|
29
25
|
export declare function maxMemoriesAllowed(): number;
|
|
30
|
-
/**
|
|
31
|
-
export declare function memoryCapReached(
|
|
32
|
-
/**
|
|
26
|
+
/** Always false — no cap is ever reached. */
|
|
27
|
+
export declare function memoryCapReached(_currentCount: number): boolean;
|
|
28
|
+
/** Always 20. */
|
|
33
29
|
export declare function lessonsLimit(): number;
|
|
34
|
-
/**
|
|
30
|
+
/** Always true — remote ingest is always allowed. */
|
|
35
31
|
export declare function remoteIngestAllowed(): boolean;
|
|
36
|
-
/** Direct read of the underlying features
|
|
32
|
+
/** Direct read of the underlying features record. */
|
|
37
33
|
export declare function getCurrentFeatures(): LicenseInfo["features"];
|
package/dist/features.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Feature gating — all gates removed as of 0.10.0.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* dodge a circular import).
|
|
5
|
+
* Personal and noncommercial use is fully featured under the
|
|
6
|
+
* PolyForm Noncommercial License. Commercial use requires a per-seat
|
|
7
|
+
* license (see COMMERCIAL.md). There is no technical feature gating;
|
|
8
|
+
* the license key's only remaining role is the "licensed to <org>"
|
|
9
|
+
* display in `hicortex status`.
|
|
11
10
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* The functions below are kept as trivial wrappers so call sites
|
|
12
|
+
* compile without churn. They will be removed entirely in a future
|
|
13
|
+
* cleanup pass once callers have been audited.
|
|
14
14
|
*/
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.initFeatures = initFeatures;
|
|
17
|
+
exports.getValidatedLicense = getValidatedLicense;
|
|
17
18
|
exports.isPro = isPro;
|
|
18
19
|
exports.maxMemoriesAllowed = maxMemoriesAllowed;
|
|
19
20
|
exports.memoryCapReached = memoryCapReached;
|
|
@@ -25,117 +26,80 @@ const node_os_1 = require("node:os");
|
|
|
25
26
|
const license_js_1 = require("./license.js");
|
|
26
27
|
const state_js_1 = require("./state.js");
|
|
27
28
|
const DEFAULT_STATE_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), ".hicortex");
|
|
28
|
-
|
|
29
|
+
// A single canonical "full" feature set — no tiers.
|
|
30
|
+
const FULL_FEATURES = {
|
|
29
31
|
reflection: true,
|
|
30
32
|
vectorSearch: true,
|
|
31
|
-
maxMemories:
|
|
33
|
+
maxMemories: -1,
|
|
32
34
|
crossAgent: true,
|
|
33
35
|
remoteIngest: true,
|
|
34
36
|
};
|
|
35
|
-
let currentFeatures =
|
|
37
|
+
let currentFeatures = FULL_FEATURES;
|
|
36
38
|
let initialized = false;
|
|
39
|
+
// Validated license info for display purposes only (no feature gating).
|
|
40
|
+
let validatedLicenseInfo = null;
|
|
37
41
|
function persistTier(stateDir, info) {
|
|
38
42
|
(0, state_js_1.updateState)((s) => {
|
|
39
43
|
s.tier = {
|
|
40
44
|
tier: info.tier,
|
|
41
45
|
validatedAt: new Date().toISOString(),
|
|
42
|
-
features:
|
|
46
|
+
features: FULL_FEATURES,
|
|
43
47
|
};
|
|
44
48
|
return s;
|
|
45
49
|
}, stateDir);
|
|
46
50
|
}
|
|
47
51
|
/**
|
|
48
|
-
* Initialize
|
|
49
|
-
*
|
|
50
|
-
* 1. Synchronously load persisted tier from disk (instant, deterministic)
|
|
51
|
-
* 2. If no persisted tier and we have a key, AWAIT first validation
|
|
52
|
-
* 3. If persisted tier exists, kick off background re-validation
|
|
53
|
-
*
|
|
54
|
-
* After this returns, sync getters (isPro, lessonsLimit, etc.) are deterministic
|
|
55
|
-
* and reflect the user's actual tier — no more "free during validation window".
|
|
52
|
+
* Initialize license display. Call ONCE at process boot.
|
|
53
|
+
* No feature gates are applied regardless of the validation result.
|
|
56
54
|
*/
|
|
57
|
-
async function initFeatures(licenseKey, stateDir = DEFAULT_STATE_DIR,
|
|
55
|
+
async function initFeatures(licenseKey, stateDir = DEFAULT_STATE_DIR, _hostVersion = "0.0.0") {
|
|
58
56
|
if (initialized)
|
|
59
57
|
return;
|
|
60
58
|
initialized = true;
|
|
61
|
-
|
|
62
|
-
const persisted = (0, state_js_1.loadState)(stateDir).tier;
|
|
63
|
-
if (persisted) {
|
|
64
|
-
currentFeatures = persisted.features;
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
currentFeatures = FREE_FEATURES;
|
|
68
|
-
}
|
|
69
|
-
// Step 2: No key → free tier, done. Pro loader is only run for paid tiers.
|
|
59
|
+
currentFeatures = FULL_FEATURES;
|
|
70
60
|
if (!licenseKey)
|
|
71
61
|
return;
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
persistTier(stateDir, info);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
// Validation failed (network, etc.) — stay on free
|
|
62
|
+
// Validate the key for display purposes only — a failure keeps the server
|
|
63
|
+
// fully functional.
|
|
64
|
+
try {
|
|
65
|
+
const info = await (0, license_js_1.validateLicense)(licenseKey, stateDir);
|
|
66
|
+
validatedLicenseInfo = info;
|
|
67
|
+
if (info.valid) {
|
|
68
|
+
persistTier(stateDir, info);
|
|
84
69
|
}
|
|
85
70
|
}
|
|
86
|
-
|
|
87
|
-
//
|
|
88
|
-
(0, license_js_1.validateLicense)(licenseKey, stateDir)
|
|
89
|
-
.then((info) => {
|
|
90
|
-
currentFeatures = info.features;
|
|
91
|
-
if (info.valid) {
|
|
92
|
-
persistTier(stateDir, info);
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
.catch(() => {
|
|
96
|
-
// Keep persisted features
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
// Step 4: If the current tier is paid, try to load the Pro extension bundle.
|
|
100
|
-
// This is best-effort — if loading fails (network, missing tarball, bad
|
|
101
|
-
// extraction, Pro package throws on activate), OSS defaults remain in effect
|
|
102
|
-
// and the host keeps running. No user-visible crash.
|
|
103
|
-
if (isPro()) {
|
|
104
|
-
try {
|
|
105
|
-
const { loadPro } = await import("./pro-loader.js");
|
|
106
|
-
await loadPro(licenseKey, stateDir, hostVersion);
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
110
|
-
console.warn(`[hicortex][pro] Pro loader failed to import: ${msg}`);
|
|
111
|
-
}
|
|
71
|
+
catch {
|
|
72
|
+
// Non-fatal — continue fully functional without a validated display tier
|
|
112
73
|
}
|
|
113
74
|
}
|
|
75
|
+
/** Returns the validated license info if a key was supplied and validated. */
|
|
76
|
+
function getValidatedLicense() {
|
|
77
|
+
return validatedLicenseInfo;
|
|
78
|
+
}
|
|
114
79
|
// ---------------------------------------------------------------------------
|
|
115
|
-
// Public API —
|
|
80
|
+
// Public API — kept for call-site compatibility; all return "fully unlocked"
|
|
116
81
|
// ---------------------------------------------------------------------------
|
|
117
|
-
/**
|
|
82
|
+
/** Always false — no memory cap. */
|
|
118
83
|
function isPro() {
|
|
119
|
-
return
|
|
84
|
+
return true;
|
|
120
85
|
}
|
|
121
|
-
/**
|
|
86
|
+
/** Always -1 (unlimited). */
|
|
122
87
|
function maxMemoriesAllowed() {
|
|
123
|
-
return
|
|
88
|
+
return -1;
|
|
124
89
|
}
|
|
125
|
-
/**
|
|
126
|
-
function memoryCapReached(
|
|
127
|
-
|
|
128
|
-
return max > 0 && currentCount >= max;
|
|
90
|
+
/** Always false — no cap is ever reached. */
|
|
91
|
+
function memoryCapReached(_currentCount) {
|
|
92
|
+
return false;
|
|
129
93
|
}
|
|
130
|
-
/**
|
|
94
|
+
/** Always 20. */
|
|
131
95
|
function lessonsLimit() {
|
|
132
|
-
return
|
|
96
|
+
return 20;
|
|
133
97
|
}
|
|
134
|
-
/**
|
|
98
|
+
/** Always true — remote ingest is always allowed. */
|
|
135
99
|
function remoteIngestAllowed() {
|
|
136
|
-
return
|
|
100
|
+
return true;
|
|
137
101
|
}
|
|
138
|
-
/** Direct read of the underlying features
|
|
102
|
+
/** Direct read of the underlying features record. */
|
|
139
103
|
function getCurrentFeatures() {
|
|
140
104
|
return currentFeatures;
|
|
141
105
|
}
|