@pyxmate/memory 1.17.17 → 1.17.19

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,4 +1,5 @@
1
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).";
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.";
2
3
  declare const PERSISTENT_MEMORY_SECTION: string;
3
4
  declare function buildDesignGuide({ appName }: {
4
5
  appName: string;
@@ -37,4 +38,4 @@ declare const STRUCTURE_GRAPH_PROMPT_DESC = "Returns a prompt that extracts the
37
38
  declare function buildGraphStructuringPrompt(content: string): string;
38
39
  declare function buildAgentSnippet(): string;
39
40
 
40
- export { AGENT_TARGETS, PERSISTENT_MEMORY_SECTION, 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 };
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 };
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  AGENT_TARGETS,
3
3
  PERSISTENT_MEMORY_SECTION,
4
+ PYX_MEMORY_COMPANION_CORE_INSTRUCTIONS,
4
5
  PYX_MEMORY_INSTRUCTIONS,
5
6
  SEARCH_ENUMERATION_CONCEPT_DESC,
6
7
  SEARCH_LIMIT_DESC,
@@ -13,10 +14,11 @@ import {
13
14
  buildAgentSnippet,
14
15
  buildDesignGuide,
15
16
  buildGraphStructuringPrompt
16
- } from "./chunk-FQW6BQ2N.mjs";
17
+ } from "./chunk-EZERG25I.mjs";
17
18
  export {
18
19
  AGENT_TARGETS,
19
20
  PERSISTENT_MEMORY_SECTION,
21
+ PYX_MEMORY_COMPANION_CORE_INSTRUCTIONS,
20
22
  PYX_MEMORY_INSTRUCTIONS,
21
23
  SEARCH_ENUMERATION_CONCEPT_DESC,
22
24
  SEARCH_LIMIT_DESC,
@@ -1,5 +1,6 @@
1
1
  // src/contract/index.ts
2
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).`;
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.`;
3
4
  var PERSISTENT_MEMORY_SECTION = [
4
5
  "## Persistent Memory",
5
6
  "",
@@ -159,6 +160,7 @@ function buildAgentSnippet() {
159
160
 
160
161
  export {
161
162
  PYX_MEMORY_INSTRUCTIONS,
163
+ PYX_MEMORY_COMPANION_CORE_INSTRUCTIONS,
162
164
  PERSISTENT_MEMORY_SECTION,
163
165
  buildDesignGuide,
164
166
  AGENT_TARGETS,
@@ -358,6 +358,15 @@ var MemoryClient = class {
358
358
  }
359
359
  return headers;
360
360
  }
361
+ exactReadAuthority(namespaceId, authority) {
362
+ if (namespaceId !== void 0 && authority?.namespaceId !== void 0 && namespaceId !== authority.namespaceId) {
363
+ throw new Error("X-Namespace-Id conflicts with the request authority scope");
364
+ }
365
+ return {
366
+ ...authority,
367
+ ...namespaceId !== void 0 ? { namespaceId } : {}
368
+ };
369
+ }
361
370
  async initialize() {
362
371
  const response = await fetch(`${this.baseUrl}/health`, {
363
372
  headers: this._authHeaders
@@ -415,7 +424,7 @@ var MemoryClient = class {
415
424
  if (params.abstentionThreshold != null)
416
425
  searchParams.set("abstentionThreshold", String(params.abstentionThreshold));
417
426
  return this.fetchApi(`/api/memory/search?${searchParams}`, {
418
- headers: this.authorityHeaders(authority)
427
+ headers: this.authorityHeaders(this.exactReadAuthority(params.namespaceId, authority))
419
428
  });
420
429
  }
421
430
  async get(id, authority) {
@@ -481,7 +490,7 @@ var MemoryClient = class {
481
490
  }
482
491
  const qs = searchParams.toString();
483
492
  return this.fetchApi(`/api/memory/entries${qs ? `?${qs}` : ""}`, {
484
- headers: this.authorityHeaders(authority)
493
+ headers: this.authorityHeaders(this.exactReadAuthority(params.namespaceId, authority))
485
494
  });
486
495
  }
487
496
  // --- File ingest ---
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MemoryClient
3
- } from "./chunk-JGFDID3B.mjs";
3
+ } from "./chunk-H6ZLMPZH.mjs";
4
4
 
5
5
  // ../dashboard/src/aggregations/consolidation-analytics.ts
6
6
  function analyzeConsolidationLog(entries) {
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  PERSISTENT_MEMORY_SECTION,
4
4
  buildDesignGuide
5
- } from "../chunk-FQW6BQ2N.mjs";
5
+ } from "../chunk-EZERG25I.mjs";
6
6
 
7
7
  // src/cli/exit-codes.ts
8
8
  var EXIT = {
@@ -836,7 +836,7 @@ function createProxyServer(client, version, uploadLocalFile) {
836
836
  return server;
837
837
  }
838
838
  async function runMcpProxyServer(opts) {
839
- const version = opts.version ?? (true ? "1.17.17" : "0.0.0-dev");
839
+ const version = opts.version ?? (true ? "1.17.19" : "0.0.0-dev");
840
840
  const read = await opts.readCredentials();
841
841
  if (!read.ok) {
842
842
  const text = read.result.content.map((c) => c.type === "text" ? c.text : "").join(" ").trim();
@@ -1540,6 +1540,147 @@ function resolveMcpMode(flags) {
1540
1540
  return { ok: true };
1541
1541
  }
1542
1542
 
1543
+ // src/cli/commands/overview.ts
1544
+ import { randomUUID as randomUUID3 } from "crypto";
1545
+ import { z } from "zod";
1546
+ var OVERVIEW_SCHEMA_VERSION = 1;
1547
+ var RECENT_ENTRY_LIMIT = 3;
1548
+ var MAX_TOPIC_CHARS = 160;
1549
+ var MAX_PROJECT_CHARS = 80;
1550
+ var entrySchema = z.object({
1551
+ id: z.string().min(1),
1552
+ metadata: z.record(z.string(), z.unknown())
1553
+ }).passthrough();
1554
+ var hostedEntriesResponseSchema = z.object({
1555
+ memories: z.array(entrySchema),
1556
+ total: z.number().int().nonnegative()
1557
+ }).passthrough();
1558
+ var selfHostedEntriesResponseSchema = z.object({
1559
+ success: z.literal(true),
1560
+ data: z.object({
1561
+ entries: z.array(entrySchema),
1562
+ totalCount: z.number().int().nonnegative()
1563
+ }).passthrough()
1564
+ }).passthrough();
1565
+ var entriesResponseSchema = z.union([
1566
+ hostedEntriesResponseSchema.transform(({ memories, total }) => ({
1567
+ entries: memories,
1568
+ totalCount: total
1569
+ })),
1570
+ selfHostedEntriesResponseSchema.transform(({ data }) => data)
1571
+ ]);
1572
+ async function overviewCommand(opts = {}) {
1573
+ const provider = opts.keychain ?? getDefaultKeychain();
1574
+ let credentials;
1575
+ try {
1576
+ credentials = await provider.read();
1577
+ } catch (error) {
1578
+ const detail = error instanceof KeychainError ? [error.message, error.guidance].filter(Boolean).join(" ") : "The OS credential store could not be read.";
1579
+ emit(report("error", null, null, detail));
1580
+ return error instanceof KeychainError ? error.exit : EXIT.CRED_UNAVAILABLE;
1581
+ }
1582
+ if (!credentials) {
1583
+ emit(report("signed_out", null, null, null));
1584
+ return EXIT.NOT_LOGGED_IN;
1585
+ }
1586
+ if (!isHttpUrl2(credentials.endpoint)) {
1587
+ emit(
1588
+ report(
1589
+ "error",
1590
+ null,
1591
+ "keychain",
1592
+ "The stored pyx-memory endpoint is invalid. Run: pyx-mem login"
1593
+ )
1594
+ );
1595
+ return EXIT.DOCTOR_FAIL;
1596
+ }
1597
+ const http = createHttpClient(credentials, opts.fetchImpl ?? fetch);
1598
+ const response = await http.requestJson({
1599
+ method: "GET",
1600
+ path: "/api/memory/entries",
1601
+ query: { status: "active", limit: RECENT_ENTRY_LIMIT },
1602
+ idempotencyKey: `cli-overview-${randomUUID3()}`
1603
+ });
1604
+ if (!response.ok) {
1605
+ const signedOut = response.status === 401;
1606
+ emit(
1607
+ report(
1608
+ signedOut ? "signed_out" : "error",
1609
+ credentials.endpoint,
1610
+ "keychain",
1611
+ overviewFailure(response.status)
1612
+ )
1613
+ );
1614
+ return signedOut ? EXIT.NOT_LOGGED_IN : EXIT.DOCTOR_FAIL;
1615
+ }
1616
+ const parsed = entriesResponseSchema.safeParse(response.data);
1617
+ if (!parsed.success) {
1618
+ emit(
1619
+ report(
1620
+ "error",
1621
+ credentials.endpoint,
1622
+ "keychain",
1623
+ "pyx-memory returned an invalid overview response. Run: pyx-mem doctor"
1624
+ )
1625
+ );
1626
+ return EXIT.DOCTOR_FAIL;
1627
+ }
1628
+ emit({
1629
+ ...report("ready", credentials.endpoint, "keychain", null),
1630
+ totalCount: parsed.data.totalCount,
1631
+ entries: parsed.data.entries.slice(0, RECENT_ENTRY_LIMIT).map((entry) => ({
1632
+ id: entry.id,
1633
+ topic: boundedLabel(entry.metadata.topic, "Untitled", MAX_TOPIC_CHARS),
1634
+ project: boundedLabel(entry.metadata.project, "Unscoped", MAX_PROJECT_CHARS)
1635
+ }))
1636
+ });
1637
+ return EXIT.OK;
1638
+ }
1639
+ function report(state, endpoint, keySource, problem) {
1640
+ return {
1641
+ schemaVersion: OVERVIEW_SCHEMA_VERSION,
1642
+ state,
1643
+ endpoint,
1644
+ keySource,
1645
+ totalCount: 0,
1646
+ entries: [],
1647
+ problem
1648
+ };
1649
+ }
1650
+ function emit(value) {
1651
+ process.stdout.write(`${JSON.stringify(value)}
1652
+ `);
1653
+ }
1654
+ function overviewFailure(status) {
1655
+ if (status === 401) {
1656
+ return "Stored pyx-memory credentials were rejected. Run: pyx-mem login";
1657
+ }
1658
+ if (status === 403) {
1659
+ return "pyx-memory denied access (HTTP 403). Check the key scope and project access.";
1660
+ }
1661
+ if (status === void 0) {
1662
+ return "Unable to reach pyx-memory. Run: pyx-mem doctor";
1663
+ }
1664
+ if (status >= 500) {
1665
+ return `pyx-memory is unavailable (HTTP ${status}). Run: pyx-mem doctor`;
1666
+ }
1667
+ return `pyx-memory overview failed (HTTP ${status}). Run: pyx-mem doctor`;
1668
+ }
1669
+ function boundedLabel(value, fallback, maxChars) {
1670
+ if (typeof value !== "string" || value.trim().length === 0) return fallback;
1671
+ const normalized = value.trim();
1672
+ const chars = [...normalized];
1673
+ return chars.length > maxChars ? `${chars.slice(0, maxChars).join("")}\u2026` : normalized;
1674
+ }
1675
+ function isHttpUrl2(value) {
1676
+ try {
1677
+ const url = new URL(value);
1678
+ return url.protocol === "http:" || url.protocol === "https:";
1679
+ } catch {
1680
+ return false;
1681
+ }
1682
+ }
1683
+
1543
1684
  // src/cli/commands/scaffold.ts
1544
1685
  import { existsSync as existsSync4, mkdirSync as mkdirSync3, statSync as statSync2, writeFileSync as writeFileSync3 } from "fs";
1545
1686
  import { basename as basename2, join as join2, resolve as resolve2 } from "path";
@@ -1720,10 +1861,10 @@ function scaffoldCommand(args = {}) {
1720
1861
  // src/cli/commands/status.ts
1721
1862
  async function statusCommand(opts = {}) {
1722
1863
  const provider = opts.keychain ?? getDefaultKeychain();
1723
- let report;
1864
+ let report2;
1724
1865
  try {
1725
1866
  const creds = await provider.read();
1726
- report = {
1867
+ report2 = {
1727
1868
  endpoint: creds?.endpoint ?? null,
1728
1869
  keyPresent: creds !== null,
1729
1870
  keySource: creds !== null ? "keychain" : null,
@@ -1734,17 +1875,17 @@ async function statusCommand(opts = {}) {
1734
1875
  throw err;
1735
1876
  }
1736
1877
  if (opts.json) {
1737
- process.stdout.write(`${JSON.stringify(report)}
1878
+ process.stdout.write(`${JSON.stringify(report2)}
1738
1879
  `);
1739
1880
  } else {
1740
1881
  const lines = [
1741
- `endpoint: ${report.endpoint ?? "(not set)"}`,
1742
- `credentials: ${report.loggedIn ? "present (keychain)" : "not logged in \u2014 run: pyx-mem login"}`
1882
+ `endpoint: ${report2.endpoint ?? "(not set)"}`,
1883
+ `credentials: ${report2.loggedIn ? "present (keychain)" : "not logged in \u2014 run: pyx-mem login"}`
1743
1884
  ];
1744
1885
  process.stdout.write(`${lines.join("\n")}
1745
1886
  `);
1746
1887
  }
1747
- return report.loggedIn ? EXIT.OK : EXIT.NOT_LOGGED_IN;
1888
+ return report2.loggedIn ? EXIT.OK : EXIT.NOT_LOGGED_IN;
1748
1889
  }
1749
1890
  function emitError(err, json) {
1750
1891
  if (json) {
@@ -1769,6 +1910,7 @@ Usage:
1769
1910
  Commands:
1770
1911
  login [--endpoint <url>] [--api-key <key>] Store endpoint and API key in OS credential store.
1771
1912
  status [--json] Show endpoint, key presence, MCP config status.
1913
+ overview --json Read memory count and three recent safe labels.
1772
1914
  logout Delete stored pyx-memory credentials.
1773
1915
  doctor [--json] Diagnose keychain, credentials, backend, MCP startup.
1774
1916
  scaffold [--name <dir>] Generate Docker, env, SDK, and memory design-guide starter files.
@@ -1915,6 +2057,12 @@ async function main() {
1915
2057
  });
1916
2058
  case "status":
1917
2059
  return statusCommand({ json: parsed.flags.json === true });
2060
+ case "overview":
2061
+ if (parsed.flags.json !== true) {
2062
+ process.stderr.write("Error: `pyx-mem overview` requires --json.\n");
2063
+ return EXIT.USAGE;
2064
+ }
2065
+ return overviewCommand();
1918
2066
  case "logout":
1919
2067
  return logoutCommand();
1920
2068
  case "doctor":
@@ -1932,10 +2080,10 @@ async function main() {
1932
2080
  }
1933
2081
  }
1934
2082
  main().then((code) => {
1935
- process.exit(code);
2083
+ process.exitCode = code;
1936
2084
  }).catch((err) => {
1937
2085
  const msg = err instanceof Error ? err.message : String(err);
1938
2086
  process.stderr.write(`Internal error: ${msg}
1939
2087
  `);
1940
- process.exit(1);
2088
+ process.exitCode = 1;
1941
2089
  });
@@ -11,8 +11,8 @@ import {
11
11
  toGraphologyFormat,
12
12
  transformGraphData,
13
13
  unreachableHealth
14
- } from "./chunk-AMKPOPH6.mjs";
15
- import "./chunk-JGFDID3B.mjs";
14
+ } from "./chunk-T35ZOOES.mjs";
15
+ import "./chunk-H6ZLMPZH.mjs";
16
16
  import "./chunk-3OLH3HYR.mjs";
17
17
  export {
18
18
  DashboardClient,
package/dist/index.d.ts CHANGED
@@ -28,6 +28,8 @@ interface MemoryListParams {
28
28
  agentId?: string;
29
29
  /** Filter by tenant ID for multi-tenant isolation. */
30
30
  tenantId?: string;
31
+ /** Exact namespace scope. Excludes legacy tenant-root entries. */
32
+ namespaceId?: string;
31
33
  /**
32
34
  * Calling principal. When supplied, list applies the AuthzPlan
33
35
  * visibility filter so entries in forbidden namespaces never reach
@@ -385,9 +387,10 @@ declare class MemoryClient implements ExtendedMemoryInterface {
385
387
  /** Encode a path segment to prevent URL injection */
386
388
  private encodePathSegment;
387
389
  private authorityHeaders;
390
+ private exactReadAuthority;
388
391
  initialize(): Promise<void>;
389
392
  store(entry: StoreInput$1, options?: StoreOptions): Promise<MemoryEntry$1>;
390
- search(params: MemorySearchParams$1, authority?: RequestAuthorityOptions): Promise<MemorySearchResult$1>;
393
+ search(params: MemorySearchParams$1, authority?: RequestAuthorityOptions & Pick<TenantScopeOptions, 'tenantId' | 'namespaceId'>): Promise<MemorySearchResult$1>;
391
394
  get(id: string, authority?: TenantScopeOptions & RequestAuthorityOptions): Promise<MemoryEntry$1 | null>;
392
395
  delete(id: string, authority?: TenantScopeOptions & RequestAuthorityOptions): Promise<boolean>;
393
396
  clearSession(sessionId: string): Promise<number>;
@@ -403,7 +406,7 @@ declare class MemoryClient implements ExtendedMemoryInterface {
403
406
  */
404
407
  status(): Promise<Topology$1>;
405
408
  shutdown(): Promise<void>;
406
- list(params?: MemoryListParams, authority?: RequestAuthorityOptions): Promise<MemoryListResult>;
409
+ list(params?: MemoryListParams, authority?: RequestAuthorityOptions & Pick<TenantScopeOptions, 'tenantId' | 'namespaceId'>): Promise<MemoryListResult>;
407
410
  /**
408
411
  * Native streaming file ingest. Yields typed {@link IngestEvent}s as the
409
412
  * server (parsing/storing) and the SDK (enrichment/result) make progress.
@@ -921,6 +924,12 @@ interface MemorySearchParams {
921
924
  userId?: string;
922
925
  /** Team/group ID within the tenant. */
923
926
  teamId?: string;
927
+ /**
928
+ * Exact namespace requested by a trusted transport boundary. `Memory.search`
929
+ * validates it against the calling principal's AuthzPlan and compiles it to
930
+ * a singleton prefilter. Exact scope excludes legacy NULL rows.
931
+ */
932
+ namespaceId?: string;
924
933
  /**
925
934
  * AuthzPlan-derived visibility list. Populated internally by `Memory.search`
926
935
  * after computing the plan from the calling principal — callers should
@@ -928,15 +937,11 @@ interface MemorySearchParams {
928
937
  * legacy NULL-namespace entries are visible). `undefined` skips the
929
938
  * filter (single-tenant / pre-ReBAC compat).
930
939
  *
931
- * "Search within this specific folder" UX is intentionally NOT supported
932
- * via a singular `namespaceId` field for v1 — adding it would force
933
- * intersection logic with the visibility list (and confused-deputy risk
934
- * if the singular value isn't validated against the plan). Callers that
935
- * need it can compute the singleton intersection client-side and pass
936
- * `namespaceIds: [chosenNamespace]` after verifying access via the
937
- * admin API.
940
+ * Callers must not set this directly; use `namespaceId` for exact scope.
938
941
  */
939
942
  namespaceIds?: string[];
943
+ /** Strict namespace equality compiled internally from `namespaceId`. */
944
+ exactNamespaceId?: string;
940
945
  /**
941
946
  * AuthzPlan-derived list of strict-mode namespaces in the caller's
942
947
  * tenant the principal CANNOT see (v0.17.0). Graph traversal MUST
package/dist/index.mjs CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  secretElevationAggregate,
22
22
  secretElevationNoticeFor,
23
23
  withSecretElevationNotice
24
- } from "./chunk-JGFDID3B.mjs";
24
+ } from "./chunk-H6ZLMPZH.mjs";
25
25
  import {
26
26
  assertGraphExtractionPayload,
27
27
  encodeListCursorToken,
package/dist/react.mjs CHANGED
@@ -11,8 +11,8 @@ import {
11
11
  toGraphologyFormat,
12
12
  transformGraphData,
13
13
  unreachableHealth
14
- } from "./chunk-AMKPOPH6.mjs";
15
- import "./chunk-JGFDID3B.mjs";
14
+ } from "./chunk-T35ZOOES.mjs";
15
+ import "./chunk-H6ZLMPZH.mjs";
16
16
  import "./chunk-3OLH3HYR.mjs";
17
17
 
18
18
  // ../dashboard/src/hooks/use-consolidation-log.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyxmate/memory",
3
- "version": "1.17.17",
3
+ "version": "1.17.19",
4
4
  "type": "module",
5
5
  "description": "SDK for pyx-memory — Memory as a Service for AI agents",
6
6
  "license": "MIT",