@pyxmate/memory 0.20.4 → 0.21.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.
@@ -13,6 +13,7 @@ import {
13
13
  unreachableHealth
14
14
  } from "./chunk-4DRKAXJE.mjs";
15
15
  import "./chunk-D5PMQYZM.mjs";
16
+ import "./chunk-7P6ASYW6.mjs";
16
17
  export {
17
18
  DashboardClient,
18
19
  Poller,
package/dist/index.mjs CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  MemoryClient,
3
3
  MemoryServerError
4
4
  } from "./chunk-D5PMQYZM.mjs";
5
+ import "./chunk-7P6ASYW6.mjs";
5
6
 
6
7
  // ../shared/src/constants/defaults.ts
7
8
  var DEFAULTS = {
package/dist/react.mjs CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  unreachableHealth
14
14
  } from "./chunk-4DRKAXJE.mjs";
15
15
  import "./chunk-D5PMQYZM.mjs";
16
+ import "./chunk-7P6ASYW6.mjs";
16
17
 
17
18
  // ../dashboard/src/hooks/use-consolidation-log.ts
18
19
  import { useCallback as useCallback2, useMemo } from "react";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyxmate/memory",
3
- "version": "0.20.4",
3
+ "version": "0.21.1",
4
4
  "type": "module",
5
5
  "description": "SDK for pyx-memory — Memory as a Service for AI agents",
6
6
  "license": "MIT",
@@ -34,17 +34,16 @@
34
34
  }
35
35
  },
36
36
  "bin": {
37
- "pyxmate-memory": "./bin/init.mjs"
37
+ "pyx-mem": "./dist/cli/pyx-mem.mjs"
38
38
  },
39
39
  "files": [
40
40
  "dist",
41
- "bin",
42
- "skills",
43
41
  "README.md",
44
42
  "LICENSE"
45
43
  ],
46
44
  "scripts": {
47
45
  "build": "tsup",
46
+ "test": "bun test",
48
47
  "typecheck": "tsc --noEmit",
49
48
  "clean": "rm -rf dist skills node_modules .turbo"
50
49
  },
@@ -56,6 +55,10 @@
56
55
  "optional": true
57
56
  }
58
57
  },
58
+ "dependencies": {
59
+ "@modelcontextprotocol/sdk": "^1.29.0",
60
+ "@napi-rs/keyring": "^1.3.0"
61
+ },
59
62
  "devDependencies": {
60
63
  "tsup": "^8.4.0"
61
64
  }
