@pyxmate/memory 1.22.3 → 1.23.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.
@@ -1,6 +1,7 @@
1
- declare const PYX_MEMORY_INSTRUCTIONS = "Use pyx-memory for durable memory across sessions, proactively \u2014 do not wait to be told. SEARCH before assuming: at the start of a task, and before proposing an approach or re-deriving a past decision, search memory for the project and topic; resolve relative times (\"last year\", \"\uB450 \uB2EC \uC804\") to an absolute ISO-8601 anchorTime so results rank by proximity to that time. STORE when durable state settles \u2014 usually before your final response or handoff; if nothing durable changed, store nothing. Otherwise capture a fact (correction, bug fix + root cause, design/architecture decision + reasoning, integration/API/auth/endpoint detail, gotcha, preference, \"remember this\"), a reusable process once stable, a milestone snapshot (type episodic, not a running log), or a changed decision (store the new state with eventTime, never a silent overwrite, so lineage traces it) \u2014 concise facts not deliberation, each with topic and project. Pass eventTime (ISO-8601, when the fact took effect) for anything that can change or go stale; recency ordering, \"as of\" queries, and stale-vs-current resolution all key off it. After a memory informs your work, call reinforce so it stays in the quick/medium tiers (idle never revives it). When the user corrects you, call record_correction; before a task, call fetch_applicable_corrections (pyx never auto-applies them). When content names people, organizations, tools, places, events, or key concepts, pass entities and relationships \u2014 you build the graph, the server does not extract it; a multi-entity store with no connecting edge is refused. Match search effort to need: quick (default, strongest) for routine recall, deep for full/archived history; use lineage to trace how a fact changed. userId/teamId/agentId and callerAccessLevel are attribution filters and sensitivity redaction, not a security isolation boundary \u2014 tenant/namespace isolation is enforced server-side (namespaces + ReBAC grants; see docs/access-control.md).";
1
+ declare const PYX_MEMORY_INSTRUCTIONS = "Use pyx-memory for durable memory across sessions, proactively \u2014 do not wait to be told. It is the memory of record: a host's built-in memory (e.g. MEMORY.md) never replaces it. At the start of each conversation, load the tools (even if deferred) and call get_memory_rules; its rules are current and supersede any older pasted copy. SEARCH before assuming: at the start of a task, and before proposing an approach or re-deriving a past decision, search memory for the project and topic; resolve relative times (\"last year\", \"\uB450 \uB2EC \uC804\") to an absolute ISO-8601 anchorTime. STORE when durable state settles \u2014 usually before your final response or handoff; if nothing durable changed, store nothing. Otherwise capture a fact (correction, bug fix + root cause, design decision + reasoning, integration/API detail, gotcha, preference, \"remember this\"), a reusable process once stable, a milestone snapshot (type episodic, not a running log), or a changed decision (store the new state with eventTime, never a silent overwrite, so lineage traces it) \u2014 concise facts not deliberation, each with topic and project. Pass eventTime (ISO-8601, when the fact took effect) for anything that can change or go stale; recency ordering, \"as of\" queries, and stale-vs-current resolution all key off it. After a memory informs your work, call reinforce so it stays in the quick/medium tiers. When the user corrects you, call record_correction; before a task, call fetch_applicable_corrections. When content names people, organizations, tools, places, events, or key concepts, pass entities and relationships \u2014 you build the graph, the server does not extract it; a multi-entity store with no connecting edge is refused. Match search effort to need: quick (default, strongest) for routine recall, deep for full/archived history; use lineage to trace how a fact changed. userId/teamId/agentId and callerAccessLevel are attribution filters, not a security isolation boundary.";
2
2
  declare const PYX_MEMORY_COMPANION_CORE_INSTRUCTIONS = "Use pyx-memory for durable memory across sessions, proactively \u2014 do not wait to be told. SEARCH (search_memories) before assuming: at the start of a task, and before re-deriving a past decision, search memory for the project and topic; resolve relative times (\"last year\", \"\uB450 \uB2EC \uC804\") to an absolute ISO-8601 anchorTime so results rank by proximity to that time. Match search effort to need: quick (default, strongest) for routine recall, deep for full/archived history. STORE (store_memory) when durable state settles \u2014 usually before your final response; if nothing durable changed, store nothing. Capture concise facts, not deliberation \u2014 a correction, bug fix + root cause, decision + reasoning, integration detail, gotcha, preference, or an explicit \"remember this\" \u2014 each with topic and project. Pass eventTime (ISO-8601, when the fact took effect) for anything that can change or go stale; recency ordering and stale-vs-current resolution key off it. When content names people, organizations, tools, places, events, or key concepts, pass entities and relationships \u2014 you build the graph; a multi-entity store with no connecting edge is refused. Recalled memories reflect what was true when written \u2014 verify named files, flags, and versions before acting.";
3
3
  declare const PERSISTENT_MEMORY_SECTION: string;
4
+ declare const PASTE_MEMORY_RULES: string;
4
5
  declare function buildDesignGuide({ appName }: {
5
6
  appName: string;
6
7
  }): string;
@@ -38,4 +39,4 @@ declare const STRUCTURE_GRAPH_PROMPT_DESC = "Returns a prompt that extracts the
38
39
  declare function buildGraphStructuringPrompt(content: string): string;
39
40
  declare function buildAgentSnippet(): string;
40
41
 
41
- export { AGENT_TARGETS, PERSISTENT_MEMORY_SECTION, PYX_MEMORY_COMPANION_CORE_INSTRUCTIONS, PYX_MEMORY_INSTRUCTIONS, SEARCH_ENUMERATION_CONCEPT_DESC, SEARCH_LIMIT_DESC, STORE_ENTITIES_DESC, STORE_EVENT_TIME_DESC, STORE_RELATIONSHIPS_DESC, STORE_TOOL_DESC, STORE_TRIPLES_DESC, STRUCTURE_GRAPH_PROMPT_DESC, buildAgentSnippet, buildDesignGuide, buildGraphStructuringPrompt };
42
+ export { AGENT_TARGETS, PASTE_MEMORY_RULES, PERSISTENT_MEMORY_SECTION, PYX_MEMORY_COMPANION_CORE_INSTRUCTIONS, PYX_MEMORY_INSTRUCTIONS, SEARCH_ENUMERATION_CONCEPT_DESC, SEARCH_LIMIT_DESC, STORE_ENTITIES_DESC, STORE_EVENT_TIME_DESC, STORE_RELATIONSHIPS_DESC, STORE_TOOL_DESC, STORE_TRIPLES_DESC, STRUCTURE_GRAPH_PROMPT_DESC, buildAgentSnippet, buildDesignGuide, buildGraphStructuringPrompt };
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  AGENT_TARGETS,
3
+ PASTE_MEMORY_RULES,
3
4
  PERSISTENT_MEMORY_SECTION,
