@gamaze/hicortex 0.17.6 → 0.18.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.
Files changed (51) hide show
  1. package/README.md +30 -28
  2. package/assets/dashboard.html +121 -5
  3. package/assets/{context.html → identity.html} +18 -18
  4. package/assets/viz.html +19 -7
  5. package/dist/claude-md.d.ts +2 -1
  6. package/dist/claude-md.js +2 -1
  7. package/dist/cli-args.d.ts +9 -0
  8. package/dist/cli-args.js +16 -0
  9. package/dist/cli.js +29 -20
  10. package/dist/consolidate.d.ts +15 -0
  11. package/dist/consolidate.js +30 -3
  12. package/dist/dashboard.d.ts +58 -1
  13. package/dist/dashboard.js +27 -1
  14. package/dist/extensions.d.ts +1 -1
  15. package/dist/extensions.js +1 -1
  16. package/dist/health.d.ts +68 -0
  17. package/dist/health.js +73 -0
  18. package/dist/identity-cli.d.ts +90 -0
  19. package/dist/{context-cli.js → identity-cli.js} +66 -48
  20. package/dist/{context-store.d.ts → identity-store.d.ts} +94 -31
  21. package/dist/{context-store.js → identity-store.js} +212 -71
  22. package/dist/index.d.ts +12 -5
  23. package/dist/index.js +57 -29
  24. package/dist/init.d.ts +44 -8
  25. package/dist/init.js +142 -37
  26. package/dist/learnings-identity.d.ts +149 -0
  27. package/dist/{lessons-context.js → learnings-identity.js} +96 -52
  28. package/dist/mcp-server.d.ts +2 -0
  29. package/dist/mcp-server.js +217 -68
  30. package/dist/memory-instructions.d.ts +6 -6
  31. package/dist/memory-instructions.js +6 -6
  32. package/dist/nightly.js +65 -6
  33. package/dist/paths.js +1 -1
  34. package/dist/recall-hook-cli.d.ts +1 -1
  35. package/dist/recall-hook-cli.js +3 -3
  36. package/dist/recall-index.js +5 -2
  37. package/dist/status.d.ts +2 -2
  38. package/dist/status.js +11 -9
  39. package/dist/telemetry.d.ts +10 -0
  40. package/dist/type-classify.js +4 -1
  41. package/dist/type-labels.d.ts +30 -0
  42. package/dist/type-labels.js +43 -0
  43. package/dist/types.d.ts +28 -0
  44. package/dist/uninstall.d.ts +12 -0
  45. package/dist/uninstall.js +21 -3
  46. package/dist/viz.d.ts +24 -11
  47. package/dist/viz.js +97 -32
  48. package/hermes-plugin/hicortex/README.md +4 -2
  49. package/package.json +2 -2
  50. package/dist/context-cli.d.ts +0 -69
  51. package/dist/lessons-context.d.ts +0 -102