package/bin/init.mjs DELETED
@@ -1,63 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { cpSync, existsSync, mkdirSync, readdirSync } from 'node:fs';
4
- import { dirname, join, resolve } from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
-
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
-
9
- const command = process.argv[2];
10
-
11
- if (command !== 'init') {
12
- console.log(`Usage: pyxmate-memory init
13
-
14
- Commands:
15
- init Copy pyx-memory skill files into .claude/skills/ for Claude Code auto-discovery`);
16
- process.exit(command ? 1 : 0);
17
- }
18
-
19
- const source = resolve(__dirname, '..', 'skills', 'pyx-memory');
20
- const target = resolve(process.cwd(), '.claude', 'skills', 'pyx-memory');
21
-
22
- if (!existsSync(source)) {
23
- console.error('Error: Skills directory not found in package. Please reinstall @pyxmate/memory.');
24
- process.exit(1);
25
- }
26
-
27
- // Ensure target parent exists
28
- mkdirSync(dirname(target), { recursive: true });
29
-
30
- // Copy skills (overwrites existing files for idempotency)
31
- cpSync(source, target, { recursive: true });
32
-
33
- // Count copied files
34
- function countFiles(dir) {
35
- let count = 0;
36
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
37
- if (entry.isDirectory()) {
38
- count += countFiles(join(dir, entry.name));
39
- } else {
40
- count++;
41
- }
42
- }
43
- return count;
44
- }
45
-
46
- function listFiles(dir, prefix = '') {
47
- const lines = [];
48
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
49
- if (entry.isDirectory()) {
50
- lines.push(...listFiles(join(dir, entry.name), `${prefix}${entry.name}/`));
51
- } else {
52
- lines.push(` ${prefix}${entry.name}`);
53
- }
54
- }
55
- return lines;
56
- }
57
-
58
- const fileCount = countFiles(target);
59
- const fileList = listFiles(target);
60
-
61
- console.log(`Copied ${fileCount} skill files to .claude/skills/pyx-memory/\n`);
62
- console.log(fileList.join('\n'));
63
- console.log('\nClaude Code will now auto-discover pyx-memory integration patterns.');
@@ -1,143 +0,0 @@
1
- ---
2
- name: pyx-memory
3
- description: >
4
- Persistent memory system for AI agents — store and retrieve knowledge across
5
- conversations via pyx-memory. Use this skill whenever you need to remember
6
- something for later, recall what was discussed or decided in a prior session,
7
- search stored memory before assuming, store a decision or bug-fix root cause,
8
- or ingest files, documents, or images into long-term memory. Also use it for
9
- the lifecycle and wiki primitives: building a per-entity profile or "wiki
10
- page" (summarizeEntity / getEntitySynthesis — an amortized "tell me about
11
- X / give me a profile of this customer" synthesis that is computed once and
12
- reused); browsing a chronological feed of what was added and when (memory
13
- log — "what has the agent learned", "what's new since last week"); linting
14
- memory health (orphaned graph nodes, stale syntheses, dedup candidates); and
15
- consolidation, decay, or session summarization. Use it for any integration
16
- work with the pyx-memory SDK, MemoryClient, or HTTP API — including
17
- multi-tenant isolation, fine-grained ReBAC (namespaces, principals, authz
18
- tuples, AuthzPlan), sensitivity classification, encryption at rest, and
19
- confidence/abstention scoring. Trigger this skill even when the user does
20
- not say "pyx-memory" by name: phrases like "remember this", "what did we
21
- decide", "recall earlier context", "store this decision", "search memory",
22
- "give me a profile of <person/customer>", "summarize everything we know
23
- about X", "what has the agent learned", or "set up per-agent / per-tenant
24
- memory isolation" all indicate this skill should be used. When in doubt
25
- about whether a request involves agent memory, prefer using this skill.
26
- allowed-tools: Read, Grep, Glob, Edit, Write, Bash(curl *)
27
- argument-hint: "[store|search|ingest] <content or query>"
28
- ---
29
-
30
- # pyx-memory — Agent Memory System
31
-
32
- Persistent memory across conversations. Store what you learn, search before you assume.
33
-
34
- ## Configuration
35
-
36
- Your endpoint and API key are in the project's CLAUDE.md or agent config. Look for a `## Persistent Memory` or `## Memory System` section.
37
-
38
- If no credentials are configured, skip to [SDK Integration](#sdk-integration) below.
39
-
40
- ## Store: after important events
41
-
42
- Immediately after any of these events, store a memory before continuing:
43
-
44
- - **User corrects you** ("no, do it this way", "don't use X") → store the correction and why
45
- - **A bug is fixed** → store the root cause and solution
46
- - **An architecture or design decision is made** → store the decision and reasoning
47
- - **An integration detail is discovered** (API format, auth flow, endpoint) → store it
48
- - **A gotcha or pitfall is encountered** → store what went wrong and the fix
49
- - **The user states a preference** about workflow or tools → store it
50
- - **The user explicitly says "remember this"** → store immediately
51
-
52
- ```bash
53
- curl -s -X POST {{ENDPOINT}}/api/memory/ingest \
54
- -H "Authorization: Bearer {{API_KEY}}" \
55
- -H "Content-Type: application/json" \
56
- -d '{"content":"WHAT_HAPPENED","type":"long-term","metadata":{"source":"agent","topic":"TOPIC","project":"PROJECT_NAME"}}'
57
- ```
58
-
59
- **Multi-tenant mode**: When the server uses `TENANT_MODE=multi`, include `X-Tenant-Id` on all requests:
60
-
61
- ```bash
62
- curl -s -X POST {{ENDPOINT}}/api/memory/ingest \
63
- -H "Authorization: Bearer {{API_KEY}}" \
64
- -H "Content-Type: application/json" \
65
- -H "X-Tenant-Id: {{TENANT_ID}}" \
66
- -d '{"content":"WHAT_HAPPENED","type":"long-term","metadata":{"source":"agent","topic":"TOPIC","project":"PROJECT_NAME"}}'
67
- ```
68
-
69
- When the memory mentions specific people, tools, organizations, or other named subjects, also include `entities` and `relationships` to populate the knowledge graph. See [reference/http-api.md](reference/http-api.md) for entity types, relationship types, and examples.
70
-
71
- ## Search: before making assumptions
72
-
73
- Search for relevant context in these situations:
74
-
75
- - **Starting a new conversation or task** → search for the project name and task topic
76
- - **Before suggesting an approach** → check if a prior decision contradicts it
77
- - **User references prior work** ("like we did before", "remember when") → search for it
78
- - **Investigating a bug** → search if it was seen before
79
-
80
- ```bash
81
- curl -s "{{ENDPOINT}}/api/memory/search?q=QUERY&limit=5" \
82
- -H "Authorization: Bearer {{API_KEY}}"
83
- ```
84
-
85
- **Multi-tenant mode**: Add `-H "X-Tenant-Id: {{TENANT_ID}}"` to scope search results to the tenant.
86
-
87
- ## Ingest files & images: when a file is worth remembering
88
-
89
- Upload files directly when the content is worth persisting — diagrams, screenshots, documents, data files.
90
-
91
- - **User shares a document or image** and says "remember this" or "store this" → ingest it
92
- - **A screenshot captures important context** (error screen, architecture diagram, UI state) → ingest with a description
93
- - **A document contains reference material** (spec, config, report) → ingest it
94
-
95
- ```bash
96
- curl -s -X POST {{ENDPOINT}}/api/memory/ingest/file \
97
- -H "Authorization: Bearer {{API_KEY}}" \
98
- -F "file=@path/to/file" \
99
- -F "description=What this file contains or shows"
100
- ```
101
-
102
- Supported formats: txt, md, csv, tsv, log, pdf, docx, xlsx, pptx, json, jsonl, html, htm, png, jpg, jpeg, webp, gif, bmp, tiff, svg (100MB limit).
103
-
104
- Ingestion memory profile, by format:
105
-
106
- - **Plain-text + structured-text** (`csv`, `tsv`, `txt`, `log`, `json`, `jsonl`, `html`, `htm`, `md`): truly streaming — peak memory ≈ a few MB regardless of file size, up to the 100 MB file cap.
107
- - **`pdf`**: streaming via the poppler `pdftotext` first-class path — peak memory ≈ a few MB. The `pdf-parse` fallback (when poppler is absent) loads the whole buffer; install poppler-utils for streaming.
108
- - **`xlsx`**: row-by-row streaming via `ExcelJS.stream.xlsx.WorkbookReader`, but **shared strings are cached for the whole workbook** (`sharedStrings: 'cache'`). Peak memory grows with shared-string count, not just file size — workbooks with dense, repeated cell strings can use significantly more memory than the file cap suggests.
109
- - **`pptx`**: the full ZIP is decompressed in memory (same shape as docx); only one slide's XML is decoded at a time. For a typical 30 MB presentation, peak memory is ~90 MB. Capped at 100 MB file / 200 MB decompressed.
110
- - **`docx`**: hard-capped at 10 MB. The underlying library (mammoth) has no streaming API and loads the whole document into memory; above 10 MB the server returns a `MemoryError` asking you to pre-extract the text upstream and re-upload as `.txt` or `.md`.
111
- - **Images** (`png`, `jpg`, `jpeg`, `webp`, `gif`, `bmp`, `tiff`, `svg`): the file is held in memory once for embedding/storage; size scales with the file, not with content complexity.
112
-
113
- If you need deterministic memory or timing for production UX (e.g. RAG over large user-supplied workbooks), prefer pre-extracting `.pptx` and large `.xlsx` upstream and uploading the text as `.txt`. See `patterns/file-uploads.md` for the consumer-side pattern.
114
-
115
- **Images require a `description`** — this is how the content gets embedded and becomes searchable. Without it, the image is stored but not findable. Use your vision capabilities to generate the description when the user doesn't provide one.
116
-
117
- **Documents don't need a `description`** — text content is extracted and chunked automatically.
118
-
119
- ## Rules
120
-
121
- - Always include `topic` and `project` in metadata
122
- - Keep content factual and concise — decisions, not deliberation
123
- - Do NOT store ephemeral info (file contents, current state, in-progress work)
124
- - One memory per concept — don't bundle unrelated things
125
- - Extract entities when content mentions specific people, tools, technologies, organizations, locations, or events by name
126
-
127
- ---
128
-
129
- ## SDK Integration
130
-
131
- For integrating pyx-memory into TypeScript/Bun projects, see the reference docs:
132
-
133
- | What you need | Where to look |
134
- |---|---|
135
- | Wire pyx-memory into a consumer project | [patterns/consumer.md](patterns/consumer.md) |
136
- | Set up embedded memory (full features) | [patterns/embedded.md](patterns/embedded.md) |
137
- | Multi-tenant, ReBAC (namespaces + tuples), sensitivity, encryption | [patterns/access-control.md](patterns/access-control.md) |
138
- | SDK quick start, package map, DO/DON'T | [reference/sdk-guide.md](reference/sdk-guide.md) |
139
- | HTTP API endpoints | [reference/http-api.md](reference/http-api.md) |
140
- | Type signatures and interfaces | [reference/types.md](reference/types.md) |
141
- | RAG strategies, bi-temporal, consolidation | [reference/advanced.md](reference/advanced.md) |
142
- | Feature parity: embedded vs sidecar | [reference/parity.md](reference/parity.md) |
143
- | Minimal code examples | [examples/](examples/) |
@@ -1,53 +0,0 @@
1
- import type { MemoryInterface, MemoryListResult } from '@pyx-memory/client';
2
- import type { MemoryEntry, MemorySearchResult, MemoryStats } from '@pyx-memory/shared';
3
-
4
- export class DisabledMemory implements MemoryInterface {
5
- async initialize(): Promise<void> {
6
- console.warn('Memory service not configured — running without memory');
7
- }
8
- async store(
9
- entry: Omit<MemoryEntry, 'id' | 'createdAt'> & { id?: string; createdAt?: string },
10
- ): Promise<MemoryEntry> {
11
- return {
12
- id: '',
13
- content: entry.content,
14
- type: entry.type,
15
- metadata: {},
16
- createdAt: new Date().toISOString(),
17
- };
18
- }
19
- async search(): Promise<MemorySearchResult> {
20
- return { entries: [], totalCount: 0, strategy: 'naive' };
21
- }
22
- async list(): Promise<MemoryListResult> {
23
- return { entries: [], totalCount: 0, page: 1, limit: 20 };
24
- }
25
- async get(): Promise<MemoryEntry | null> {
26
- return null;
27
- }
28
- async delete(): Promise<boolean> {
29
- return false;
30
- }
31
- async clearSession(): Promise<number> {
32
- return 0;
33
- }
34
- async stats(): Promise<MemoryStats> {
35
- return {
36
- totalEntries: 0,
37
- storageUsedBytes: 0,
38
- vectorCount: 0,
39
- recentAccessCount: 0,
40
- connected: false,
41
- };
42
- }
43
- async shutdown(): Promise<void> {}
44
- }
45
-
46
- // Usage: pick the right implementation based on config
47
- import { MemoryClient } from '@pyx-memory/client';
48
-
49
- const memory: MemoryInterface = process.env.MEMORY_URL
50
- ? new MemoryClient(process.env.MEMORY_URL, process.env.MEMORY_API_KEY)
51
- : new DisabledMemory();
52
-
53
- await memory.initialize();
@@ -1,37 +0,0 @@
1
- import { Memory } from '@pyx-memory/core';
2
-
3
- const memory = new Memory({ dataDir: './data' });
4
- await memory.initialize(); // REQUIRED — throws if you skip this
5
-
6
- // Store (default targets: sqlite + vector)
7
- await memory.store({
8
- content: 'User prefers dark mode',
9
- type: 'long-term',
10
- metadata: { source: 'settings' },
11
- });
12
-
13
- // Store with entities — populates the knowledge graph
14
- await memory.store({
15
- content: 'Alice switched the project to TypeScript for type safety',
16
- type: 'long-term',
17
- metadata: { source: 'decisions' },
18
- entities: [
19
- { name: 'Alice', type: 'PERSON' },
20
- { name: 'TypeScript', type: 'TOOL' },
21
- ],
22
- relationships: [{ source: 'Alice', target: 'TypeScript', type: 'USES' }],
23
- });
24
-
25
- // Store with explicit targets (e.g., sqlite only)
26
- await memory.store({
27
- content: 'Temporary working note',
28
- type: 'working',
29
- metadata: {},
30
- targets: ['sqlite'],
31
- });
32
-
33
- // Search
34
- const _results = await memory.search({ query: 'user preferences', limit: 5 });
35
-
36
- // Cleanup
37
- await memory.shutdown(); // REQUIRED — releases SQLite + LanceDB resources
@@ -1,14 +0,0 @@
1
- import { MemoryClient } from '@pyx-memory/client';
2
-
3
- // Without auth (local dev)
4
- const memory = new MemoryClient('http://localhost:7822');
5
-
6
- // With auth (production — pass API key as second argument)
7
- // const memory = new MemoryClient('http://localhost:7822', process.env.MEMORY_API_KEY);
8
-
9
- await memory.initialize(); // verifies server connectivity via /health
10
-
11
- await memory.store({ content: 'Important fact', type: 'long-term', metadata: {} });
12
- const _results = await memory.search({ query: 'fact', limit: 5 });
13
-
14
- // Start the server: bun packages/server/src/index.ts