4
5
  PYX_MEMORY_COMPANION_CORE_INSTRUCTIONS,
5
6
  PYX_MEMORY_INSTRUCTIONS,
@@ -14,9 +15,10 @@ import {
14
15
  buildAgentSnippet,
15
16
  buildDesignGuide,
16
17
  buildGraphStructuringPrompt
17
- } from "./chunk-EZERG25I.mjs";
18
+ } from "./chunk-QD7G23CN.mjs";
18
19
  export {
19
20
  AGENT_TARGETS,
21
+ PASTE_MEMORY_RULES,
20
22
  PERSISTENT_MEMORY_SECTION,
21
23
  PYX_MEMORY_COMPANION_CORE_INSTRUCTIONS,
22
24
  PYX_MEMORY_INSTRUCTIONS,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MemoryClient
3
- } from "./chunk-HVJZDJGH.mjs";
3
+ } from "./chunk-SGL73IY5.mjs";
4
4
 
5
5
  // ../dashboard/src/aggregations/consolidation-analytics.ts
6
6
  function analyzeConsolidationLog(entries) {
@@ -256,6 +256,11 @@ var DATA_PLANE_OPERATION_COVERAGE = {
256
256
  reasonCode: "nonchargeable_operation",
257
257
  reason: "status is nonchargeable and must bypass data-plane reservation"
258
258
  },
259
+ "mcp:get_memory_rules": {
260
+ support: "not_execution_ready",
261
+ reasonCode: "nonchargeable_operation",
262
+ reason: "the rules text is nonchargeable and must bypass data-plane reservation"
263
+ },
259
264
  "mcp:get_user_profile": { support: "sqlite_atomic_one_step" },
260
265
  "mcp:upsert_user_profile": { support: "sqlite_atomic_one_step" },
261
266
  "mcp:record_correction": { support: "sqlite_atomic_one_step" },
@@ -1,10 +1,10 @@
1
1
  // src/contract/index.ts
2
- var PYX_MEMORY_INSTRUCTIONS = `Use pyx-memory for durable memory across sessions, proactively \u2014 do not wait to be told. SEARCH before assuming: at the start of a task, and before proposing an approach or re-deriving a past decision, search memory for the project and topic; resolve relative times ("last year", "\uB450 \uB2EC \uC804") to an absolute ISO-8601 anchorTime so results rank by proximity to that time. STORE when durable state settles \u2014 usually before your final response or handoff; if nothing durable changed, store nothing. Otherwise capture a fact (correction, bug fix + root cause, design/architecture decision + reasoning, integration/API/auth/endpoint detail, gotcha, preference, "remember this"), a reusable process once stable, a milestone snapshot (type episodic, not a running log), or a changed decision (store the new state with eventTime, never a silent overwrite, so lineage traces it) \u2014 concise facts not deliberation, each with topic and project. Pass eventTime (ISO-8601, when the fact took effect) for anything that can change or go stale; recency ordering, "as of" queries, and stale-vs-current resolution all key off it. After a memory informs your work, call reinforce so it stays in the quick/medium tiers (idle never revives it). When the user corrects you, call record_correction; before a task, call fetch_applicable_corrections (pyx never auto-applies them). When content names people, organizations, tools, places, events, or key concepts, pass entities and relationships \u2014 you build the graph, the server does not extract it; a multi-entity store with no connecting edge is refused. Match search effort to need: quick (default, strongest) for routine recall, deep for full/archived history; use lineage to trace how a fact changed. userId/teamId/agentId and callerAccessLevel are attribution filters and sensitivity redaction, not a security isolation boundary \u2014 tenant/namespace isolation is enforced server-side (namespaces + ReBAC grants; see docs/access-control.md).`;
2
+ var PYX_MEMORY_INSTRUCTIONS = `Use pyx-memory for durable memory across sessions, proactively \u2014 do not wait to be told. It is the memory of record: a host's built-in memory (e.g. MEMORY.md) never replaces it. At the start of each conversation, load the tools (even if deferred) and call get_memory_rules; its rules are current and supersede any older pasted copy. SEARCH before assuming: at the start of a task, and before proposing an approach or re-deriving a past decision, search memory for the project and topic; resolve relative times ("last year", "\uB450 \uB2EC \uC804") to an absolute ISO-8601 anchorTime. STORE when durable state settles \u2014 usually before your final response or handoff; if nothing durable changed, store nothing. Otherwise capture a fact (correction, bug fix + root cause, design decision + reasoning, integration/API detail, gotcha, preference, "remember this"), a reusable process once stable, a milestone snapshot (type episodic, not a running log), or a changed decision (store the new state with eventTime, never a silent overwrite, so lineage traces it) \u2014 concise facts not deliberation, each with topic and project. Pass eventTime (ISO-8601, when the fact took effect) for anything that can change or go stale; recency ordering, "as of" queries, and stale-vs-current resolution all key off it. After a memory informs your work, call reinforce so it stays in the quick/medium tiers. When the user corrects you, call record_correction; before a task, call fetch_applicable_corrections. When content names people, organizations, tools, places, events, or key concepts, pass entities and relationships \u2014 you build the graph, the server does not extract it; a multi-entity store with no connecting edge is refused. Match search effort to need: quick (default, strongest) for routine recall, deep for full/archived history; use lineage to trace how a fact changed. userId/teamId/agentId and callerAccessLevel are attribution filters, not a security isolation boundary.`;
3
3
  var PYX_MEMORY_COMPANION_CORE_INSTRUCTIONS = `Use pyx-memory for durable memory across sessions, proactively \u2014 do not wait to be told. SEARCH (search_memories) before assuming: at the start of a task, and before re-deriving a past decision, search memory for the project and topic; resolve relative times ("last year", "\uB450 \uB2EC \uC804") to an absolute ISO-8601 anchorTime so results rank by proximity to that time. Match search effort to need: quick (default, strongest) for routine recall, deep for full/archived history. STORE (store_memory) when durable state settles \u2014 usually before your final response; if nothing durable changed, store nothing. Capture concise facts, not deliberation \u2014 a correction, bug fix + root cause, decision + reasoning, integration detail, gotcha, preference, or an explicit "remember this" \u2014 each with topic and project. Pass eventTime (ISO-8601, when the fact took effect) for anything that can change or go stale; recency ordering and stale-vs-current resolution key off it. When content names people, organizations, tools, places, events, or key concepts, pass entities and relationships \u2014 you build the graph; a multi-entity store with no connecting edge is refused. Recalled memories reflect what was true when written \u2014 verify named files, flags, and versions before acting.`;
4
4
  var PERSISTENT_MEMORY_SECTION = [
5
5
  "## Persistent Memory",
6
6
  "",
7
- "Use the configured `pyx-memory` MCP tools for durable memory across conversations.",
7
+ "Use the configured `pyx-memory` MCP tools as your memory of record across conversations; a host's built-in memory (e.g. `MEMORY.md`) never replaces them. Load them first if deferred.",
8
8
  "",
9
9
  "Search before assuming:",
10
10
  "",
@@ -28,7 +28,7 @@ var PERSISTENT_MEMORY_SECTION = [
28
28
  "Store when durable state settles, usually before a final response/handoff; if nothing durable changed, store nothing. Capture:",
29
29
  "",
30
30
  '- Facts (default) \u2014 one correction/preference, root-cause fix, reasoned design decision, integration detail, gotcha, or explicit "remember this" request per memory.',
31
- "- Process (`type: long-term`) \u2014 a reusable workflow, convention, or playbook a fresh session should follow. Store it once stabilized or adopted.",
31
+ "- Process (`type: long-term`) \u2014 a reusable workflow, convention, or playbook a fresh session should follow, once stabilized or adopted.",
32
32
  "- Trajectory (`type: episodic`) \u2014 only at a real milestone, handoff, or user-requested checkpoint: one dated snapshot of what changed, where it stands, and the open frontier. Not a running log.",
33
33
  "- Ordinary conversational facts omit `id` and evolve through new entries with `eventTime`. Only application-owned canonical mirrors may reuse an app-supplied stable `id` with `metadata.dbRef.revision`. Revisions are opaque; retry with the same stable `id`, opaque revision, and byte-exact identical payload. Never invent, randomize, or timestamp-suffix IDs; replay stale snapshots or manifests; or use store-new plus delete-old. On `revision_reuse_conflict`, reread the authoritative source; do not mint a new ID or revision.",
34
34
  "",
@@ -36,15 +36,19 @@ var PERSISTENT_MEMORY_SECTION = [
36
36
  "",
37
37
  "- Always include `topic` and `project`.",
38
38
  "- Store concise facts and decisions, not deliberation.",
39
- "- Keep one memory per concept; do not bundle unrelated facts.",
40
39
  "- Do not store ephemeral files, raw logs, or progress. Aggregate high-frequency streams into a dated fact/summary with `eventTime`; never one memory or graph node per sample.",
41
40
  "- Pass `eventTime` (ISO-8601, when a changeable/stale fact happened/took effect); recency/as-of/stale-vs-current key off it.",
42
41
  "- Graph is for retrieval. For named people, organizations, tools, places, events, or concepts, pass `entities` + `relationships` (caller-wins); connect multi-entity stores with a relationship or `triples`. Relationships matter as much as entities. Entity-free memories are valid.",
43
42
  '- Use specific durable entities, never catch-all hubs ("me", "health"); bounded `IS_A` categories are the exception.',
44
43
  '- For countable categories the user may later enumerate, add a canonical category `CONCEPT` node and an `IS_A` edge from each member to it (`"yoga"` IS_A `"fitness classes"`).',
45
44
  "- Taxonomy: when a store response reports unnamed clusters, call get_taxonomy_state and name each via name_cluster (short, domain-true, user's language); rename only when composition clearly changed.",
46
- "- Ingest documents/images only when they are worth persisting; images require a short description so they are searchable.",
47
- "- Before ingesting docx/xlsx/pptx, prefer pre-extracting to `.md`; headings preserve section context."
45
+ "- Ingest documents/images only when worth persisting; images need a short description to be searchable.",
46
+ "- Before ingesting docx/xlsx/pptx, pre-extract to `.md`; headings keep section context."
47
+ ].join("\n");
48
+ var PASTE_MEMORY_RULES = [
49
+ "## Persistent Memory",
50
+ "",
51
+ "Use the configured `pyx-memory` MCP tools as your memory of record across conversations; a host's built-in memory never replaces them. At the start of every conversation, load them (even if deferred), call `get_memory_rules`, and follow the rules it returns \u2014 they are always current."
48
52
  ].join("\n");
49
53
  function buildDesignGuide({ appName }) {
50
54
  const name = appName.trim() || "your app";
@@ -154,7 +158,7 @@ function buildAgentSnippet() {
154
158
  "",
155
159
  "Install only the section below, verbatim. After writing, tell the user which file you updated.",
156
160
  "",
157
- PERSISTENT_MEMORY_SECTION
161
+ PASTE_MEMORY_RULES
158
162
  ].join("\n");
159
163
  }
160
164
 
@@ -162,6 +166,7 @@ export {
162
166
  PYX_MEMORY_INSTRUCTIONS,
163
167
  PYX_MEMORY_COMPANION_CORE_INSTRUCTIONS,
164
168
  PERSISTENT_MEMORY_SECTION,
169
+ PASTE_MEMORY_RULES,
165
170
  buildDesignGuide,
166
171
  AGENT_TARGETS,
167
172
  STORE_ENTITIES_DESC,
@@ -2,7 +2,7 @@ import {
2
2
  RAGStrategy,
3
3
  assertGraphExtractionPayload,
4
4
  mergeExtractedEntities
5
- } from "./chunk-BUKDWHTY.mjs";
5
+ } from "./chunk-C46EE5BH.mjs";
6
6
 
7
7
  // ../client/src/disabled-memory.ts
8
8
  var DEFAULT_PAGE_LIMIT = 20;
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  PERSISTENT_MEMORY_SECTION,
4
4
  buildDesignGuide
5
- } from "../chunk-EZERG25I.mjs";
5
+ } from "../chunk-QD7G23CN.mjs";
6
6
  import {
7
7
  MEMORY_PROJECT_LABEL_MAX_CHARS,
8
8
  TAXONOMY_MAX_CATEGORIES,
@@ -10,7 +10,7 @@ import {
10
10
  TAXONOMY_MAX_SAMPLE_TOPICS,
11
11
  TAXONOMY_MAX_TOP_ENTITIES
12
12
  } from "../chunk-KZKGRND2.mjs";
13
- import "../chunk-BUKDWHTY.mjs";
13
+ import "../chunk-C46EE5BH.mjs";
14
14
 
15
15
  // src/cli/exit-codes.ts
16
16
  var EXIT = {
@@ -2223,7 +2223,7 @@ function createProxyServer(client, version, uploadLocalFile) {
2223
2223
  return server;
2224
2224
  }
2225
2225
  async function runMcpProxyServer(opts) {
2226
- const version = opts.version ?? (true ? "1.22.3" : "0.0.0-dev");
2226
+ const version = opts.version ?? (true ? "1.23.1" : "0.0.0-dev");
2227
2227
  const read = await opts.readCredentials();
2228
2228
  if (!read.ok) {
2229
2229
  throw new Error(
@@ -2257,7 +2257,9 @@ async function runMcpProxyServer(opts) {
2257
2257
  const closed = new Promise((resolve3) => {
2258
2258
  transport.onclose = () => resolve3();
2259
2259
  });
2260
+ process.stdin.once("end", () => void transport.close());
2260
2261
  await server.connect(transport);
2262
+ void opts.onConnected?.(client);
2261
2263
  await closed;
2262
2264
  } finally {
2263
2265
  await client.close().catch(() => {
@@ -2267,7 +2269,7 @@ async function runMcpProxyServer(opts) {
2267
2269
 
2268
2270
  // src/cli/commands/mcp-install.ts
2269
2271
  import { spawnSync as nodeSpawnSync } from "child_process";
2270
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
2272
+ import { existsSync as existsSync3 } from "fs";
2271
2273
  import { homedir as homedir2 } from "os";
2272
2274
  import { join as join2 } from "path";
2273
2275
 
@@ -2387,7 +2389,20 @@ function indent(text) {
2387
2389
  }
2388
2390
 
2389
2391
  // src/cli/commands/memory-rules-merge.ts
2390
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, statSync, writeFileSync as writeFileSync2 } from "fs";
2392
+ import { randomUUID as randomUUID4 } from "crypto";
2393
+ import {
2394
+ chmodSync,
2395
+ existsSync as existsSync2,
2396
+ linkSync,
2397
+ lstatSync,
2398
+ mkdirSync as mkdirSync2,
2399
+ readFileSync as readFileSync2,
2400
+ realpathSync,
2401
+ renameSync as renameSync2,
2402
+ rmSync,
2403
+ statSync,
2404
+ writeFileSync as writeFileSync2
2405
+ } from "fs";
2391
2406
  import { dirname as dirname3 } from "path";
2392
2407
  var RULES_BEGIN_MARKER = "<!-- pyx-memory:begin (managed by `pyx-mem mcp install`; edit outside these markers) -->";
2393
2408
  var RULES_END_MARKER = "<!-- pyx-memory:end -->";
@@ -2395,6 +2410,15 @@ var BEGIN_MARKER_PREFIX = "<!-- pyx-memory:begin";
2395
2410
  var PM_HEADING_RE = /^ {0,3}##[ \t]+Persistent Memory[ \t]*$/;
2396
2411
  var H1_OR_H2_RE = /^ {0,3}#{1,2}[ \t]+\S/;
2397
2412
  var FENCE_RE = /^ {0,3}(`{3,}|~{3,})/;
2413
+ var CLOSING_FENCE_RE = /^ {0,3}(`{3,}|~{3,})[ \t]*$/;
2414
+ var BEGIN_MARKER_RE = /^ {0,3}<!-- pyx-memory:begin(?:[ \t][^>]*)?-->[ \t]*$/;
2415
+ var END_MARKER_RE = /^ {0,3}<!-- pyx-memory:end -->[ \t]*$/;
2416
+ function isBeginMarker(line) {
2417
+ return BEGIN_MARKER_RE.test(line);
2418
+ }
2419
+ function isEndMarker(line) {
2420
+ return END_MARKER_RE.test(line);
2421
+ }
2398
2422
  function fenceMask(lines) {
2399
2423
  const mask = new Array(lines.length).fill(false);
2400
2424
  let openIdx = -1;
@@ -2409,7 +2433,7 @@ function fenceMask(lines) {
2409
2433
  openLen = fence.length;
2410
2434
  continue;
2411
2435
  }
2412
- if (fence.charAt(0) === delim && fence.length >= openLen) {
2436
+ if (CLOSING_FENCE_RE.test(lines[i] ?? "") && fence.charAt(0) === delim && fence.length >= openLen) {
2413
2437
  for (let j = openIdx; j <= i; j++) mask[j] = true;
2414
2438
  openIdx = -1;
2415
2439
  delim = "";
@@ -2430,36 +2454,29 @@ function findCompleteManagedRange(lines, mask) {
2430
2454
  for (let i = 0; i < lines.length; i++) {
2431
2455
  const line = lines[i];
2432
2456
  if (line === void 0 || mask[i]) continue;
2433
- const t = line.trim();
2434
- if (begin === -1) {
2435
- if (t.startsWith(BEGIN_MARKER_PREFIX)) begin = i;
2436
- } else if (t === RULES_END_MARKER) {
2437
- return [begin, i + 1];
2438
- }
2457
+ if (isBeginMarker(line)) begin = i;
2458
+ else if (begin !== -1 && isEndMarker(line)) return [begin, i + 1];
2439
2459
  }
2440
2460
  return null;
2441
2461
  }
2442
- function findOrphanBeginLine(lines, mask) {
2462
+ function findBeginLines(lines, mask) {
2463
+ const found = [];
2443
2464
  for (let i = 0; i < lines.length; i++) {
2444
2465
  const line = lines[i];
2445
- if (line !== void 0 && !mask[i] && line.trim().startsWith(BEGIN_MARKER_PREFIX)) return i;
2466
+ if (line !== void 0 && !mask[i] && isBeginMarker(line)) found.push(i);
2446
2467
  }
2447
- return -1;
2468
+ return found;
2448
2469
  }
2449
2470
  function findLegacyPyxRange(lines, mask) {
2450
2471
  for (let i = 0; i < lines.length; i++) {
2451
2472
  const line = lines[i];
2452
2473
  if (line === void 0 || mask[i] || !PM_HEADING_RE.test(line)) continue;
2453
2474
  const end = nextH1OrH2(lines, mask, i + 1);
2454
- if (lines.slice(i, end).join("\n").toLowerCase().includes("pyx-memory")) return [i, end];
2475
+ const own = lines.slice(i, end).filter((l, k) => !mask[i + k] && !isBeginMarker(l) && !isEndMarker(l));
2476
+ if (own.join("\n").toLowerCase().includes("pyx-memory")) return [i, end];
2455
2477
  }
2456
2478
  return null;
2457
2479
  }
2458
- function hasPyxMemoryRules(content) {
2459
- const lines = content.replace(/\r\n/g, "\n").split("\n");
2460
- const mask = fenceMask(lines);
2461
- return findCompleteManagedRange(lines, mask) !== null || findOrphanBeginLine(lines, mask) !== -1 || findLegacyPyxRange(lines, mask) !== null;
2462
- }
2463
2480
  function spliceBlock(lines, from, toExclusive, blockLines) {
2464
2481
  const before = lines.slice(0, from);
2465
2482
  const after = lines.slice(toExclusive);
@@ -2476,7 +2493,13 @@ function joinWithTrailingNewline(lines, eol) {
2476
2493
  const body = lines.join(eol);
2477
2494
  return body.endsWith(eol) ? body : `${body}${eol}`;
2478
2495
  }
2496
+ var BOM = "\uFEFF";
2479
2497
  function mergeMemoryRules(existing, section) {
2498
+ const bom = existing.startsWith(BOM) ? BOM : "";
2499
+ const merged = mergeBody(existing.slice(bom.length), section);
2500
+ return { ...merged, content: bom + merged.content };
2501
+ }
2502
+ function mergeBody(existing, section) {
2480
2503
  if (section.includes(BEGIN_MARKER_PREFIX) || section.includes(RULES_END_MARKER)) {
2481
2504
  throw new Error("pyx-memory rules section must not contain the managed markers.");
2482
2505
  }
@@ -2493,9 +2516,9 @@ function mergeMemoryRules(existing, section) {
2493
2516
  const next2 = spliceBlock(lines, complete[0], complete[1], blockLines);
2494
2517
  return { content: joinWithTrailingNewline(next2, eol), action: "updated" };
2495
2518
  }
2496
- const orphan = findOrphanBeginLine(lines, mask);
2497
- if (orphan !== -1) {
2498
- lines = [...lines.slice(0, orphan), ...lines.slice(orphan + 1)];
2519
+ const orphans = new Set(findBeginLines(lines, mask));
2520
+ if (orphans.size > 0) {
2521
+ lines = lines.filter((_, i) => !orphans.has(i));
2499
2522
  mask = fenceMask(lines);
2500
2523
  }
2501
2524
  const legacy = findLegacyPyxRange(lines, mask);
@@ -2506,12 +2529,53 @@ function mergeMemoryRules(existing, section) {
2506
2529
  const next = spliceBlock(lines, lines.length, lines.length, blockLines);
2507
2530
  return { content: joinWithTrailingNewline(next, eol), action: "appended" };
2508
2531
  }
2532
+ function refreshMemoryRules(file, section) {
2533
+ const bom = file.startsWith(BOM) ? BOM : "";
2534
+ const refreshed = refreshBody(file.slice(bom.length), section);
2535
+ return refreshed === null ? null : bom + refreshed;
2536
+ }
2537
+ function refreshBody(existing, section) {
2538
+ const lines = existing.replace(/\r\n/g, "\n").split("\n");
2539
+ const complete = findCompleteManagedRange(lines, fenceMask(lines));
2540
+ if (!complete) return null;
2541
+ const [first, last] = [complete[0], complete[1] - 1];
2542
+ const starts = [0];
2543
+ for (let i = 0; i < existing.length; i++) if (existing[i] === "\n") starts.push(i + 1);
2544
+ const from = starts[first] ?? 0;
2545
+ const lastStart = starts[last] ?? 0;
2546
+ const to = lastStart + (lines[last] ?? "").length;
2547
+ const eol = existing.slice(from).match(/\r?\n/)?.[0] ?? "\n";
2548
+ const block = [RULES_BEGIN_MARKER, ...section.split(/\r?\n/), RULES_END_MARKER].join(eol);
2549
+ return existing.slice(0, from) + block + existing.slice(to);
2550
+ }
2551
+ function changedDuringWrite(filePath) {
2552
+ return new Error(`${filePath} changed while updating the pyx-memory rules; retry.`);
2553
+ }
2554
+ function readUtf8Strict(path) {
2555
+ try {
2556
+ return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(readFileSync2(path));
2557
+ } catch (err) {
2558
+ if (err instanceof TypeError) {
2559
+ throw new Error(`${path} is not valid UTF-8; the pyx-memory rules were not changed.`);
2560
+ }
2561
+ throw err;
2562
+ }
2563
+ }
2509
2564
  function writeMemoryRulesFile(opts) {
2510
2565
  const { filePath, section } = opts;
2511
2566
  const fileExists = existsSync2(filePath);
2512
- const existing = fileExists ? readFileSync2(filePath, "utf8") : "";
2513
- const { content, action } = mergeMemoryRules(existing, section);
2514
- if (content === existing) {
2567
+ if (!fileExists && lstatSync(filePath, { throwIfNoEntry: false })?.isSymbolicLink()) {
2568
+ throw new Error(`${filePath} is a broken link; fix or remove it, then retry.`);
2569
+ }
2570
+ const target = fileExists ? realpathSync(filePath) : filePath;
2571
+ const existing = fileExists ? readUtf8Strict(target) : "";
2572
+ let merged = null;
2573
+ if (!opts.refreshOnly) merged = mergeMemoryRules(existing, section);
2574
+ else {
2575
+ const content = refreshMemoryRules(existing, section);
2576
+ if (content !== null) merged = { content, action: "updated" };
2577
+ }
2578
+ if (merged === null || merged.content === existing) {
2515
2579
  return {
2516
2580
  action: "unchanged",
2517
2581
  filePath,
@@ -2519,15 +2583,32 @@ function writeMemoryRulesFile(opts) {
2519
2583
  `
2520
2584
  };
2521
2585
  }
2522
- const parent = dirname3(filePath);
2586
+ const parent = dirname3(target);
2523
2587
  if (!existsSync2(parent)) mkdirSync2(parent, { recursive: true });
2524
- const mode = fileExists ? statSync(filePath).mode & 511 : 420;
2525
- const tmpPath = `${filePath}.tmp`;
2526
- writeFileSync2(tmpPath, content, { mode });
2527
- renameSync2(tmpPath, filePath);
2528
- const verb = action === "created" ? "Wrote" : action === "appended" ? "Added" : "Updated";
2588
+ const mode = fileExists ? statSync(target).mode & 511 : 420;
2589
+ const tmpPath = `${target}.${process.pid}.${randomUUID4()}.tmp`;
2590
+ try {
2591
+ writeFileSync2(tmpPath, merged.content, { mode });
2592
+ chmodSync(tmpPath, mode);
2593
+ if (fileExists) {
2594
+ if (readUtf8Strict(target) !== existing) throw changedDuringWrite(filePath);
2595
+ renameSync2(tmpPath, target);
2596
+ } else {
2597
+ try {
2598
+ linkSync(tmpPath, target);
2599
+ } catch (err) {
2600
+ if (err.code === "EEXIST") throw changedDuringWrite(filePath);
2601
+ throw err;
2602
+ }
2603
+ rmSync(tmpPath);
2604
+ }
2605
+ } catch (err) {
2606
+ rmSync(tmpPath, { force: true });
2607
+ throw err;
2608
+ }
2609
+ const verb = merged.action === "created" ? "Wrote" : merged.action === "appended" ? "Added" : "Updated";
2529
2610
  return {
2530
- action,
2611
+ action: merged.action,
2531
2612
  filePath,
2532
2613
  message: `${verb} the pyx-memory rules in ${filePath}.
2533
2614
  `
@@ -2591,17 +2672,26 @@ function mcpInstallCodexCommand(opts = {}) {
2591
2672
  const remote = opts.remote ?? false;
2592
2673
  const spawnSync = opts._spawnSync ?? nodeSpawnSync;
2593
2674
  const home = opts._homeDir ?? homedir2();
2675
+ const codexHome = (opts._env ?? process.env).CODEX_HOME;
2594
2676
  const probe = spawnSync("codex", ["--version"], { stdio: "pipe" });
2595
2677
  if (probe.error || probe.status !== 0) {
2596
- printCodexManualInstructions(home, remote);
2678
+ printCodexManualInstructions(home, remote, codexHome);
2597
2679
  return EXIT.OK;
2598
2680
  }
2599
- const cmd = ["mcp", "add", SERVER_NAME, "--", "pyx-mem", ...pyxMemArgs(remote)];
2681
+ const cmd = [
2682
+ "mcp",
2683
+ "add",
2684
+ SERVER_NAME,
2685
+ ...codexHome ? ["--env", `CODEX_HOME=${codexHome}`] : [],
2686
+ "--",
2687
+ "pyx-mem",
2688
+ ...pyxMemArgs(remote)
2689
+ ];
2600
2690
  const res = spawnSync("codex", cmd, { stdio: "inherit" });
2601
2691
  if (res.status !== 0) {
2602
2692
  process.stderr.write(`\`codex ${cmd.join(" ")}\` exited with code ${res.status ?? "null"}.
2603
2693
  `);
2604
- printCodexManualInstructions(home, remote);
2694
+ printCodexManualInstructions(home, remote, codexHome);
2605
2695
  return EXIT.USAGE;
2606
2696
  }
2607
2697
  process.stdout.write(
@@ -2611,20 +2701,21 @@ Restart Codex CLI to make the tools available. No API key was written to config.
2611
2701
  );
2612
2702
  return EXIT.OK;
2613
2703
  }
2614
- function printCodexManualInstructions(home, remote) {
2615
- const configPath = join2(home, ".codex", "config.toml");
2704
+ function printCodexManualInstructions(home, remote, codexHome) {
2705
+ const configPath = join2(codexHome ?? join2(home, ".codex"), "config.toml");
2616
2706
  process.stdout.write(
2617
2707
  [
2618
2708
  "The `codex` CLI is not on PATH, or the install command failed.",
2619
2709
  "",
2620
2710
  "Run this once Codex CLI is installed:",
2621
- ` codex mcp add ${SERVER_NAME} -- pyx-mem ${pyxMemArgs(remote).join(" ")}`,
2711
+ ` codex mcp add ${SERVER_NAME}${codexHome ? ` --env ${JSON.stringify(`CODEX_HOME=${codexHome}`)}` : ""} -- pyx-mem ${pyxMemArgs(remote).join(" ")}`,
2622
2712
  "",
2623
2713
  `Or add this section manually to ${configPath}:`,
2624
2714
  "",
2625
2715
  `[mcp_servers.${SERVER_NAME}]`,
2626
2716
  `command = "pyx-mem"`,
2627
2717
  `args = ${JSON.stringify(pyxMemArgs(remote))}`,
2718
+ ...codexHome ? [`env = { CODEX_HOME = ${JSON.stringify(codexHome)} }`] : [],
2628
2719
  "",
2629
2720
  "Do NOT add your pyx-memory API key here. Run `pyx-mem login` to store it in the OS credential store.",
2630
2721
  ""
@@ -2841,35 +2932,48 @@ function printHermesManualInstructions(remote) {
2841
2932
  );
2842
2933
  }
2843
2934
  var RULES_FILE_TARGETS = {
2844
- "claude-code": [".claude", "CLAUDE.md"],
2845
- codex: [".codex", "AGENTS.md"],
2846
- "gemini-cli": [".gemini", "GEMINI.md"],
2847
- "oh-my-pi": [".omp", "agent", "RULES.md"]
2935
+ "claude-code": { envDir: "CLAUDE_CONFIG_DIR", dir: [".claude"], file: "CLAUDE.md" },
2936
+ codex: { envDir: "CODEX_HOME", dir: [".codex"], file: "AGENTS.md" },
2937
+ "gemini-cli": { dir: [".gemini"], file: "GEMINI.md" },
2938
+ "oh-my-pi": { dir: [".omp", "agent"], file: "RULES.md" }
2848
2939
  };
2940
+ function rulesFilePath(target, opts) {
2941
+ if (!Object.hasOwn(RULES_FILE_TARGETS, target)) return void 0;
2942
+ const spec = RULES_FILE_TARGETS[target];
2943
+ const env = opts._env ?? (opts._homeDir === void 0 ? process.env : {});
2944
+ const configDir = spec.envDir ? env[spec.envDir] : void 0;
2945
+ return configDir ? join2(configDir, spec.file) : join2(opts._homeDir ?? homedir2(), ...spec.dir, spec.file);
2946
+ }
2849
2947
  function installMemoryRules(opts) {
2850
- const segs = RULES_FILE_TARGETS[opts.target];
2851
- if (!segs) return;
2948
+ const filePath = rulesFilePath(opts.target, opts);
2949
+ if (!filePath) return;
2852
2950
  if (opts.noRules) {
2853
2951
  process.stdout.write(
2854
2952
  'Skipped writing the memory rules (--no-rules). The tools are installed, but the agent will reach for memory only when you ask; add the "## Persistent Memory" rules yourself to change that.\n'
2855
2953
  );
2856
2954
  return;
2857
2955
  }
2858
- const home = opts._homeDir ?? homedir2();
2859
- const result = writeMemoryRulesFile({
2860
- filePath: join2(home, ...segs),
2861
- section: PERSISTENT_MEMORY_SECTION
2862
- });
2956
+ const result = writeMemoryRulesFile({ filePath, section: PERSISTENT_MEMORY_SECTION });
2863
2957
  process.stdout.write(result.message);
2864
2958
  }
2959
+ function installMemoryRulesOnly(target, opts = {}) {
2960
+ if (target === void 0 || !rulesFilePath(target, opts)) {
2961
+ process.stderr.write(
2962
+ `Error: \`pyx-mem mcp rules\` needs a host with a known rules file: ${Object.keys(RULES_FILE_TARGETS).join(", ")}.
2963
+ `
2964
+ );
2965
+ return EXIT.USAGE;
2966
+ }
2967
+ installMemoryRules({ ...opts, target, noRules: false });
2968
+ return EXIT.OK;
2969
+ }
2865
2970
  function reconcileMemoryRules(opts = {}) {
2866
- const home = opts._homeDir ?? homedir2();
2867
- for (const segs of Object.values(RULES_FILE_TARGETS)) {
2868
- const filePath = join2(home, ...segs);
2971
+ const section = opts.section ?? PERSISTENT_MEMORY_SECTION;
2972
+ for (const target of Object.keys(RULES_FILE_TARGETS)) {
2973
+ const filePath = rulesFilePath(target, opts);
2869
2974
  try {
2870
2975
  if (!existsSync3(filePath)) continue;
2871
- if (!hasPyxMemoryRules(readFileSync3(filePath, "utf8"))) continue;
2872
- const result = writeMemoryRulesFile({ filePath, section: PERSISTENT_MEMORY_SECTION });
2976
+ const result = writeMemoryRulesFile({ filePath, section, refreshOnly: true });
2873
2977
  if (result.action !== "unchanged") {
2874
2978
  process.stderr.write(
2875
2979
  `pyx-memory: refreshed the "## Persistent Memory" rules in ${filePath}
@@ -2880,6 +2984,31 @@ function reconcileMemoryRules(opts = {}) {
2880
2984
  }
2881
2985
  }
2882
2986
  }
2987
+ var MAX_SERVER_RULES_BYTES = 16 * 1024;
2988
+ async function syncMemoryRulesFromServer(client, opts = {}) {
2989
+ try {
2990
+ const { tools } = await client.listTools();
2991
+ if (!tools.some((tool) => tool.name === "get_memory_rules")) {
2992
+ reconcileMemoryRules(opts);
2993
+ return;
2994
+ }
2995
+ const result = await client.callTool({ name: "get_memory_rules", arguments: {} });
2996
+ const [first] = result.content ?? [];
2997
+ const section = first?.type === "text" ? first.text : void 0;
2998
+ if (result.isError || !section || !isRulesSection(section)) {
2999
+ throw new Error('the server returned no valid "## Persistent Memory" section');
3000
+ }
3001
+ reconcileMemoryRules({ ...opts, section });
3002
+ } catch (err) {
3003
+ process.stderr.write(
3004
+ `pyx-memory: left the installed memory rules unchanged \u2014 could not fetch current rules (${err instanceof Error ? err.message : String(err)}).
3005
+ `
3006
+ );
3007
+ }
3008
+ }
3009
+ function isRulesSection(text) {
3010
+ return text.startsWith("## Persistent Memory\n") && Buffer.byteLength(text, "utf8") <= MAX_SERVER_RULES_BYTES && !text.includes("<!-- pyx-memory:") && !/^\s*(```|~~~)/m.test(text);
3011
+ }
2883
3012
  function validateScope(scope) {
2884
3013
  if (VALID_SCOPES.has(scope)) return true;
2885
3014
  process.stderr.write(`Error: invalid --scope \`${scope}\`. Expected: local | user | project.
@@ -2909,14 +3038,12 @@ function writeJsonAndReport(filePath, agentLabel, entry, opts = {}) {
2909
3038
 
2910
3039
  // src/cli/commands/mcp.ts
2911
3040
  async function mcpCommand() {
2912
- reconcileMemoryRules();
2913
3041
  const readCredentials = createReadCredentials(() => getDefaultKeychain());
2914
- const onStdinEnd = new Promise((resolve3) => {
2915
- process.stdin.once("end", resolve3);
2916
- process.stdin.once("close", resolve3);
2917
- });
2918
3042
  try {
2919
- await Promise.race([runMcpProxyServer({ readCredentials }), onStdinEnd]);
3043
+ await runMcpProxyServer({
3044
+ readCredentials,
3045
+ onConnected: (client) => syncMemoryRulesFromServer(client)
3046
+ });
2920
3047
  return EXIT.OK;
2921
3048
  } catch (err) {
2922
3049
  process.stderr.write(`Internal error: ${err instanceof Error ? err.message : String(err)}
@@ -3370,6 +3497,10 @@ Commands:
3370
3497
  your other content is preserved) so memory fires by
3371
3498
  default. Pass --no-rules to skip that write.
3372
3499
  Targets: claude-code, codex, cursor, cline, continue, windsurf, gemini-cli, pi, oh-my-pi, openclaw, hermes.
3500
+ mcp rules <target> Write or refresh only the always-on rules for
3501
+ claude-code, codex, gemini-cli, or oh-my-pi (no MCP
3502
+ registration). Honors CLAUDE_CONFIG_DIR / CODEX_HOME;
3503
+ 'pyx-mem mcp' keeps them current from the server.
3373
3504
 
3374
3505
  Notes:
3375
3506
  - Credentials are stored only in the OS credential store (Keychain / libsecret / Credential Manager).
@@ -3473,6 +3604,13 @@ function runMcpCommand(parsed) {
3473
3604
  parsed.flags["no-rules"] === true
3474
3605
  );
3475
3606
  }
3607
+ if (parsed.subcommand === "rules") {
3608
+ if (Object.keys(parsed.flags).length > 0) {
3609
+ process.stderr.write("Error: `pyx-mem mcp rules <host>` takes no flags.\n");
3610
+ return EXIT.USAGE;
3611
+ }
3612
+ return installMemoryRulesOnly(parsed.positional[0]);
3613
+ }
3476
3614
  process.stderr.write(
3477
3615
  `Error: unknown subcommand \`mcp ${parsed.subcommand}\`. Run \`pyx-mem --help\`.
3478
3616
  `
@@ -11,10 +11,10 @@ import {
11
11
  toGraphologyFormat,
12
12
  transformGraphData,
13
13
  unreachableHealth
14
- } from "./chunk-QWLTZIIK.mjs";
15
- import "./chunk-HVJZDJGH.mjs";
14
+ } from "./chunk-7YHCNO3N.mjs";
15
+ import "./chunk-SGL73IY5.mjs";
16
16
  import "./chunk-KZKGRND2.mjs";
17
- import "./chunk-BUKDWHTY.mjs";
17
+ import "./chunk-C46EE5BH.mjs";
18
18
  export {
19
19
  DashboardClient,
20
20
  Poller,
@@ -186,6 +186,11 @@ declare const DATA_PLANE_OPERATION_COVERAGE: {
186
186
  readonly reasonCode: "nonchargeable_operation";
187
187
  readonly reason: "status is nonchargeable and must bypass data-plane reservation";
188
188
  };
189
+ readonly 'mcp:get_memory_rules': {
190
+ readonly support: "not_execution_ready";
191
+ readonly reasonCode: "nonchargeable_operation";
192
+ readonly reason: "the rules text is nonchargeable and must bypass data-plane reservation";
193
+ };
189
194
  readonly 'mcp:get_user_profile': {
190
195
  readonly support: "sqlite_atomic_one_step";
191
196
  };
@@ -1 +1 @@
1
- export { C as CanonicalDataPlaneObject, a as CanonicalDataPlaneValue, b as CompileContext, c as CompileDataPlaneRequest, d as CompileDataPlaneResult, f as CompiledDataPlaneExecutionPlan, D as DATA_PLANE_CATALOG_VERSION, g as DATA_PLANE_COMPILER_LIMITS, h as DATA_PLANE_CONTRACT_VERSION, i as DATA_PLANE_HTTP_RESPONSE_FRAME, j as DATA_PLANE_MANIFEST_FRAME, k as DATA_PLANE_MANIFEST_VERSION, l as DATA_PLANE_OPERATION_COVERAGE, m as DATA_PLANE_SEARCH_EMBEDDING_CONTRACT, n as DATA_PLANE_STEP_INPUT_FRAME, o as DataPlaneCatalogOperation, q as DataPlaneUnsupportedReasonCode, S as SupportedDataPlaneCatalogOperation, r as canonicalDataPlaneJson, s as compileDataPlaneRequest, t as hashDataPlaneHttpResponseV1, u as hashDataPlaneManifestV1, v as hashDataPlaneStepInputV1 } from './data-plane-contract-webbeMs5.js';
1
+ export { C as CanonicalDataPlaneObject, a as CanonicalDataPlaneValue, b as CompileContext, c as CompileDataPlaneRequest, d as CompileDataPlaneResult, f as CompiledDataPlaneExecutionPlan, D as DATA_PLANE_CATALOG_VERSION, g as DATA_PLANE_COMPILER_LIMITS, h as DATA_PLANE_CONTRACT_VERSION, i as DATA_PLANE_HTTP_RESPONSE_FRAME, j as DATA_PLANE_MANIFEST_FRAME, k as DATA_PLANE_MANIFEST_VERSION, l as DATA_PLANE_OPERATION_COVERAGE, m as DATA_PLANE_SEARCH_EMBEDDING_CONTRACT, n as DATA_PLANE_STEP_INPUT_FRAME, o as DataPlaneCatalogOperation, q as DataPlaneUnsupportedReasonCode, S as SupportedDataPlaneCatalogOperation, r as canonicalDataPlaneJson, s as compileDataPlaneRequest, t as hashDataPlaneHttpResponseV1, u as hashDataPlaneManifestV1, v as hashDataPlaneStepInputV1 } from './data-plane-contract-C5VqxrpF.js';
@@ -13,7 +13,7 @@ import {
13
13
  hashDataPlaneHttpResponseV1,
14
14
  hashDataPlaneManifestV1,
15
15
  hashDataPlaneStepInputV1
16
- } from "./chunk-BUKDWHTY.mjs";
16
+ } from "./chunk-C46EE5BH.mjs";
17
17
  export {
18
18
  DATA_PLANE_CATALOG_VERSION,
19
19
  DATA_PLANE_COMPILER_LIMITS,
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { StoreInput as StoreInput$1, MemoryEntry as MemoryEntry$1, MemorySearchParams as MemorySearchParams$1, MemorySearchResult as MemorySearchResult$1, MemoryType as MemoryType$1, PrincipalContext as PrincipalContext$1, SensitivityLevel as SensitivityLevel$1, MemoryStats as MemoryStats$1, MemoryInsights as MemoryInsights$1, LineageParams as LineageParams$1, LineageResult as LineageResult$1, ReinforceParams as ReinforceParams$1, ReinforceResult as ReinforceResult$1, WikiLintReport as WikiLintReport$1, GraphRepairResult as GraphRepairResult$1, ExtractedImageMeta as ExtractedImageMeta$1, IngestEntity as IngestEntity$1, IngestRelationship as IngestRelationship$1, EntityExtractionResult as EntityExtractionResult$1, Topology as Topology$1, IngestEvent as IngestEvent$1, GraphEnrichEvent as GraphEnrichEvent$1, GraphNode as GraphNode$1, GraphTraversalResult as GraphTraversalResult$1, CorrectionRecord as CorrectionRecord$1 } from '@pyx-memory/shared';
2
2
  export { documentContentSource, documentGraphSource, documentImageSource } from '@pyx-memory/shared';
3
- export { e as encodeListCursorToken, p as parseListCursorToken } from './data-plane-contract-webbeMs5.js';
3
+ export { e as encodeListCursorToken, p as parseListCursorToken } from './data-plane-contract-C5VqxrpF.js';
4
4
 
5
5
  /** ISO 8601 timestamp string */
6
6
  type Timestamp = string;
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  DisabledMemory,
3
3
  MemoryClient,
4
4
  MemoryServerError
5
- } from "./chunk-HVJZDJGH.mjs";
5
+ } from "./chunk-SGL73IY5.mjs";
6
6
  import {
7
7
  DEFAULTS,
8
8
  MEMORY_PROJECT_LABEL_MAX_CHARS,
@@ -37,7 +37,7 @@ import {
37
37
  normalizeGraphLabel,
38
38
  normalizeNameKey,
39
39
  parseListCursorToken
40
- } from "./chunk-BUKDWHTY.mjs";
40
+ } from "./chunk-C46EE5BH.mjs";
41
41
 
42
42
  // src/preset.ts
43
43
  var DEFAULT_MEMORY_URL = `http://localhost:${DEFAULTS.MEMORY_SERVER_PORT}`;
package/dist/react.mjs CHANGED
@@ -11,10 +11,10 @@ import {
11
11
  toGraphologyFormat,
12
12
  transformGraphData,
13
13
  unreachableHealth
14
- } from "./chunk-QWLTZIIK.mjs";
15
- import "./chunk-HVJZDJGH.mjs";
14
+ } from "./chunk-7YHCNO3N.mjs";
15
+ import "./chunk-SGL73IY5.mjs";
16
16
  import "./chunk-KZKGRND2.mjs";
17
- import "./chunk-BUKDWHTY.mjs";
17
+ import "./chunk-C46EE5BH.mjs";
18
18
 
19
19
  // ../dashboard/src/hooks/use-consolidation-log.ts
20
20
  import { useCallback as useCallback2, useMemo } from "react";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyxmate/memory",
3
- "version": "1.22.3",
3
+ "version": "1.23.1",
4
4
  "type": "module",
5
5
  "description": "SDK for pyx-memory — Memory as a Service for AI agents",
6
6
  "license": "MIT",