@@ -0,0 +1,149 @@
1
+ /**
2
+ * learnings-identity — query-time identity + lessons injection for the CC
3
+ * SessionStart hook. (Canonical command name `learnings-identity` since #264;
4
+ * the legacy `lessons-context` subcommand is kept as a backcompat alias via
5
+ * resolveCommandAlias so existing installed hooks keep working. Fetches the
6
+ * identity layer + the lessons block.)
7
+ *
8
+ * Replaces file-based injection (injectLessons / injectLessonsFromServer).
9
+ * Reads ~/.hicortex/config.json to find the server URL, then fetches TWO
10
+ * endpoints concurrently and prints a compact Markdown block to stdout so CC
11
+ * picks it up as session context:
12
+ *
13
+ * GET /identity → the standing identity layer (user info + rules; 0.12,
14
+ * renamed from /context in 0.18 #264). Injected as a
15
+ * `## Identity` block ONLY when this harness ("cc") is in
16
+ * the server-resolved `clients` list (self-gate).
17
+ * GET /lessons → episodic memory lessons + memory index, rendered as the
18
+ * existing `## Hicortex Memory` block.
19
+ *
20
+ * The two fetches run in Promise.all, each with its OWN 3 s timeout and
21
+ * INDEPENDENT fail-soft: an /identity failure must never cost the lessons
22
+ * block, and vice versa. Sequential fetches would double worst-case
23
+ * SessionStart latency (~6 s) — see spec §7.
24
+ *
25
+ * Fail-soft by design: ANY failure (missing config, network error, non-2xx,
26
+ * parse error) results in silent exit-0. A broken hook must never block a
27
+ * CC session, and a broken /identity fetch must never blank the whole output.
28
+ */
29
+ import { type AgentMode } from "./identity-store.js";
30
+ /**
31
+ * The GET /identity response shape, shared by the CC hook and the OC plugin so
32
+ * their gating cannot drift. `agent`/`mode` are echoed by a 0.13 server whenever
33
+ * `?agent=` was sent (in EVERY mode); a pre-0.13 server omits them.
34
+ */
35
+ export interface IdentityResponse {
36
+ sections?: Record<string, string>;
37
+ updated_at?: string;
38
+ clients?: string[];
39
+ agent?: string;
40
+ mode?: string;
41
+ }
42
+ export interface ResolvedConfig {
43
+ serverUrl: string;
44
+ authToken: string | undefined;
45
+ home: string;
46
+ /** Per-agent identity id sent as ?agent= (0.13); null → global (no param). */
47
+ agentName: string | null;
48
+ /** Max lessons to inject (config.lessonsLimit, default 10). */
49
+ lessonsLimit?: number;
50
+ }
51
+ /**
52
+ * Read ~/.hicortex/config.json and resolve the server URL + auth token, or
53
+ * null when there is no usable config (server not set up yet — fail soft).
54
+ * Exported for reuse by the recall-hook CLI (#192) so the two CC hooks can
55
+ * never resolve the server differently.
56
+ */
57
+ export declare function resolveConfig(): ResolvedConfig | null;
58
+ /**
59
+ * Title-case a section name for its heading: split on `-`/`_`, capitalize each
60
+ * word ("user" → "User", "my_notes" → "My Notes").
61
+ * Exported so the OC plugin (index.ts) renders the `## Identity` block
62
+ * identically to the CC hook rather than duplicating the logic.
63
+ */
64
+ export declare function titleCaseSection(name: string): string;
65
+ /**
66
+ * Stable section ordering: `user` first, then `rules` (the seeded primary
67
+ * sections, spec §8), then every other section alphabetically. Server-side
68
+ * enumeration order (readdirSync) is FS-dependent, so we sort here for a
69
+ * deterministic injection block. Exported for reuse by the OC plugin.
70
+ */
71
+ export declare function orderSectionNames(names: string[]): string[];
72
+ /**
73
+ * Render the `## Identity` block from a resolved section map, or null when there
74
+ * is nothing to inject (no sections, or every section blank after trimming).
75
+ * Pure — no gating, no I/O. Shared verbatim by the CC hook and the OC plugin so
76
+ * both harnesses emit an identical block. Sections are ordered (user, rules,
77
+ * then alphabetical) and rendered under title-cased `###` headings.
78
+ */
79
+ export declare function renderIdentityBlock(sections: Record<string, string>): string | null;
80
+ /**
81
+ * Gate a GET /identity response and render the `## Identity` block, or null when
82
+ * nothing should be injected: `harness` not in the server-resolved `clients`,
83
+ * an empty/blank section set, or — when `requireAgentEcho` — a response that
84
+ * does not echo `agent`. The SINGLE gate used by both CC and OC so the two can
85
+ * never drift (the Python Hermes plugin `provider.py::_context_block` mirrors
86
+ * this logic — keep them in sync).
87
+ *
88
+ * `requireAgentEcho` is the old-server guard, and it is the CALLER's decision:
89
+ * - OC passes `agentId !== null` — when it actually sent an id, a 0.12 server
90
+ * that ignores `?agent=` (200 global, no echo) must NOT leak global identity
91
+ * into every persona; on a bare fetch (no id) the guard is off (amendment
92
+ * A2).
93
+ * - CC passes `false` ALWAYS and deliberately (see the call site): a thin CC
94
+ * client auto-upgrades via npx BEFORE the server does, so during the upgrade
95
+ * window it talks to a 0.12 server that cannot hold ANY per-agent config —
96
+ * global IS the operator's intended state there, and a guard would instead
97
+ * blank ALL identity for every CC session in that window.
98
+ */
99
+ /**
100
+ * Result of `buildIdentityToolResult` — the MCP tool handler maps this to its
101
+ * `{content:[{type:"text",text}],isError?}` shape. Pure value: no MCP SDK
102
+ * types leak here so the function is unit-testable with no harness.
103
+ */
104
+ export interface IdentityToolResult {
105
+ text: string;
106
+ isError?: boolean;
107
+ }
108
+ /**
109
+ * Build the `hicortex_identity` MCP tool result from the SAME pure pipeline the
110
+ * REST `GET /identity` route and the SessionStart hook use (#264 CRITICAL fix:
111
+ * previously the tool was a closure inside `createMcpServer()` that tests
112
+ * re-implemented locally, so the production path was never exercised).
113
+ *
114
+ * Pipeline (kept identical to REST + hook by CONSTRUCTION, not by mirroring):
115
+ * 1. `handleIdentityGet` — the real GET /identity handler, with the optional
116
+ * `agent` param forwarded so per-agent installs resolve the right scope
117
+ * (WARNING-2: previously the tool always passed `{}` → global, so an agent
118
+ * with an override saw the wrong identity).
119
+ * 2. `injectMemorySection` — the synthetic product-owned `memory` section
120
+ * (WARNING-1: the REST route + SessionStart hook inject it; the tool did
121
+ * not, contradicting its "same data" docs).
122
+ * 3. optional `name` filter, then `renderIdentityBlock` for the `### <Title>`
123
+ * markdown the hook injects.
124
+ *
125
+ * Pure: no I/O of its own (the only I/O is `handleIdentityGet` reading the
126
+ * identity dir, which is the same I/O the REST route does). Takes the resolved
127
+ * `identityClients` / `identityAgents` the daemon already holds at boot.
128
+ */
129
+ export declare function buildIdentityToolResult(identityDir: string, identityClients: string[], identityAgents: Record<string, AgentMode>, opts: {
130
+ name?: string;
131
+ agent?: string;
132
+ memoryInstructionsEnabled: boolean;
133
+ }): IdentityToolResult;
134
+ export declare function gateAndRenderIdentity(data: IdentityResponse, harness: string, opts: {
135
+ requireAgentEcho: boolean;
136
+ }): string | null;
137
+ /**
138
+ * Fetch identity + lessons concurrently and return the combined Markdown block,
139
+ * or null when neither yields anything (nothing to inject; caller prints
140
+ * nothing and exits 0). The `## Identity` block is prepended before the existing
141
+ * `## Hicortex Memory` block.
142
+ */
143
+ export declare function fetchLessonsIdentity(): Promise<string | null>;
144
+ /** Backcompat alias (#264). */
145
+ export declare const fetchLessonsContext: typeof fetchLessonsIdentity;
146
+ /** Backcompat aliases (#264) for the renamed symbols. */
147
+ export declare const renderContextBlock: typeof renderIdentityBlock;
148
+ export declare const gateAndRenderContext: typeof gateAndRenderIdentity;
149
+ export type ContextResponse = IdentityResponse;
@@ -1,43 +1,51 @@
1
1
  "use strict";
2
2
  /**
3
- * lessons-context — query-time context injection for the CC SessionStart hook.
3
+ * learnings-identity — query-time identity + lessons injection for the CC
4
+ * SessionStart hook. (Canonical command name `learnings-identity` since #264;
5
+ * the legacy `lessons-context` subcommand is kept as a backcompat alias via
6
+ * resolveCommandAlias so existing installed hooks keep working. Fetches the
7
+ * identity layer + the lessons block.)
4
8
  *
5
9
  * Replaces file-based injection (injectLessons / injectLessonsFromServer).
6
10
  * Reads ~/.hicortex/config.json to find the server URL, then fetches TWO
7
11
  * endpoints concurrently and prints a compact Markdown block to stdout so CC
8
12
  * picks it up as session context:
9
13
  *
10
- * GET /context → the standing context layer (user info + rules; 0.12).
11
- * Injected as a `## Context` block ONLY when this harness
12
- * ("cc") is in the server-resolved `clients` list (self-gate).
14
+ * GET /identity → the standing identity layer (user info + rules; 0.12,
15
+ * renamed from /context in 0.18 #264). Injected as a
16
+ * `## Identity` block ONLY when this harness ("cc") is in
17
+ * the server-resolved `clients` list (self-gate).
13
18
  * GET /lessons → episodic memory lessons + memory index, rendered as the
14
19
  * existing `## Hicortex Memory` block.
15
20
  *
16
21
  * The two fetches run in Promise.all, each with its OWN 3 s timeout and
17
- * INDEPENDENT fail-soft: a /context failure must never cost the lessons block,
18
- * and vice versa. Sequential fetches would double worst-case SessionStart
19
- * latency (~6 s) — see spec §7.
22
+ * INDEPENDENT fail-soft: an /identity failure must never cost the lessons
23
+ * block, and vice versa. Sequential fetches would double worst-case
24
+ * SessionStart latency (~6 s) — see spec §7.
20
25
  *
21
26
  * Fail-soft by design: ANY failure (missing config, network error, non-2xx,
22
27
  * parse error) results in silent exit-0. A broken hook must never block a
23
- * CC session, and a broken /context fetch must never blank the whole output.
28
+ * CC session, and a broken /identity fetch must never blank the whole output.
24
29
  */
25
30
  Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.gateAndRenderContext = exports.renderContextBlock = exports.fetchLessonsContext = void 0;
26
32
  exports.resolveConfig = resolveConfig;
27
33
  exports.titleCaseSection = titleCaseSection;
28
34
  exports.orderSectionNames = orderSectionNames;
29
- exports.renderContextBlock = renderContextBlock;
30
- exports.gateAndRenderContext = gateAndRenderContext;
31
- exports.fetchLessonsContext = fetchLessonsContext;
35
+ exports.renderIdentityBlock = renderIdentityBlock;
36
+ exports.buildIdentityToolResult = buildIdentityToolResult;
37
+ exports.gateAndRenderIdentity = gateAndRenderIdentity;
38
+ exports.fetchLessonsIdentity = fetchLessonsIdentity;
32
39
  const node_fs_1 = require("node:fs");
33
40
  const node_path_1 = require("node:path");
34
- const context_store_js_1 = require("./context-store.js");
41
+ const identity_store_js_1 = require("./identity-store.js");
42
+ const memory_instructions_js_1 = require("./memory-instructions.js");
35
43
  const features_js_1 = require("./features.js");
36
44
  const extensions_js_1 = require("./extensions.js");
37
45
  const state_js_1 = require("./state.js");
38
46
  const paths_js_1 = require("./paths.js");
39
47
  const DEFAULT_PORT = 8787;
40
- /** Harness name this hook injects for — used to self-gate on GET /context `clients`. */
48
+ /** Harness name this hook injects for — used to self-gate on GET /identity `clients`. */
41
49
  const THIS_HARNESS = "cc";
42
50
  /**
43
51
  * Read ~/.hicortex/config.json and resolve the server URL + auth token, or
@@ -58,12 +66,12 @@ function resolveConfig() {
58
66
  const serverUrl = config.mode === "client" && typeof config.serverUrl === "string"
59
67
  ? config.serverUrl.replace(/\/+$/, "")
60
68
  : `http://127.0.0.1:${config.port ?? DEFAULT_PORT}`;
61
- // Per-agent context id (0.13) via the shared resolver, so the id sent here
69
+ // Per-agent identity id (0.13) via the shared resolver, so the id sent here
62
70
  // always matches what `hicortex status` reports. No configured agentName →
63
71
  // agentId null → NO ?agent= (bare fetch): CC's default is the shared global
64
- // context. A configured agentName that sanitizes to null → agentId null too
72
+ // identity. A configured agentName that sanitizes to null → agentId null too
65
73
  // (NO ?agent=), never a 400 that the fail-soft hook would silently swallow.
66
- const agentName = (0, context_store_js_1.resolveAgentIdentity)(config).agentId;
74
+ const agentName = (0, identity_store_js_1.resolveAgentIdentity)(config).agentId;
67
75
  return {
68
76
  serverUrl,
69
77
  authToken: config.authToken,
@@ -133,7 +141,7 @@ async function fetchLessonsBlock(cfg) {
133
141
  /**
134
142
  * Title-case a section name for its heading: split on `-`/`_`, capitalize each
135
143
  * word ("user" → "User", "my_notes" → "My Notes").
136
- * Exported so the OC plugin (index.ts) renders the `## Context` block
144
+ * Exported so the OC plugin (index.ts) renders the `## Identity` block
137
145
  * identically to the CC hook rather than duplicating the logic.
138
146
  */
139
147
  function titleCaseSection(name) {
@@ -155,13 +163,13 @@ function orderSectionNames(names) {
155
163
  return [...primaries, ...rest];
156
164
  }
157
165
  /**
158
- * Render the `## Context` block from a resolved section map, or null when there
166
+ * Render the `## Identity` block from a resolved section map, or null when there
159
167
  * is nothing to inject (no sections, or every section blank after trimming).
160
168
  * Pure — no gating, no I/O. Shared verbatim by the CC hook and the OC plugin so
161
169
  * both harnesses emit an identical block. Sections are ordered (user, rules,
162
170
  * then alphabetical) and rendered under title-cased `###` headings.
163
171
  */
164
- function renderContextBlock(sections) {
172
+ function renderIdentityBlock(sections) {
165
173
  if (!sections || typeof sections !== "object" || Array.isArray(sections))
166
174
  return null;
167
175
  const names = orderSectionNames(Object.keys(sections));
@@ -174,28 +182,59 @@ function renderContextBlock(sections) {
174
182
  }
175
183
  if (bodyParts.length === 0)
176
184
  return null;
177
- return ["## Context", "", ...bodyParts].join("\n");
185
+ return ["## Identity", "", ...bodyParts].join("\n");
178
186
  }
179
187
  /**
180
- * Gate a GET /context response and render the `## Context` block, or null when
181
- * nothing should be injected: `harness` not in the server-resolved `clients`,
182
- * an empty/blank section set, or when `requireAgentEcho` a response that
183
- * does not echo `agent`. The SINGLE gate used by both CC and OC so the two can
184
- * never drift (the Python Hermes plugin `provider.py::_context_block` mirrors
185
- * this logic — keep them in sync).
188
+ * Build the `hicortex_identity` MCP tool result from the SAME pure pipeline the
189
+ * REST `GET /identity` route and the SessionStart hook use (#264 CRITICAL fix:
190
+ * previously the tool was a closure inside `createMcpServer()` that tests
191
+ * re-implemented locally, so the production path was never exercised).
186
192
  *
187
- * `requireAgentEcho` is the old-server guard, and it is the CALLER's decision:
188
- * - OC passes `agentId !== null` — when it actually sent an id, a 0.12 server
189
- * that ignores `?agent=` (200 global, no echo) must NOT leak global context
190
- * into every persona; on a bare fetch (no id) the guard is off (amendment
191
- * A2).
192
- * - CC passes `false` ALWAYS and deliberately (see the call site): a thin CC
193
- * client auto-upgrades via npx BEFORE the server does, so during the upgrade
194
- * window it talks to a 0.12 server that cannot hold ANY per-agent config —
195
- * global IS the operator's intended state there, and a guard would instead
196
- * blank ALL context for every CC session in that window.
193
+ * Pipeline (kept identical to REST + hook by CONSTRUCTION, not by mirroring):
194
+ * 1. `handleIdentityGet` — the real GET /identity handler, with the optional
195
+ * `agent` param forwarded so per-agent installs resolve the right scope
196
+ * (WARNING-2: previously the tool always passed `{}` global, so an agent
197
+ * with an override saw the wrong identity).
198
+ * 2. `injectMemorySection` the synthetic product-owned `memory` section
199
+ * (WARNING-1: the REST route + SessionStart hook inject it; the tool did
200
+ * not, contradicting its "same data" docs).
201
+ * 3. optional `name` filter, then `renderIdentityBlock` for the `### <Title>`
202
+ * markdown the hook injects.
203
+ *
204
+ * Pure: no I/O of its own (the only I/O is `handleIdentityGet` reading the
205
+ * identity dir, which is the same I/O the REST route does). Takes the resolved
206
+ * `identityClients` / `identityAgents` the daemon already holds at boot.
197
207
  */
198
- function gateAndRenderContext(data, harness, opts) {
208
+ function buildIdentityToolResult(identityDir, identityClients, identityAgents, opts) {
209
+ // WARNING-2: forward `agent` so per-agent installs resolve the right scope.
210
+ // An invalid id makes handleIdentityGet return a 400 → surfaced as isError.
211
+ const query = opts.agent ? { agent: opts.agent } : {};
212
+ const r = (0, identity_store_js_1.handleIdentityGet)(identityDir, identityClients, query, identityAgents);
213
+ if (r.status !== 200) {
214
+ const errBody = r.body;
215
+ return {
216
+ text: `Identity fetch failed: ${JSON.stringify(errBody.error ?? r.body)}`,
217
+ isError: true,
218
+ };
219
+ }
220
+ // WARNING-1: inject the synthetic `memory` section exactly like REST + the
221
+ // SessionStart hook. `injectMemorySection` is a no-op when disabled or when
222
+ // agent mode === "off".
223
+ (0, memory_instructions_js_1.injectMemorySection)(r.body, opts.memoryInstructionsEnabled);
224
+ const sections = r.body.sections ?? {};
225
+ const filtered = opts.name
226
+ ? (sections[opts.name] !== undefined ? { [opts.name]: sections[opts.name] } : {})
227
+ : sections;
228
+ const block = renderIdentityBlock(filtered);
229
+ if (block === null) {
230
+ const text = opts.name
231
+ ? `No identity section named '${opts.name}'.`
232
+ : "No identity sections configured.";
233
+ return { text };
234
+ }
235
+ return { text: block };
236
+ }
237
+ function gateAndRenderIdentity(data, harness, opts) {
199
238
  if (!data || typeof data !== "object")
200
239
  return null;
201
240
  const clients = Array.isArray(data.clients) ? data.clients : [];
@@ -203,21 +242,21 @@ function gateAndRenderContext(data, harness, opts) {
203
242
  return null;
204
243
  if (opts.requireAgentEcho && typeof data.agent !== "string")
205
244
  return null;
206
- return renderContextBlock(data.sections ?? {});
245
+ return renderIdentityBlock(data.sections ?? {});
207
246
  }
208
247
  /**
209
- * Fetch /context and build the `## Context` block, or null when nothing should
248
+ * Fetch /identity and build the `## Identity` block, or null when nothing should
210
249
  * be injected: non-2xx, this harness not in `clients`, no sections, or all
211
250
  * sections empty. Throws propagate to the caller's fail-soft catch.
212
251
  */
213
- async function fetchContextBlock(cfg) {
252
+ async function fetchIdentityBlock(cfg) {
214
253
  // Send ?agent= only when we have a valid id; the server does the merge and
215
254
  // returns the resolved sections, so the hook stays dumb (no client-side mode
216
255
  // logic). A null id (CC's default: no configured agentName, or a configured
217
- // value that sanitizes to nothing) → bare /context → the shared global set.
256
+ // value that sanitizes to nothing) → bare /identity → the shared global set.
218
257
  const url = cfg.agentName
219
- ? `${cfg.serverUrl}/context?agent=${encodeURIComponent(cfg.agentName)}`
220
- : `${cfg.serverUrl}/context`;
258
+ ? `${cfg.serverUrl}/identity?agent=${encodeURIComponent(cfg.agentName)}`
259
+ : `${cfg.serverUrl}/identity`;
221
260
  const resp = await fetch(url, {
222
261
  headers: authHeaders(cfg.authToken),
223
262
  signal: AbortSignal.timeout(3000),
@@ -227,30 +266,35 @@ async function fetchContextBlock(cfg) {
227
266
  const data = await resp.json();
228
267
  // CC deliberately passes requireAgentEcho: false (NOT the OC/Hermes old-server
229
268
  // guard). A thin CC client auto-upgrades via npx BEFORE the server does, so
230
- // mid-upgrade it may hit a 0.12 server that returns global context with no
269
+ // mid-upgrade it may hit a 0.12 server that returns global identity with no
231
270
  // `agent` echo — and a 0.12 server cannot hold per-agent config, so global is
232
- // the intended state. Guarding here would blank ALL CC context in that window.
233
- return gateAndRenderContext(data, THIS_HARNESS, { requireAgentEcho: false });
271
+ // the intended state. Guarding here would blank ALL CC identity in that window.
272
+ return gateAndRenderIdentity(data, THIS_HARNESS, { requireAgentEcho: false });
234
273
  }
235
274
  /**
236
- * Fetch context + lessons concurrently and return the combined Markdown block,
275
+ * Fetch identity + lessons concurrently and return the combined Markdown block,
237
276
  * or null when neither yields anything (nothing to inject; caller prints
238
- * nothing and exits 0). The `## Context` block is prepended before the existing
277
+ * nothing and exits 0). The `## Identity` block is prepended before the existing
239
278
  * `## Hicortex Memory` block.
240
279
  */
241
- async function fetchLessonsContext() {
280
+ async function fetchLessonsIdentity() {
242
281
  const cfg = resolveConfig();
243
282
  if (!cfg)
244
283
  return null;
245
284
  // Independent fail-soft: each branch degrades to null without affecting the
246
285
  // other. Promise.all runs them concurrently — each carries its own 3 s
247
286
  // timeout, so worst-case latency stays ~3 s, not ~6 s (spec §7).
248
- const [contextBlock, lessonsBlock] = await Promise.all([
249
- fetchContextBlock(cfg).catch(() => null),
287
+ const [identityBlock, lessonsBlock] = await Promise.all([
288
+ fetchIdentityBlock(cfg).catch(() => null),
250
289
  fetchLessonsBlock(cfg).catch(() => null),
251
290
  ]);
252
- const blocks = [contextBlock, lessonsBlock].filter((b) => b !== null && b !== "");
291
+ const blocks = [identityBlock, lessonsBlock].filter((b) => b !== null && b !== "");
253
292
  if (blocks.length === 0)
254
293
  return null;
255
294
  return blocks.join("\n\n");
256
295
  }
296
+ /** Backcompat alias (#264). */
297
+ exports.fetchLessonsContext = fetchLessonsIdentity;
298
+ /** Backcompat aliases (#264) for the renamed symbols. */
299
+ exports.renderContextBlock = renderIdentityBlock;
300
+ exports.gateAndRenderContext = gateAndRenderIdentity;
@@ -10,9 +10,11 @@
10
10
  * GET /sse — SSE stream for MCP clients
11
11
  * POST /messages — message endpoint for MCP clients
12
12
  */
13
+ import type { MemorySearchResult } from "./types.js";
13
14
  export declare function startServer(options?: {
14
15
  port?: number;
15
16
  host?: string;
16
17
  dbPath?: string;
17
18
  licenseKey?: string;
18
19
  }): Promise<void>;
20
+ export declare function formatResults(results: MemorySearchResult[]): string;