diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json
index d127211e..131a244c 100644
--- a/.claude-plugin/plugin.json
+++ b/.claude-plugin/plugin.json
@@ -6,7 +6,7 @@
"name": "Alex Newman"
},
"repository": "https://github.com/thedotmack/claude-mem",
- "license": "AGPL-3.0",
+ "license": "Apache-2.0",
"keywords": [
"claude",
"claude-code",
diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json
index 18f67c14..c1bcf6e1 100644
--- a/.codex-plugin/plugin.json
+++ b/.codex-plugin/plugin.json
@@ -8,7 +8,7 @@
},
"homepage": "https://github.com/thedotmack/claude-mem#readme",
"repository": "https://github.com/thedotmack/claude-mem",
- "license": "AGPL-3.0",
+ "license": "Apache-2.0",
"keywords": [
"claude",
"claude-code",
diff --git a/LICENSE b/LICENSE
index 5bb20ff7..d6456956 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,630 +1,202 @@
- GNU AFFERO GENERAL PUBLIC LICENSE
- Version 3, 19 November 2007
-
- Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-
- This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >8),u.push(f&255);return u},l.prototype.toNormalizedString=function(){var u,d,p;return u=(function(){var f,m,y,b;for(y=this.parts,b=[],f=0,m=y.length;f
+
@@ -385,20 +385,17 @@ See [Development Guide](https://docs.claude-mem.ai/development) for contribution
## License
-This project is licensed under the **GNU Affero General Public License v3.0** (AGPL-3.0).
+Claude-Mem is licensed under the Apache License 2.0.
-Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
+We chose Apache-2.0 because durable agentic memory should be easy to embed in
+developer tools, local agents, MCP servers, enterprise systems, robotics stacks,
+and production agent harnesses.
-See the [LICENSE](LICENSE) file for full details.
+See the [LICENSE](LICENSE) file for full details. See [docs/license.md](docs/license.md)
+and [docs/ip-boundary.md](docs/ip-boundary.md) for licensing scope and the
+open/commercial boundary.
-**What This Means:**
-
-- You can use, modify, and distribute this software freely
-- If you modify and deploy on a network server, you must make your source code available
-- Derivative works must also be licensed under AGPL-3.0
-- There is NO WARRANTY for this software
-
-**Note on Ragtime**: The `ragtime/` directory is licensed separately under the **PolyForm Noncommercial License 1.0.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
+**Note on Ragtime**: The `ragtime/` directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
@@ -413,7 +410,7 @@ See the [LICENSE](LICENSE) file for full details.
---
-**Built with Claude Agent SDK** | **Powered by Claude Code** | **Made with TypeScript**
+**Built with Claude Agent SDK** | **Works with Claude Code** | **Made with TypeScript**
---
diff --git a/docker-compose.e2e.yml b/docker-compose.e2e.yml
new file mode 100644
index 00000000..854dab8a
--- /dev/null
+++ b/docker-compose.e2e.yml
@@ -0,0 +1,16 @@
+services:
+ server-beta-e2e:
+ image: node:20-alpine
+ depends_on:
+ claude-mem-server:
+ condition: service_healthy
+ valkey:
+ condition: service_healthy
+ environment:
+ E2E_BASE_URL: http://claude-mem-server:37777
+ E2E_REDIS_HOST: valkey
+ E2E_REDIS_PORT: 6379
+ volumes:
+ - ./docker/e2e:/e2e:ro
+ working_dir: /e2e
+ command: ["node", "/e2e/server-beta-e2e.mjs"]
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..bc32e177
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,45 @@
+services:
+ valkey:
+ image: valkey/valkey:8-alpine
+ command: ["valkey-server", "--appendonly", "yes"]
+ volumes:
+ - valkey-data:/data
+ healthcheck:
+ test: ["CMD", "valkey-cli", "ping"]
+ interval: 10s
+ timeout: 3s
+ retries: 5
+
+ claude-mem-server:
+ build:
+ context: .
+ dockerfile: docker/claude-mem/Dockerfile
+ depends_on:
+ valkey:
+ condition: service_healthy
+ environment:
+ CLAUDE_MEM_HOST: 0.0.0.0
+ CLAUDE_MEM_WORKER_HOST: 0.0.0.0
+ CLAUDE_MEM_WORKER_PORT: 37777
+ CLAUDE_MEM_DATA_DIR: /data/claude-mem
+ CLAUDE_MEM_QUEUE_ENGINE: bullmq
+ CLAUDE_MEM_REDIS_URL: redis://valkey:6379
+ CLAUDE_MEM_REDIS_MODE: docker
+ CLAUDE_MEM_AUTH_MODE: api-key
+ CLAUDE_MEM_CHROMA_ENABLED: "false"
+ ports:
+ - "37777:37777"
+ volumes:
+ - claude-mem-data:/data/claude-mem
+ - ${HOME}/.claude:/home/node/.claude:ro
+ command: ["bun", "/opt/claude-mem/scripts/worker-service.cjs", "--daemon"]
+ healthcheck:
+ test: ["CMD", "curl", "-fsS", "http://127.0.0.1:37777/healthz"]
+ interval: 10s
+ timeout: 3s
+ retries: 12
+ start_period: 20s
+
+volumes:
+ claude-mem-data:
+ valkey-data:
diff --git a/docker/claude-mem/Dockerfile b/docker/claude-mem/Dockerfile
index a2cab0a4..e452071a 100644
--- a/docker/claude-mem/Dockerfile
+++ b/docker/claude-mem/Dockerfile
@@ -41,14 +41,19 @@ USER root
COPY plugin/ /opt/claude-mem/
RUN chown -R node:node /opt/claude-mem
-RUN mkdir -p /home/node/.claude /home/node/.claude-mem \
- && chown -R node:node /home/node/.claude /home/node/.claude-mem
-
USER node
-WORKDIR /home/node
+RUN cd /opt/claude-mem \
+ && npm install --omit=dev --legacy-peer-deps
+
+USER root
+RUN mkdir -p /home/node/.claude /home/node/.claude-mem /data/claude-mem \
+ && chown -R node:node /home/node/.claude /home/node/.claude-mem /data/claude-mem
COPY --chown=node:node docker/claude-mem/entrypoint.sh /usr/local/bin/claude-mem-entrypoint
RUN chmod +x /usr/local/bin/claude-mem-entrypoint
+USER node
+WORKDIR /home/node
+
ENTRYPOINT ["/usr/local/bin/claude-mem-entrypoint"]
CMD ["bash"]
diff --git a/docker/e2e/server-beta-e2e.mjs b/docker/e2e/server-beta-e2e.mjs
new file mode 100644
index 00000000..a3923987
--- /dev/null
+++ b/docker/e2e/server-beta-e2e.mjs
@@ -0,0 +1,307 @@
+import net from 'node:net';
+
+const baseUrl = process.env.E2E_BASE_URL ?? 'http://claude-mem-server:37777';
+const redisHost = process.env.E2E_REDIS_HOST ?? 'valkey';
+const redisPort = Number.parseInt(process.env.E2E_REDIS_PORT ?? '6379', 10);
+const phase = process.env.E2E_PHASE ?? 'phase1';
+const apiKey = requiredEnv('E2E_API_KEY');
+const readOnlyKey = process.env.E2E_READ_ONLY_API_KEY ?? '';
+const revokedKey = process.env.E2E_REVOKED_API_KEY ?? '';
+const runId = process.env.E2E_RUN_ID ?? `e2e-${Date.now()}`;
+const projectRoot = `/tmp/claude-mem-server-beta-${runId}`;
+
+function requiredEnv(key) {
+ const value = process.env[key];
+ if (!value) {
+ throw new Error(`${key} is required`);
+ }
+ return value;
+}
+
+function assert(condition, message) {
+ if (!condition) {
+ throw new Error(message);
+ }
+}
+
+async function sleep(ms) {
+ await new Promise(resolve => setTimeout(resolve, ms));
+}
+
+async function request(path, options = {}) {
+ const headers = {
+ ...(options.json !== undefined ? { 'content-type': 'application/json' } : {}),
+ ...(options.apiKey ? { authorization: `Bearer ${options.apiKey}` } : {}),
+ ...(options.headers ?? {}),
+ };
+ return fetch(`${baseUrl}${path}`, {
+ method: options.method ?? (options.json === undefined ? 'GET' : 'POST'),
+ headers,
+ body: options.json === undefined ? undefined : JSON.stringify(options.json),
+ });
+}
+
+async function json(response) {
+ const text = await response.text();
+ try {
+ return text ? JSON.parse(text) : null;
+ } catch (error) {
+ throw new Error(`Invalid JSON response (${response.status}): ${text}\n${error instanceof Error ? error.message : String(error)}`);
+ }
+}
+
+async function requestJson(path, options = {}) {
+ const response = await request(path, options);
+ const body = await json(response);
+ return { response, body };
+}
+
+async function expectStatus(path, status, options = {}) {
+ const response = await request(path, options);
+ assert(response.status === status, `${path} expected HTTP ${status}, got ${response.status}: ${await response.text()}`);
+}
+
+async function waitForReadiness() {
+ const deadline = Date.now() + 120_000;
+ let lastError = '';
+ while (Date.now() < deadline) {
+ try {
+ const health = await request('/healthz');
+ const readiness = await request('/api/readiness');
+ if (health.ok && readiness.ok) {
+ return;
+ }
+ lastError = `health=${health.status} readiness=${readiness.status}`;
+ } catch (error) {
+ lastError = error instanceof Error ? error.message : String(error);
+ }
+ await sleep(1000);
+ }
+ throw new Error(`Server did not become ready: ${lastError}`);
+}
+
+async function assertRedisPing() {
+ const result = await new Promise((resolve, reject) => {
+ const socket = net.createConnection({ host: redisHost, port: redisPort });
+ socket.setTimeout(3000);
+ let data = '';
+ socket.on('connect', () => socket.write('*1\r\n$4\r\nPING\r\n'));
+ socket.on('data', chunk => {
+ data += chunk.toString('utf8');
+ if (data.includes('PONG')) {
+ socket.end();
+ resolve(data);
+ }
+ });
+ socket.on('timeout', () => {
+ socket.destroy();
+ reject(new Error('Redis PING timed out'));
+ });
+ socket.on('error', reject);
+ socket.on('close', () => {
+ if (!data.includes('PONG')) {
+ reject(new Error(`Redis PING failed: ${data}`));
+ }
+ });
+ });
+ assert(String(result).includes('PONG'), `Redis did not return PONG: ${result}`);
+}
+
+async function assertQueueHealth() {
+ const { response, body } = await requestJson('/api/health');
+ assert(response.ok, `/api/health expected OK, got ${response.status}`);
+ assert(body.queue?.engine === 'bullmq', `expected BullMQ queue engine, got ${JSON.stringify(body.queue)}`);
+ assert(body.queue?.redis?.status === 'ok', `expected Redis health ok, got ${JSON.stringify(body.queue?.redis)}`);
+ assert(body.queue?.redis?.mode === 'docker', `expected docker Redis mode, got ${JSON.stringify(body.queue?.redis)}`);
+}
+
+async function phase1() {
+ console.log(`[e2e] phase1 starting (${runId})`);
+ await waitForReadiness();
+ await assertQueueHealth();
+ await assertRedisPing();
+
+ await expectStatus('/v1/projects', 401, {
+ method: 'POST',
+ json: { name: 'unauthenticated' },
+ });
+ await expectStatus('/v1/projects', 403, {
+ method: 'POST',
+ apiKey: 'cmem_invalid_key',
+ json: { name: 'invalid' },
+ });
+ if (readOnlyKey) {
+ await expectStatus('/v1/projects', 403, {
+ method: 'POST',
+ apiKey: readOnlyKey,
+ json: { name: 'read-only denied' },
+ });
+ const readOnlyProjects = await request('/v1/projects', { apiKey: readOnlyKey });
+ assert(readOnlyProjects.ok, `read-only key should read projects, got ${readOnlyProjects.status}`);
+ }
+
+ const createdProject = await requestJson('/v1/projects', {
+ apiKey,
+ json: {
+ name: `Server Beta E2E ${runId}`,
+ rootPath: projectRoot,
+ metadata: { runId },
+ },
+ });
+ assert(createdProject.response.status === 201, `project create failed: ${JSON.stringify(createdProject.body)}`);
+ const project = createdProject.body.project;
+ assert(project?.id, 'project response missing id');
+
+ const createdSession = await requestJson('/v1/sessions/start', {
+ apiKey,
+ json: {
+ projectId: project.id,
+ contentSessionId: `content-${runId}`,
+ memorySessionId: `memory-${runId}`,
+ platformSource: 'docker-e2e',
+ title: 'Docker E2E session',
+ },
+ });
+ assert(createdSession.response.status === 201, `session create failed: ${JSON.stringify(createdSession.body)}`);
+ const session = createdSession.body.session;
+
+ const createdEvent = await requestJson('/v1/events', {
+ apiKey,
+ json: {
+ projectId: project.id,
+ serverSessionId: session.id,
+ sourceType: 'api',
+ eventType: 'observation.created',
+ contentSessionId: `content-${runId}`,
+ memorySessionId: `memory-${runId}`,
+ payload: { tool_name: 'Read', runId },
+ occurredAtEpoch: Date.now(),
+ },
+ });
+ assert(createdEvent.response.status === 201, `event create failed: ${JSON.stringify(createdEvent.body)}`);
+ const event = createdEvent.body.event;
+
+ const batchEvents = await requestJson('/v1/events/batch', {
+ apiKey,
+ json: [
+ {
+ projectId: project.id,
+ sourceType: 'api',
+ eventType: 'observation.created',
+ payload: { index: 1, runId },
+ occurredAtEpoch: Date.now(),
+ },
+ {
+ projectId: project.id,
+ sourceType: 'api',
+ eventType: 'observation.created',
+ payload: { index: 2, runId },
+ occurredAtEpoch: Date.now(),
+ },
+ ],
+ });
+ assert(batchEvents.response.status === 201, `event batch failed: ${JSON.stringify(batchEvents.body)}`);
+ assert(batchEvents.body.events.length === 2, 'event batch did not return two events');
+
+ const fetchedEvent = await requestJson(`/v1/events/${event.id}`, { apiKey });
+ assert(fetchedEvent.response.ok, `event fetch failed: ${JSON.stringify(fetchedEvent.body)}`);
+
+ const createdMemory = await requestJson('/v1/memories', {
+ apiKey,
+ json: {
+ projectId: project.id,
+ serverSessionId: session.id,
+ kind: 'manual',
+ type: 'decision',
+ title: `Docker E2E memory ${runId}`,
+ narrative: `Server beta Docker E2E memory survives restart for ${runId}.`,
+ facts: ['BullMQ health is backed by Valkey', `run:${runId}`],
+ concepts: ['server-beta', 'docker-e2e'],
+ metadata: { runId },
+ },
+ });
+ assert(createdMemory.response.status === 201, `memory create failed: ${JSON.stringify(createdMemory.body)}`);
+ const memory = createdMemory.body.memory;
+
+ const patchedMemory = await requestJson(`/v1/memories/${memory.id}`, {
+ method: 'PATCH',
+ apiKey,
+ json: {
+ projectId: project.id,
+ kind: 'manual',
+ type: 'decision',
+ narrative: `Patched Docker E2E memory survives restart for ${runId}.`,
+ facts: ['patched', `run:${runId}`],
+ },
+ });
+ assert(patchedMemory.response.ok, `memory patch failed: ${JSON.stringify(patchedMemory.body)}`);
+ assert(patchedMemory.body.memory.narrative.includes('Patched'), 'patched memory narrative was not returned');
+
+ const fetchedMemory = await requestJson(`/v1/memories/${memory.id}`, { apiKey });
+ assert(fetchedMemory.response.ok, `memory fetch failed: ${JSON.stringify(fetchedMemory.body)}`);
+
+ const search = await requestJson('/v1/search', {
+ apiKey,
+ json: { projectId: project.id, query: runId, limit: 10 },
+ });
+ assert(search.response.ok, `search failed: ${JSON.stringify(search.body)}`);
+ assert(search.body.memories.some(item => item.id === memory.id), 'search did not return created memory');
+
+ const context = await requestJson('/v1/context', {
+ apiKey,
+ json: { projectId: project.id, query: 'patched', limit: 5 },
+ });
+ assert(context.response.ok, `context failed: ${JSON.stringify(context.body)}`);
+ assert(context.body.context.includes(runId), 'context did not include created memory text');
+
+ const endedSession = await requestJson(`/v1/sessions/${session.id}/end`, {
+ method: 'POST',
+ apiKey,
+ json: {},
+ });
+ assert(endedSession.response.ok, `session end failed: ${JSON.stringify(endedSession.body)}`);
+ assert(endedSession.body.session.status === 'completed', 'session did not complete');
+
+ const audit = await requestJson(`/v1/audit?projectId=${encodeURIComponent(project.id)}`, { apiKey });
+ assert(audit.response.ok, `audit failed: ${JSON.stringify(audit.body)}`);
+ assert(audit.body.audit.some(row => row.action === 'memory.write'), 'audit log missing memory.write');
+
+ console.log(`[e2e] phase1 passed project=${project.id} memory=${memory.id}`);
+}
+
+async function phase2() {
+ console.log(`[e2e] phase2 after restart starting (${runId})`);
+ await waitForReadiness();
+ await assertQueueHealth();
+ await assertRedisPing();
+
+ if (revokedKey) {
+ await expectStatus('/v1/projects', 403, { apiKey: revokedKey });
+ }
+
+ const projects = await requestJson('/v1/projects', { apiKey });
+ assert(projects.response.ok, `project list failed after restart: ${JSON.stringify(projects.body)}`);
+ const project = projects.body.projects.find(item => item.rootPath === projectRoot);
+ assert(project?.id, `persisted project not found for ${projectRoot}`);
+
+ const search = await requestJson('/v1/search', {
+ apiKey,
+ json: { projectId: project.id, query: runId, limit: 10 },
+ });
+ assert(search.response.ok, `search failed after restart: ${JSON.stringify(search.body)}`);
+ assert(search.body.memories.some(item => String(item.narrative ?? '').includes(runId)), 'persisted memory not found after restart');
+
+ const audit = await requestJson(`/v1/audit?projectId=${encodeURIComponent(project.id)}`, { apiKey });
+ assert(audit.response.ok, `audit failed after restart: ${JSON.stringify(audit.body)}`);
+ assert(audit.body.audit.length > 0, 'audit log did not persist after restart');
+
+ console.log(`[e2e] phase2 passed project=${project.id}`);
+}
+
+if (phase === 'phase1') {
+ await phase1();
+} else if (phase === 'phase2') {
+ await phase2();
+} else {
+ throw new Error(`Unknown E2E_PHASE: ${phase}`);
+}
diff --git a/docs/adapters.md b/docs/adapters.md
new file mode 100644
index 00000000..ac1b231b
--- /dev/null
+++ b/docs/adapters.md
@@ -0,0 +1,5 @@
+# Adapters
+
+Claude Code hook payloads are mapped through `src/adapters/claude-code/mapper.ts` into `AgentEvent` records. The mapper preserves legacy fields such as `contentSessionId`, `tool_name`, `tool_input`, `tool_response`, `cwd`, `agentId`, `agentType`, `platformSource`, and both `tool_use_id` and `toolUseId`.
+
+Generic agent examples live in `src/adapters/generic-rest/examples.ts` for Codex, OpenCode, and custom REST ingestion. New adapters should emit the REST V1 event shape instead of coupling their payloads to Claude Code internals.
diff --git a/docs/api.md b/docs/api.md
new file mode 100644
index 00000000..07599dbd
--- /dev/null
+++ b/docs/api.md
@@ -0,0 +1,25 @@
+# Server API
+
+REST V1 is mounted under `/v1`; legacy worker routes remain under `/api`.
+
+Available beta endpoints:
+
+- `GET /healthz`
+- `GET /v1/info`
+- `GET /v1/projects`
+- `POST /v1/projects`
+- `GET /v1/projects/:id`
+- `POST /v1/sessions/start`
+- `POST /v1/sessions/:id/end`
+- `GET /v1/sessions/:id`
+- `POST /v1/events`
+- `POST /v1/events/batch`
+- `GET /v1/events/:id`
+- `POST /v1/memories`
+- `GET /v1/memories/:id`
+- `PATCH /v1/memories/:id`
+- `POST /v1/search`
+- `POST /v1/context`
+- `GET /v1/audit?projectId=
+
@@ -275,25 +275,21 @@ npm run bug-report
---
-## الترخيص (License)
+## License
-هذا المشروع مرخص بموجب **ترخيص GNU Affero العام الإصدار 3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-حقوق النشر (C) 2025 Alex Newman (@thedotmack). جميع الحقوق محفوظة.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-انظر ملف [LICENSE](LICENSE) للتفاصيل الكاملة.
+See the [LICENSE](LICENSE) file for full details.
-**ماذا يعني هذا:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- يمكنك استخدام وتعديل وتوزيع هذا البرنامج بحرية
-- إذا قمت بتعديل ونشر على خادم شبكة، يجب أن تتيح كود المصدر الخاص بك
-- الأعمال المشتقة يجب أن تكون مرخصة أيضًا تحت AGPL-3.0
-- لا يوجد ضمان لهذا البرنامج
-
-**ملاحظة حول Ragtime**: دليل `ragtime/` مرخص بشكل منفصل تحت **ترخيص PolyForm Noncommercial 1.0.0**. انظر [ragtime/LICENSE](ragtime/LICENSE) للتفاصيل.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## الدعم
- **التوثيق**: [docs/](docs/)
diff --git a/docs/i18n/README.bn.md b/docs/i18n/README.bn.md
index 592de8a1..19a44285 100644
--- a/docs/i18n/README.bn.md
+++ b/docs/i18n/README.bn.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ npm run bug-report
---
-## লাইসেন্স
+## License
-এই প্রকল্পটি **GNU Affero General Public License v3.0** (AGPL-3.0) এর অধীনে লাইসেন্সপ্রাপ্ত।
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). সর্বস্বত্ব সংরক্ষিত।
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-সম্পূর্ণ বিবরণের জন্য [LICENSE](LICENSE) ফাইল দেখুন।
+See the [LICENSE](LICENSE) file for full details.
-**এর অর্থ কী:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- আপনি এই সফটওয়্যারটি অবাধে ব্যবহার, পরিবর্তন এবং বিতরণ করতে পারেন
-- যদি আপনি পরিবর্তন করেন এবং একটি নেটওয়ার্ক সার্ভারে ডিপ্লয় করেন, তাহলে আপনাকে আপনার সোর্স কোড উপলব্ধ করতে হবে
-- ডেরিভেটিভ কাজগুলিও AGPL-3.0 এর অধীনে লাইসেন্সপ্রাপ্ত হতে হবে
-- এই সফটওয়্যারের জন্য কোনও ওয়ারেন্টি নেই
-
-**Ragtime সম্পর্কে নোট**: `ragtime/` ডিরেক্টরি আলাদাভাবে **PolyForm Noncommercial License 1.0.0** এর অধীনে লাইসেন্সপ্রাপ্ত। বিস্তারিত জানতে [ragtime/LICENSE](ragtime/LICENSE) দেখুন।
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## সাপোর্ট
- **ডকুমেন্টেশন**: [docs/](docs/)
diff --git a/docs/i18n/README.cs.md b/docs/i18n/README.cs.md
index 424951d0..a5bb8918 100644
--- a/docs/i18n/README.cs.md
+++ b/docs/i18n/README.cs.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Pracovní postup pro přispívání najdete v [Průvodci vývojem](https://docs.
---
-## Licence
+## License
-Tento projekt je licencován pod **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Všechna práva vyhrazena.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Úplné podrobnosti najdete v souboru [LICENSE](LICENSE).
+See the [LICENSE](LICENSE) file for full details.
-**Co to znamená:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Software můžete volně používat, upravovat a distribuovat
-- Pokud jej upravíte a nasadíte na síťovém serveru, musíte zpřístupnit svůj zdrojový kód
-- Odvozená díla musí být také licencována pod AGPL-3.0
-- Pro tento software neexistuje ŽÁDNÁ ZÁRUKA
-
-**Poznámka k Ragtime**: Adresář `ragtime/` je licencován samostatně pod **PolyForm Noncommercial License 1.0.0**. Podrobnosti najdete v [ragtime/LICENSE](ragtime/LICENSE).
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Podpora
- **Dokumentace**: [docs/](docs/)
diff --git a/docs/i18n/README.da.md b/docs/i18n/README.da.md
index f11e9c5a..b69b047a 100644
--- a/docs/i18n/README.da.md
+++ b/docs/i18n/README.da.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Se [Udviklingsguide](https://docs.claude-mem.ai/development) for bidragsworkflow
---
-## Licens
+## License
-Dette projekt er licenseret under **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Alle rettigheder forbeholdes.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Se [LICENSE](LICENSE)-filen for fulde detaljer.
+See the [LICENSE](LICENSE) file for full details.
-**Hvad Dette Betyder:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Du kan bruge, modificere og distribuere denne software frit
-- Hvis du modificerer og implementerer på en netværksserver, skal du gøre din kildekode tilgængelig
-- Afledte værker skal også licenseres under AGPL-3.0
-- Der er INGEN GARANTI for denne software
-
-**Bemærkning om Ragtime**: `ragtime/`-kataloget er licenseret separat under **PolyForm Noncommercial License 1.0.0**. Se [ragtime/LICENSE](ragtime/LICENSE) for detaljer.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Support
- **Dokumentation**: [docs/](docs/)
diff --git a/docs/i18n/README.de.md b/docs/i18n/README.de.md
index ce7bcb72..abd1dacd 100644
--- a/docs/i18n/README.de.md
+++ b/docs/i18n/README.de.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Siehe [Entwicklungsanleitung](https://docs.claude-mem.ai/development) für den B
---
-## Lizenz
+## License
-Dieses Projekt ist unter der **GNU Affero General Public License v3.0** (AGPL-3.0) lizenziert.
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Alle Rechte vorbehalten.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Siehe die [LICENSE](LICENSE)-Datei für vollständige Details.
+See the [LICENSE](LICENSE) file for full details.
-**Was das bedeutet:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Sie können diese Software frei verwenden, modifizieren und verteilen
-- Wenn Sie sie modifizieren und auf einem Netzwerkserver bereitstellen, müssen Sie Ihren Quellcode verfügbar machen
-- Abgeleitete Werke müssen ebenfalls unter AGPL-3.0 lizenziert werden
-- Es gibt KEINE GARANTIE für diese Software
-
-**Hinweis zu Ragtime**: Das `ragtime/`-Verzeichnis ist separat unter der **PolyForm Noncommercial License 1.0.0** lizenziert. Siehe [ragtime/LICENSE](ragtime/LICENSE) für Details.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Support
- **Dokumentation**: [docs/](docs/)
@@ -301,4 +297,4 @@ Siehe die [LICENSE](LICENSE)-Datei für vollständige Details.
---
-**Erstellt mit Claude Agent SDK** | **Powered by Claude Code** | **Made with TypeScript**
\ No newline at end of file
+**Erstellt mit Claude Agent SDK** | **Works with Claude Code** | **Made with TypeScript**
\ No newline at end of file
diff --git a/docs/i18n/README.el.md b/docs/i18n/README.el.md
index 0264e21f..c56d4f15 100644
--- a/docs/i18n/README.el.md
+++ b/docs/i18n/README.el.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ npm run bug-report
---
-## Άδεια Χρήσης
+## License
-Αυτό το έργο διατίθεται με άδεια **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Με επιφύλαξη παντός δικαιώματος.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Δείτε το αρχείο [LICENSE](LICENSE) για πλήρεις λεπτομέρειες.
+See the [LICENSE](LICENSE) file for full details.
-**Τι Σημαίνει Αυτό:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Μπορείτε να χρησιμοποιήσετε, να τροποποιήσετε και να διανείμετε ελεύθερα αυτό το λογισμικό
-- Εάν τροποποιήσετε και αναπτύξετε σε διακομιστή δικτύου, πρέπει να καταστήσετε διαθέσιμο τον πηγαίο κώδικά σας
-- Τα παράγωγα έργα πρέπει επίσης να διατίθενται με άδεια AGPL-3.0
-- ΔΕΝ υπάρχει ΕΓΓΥΗΣΗ για αυτό το λογισμικό
-
-**Σημείωση για το Ragtime**: Ο κατάλογος `ragtime/` διατίθεται χωριστά με άδεια **PolyForm Noncommercial License 1.0.0**. Δείτε το [ragtime/LICENSE](ragtime/LICENSE) για λεπτομέρειες.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Υποστήριξη
- **Τεκμηρίωση**: [docs/](docs/)
diff --git a/docs/i18n/README.es.md b/docs/i18n/README.es.md
index 72bdb98e..83e8e7c7 100644
--- a/docs/i18n/README.es.md
+++ b/docs/i18n/README.es.md
@@ -51,7 +51,7 @@
+
@@ -274,25 +274,21 @@ Ver [Guía de Desarrollo](https://docs.claude-mem.ai/development) para el flujo
---
-## Licencia
+## License
-Este proyecto está licenciado bajo la **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Todos los derechos reservados.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Ver el archivo [LICENSE](LICENSE) para detalles completos.
+See the [LICENSE](LICENSE) file for full details.
-**Lo Que Esto Significa:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Puedes usar, modificar y distribuir este software libremente
-- Si modificas y despliegas en un servidor de red, debes hacer tu código fuente disponible
-- Los trabajos derivados también deben estar licenciados bajo AGPL-3.0
-- NO hay GARANTÍA para este software
-
-**Nota sobre Ragtime**: El directorio `ragtime/` está licenciado por separado bajo la **PolyForm Noncommercial License 1.0.0**. Ver [ragtime/LICENSE](ragtime/LICENSE) para detalles.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Soporte
- **Documentación**: [docs/](docs/)
diff --git a/docs/i18n/README.fi.md b/docs/i18n/README.fi.md
index 9fcb24ab..d1096593 100644
--- a/docs/i18n/README.fi.md
+++ b/docs/i18n/README.fi.md
@@ -49,7 +49,7 @@
+
@@ -272,25 +272,21 @@ Katso [Kehitysopas](https://docs.claude-mem.ai/development) osallistumisen työn
---
-## Lisenssi
+## License
-Tämä projekti on lisensoitu **GNU Affero General Public License v3.0** (AGPL-3.0) -lisenssillä.
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Kaikki oikeudet pidätetään.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Katso [LICENSE](LICENSE)-tiedosto täydellisistä yksityiskohdista.
+See the [LICENSE](LICENSE) file for full details.
-**Mitä tämä tarkoittaa:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Voit käyttää, muokata ja jakaa tätä ohjelmistoa vapaasti
-- Jos muokkaat ja otat käyttöön verkkopalvelimella, sinun on asetettava lähdekoodisi saataville
-- Johdannaisten teosten on myös oltava AGPL-3.0-lisensoituja
-- Tälle ohjelmistolle EI OLE TAKUUTA
-
-**Huomautus Ragtimesta**: `ragtime/`-hakemisto on erikseen lisensoitu **PolyForm Noncommercial License 1.0.0** -lisenssillä. Katso [ragtime/LICENSE](ragtime/LICENSE) yksityiskohdista.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Tuki
- **Dokumentaatio**: [docs/](docs/)
diff --git a/docs/i18n/README.fr.md b/docs/i18n/README.fr.md
index d0c3ef2b..346a225e 100644
--- a/docs/i18n/README.fr.md
+++ b/docs/i18n/README.fr.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Voir le [Guide de développement](https://docs.claude-mem.ai/development) pour l
---
-## Licence
+## License
-Ce projet est sous licence **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Tous droits réservés.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Voir le fichier [LICENSE](LICENSE) pour tous les détails.
+See the [LICENSE](LICENSE) file for full details.
-**Ce que cela signifie :**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Vous pouvez utiliser, modifier et distribuer ce logiciel librement
-- Si vous modifiez et déployez sur un serveur réseau, vous devez rendre votre code source disponible
-- Les œuvres dérivées doivent également être sous licence AGPL-3.0
-- Il n'y a AUCUNE GARANTIE pour ce logiciel
-
-**Note sur Ragtime** : Le répertoire `ragtime/` est sous licence séparée sous la **PolyForm Noncommercial License 1.0.0**. Voir [ragtime/LICENSE](ragtime/LICENSE) pour plus de détails.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Support
- **Documentation** : [docs/](docs/)
diff --git a/docs/i18n/README.he.md b/docs/i18n/README.he.md
index 8b7c5e4b..6969d359 100644
--- a/docs/i18n/README.he.md
+++ b/docs/i18n/README.he.md
@@ -49,7 +49,7 @@
+
@@ -272,25 +272,21 @@ npm run bug-report
---
-## רישיון
+## License
-פרויקט זה מורשה תחת **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-זכויות יוצרים (C) 2025 Alex Newman (@thedotmack). כל הזכויות שמורות.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-ראה את קובץ [LICENSE](LICENSE) לפרטים מלאים.
+See the [LICENSE](LICENSE) file for full details.
-**משמעות הדבר:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- אתה יכול לשימוש, שינוי והפצה של תוכנה זו בחופשיות
-- אם אתה משנה ופורס על שרת רשת, עליך להנגיש את קוד המקור שלך
-- עבודות נגזרות חייבות להיות מורשות גם כן תחת AGPL-3.0
-- אין אחריות לתוכנה זו
-
-**הערה על Ragtime**: ספריית `ragtime/` מורשית בנפרד תחת **PolyForm Noncommercial License 1.0.0**. ראה [ragtime/LICENSE](ragtime/LICENSE) לפרטים.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## תמיכה
- **תיעוד**: [docs/](docs/)
diff --git a/docs/i18n/README.hi.md b/docs/i18n/README.hi.md
index 1abf14de..4a26e361 100644
--- a/docs/i18n/README.hi.md
+++ b/docs/i18n/README.hi.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ npm run bug-report
---
-## लाइसेंस
+## License
-यह प्रोजेक्ट **GNU Affero General Public License v3.0** (AGPL-3.0) के तहत लाइसेंस प्राप्त है।
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack)। सर्वाधिकार सुरक्षित।
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-पूर्ण विवरण के लिए [LICENSE](LICENSE) फ़ाइल देखें।
+See the [LICENSE](LICENSE) file for full details.
-**इसका क्या अर्थ है:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- आप इस सॉफ़्टवेयर को स्वतंत्र रूप से उपयोग, संशोधित और वितरित कर सकते हैं
-- यदि आप नेटवर्क सर्वर पर संशोधित और तैनात करते हैं, तो आपको अपना स्रोत कोड उपलब्ध कराना होगा
-- व्युत्पन्न कार्यों को भी AGPL-3.0 के तहत लाइसेंस प्राप्त होना चाहिए
-- इस सॉफ़्टवेयर के लिए कोई वारंटी नहीं है
-
-**Ragtime पर नोट**: `ragtime/` डायरेक्टरी को **PolyForm Noncommercial License 1.0.0** के तहत अलग से लाइसेंस प्राप्त है। विवरण के लिए [ragtime/LICENSE](ragtime/LICENSE) देखें।
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## समर्थन
- **दस्तावेज़ीकरण**: [docs/](docs/)
diff --git a/docs/i18n/README.hu.md b/docs/i18n/README.hu.md
index fc1c1746..5b7dffb5 100644
--- a/docs/i18n/README.hu.md
+++ b/docs/i18n/README.hu.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ A hozzájárulási munkafolyamatért lásd a [Fejlesztési útmutatót](https://
---
-## Licenc
+## License
-Ez a projekt a **GNU Affero General Public License v3.0** (AGPL-3.0) alatt licencelt.
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Minden jog fenntartva.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-A teljes részletekért lásd a [LICENSE](LICENSE) fájlt.
+See the [LICENSE](LICENSE) file for full details.
-**Mit jelent ez:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Szabadon használhatja, módosíthatja és terjesztheti ezt a szoftvert
-- Ha módosítja és hálózati szerveren telepíti, elérhetővé kell tennie a forráskódot
-- A származékos munkáknak szintén AGPL-3.0 alatt kell licencelve lenniük
-- Ehhez a szoftverhez NINCS GARANCIA
-
-**Megjegyzés a Ragtime-ról**: A `ragtime/` könyvtár külön licencelt a **PolyForm Noncommercial License 1.0.0** alatt. Részletekért lásd a [ragtime/LICENSE](ragtime/LICENSE) fájlt.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Támogatás
- **Dokumentáció**: [docs/](docs/)
diff --git a/docs/i18n/README.id.md b/docs/i18n/README.id.md
index a615a5a9..f90c6419 100644
--- a/docs/i18n/README.id.md
+++ b/docs/i18n/README.id.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Lihat [Panduan Pengembangan](https://docs.claude-mem.ai/development) untuk alur
---
-## Lisensi
+## License
-Proyek ini dilisensikan di bawah **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Lihat file [LICENSE](LICENSE) untuk detail lengkap.
+See the [LICENSE](LICENSE) file for full details.
-**Apa Artinya:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Anda dapat menggunakan, memodifikasi, dan mendistribusikan perangkat lunak ini dengan bebas
-- Jika Anda memodifikasi dan men-deploy di server jaringan, Anda harus membuat kode sumber Anda tersedia
-- Karya turunan juga harus dilisensikan di bawah AGPL-3.0
-- TIDAK ADA JAMINAN untuk perangkat lunak ini
-
-**Catatan tentang Ragtime**: Direktori `ragtime/` dilisensikan secara terpisah di bawah **PolyForm Noncommercial License 1.0.0**. Lihat [ragtime/LICENSE](ragtime/LICENSE) untuk detail.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Dukungan
- **Dokumentasi**: [docs/](docs/)
@@ -301,6 +297,6 @@ Lihat file [LICENSE](LICENSE) untuk detail lengkap.
---
-**Built with Claude Agent SDK** | **Powered by Claude Code** | **Made with TypeScript**
+**Built with Claude Agent SDK** | **Works with Claude Code** | **Made with TypeScript**
---
\ No newline at end of file
diff --git a/docs/i18n/README.it.md b/docs/i18n/README.it.md
index 550d813d..8ee65db9 100644
--- a/docs/i18n/README.it.md
+++ b/docs/i18n/README.it.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Vedi [Guida allo Sviluppo](https://docs.claude-mem.ai/development) per il flusso
---
-## Licenza
+## License
-Questo progetto è rilasciato sotto la **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Tutti i diritti riservati.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Vedi il file [LICENSE](LICENSE) per i dettagli completi.
+See the [LICENSE](LICENSE) file for full details.
-**Cosa Significa:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Puoi usare, modificare e distribuire questo software liberamente
-- Se modifichi e distribuisci su un server di rete, devi rendere disponibile il tuo codice sorgente
-- Le opere derivate devono anche essere rilasciate sotto AGPL-3.0
-- NON c'è GARANZIA per questo software
-
-**Nota su Ragtime**: La directory `ragtime/` è rilasciata separatamente sotto la **PolyForm Noncommercial License 1.0.0**. Vedi [ragtime/LICENSE](ragtime/LICENSE) per i dettagli.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Supporto
- **Documentazione**: [docs/](docs/)
diff --git a/docs/i18n/README.ja.md b/docs/i18n/README.ja.md
index 66c0e7ca..1568855a 100644
--- a/docs/i18n/README.ja.md
+++ b/docs/i18n/README.ja.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ npm run bug-report
---
-## ライセンス
+## License
-このプロジェクトは**GNU Affero General Public License v3.0**(AGPL-3.0)の下でライセンスされています。
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-詳細は[LICENSE](LICENSE)ファイルを参照してください。
+See the [LICENSE](LICENSE) file for full details.
-**これが意味すること:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- このソフトウェアを自由に使用、変更、配布できます
-- ネットワークサーバーで変更して展開する場合、ソースコードを利用可能にする必要があります
-- 派生作品もAGPL-3.0の下でライセンスする必要があります
-- このソフトウェアには保証がありません
-
-**Ragtimeに関する注意**: `ragtime/`ディレクトリは **PolyForm Noncommercial License 1.0.0** の下で個別にライセンスされています。詳細は[ragtime/LICENSE](ragtime/LICENSE)を参照してください。
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## サポート
- **ドキュメント**: [docs/](docs/)
diff --git a/docs/i18n/README.ko.md b/docs/i18n/README.ko.md
index 0d5724c3..13dcc6a3 100644
--- a/docs/i18n/README.ko.md
+++ b/docs/i18n/README.ko.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ npm run bug-report
---
-## 라이선스
+## License
-이 프로젝트는 **GNU Affero General Public License v3.0** (AGPL-3.0)에 따라 라이선스가 부여됩니다.
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-전체 세부 정보는 [LICENSE](LICENSE) 파일을 참조하세요.
+See the [LICENSE](LICENSE) file for full details.
-**의미:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- 이 소프트웨어를 자유롭게 사용, 수정 및 배포할 수 있습니다
-- 수정하여 네트워크 서버에 배포하는 경우 소스 코드를 공개해야 합니다
-- 파생 작업물도 AGPL-3.0에 따라 라이선스가 부여되어야 합니다
-- 이 소프트웨어에는 보증이 없습니다
-
-**Ragtime에 대한 참고 사항**: `ragtime/` 디렉토리는 **PolyForm Noncommercial License 1.0.0**에 따라 별도로 라이선스가 부여됩니다. 자세한 내용은 [ragtime/LICENSE](ragtime/LICENSE)를 참조하세요.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## 지원
- **문서**: [docs/](docs/)
diff --git a/docs/i18n/README.nl.md b/docs/i18n/README.nl.md
index 3437cdbf..ced07e0e 100644
--- a/docs/i18n/README.nl.md
+++ b/docs/i18n/README.nl.md
@@ -49,7 +49,7 @@
+
@@ -272,25 +272,21 @@ Zie [Ontwikkelingsgids](https://docs.claude-mem.ai/development) voor bijdragewor
---
-## Licentie
+## License
-Dit project is gelicentieerd onder de **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Alle rechten voorbehouden.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Zie het [LICENSE](LICENSE) bestand voor volledige details.
+See the [LICENSE](LICENSE) file for full details.
-**Wat Dit Betekent:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Je kunt deze software vrijelijk gebruiken, aanpassen en distribueren
-- Als je aanpast en implementeert op een netwerkserver, moet je je broncode beschikbaar maken
-- Afgeleide werken moeten ook gelicentieerd zijn onder AGPL-3.0
-- Er is GEEN GARANTIE voor deze software
-
-**Opmerking over Ragtime**: De `ragtime/` directory is afzonderlijk gelicentieerd onder de **PolyForm Noncommercial License 1.0.0**. Zie [ragtime/LICENSE](ragtime/LICENSE) voor details.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Ondersteuning
- **Documentatie**: [docs/](docs/)
diff --git a/docs/i18n/README.no.md b/docs/i18n/README.no.md
index a50b5995..be666e5d 100644
--- a/docs/i18n/README.no.md
+++ b/docs/i18n/README.no.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Se [Utviklingsveiledning](https://docs.claude-mem.ai/development) for bidragsfly
---
-## Lisens
+## License
-Dette prosjektet er lisensiert under **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Alle rettigheter reservert.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Se [LICENSE](LICENSE)-filen for fullstendige detaljer.
+See the [LICENSE](LICENSE) file for full details.
-**Hva Dette Betyr:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Du kan bruke, modifisere og distribuere denne programvaren fritt
-- Hvis du modifiserer og distribuerer på en nettverkstjener, må du gjøre kildekoden din tilgjengelig
-- Avledede verk må også være lisensiert under AGPL-3.0
-- Det er INGEN GARANTI for denne programvaren
-
-**Merknad om Ragtime**: `ragtime/`-katalogen er lisensiert separat under **PolyForm Noncommercial License 1.0.0**. Se [ragtime/LICENSE](ragtime/LICENSE) for detaljer.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Støtte
- **Dokumentasjon**: [docs/](docs/)
diff --git a/docs/i18n/README.pl.md b/docs/i18n/README.pl.md
index fcef5ebd..33e81175 100644
--- a/docs/i18n/README.pl.md
+++ b/docs/i18n/README.pl.md
@@ -49,7 +49,7 @@
+
@@ -272,25 +272,21 @@ Zobacz [Przewodnik Rozwoju](https://docs.claude-mem.ai/development) dla przepły
---
-## Licencja
+## License
-Ten projekt jest licencjonowany na podstawie **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Wszelkie prawa zastrzeżone.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Zobacz plik [LICENSE](LICENSE) dla pełnych szczegółów.
+See the [LICENSE](LICENSE) file for full details.
-**Co To Oznacza:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Możesz używać, modyfikować i dystrybuować to oprogramowanie swobodnie
-- Jeśli zmodyfikujesz i wdrożysz na serwerze sieciowym, musisz udostępnić swój kod źródłowy
-- Dzieła pochodne muszą być również licencjonowane na podstawie AGPL-3.0
-- Nie ma GWARANCJI dla tego oprogramowania
-
-**Uwaga o Ragtime**: Katalog `ragtime/` jest licencjonowany osobno na podstawie **PolyForm Noncommercial License 1.0.0**. Zobacz [ragtime/LICENSE](ragtime/LICENSE) dla szczegółów.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Wsparcie
- **Dokumentacja**: [docs/](docs/)
diff --git a/docs/i18n/README.pt-br.md b/docs/i18n/README.pt-br.md
index bcb2c43a..9bb03858 100644
--- a/docs/i18n/README.pt-br.md
+++ b/docs/i18n/README.pt-br.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Veja [Guia de Desenvolvimento](https://docs.claude-mem.ai/development) para o fl
---
-## Licença
+## License
-Este projeto está licenciado sob a **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Todos os direitos reservados.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Veja o arquivo [LICENSE](LICENSE) para detalhes completos.
+See the [LICENSE](LICENSE) file for full details.
-**O Que Isso Significa:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Você pode usar, modificar e distribuir este software livremente
-- Se você modificar e implantar em um servidor de rede, você deve disponibilizar seu código-fonte
-- Trabalhos derivados também devem ser licenciados sob AGPL-3.0
-- NÃO HÁ GARANTIA para este software
-
-**Nota sobre Ragtime**: O diretório `ragtime/` é licenciado separadamente sob a **PolyForm Noncommercial License 1.0.0**. Veja [ragtime/LICENSE](ragtime/LICENSE) para detalhes.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Suporte
- **Documentação**: [docs/](docs/)
diff --git a/docs/i18n/README.ro.md b/docs/i18n/README.ro.md
index 69ad6e0d..1bfd9067 100644
--- a/docs/i18n/README.ro.md
+++ b/docs/i18n/README.ro.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Consultați [Ghidul de Dezvoltare](https://docs.claude-mem.ai/development) pentr
---
-## Licență
+## License
-Acest proiect este licențiat sub **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Toate drepturile rezervate.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Consultați fișierul [LICENSE](LICENSE) pentru detalii complete.
+See the [LICENSE](LICENSE) file for full details.
-**Ce Înseamnă Asta:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Puteți folosi, modifica și distribui acest software liber
-- Dacă modificați și implementați pe un server de rețea, trebuie să faceți disponibil codul sursă
-- Lucrările derivate trebuie să fie licențiate și ele sub AGPL-3.0
-- NU EXISTĂ NICIO GARANȚIE pentru acest software
-
-**Notă despre Ragtime**: Directorul `ragtime/` este licențiat separat sub **PolyForm Noncommercial License 1.0.0**. Consultați [ragtime/LICENSE](ragtime/LICENSE) pentru detalii.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Suport
- **Documentație**: [docs/](docs/)
diff --git a/docs/i18n/README.ru.md b/docs/i18n/README.ru.md
index 7bc3ac07..3a7b2d74 100644
--- a/docs/i18n/README.ru.md
+++ b/docs/i18n/README.ru.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ npm run bug-report
---
-## Лицензия
+## License
-Этот проект лицензирован под **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Все права защищены.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Полные сведения см. в файле [LICENSE](LICENSE).
+See the [LICENSE](LICENSE) file for full details.
-**Что это означает:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Вы можете свободно использовать, модифицировать и распространять это программное обеспечение
-- Если вы модифицируете и развертываете на сетевом сервере, вы должны сделать свой исходный код доступным
-- Производные работы также должны быть лицензированы под AGPL-3.0
-- Для этого программного обеспечения НЕТ ГАРАНТИЙ
-
-**Примечание о Ragtime**: Директория `ragtime/` лицензирована отдельно под **PolyForm Noncommercial License 1.0.0**. Подробности см. в [ragtime/LICENSE](ragtime/LICENSE).
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Поддержка
- **Документация**: [docs/](docs/)
diff --git a/docs/i18n/README.sv.md b/docs/i18n/README.sv.md
index 39c9cb3b..e07898dc 100644
--- a/docs/i18n/README.sv.md
+++ b/docs/i18n/README.sv.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Se [Utvecklingsguide](https://docs.claude-mem.ai/development) för bidragsarbets
---
-## Licens
+## License
-Detta projekt är licensierat under **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Alla rättigheter förbehållna.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Se [LICENSE](LICENSE)-filen för fullständiga detaljer.
+See the [LICENSE](LICENSE) file for full details.
-**Vad detta betyder:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Du kan använda, modifiera och distribuera denna programvara fritt
-- Om du modifierar och distribuerar på en nätverksserver måste du göra din källkod tillgänglig
-- Härledda verk måste också licensieras under AGPL-3.0
-- Det finns INGEN GARANTI för denna programvara
-
-**Notering om Ragtime**: Katalogen `ragtime/` är licensierad separat under **PolyForm Noncommercial License 1.0.0**. Se [ragtime/LICENSE](ragtime/LICENSE) för detaljer.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Support
- **Dokumentation**: [docs/](docs/)
diff --git a/docs/i18n/README.th.md b/docs/i18n/README.th.md
index cb77f90a..2b19e86d 100644
--- a/docs/i18n/README.th.md
+++ b/docs/i18n/README.th.md
@@ -49,7 +49,7 @@
+
@@ -272,25 +272,21 @@ npm run bug-report
---
-## ใบอนุญาต
+## License
-โปรเจกต์นี้ได้รับอนุญาตภายใต้ **GNU Affero General Public License v3.0** (AGPL-3.0)
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack) สงวนลิขสิทธิ์ทั้งหมด
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-ดูไฟล์ [LICENSE](LICENSE) สำหรับรายละเอียดทั้งหมด
+See the [LICENSE](LICENSE) file for full details.
-**ความหมาย:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- คุณสามารถใช้ ดัดแปลง และแจกจ่ายซอฟต์แวร์นี้ได้อย่างอิสระ
-- หากคุณดัดแปลงและปรับใช้บนเซิร์ฟเวอร์เครือข่าย คุณต้องทำให้ซอร์สโค้ดของคุณพร้อมใช้งาน
-- งานที่เป็นอนุพันธ์ต้องได้รับอนุญาตภายใต้ AGPL-3.0 ด้วย
-- ไม่มีการรับประกันสำหรับซอฟต์แวร์นี้
-
-**หมายเหตุเกี่ยวกับ Ragtime**: ไดเรกทอรี `ragtime/` ได้รับอนุญาตแยกต่างหากภายใต้ **PolyForm Noncommercial License 1.0.0** ดู [ragtime/LICENSE](ragtime/LICENSE) สำหรับรายละเอียด
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## การสนับสนุน
- **เอกสาร**: [docs/](docs/)
diff --git a/docs/i18n/README.tl.md b/docs/i18n/README.tl.md
index fa56d764..f3b93756 100644
--- a/docs/i18n/README.tl.md
+++ b/docs/i18n/README.tl.md
@@ -51,7 +51,7 @@
+
@@ -297,25 +297,21 @@ Tingnan ang [Gabay nang pagbuo](https://docs.claude-mem.ai/development) para sa
---
-## Lisensya
+## License
-Ang proyektong ito ay licensed sa ilalim ng **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Tingnan ang [LICENSE](LICENSE) file para sa buong detalye.
+See the [LICENSE](LICENSE) file for full details.
-**Ano ang ibig sabihin nito:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Maaari mong gamitin, baguhin, at ipamahagi ang software na ito nang libre
-- Kung babaguhin mo at i-deploy sa isang network server, kailangan mong gawing available ang iyong source code
-- Dapat ding naka-license sa AGPL-3.0 ang mga derivative works
-- WALANG WARRANTY para sa software na ito
-
-**Tala tungkol sa Ragtime**: Ang `ragtime/` directory ay may hiwalay na lisensya sa ilalim ng **PolyForm Noncommercial License 1.0.0**. Tingnan ang [ragtime/LICENSE](ragtime/LICENSE) para sa detalye.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Suporta
- **Dokumentasyon**: [docs/](docs/)
@@ -325,4 +321,4 @@ Tingnan ang [LICENSE](LICENSE) file para sa buong detalye.
---
-**Built with Claude Agent SDK** | **Powered by Claude Code** | **Made with TypeScript**
+**Built with Claude Agent SDK** | **Works with Claude Code** | **Made with TypeScript**
diff --git a/docs/i18n/README.tr.md b/docs/i18n/README.tr.md
index 3c36f6ab..fcc79986 100644
--- a/docs/i18n/README.tr.md
+++ b/docs/i18n/README.tr.md
@@ -49,7 +49,7 @@
+
@@ -272,25 +272,21 @@ Katkı iş akışı için [Geliştirme Kılavuzu](https://docs.claude-mem.ai/dev
---
-## Lisans
+## License
-Bu proje **GNU Affero General Public License v3.0** (AGPL-3.0) altında lisanslanmıştır.
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Telif Hakkı (C) 2025 Alex Newman (@thedotmack). Tüm hakları saklıdır.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Tam detaylar için [LICENSE](LICENSE) dosyasına bakın.
+See the [LICENSE](LICENSE) file for full details.
-**Bu Ne Anlama Gelir:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Bu yazılımı özgürce kullanabilir, değiştirebilir ve dağıtabilirsiniz
-- Değiştirip bir ağ sunucusunda dağıtırsanız, kaynak kodunuzu kullanılabilir hale getirmelisiniz
-- Türev çalışmalar da AGPL-3.0 altında lisanslanmalıdır
-- Bu yazılım için HİÇBİR GARANTİ yoktur
-
-**Ragtime Hakkında Not**: `ragtime/` dizini ayrı olarak **PolyForm Noncommercial License 1.0.0** altında lisanslanmıştır. Detaylar için [ragtime/LICENSE](ragtime/LICENSE) dosyasına bakın.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Destek
- **Dokümantasyon**: [docs/](docs/)
diff --git a/docs/i18n/README.uk.md b/docs/i18n/README.uk.md
index b7aa2a39..7ea180ea 100644
--- a/docs/i18n/README.uk.md
+++ b/docs/i18n/README.uk.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ npm run bug-report
---
-## Ліцензія
+## License
-Цей проєкт ліцензовано під **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Авторське право (C) 2025 Alex Newman (@thedotmack). Всі права захищені.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Дивіться файл [LICENSE](LICENSE) для повних деталей.
+See the [LICENSE](LICENSE) file for full details.
-**Що це означає:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Ви можете використовувати, модифікувати та поширювати це програмне забезпечення вільно
-- Якщо ви модифікуєте та розгортаєте на мережевому сервері, ви повинні зробити свій вихідний код доступним
-- Похідні роботи також повинні бути ліцензовані під AGPL-3.0
-- Для цього програмного забезпечення НЕМАЄ ГАРАНТІЇ
-
-**Примітка про Ragtime**: Каталог `ragtime/` ліцензовано окремо під **PolyForm Noncommercial License 1.0.0**. Дивіться [ragtime/LICENSE](ragtime/LICENSE) для деталей.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Підтримка
- **Документація**: [docs/](docs/)
diff --git a/docs/i18n/README.ur.md b/docs/i18n/README.ur.md
index c67e593d..8f4a0b17 100644
--- a/docs/i18n/README.ur.md
+++ b/docs/i18n/README.ur.md
@@ -50,7 +50,7 @@
+
@@ -278,25 +278,21 @@ npm run bug-report
---
-## لائسنس
+## License
-یہ منصوبہ **GNU Affero General Public License v3.0** (AGPL-3.0) کے تحت لائسنس ہے۔
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack)۔ تمام حقوق محفوظ ہیں۔
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-مکمل تفصیلات کے لیے [LICENSE](LICENSE) فائل دیکھیں۔
+See the [LICENSE](LICENSE) file for full details.
-**اس کا مطلب کیا ہے:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- آپ اس سافٹ ویئر کو آزادی سے استعمال، تبدیل اور تقسیم کر سکتے ہیں
-- اگر آپ اسے تبدیل کریں اور نیٹ ورک سرور میں نشر کریں تو آپ کو اپنا سورس کوڈ دستیاب کرنا ہوگا
-- ماخوذ کام بھی AGPL-3.0 کے تحت لائسنس ہونے چاہیں
-- اس سافٹ ویئر کے لیے کوئی وارنٹی نہیں
-
-**Ragtime کے بارے میں نوٹ**: `ragtime/` ڈائریکٹری الگ سے **PolyForm Noncommercial License 1.0.0** کے تحت لائسنس ہے۔ تفصیلات کے لیے [ragtime/LICENSE](ragtime/LICENSE) دیکھیں۔
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## معاونت
- **دستاویزات**: [docs/](docs/)
diff --git a/docs/i18n/README.vi.md b/docs/i18n/README.vi.md
index a0a99a48..a6b9922d 100644
--- a/docs/i18n/README.vi.md
+++ b/docs/i18n/README.vi.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ Xem [Hướng Dẫn Phát Triển](https://docs.claude-mem.ai/development) để
---
-## Giấy Phép
+## License
-Dự án này được cấp phép theo **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Bảo lưu mọi quyền.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Xem tệp [LICENSE](LICENSE) để biết chi tiết đầy đủ.
+See the [LICENSE](LICENSE) file for full details.
-**Điều Này Có Nghĩa Là:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Bạn có thể sử dụng, sửa đổi và phân phối phần mềm này tự do
-- Nếu bạn sửa đổi và triển khai trên máy chủ mạng, bạn phải cung cấp mã nguồn của mình
-- Các tác phẩm phái sinh cũng phải được cấp phép theo AGPL-3.0
-- KHÔNG CÓ BẢO HÀNH cho phần mềm này
-
-**Lưu Ý Về Ragtime**: Thư mục `ragtime/` được cấp phép riêng theo **PolyForm Noncommercial License 1.0.0**. Xem [ragtime/LICENSE](ragtime/LICENSE) để biết chi tiết.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Hỗ Trợ
- **Tài Liệu**: [docs/](docs/)
diff --git a/docs/i18n/README.zh-tw.md b/docs/i18n/README.zh-tw.md
index 47406a7f..54c3a153 100644
--- a/docs/i18n/README.zh-tw.md
+++ b/docs/i18n/README.zh-tw.md
@@ -49,7 +49,7 @@
+
@@ -278,25 +278,21 @@ npm run bug-report
---
-## 授權條款
+## License
-本專案採用 **GNU Affero 通用公共授權條款 v3.0**(AGPL-3.0)授權。
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-完整詳情請參閱 [LICENSE](LICENSE) 檔案。
+See the [LICENSE](LICENSE) file for full details.
-**這代表什麼:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- 您可以自由使用、修改與散佈此軟體
-- 如果您修改並部署於網路伺服器上,您必須公開您的原始碼
-- 衍生作品也必須採用 AGPL-3.0 授權
-- 本軟體不提供任何擔保
-
-**關於 Ragtime 的說明**:`ragtime/` 目錄採用 **PolyForm Noncommercial License 1.0.0** 另行授權。詳情請參閱 [ragtime/LICENSE](ragtime/LICENSE)。
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## 支援
- **文件**:[docs/](docs/)
diff --git a/docs/i18n/README.zh.md b/docs/i18n/README.zh.md
index 75c26a5d..63cfca16 100644
--- a/docs/i18n/README.zh.md
+++ b/docs/i18n/README.zh.md
@@ -50,7 +50,7 @@
+
@@ -273,25 +273,21 @@ npm run bug-report
---
-## 许可证
+## License
-本项目采用 **GNU Affero General Public License v3.0** (AGPL-3.0) 许可。
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack)。保留所有权利。
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-详见 [LICENSE](LICENSE) 文件了解完整详情。
+See the [LICENSE](LICENSE) file for full details.
-**这意味着什么:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- 您可以自由使用、修改和分发本软件
-- 如果您修改并部署到网络服务器上,必须公开您的源代码
-- 衍生作品也必须采用 AGPL-3.0 许可
-- 本软件不提供任何保证
-
-**关于 Ragtime 的说明**: `ragtime/` 目录单独采用 **PolyForm Noncommercial License 1.0.0** 许可。详见 [ragtime/LICENSE](ragtime/LICENSE)。
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## 支持
- **文档**: [docs/](docs/)
diff --git a/docs/i18n/pt.md b/docs/i18n/pt.md
index 3740ca16..9dca97c4 100644
--- a/docs/i18n/pt.md
+++ b/docs/i18n/pt.md
@@ -51,7 +51,7 @@
+
@@ -274,25 +274,21 @@ Veja [Guia de Desenvolvimento](https://docs.claude-mem.ai/development) para o fl
---
-## Licença
+## License
-Este projeto está licenciado sob a **GNU Affero General Public License v3.0** (AGPL-3.0).
+This project is licensed under the **Apache License 2.0** (Apache-2.0).
-Copyright (C) 2025 Alex Newman (@thedotmack). Todos os direitos reservados.
+Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
-Veja o arquivo [LICENSE](LICENSE) para detalhes completos.
+See the [LICENSE](LICENSE) file for full details.
-**O Que Isso Significa:**
+Apache-2.0 allows broad use, modification, distribution, and commercial use, subject to its terms.
-- Você pode usar, modificar e distribuir este software livremente
-- Se você modificar e implantar em um servidor de rede, você deve disponibilizar seu código-fonte
-- Trabalhos derivados também devem ser licenciados sob AGPL-3.0
-- NÃO HÁ GARANTIA para este software
-
-**Nota sobre Ragtime**: O diretório `ragtime/` é licenciado separadamente sob a **PolyForm Noncommercial License 1.0.0**. Veja [ragtime/LICENSE](ragtime/LICENSE) para detalhes.
+**Ragtime note**: The ragtime/ directory is licensed under the **Apache License 2.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.
---
+
## Suporte
- **Documentação**: [docs/](docs/)
diff --git a/docs/ip-boundary.md b/docs/ip-boundary.md
new file mode 100644
index 00000000..eb49b0e4
--- /dev/null
+++ b/docs/ip-boundary.md
@@ -0,0 +1,45 @@
+# IP Boundary
+
+Claude-Mem uses an open-core structure.
+
+## Apache-2.0 components
+
+- Core memory engine
+- Claude-Mem Server
+- CLI
+- SDKs
+- REST API schemas
+- MCP tools/resources/prompts
+- Claude Code adapter
+- Generic agent adapters
+- Storage adapters
+- Reference knowledge agents
+- Tests
+- Examples
+- Public documentation
+
+## Reserved commercial/private areas
+
+These areas are not shipped by Claude-Mem Server v0.1 and should remain outside
+the Apache-2.0 public implementation unless maintainers explicitly open-source
+them later.
+
+- Magic Recall hosted cloud
+- Team/org memory sync
+- Admin dashboard
+- SSO/SAML/SCIM
+- Enterprise RBAC
+- Enterprise audit log UI
+- DLP/policy engine
+- Premium knowledge agents
+- Managed evals
+- Customer deployment tooling
+- Enterprise observability
+- Support/SLA workflows
+- Internal eval datasets
+- Private customer connectors
+
+## Rule
+
+Do not put commercial/private implementation code into the Apache-2.0 public repo
+unless the maintainers intentionally decide to open-source it.
diff --git a/docs/license.md b/docs/license.md
new file mode 100644
index 00000000..86cea6ea
--- /dev/null
+++ b/docs/license.md
@@ -0,0 +1,29 @@
+# License
+
+Claude-Mem is licensed under the Apache License 2.0.
+
+The Apache-2.0 license applies to the open-source core, including the memory
+engine, Claude-Mem Server, CLI, SDKs, adapters, MCP tools, schemas, tests,
+examples, and public documentation.
+
+Apache-2.0 allows broad use, modification, distribution, and commercial use,
+subject to the license terms.
+
+## Why Apache-2.0?
+
+Claude-Mem is intended to be embedded broadly inside developer tools, local
+agents, MCP clients, enterprise systems, robotics stacks, and production agent
+harnesses. Apache-2.0 supports that goal while preserving attribution and
+including explicit patent license terms.
+
+## Reserved commercial/private areas
+
+Claude-Mem Server v0.1 does not ship hosted cloud, team sync, enterprise
+features, premium knowledge agents, private evals, or customer deployment
+tooling. Those areas are reserved outside the Apache-2.0 public implementation
+unless maintainers explicitly open-source them later.
+
+## Third-party marks
+
+Apache-2.0 licenses code. It does not grant rights to third-party trademarks or
+brand names.
diff --git a/docs/migration-worker-to-server.md b/docs/migration-worker-to-server.md
new file mode 100644
index 00000000..092b8b87
--- /dev/null
+++ b/docs/migration-worker-to-server.md
@@ -0,0 +1,13 @@
+# Worker To Server Migration
+
+Claude-Mem 13 keeps the worker path in place. Server beta is an additional runtime option for teams, deployable containers, API keys, and BullMQ/Valkey queues.
+
+Compatibility commands remain available:
+
+```sh
+claude-mem start
+claude-mem worker start
+claude-mem server start
+```
+
+The server storage boundary reads legacy worker data while adding server-owned projects, sessions, agent events, memory items, teams, API keys, and audit logs. Migrate adapters gradually by writing to `/v1/events` and `/v1/memories`; keep existing `/api/*` hook routes enabled until all clients move.
diff --git a/docs/public/docs.json b/docs/public/docs.json
index 805ee1bb..74cad7f6 100644
--- a/docs/public/docs.json
+++ b/docs/public/docs.json
@@ -127,7 +127,7 @@
"header": "Legal",
"items": [
{
- "label": "License (AGPL-3.0)",
+ "label": "License (Apache-2.0)",
"href": "https://github.com/thedotmack/claude-mem/blob/main/LICENSE"
}
]
diff --git a/docs/security.md b/docs/security.md
new file mode 100644
index 00000000..0a331bbd
--- /dev/null
+++ b/docs/security.md
@@ -0,0 +1,7 @@
+# Security
+
+Server beta defaults to API-key auth. `CLAUDE_MEM_AUTH_MODE=local-dev` only enables the loopback development bypass when `CLAUDE_MEM_ALLOW_LOCAL_DEV_BYPASS=1` is also set; do not use it behind a reverse proxy or on a publicly reachable bind address.
+
+API keys are generated with the `cmem_` prefix and displayed once. Claude-Mem stores only a SHA-256 hash, prefix metadata, scopes, status, and timestamps in SQLite.
+
+BullMQ mode requires Redis or Valkey. Queue payloads are limited to work needed to resume observation processing; SQLite remains the canonical memory store. Use Redis persistence for deployable examples and avoid placing server ports on public networks without auth.
diff --git a/docs/server-storage-boundary.md b/docs/server-storage-boundary.md
new file mode 100644
index 00000000..9d44679a
--- /dev/null
+++ b/docs/server-storage-boundary.md
@@ -0,0 +1,52 @@
+# Server Storage Boundary
+
+Phase 4 adds the contracts and SQLite tables for the future server-owned storage model. It is additive only: worker routes, providers, existing search, and legacy observation writes still use the current `sdk_sessions`, `observations`, `session_summaries`, `user_prompts`, and `pending_messages` tables.
+
+## Tables
+
+Server-owned tables are created by `ensureServerStorageSchema()` in `src/storage/sqlite/schema.ts`:
+
+- `projects`
+- `server_sessions`
+- `agent_events`
+- `memory_items`
+- `memory_sources`
+- `teams`
+- `team_members`
+- `api_keys`
+- `audit_log`
+
+`MigrationRunner` records these tables as schema version 33. Repositories also call the same helper so future server bootstrap code can use the storage boundary without depending on worker initialization.
+
+## Contracts
+
+Shared Zod contracts live under `src/core/schemas/`. Repository methods parse inputs and outputs through these schemas and store structured fields as JSON `TEXT`, matching the existing Bun SQLite style.
+
+## Observation To Memory Translation
+
+The translation layer is intentionally documented but not wired into existing search in this phase.
+
+Decision: legacy `observations` remain the source of truth until a later migration explicitly backfills and switches readers. A future translator should create one `memory_items` row per legacy `observations` row with:
+
+- `memory_items.kind = 'observation'`
+- `memory_items.type = observations.type`
+- `memory_items.project_id` resolved from the canonical `projects` row for `observations.project`
+- `memory_items.server_session_id` resolved through `server_sessions.memory_session_id = observations.memory_session_id`
+- `memory_items.legacy_observation_id = observations.id`
+- `title`, `subtitle`, `text`, `narrative`, `facts`, `concepts`, `files_read`, and `files_modified` copied from the legacy row
+- one `memory_sources` row with `source_type = 'observation'`, `legacy_table = 'observations'`, and `legacy_id = observations.id`
+
+The schema enforces this as an idempotent backfill target with partial unique
+indexes on `memory_items.legacy_observation_id` and
+`memory_sources(source_type, legacy_table, legacy_id)` when legacy source IDs are
+present.
+
+Until that backfill exists, new repositories may write `memory_items` directly for server-owned workflows, but no worker path should read from `memory_items` as a replacement for `observations`.
+
+Rows that reference `server_sessions` must stay inside the same `project_id`.
+SQLite triggers reject cross-project `agent_events` and `memory_items` links so
+project-scoped reads cannot accidentally mix memories from another project.
+
+## Auth Placeholder
+
+`api_keys` is a local placeholder for future Better Auth integration. This phase stores hashes, prefixes, scopes, and status locally; it does not introduce a Better Auth runtime dependency or middleware wiring.
diff --git a/docs/server.md b/docs/server.md
new file mode 100644
index 00000000..cdadcd48
--- /dev/null
+++ b/docs/server.md
@@ -0,0 +1,13 @@
+# Claude-Mem Server
+
+Claude-Mem Server is the beta server runtime for Claude-Mem 13. The existing worker remains available for compatibility; server beta adds API-key auth, team/project-aware storage contracts, REST V1 routes, and an optional BullMQ queue backend.
+
+Local development can use SQLite queues and the explicit `CLAUDE_MEM_AUTH_MODE=local-dev` plus `CLAUDE_MEM_ALLOW_LOCAL_DEV_BYPASS=1` loopback bypass. Deployable mode should use:
+
+```sh
+CLAUDE_MEM_QUEUE_ENGINE=bullmq
+CLAUDE_MEM_REDIS_URL=redis://127.0.0.1:6379
+CLAUDE_MEM_AUTH_MODE=api-key
+```
+
+Use `claude-mem server api-key create --scope memories:read,memories:write` to create a bearer key. The raw key is shown once; only a SHA-256 hash is stored.
diff --git a/openclaw/openclaw.plugin.json b/openclaw/openclaw.plugin.json
index 18b6d1dc..ddabf71c 100644
--- a/openclaw/openclaw.plugin.json
+++ b/openclaw/openclaw.plugin.json
@@ -1,9 +1,10 @@
{
"id": "claude-mem",
"name": "Claude-Mem (Persistent Memory)",
- "description": "Official OpenClaw plugin for Claude-Mem. Records observations from embedded runner sessions and streams them to messaging channels.",
+ "description": "OpenClaw plugin for Claude-Mem. Records observations from embedded runner sessions and streams them to messaging channels.",
"kind": "memory",
"version": "12.7.5",
+ "license": "Apache-2.0",
"author": "thedotmack",
"homepage": "https://claude-mem.com",
"skills": ["skills/make-plan", "skills/do"],
diff --git a/openclaw/package.json b/openclaw/package.json
index 8bbb27d2..8a6752f3 100644
--- a/openclaw/package.json
+++ b/openclaw/package.json
@@ -2,6 +2,7 @@
"name": "@openclaw/claude-mem",
"version": "1.0.0",
"private": true,
+ "license": "Apache-2.0",
"type": "module",
"main": "dist/index.js",
"scripts": {
diff --git a/package.json b/package.json
index e5e5ba37..a2097a08 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"nodejs"
],
"author": "Alex Newman",
- "license": "AGPL-3.0",
+ "license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/thedotmack/claude-mem.git"
@@ -66,7 +66,7 @@
"scripts": {
"dev": "npm run build-and-sync",
"build": "node scripts/sync-plugin-manifests.js && node scripts/build-hooks.js",
- "build-and-sync": "npm run build && npm run sync-marketplace && sleep 1 && (cd ~/.claude/plugins/marketplaces/thedotmack && npm run worker:restart) && npm run queue:clear",
+ "build-and-sync": "npm run build && npm run sync-marketplace && sleep 1 && (cd ~/.claude/plugins/marketplaces/thedotmack && npm run worker:restart)",
"sync-marketplace": "node scripts/sync-marketplace.cjs",
"sync-marketplace:force": "node scripts/sync-marketplace.cjs --force",
"build:binaries": "node scripts/build-worker-binary.js",
@@ -81,7 +81,7 @@
"worker:status": "bun plugin/scripts/worker-service.cjs status",
"queue": "bun scripts/check-pending-queue.ts",
"queue:process": "bun scripts/check-pending-queue.ts --process",
- "queue:clear": "bun scripts/clear-failed-queue.ts --all --force",
+ "queue:clear:pending": "bun scripts/clear-pending-queue.ts --all --force",
"pr:status": "bun scripts/pr-babysit-status.ts",
"claude-md:regenerate": "bun scripts/regenerate-claude-md.ts",
"claude-md:dry-run": "bun scripts/regenerate-claude-md.ts --dry-run",
@@ -109,6 +109,7 @@
"test:context": "bun test tests/context/",
"test:infra": "bun test tests/infrastructure/",
"test:server": "bun test tests/server/",
+ "e2e:server-beta:docker": "bash scripts/e2e-server-beta-docker.sh",
"prepublishOnly": "npm run build",
"release": "np",
"release:patch": "np patch --no-cleanup",
@@ -123,13 +124,19 @@
},
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.2.119",
+ "@better-auth/api-key": "^1.6.9",
"@clack/prompts": "^1.2.0",
"@modelcontextprotocol/sdk": "^1.29.0",
"ansi-to-html": "^0.7.2",
+ "better-auth": "^1.6.9",
+ "bullmq": "^5.76.6",
+ "cors": "^2.8.6",
"dompurify": "^3.4.1",
"express": "^5.2.1",
"glob": "^13.0.6",
"handlebars": "^4.7.9",
+ "ioredis": "^5.10.1",
+ "pg": "^8.20.0",
"picocolors": "^1.1.1",
"react": "^19.2.5",
"react-dom": "^19.2.5",
@@ -150,6 +157,7 @@
"@types/dompurify": "^3.2.0",
"@types/express": "^5.0.6",
"@types/node": "^25.6.0",
+ "@types/pg": "^8.20.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"esbuild": "^0.28.0",
diff --git a/plans/2026-05-06-observation-queue-engine-deep-dive.md b/plans/2026-05-06-observation-queue-engine-deep-dive.md
new file mode 100644
index 00000000..cdb3eb8c
--- /dev/null
+++ b/plans/2026-05-06-observation-queue-engine-deep-dive.md
@@ -0,0 +1,249 @@
+# Observation Queue Engine Deep Dive: BullMQ vs Bee-Queue
+
+Date: 2026-05-06
+
+## Executive decision
+
+If claude-mem replaces its observation queue with one of the two Redis-backed libraries, choose **BullMQ**, not Bee-Queue.
+
+That said, the current observation queue is not a generic background job queue. It is a durable, per-session input stream feeding long-lived provider generators. Replacing it with Redis should not be the default local install path unless claude-mem is willing to require, bundle, or supervise Redis. If Redis is not acceptable as a new operational dependency, the better path is to keep the SQLite queue and fix the contract/test drift.
+
+Recommended path:
+
+1. Stabilize the current queue contract and tests.
+2. Add a queue-engine adapter boundary.
+3. Keep SQLite as the default backend.
+4. Add BullMQ as an optional backend for users who explicitly configure Redis.
+5. Do not adopt Bee-Queue.
+
+## Current claude-mem queue shape
+
+The active queue path is:
+
+- `src/services/worker/http/shared.ts` and `SessionRoutes.ts` ingest observations/summarize requests.
+- `SessionManager.queueObservation()` and `queueSummarize()` persist rows through `PendingMessageStore.enqueue()`.
+- `SessionQueueProcessor.createIterator()` claims one row at a time and wakes via a per-session `EventEmitter`.
+- Provider loops in `ClaudeProvider`, `GeminiProvider`, and `OpenRouterProvider` consume `sessionManager.getMessageIterator(sessionDbId)`.
+- Parsed agent output is stored through `processAgentResponse()`, then `SessionManager.clearPendingForSession()` clears that session's pending rows.
+
+Key semantics that must survive any replacement:
+
+- Per-session FIFO ordering.
+- At-most-one active consumer per session.
+- Durable queue across worker restarts.
+- Startup recovery from `processing` back to `pending`.
+- Low-latency wakeup when new tool observations arrive.
+- Deduplication by `content_session_id + tool_use_id`.
+- Original observation timestamp preservation for storage/broadcast.
+- Queue depth for `/api/processing-status` and SSE.
+- Local-first behavior and simple install are product requirements, not just implementation details.
+
+Important mismatch found during the dive:
+
+- Current `PendingMessageStore` only models `pending` and `processing`.
+- Older migrations, tests, and scripts still reference `processed`, `failed`, `retry_count`, `completed_at_epoch`, `failed_at_epoch`, and `worker_pid`.
+- `storeObservationsAndMarkComplete()` still updates a row to `processed`, while the currently visible queue path clears all pending messages for the session after parsing.
+- `src/services/sqlite/schema.sql` still creates `idx_pending_messages_worker_pid` even though the visible table definition has no `worker_pid`.
+
+Focused test run:
+
+```sh
+bun test tests/services/sqlite/PendingMessageStore.test.ts tests/services/queue/SessionQueueProcessor.test.ts
+```
+
+Result: 10 pass, 6 fail. Failures show stale tests/contract drift:
+
+- `PendingMessageStore.test.ts` passes `3` as constructor arg, but constructor now expects `onMutate?: () => void`.
+- `SessionQueueProcessor.test.ts` expects retry-after-store-error behavior, but current implementation logs and exits the iterator on claim failure.
+
+This needs to be reconciled before swapping engines; otherwise the migration will encode inconsistent behavior.
+
+## BullMQ deep dive
+
+Sources checked:
+
+- GitHub: https://github.com/taskforcesh/bullmq
+- NPM: https://www.npmjs.com/package/bullmq
+- Docs: https://docs.bullmq.io/
+- Queues: https://docs.bullmq.io/guide/queues
+- Connections/Redis constraints: https://docs.bullmq.io/guide/connections
+- Production notes: https://docs.bullmq.io/guide/going-to-production
+- Manual processing: https://docs.bullmq.io/patterns/manually-fetching-jobs
+- Job IDs/dedupe: https://docs.bullmq.io/guide/jobs/job-ids
+- Stalled jobs: https://docs.bullmq.io/guide/workers/stalled-jobs
+
+Current package/repo facts captured on 2026-05-06:
+
+- NPM latest: `bullmq@5.76.5`.
+- NPM modified: 2026-05-02.
+- GitHub pushed: 2026-05-05.
+- GitHub stars/forks/open issues at capture time: 8808 / 606 / 414.
+- License: MIT.
+- Unpacked size: about 2.5 MB.
+- Dependencies: `ioredis`, `cron-parser`, `msgpackr`, `node-abort-controller`, `semver`, `tslib`.
+- TypeScript types are bundled.
+- A Bun import smoke test succeeded for `import { Queue } from 'bullmq'`.
+
+Strengths for claude-mem:
+
+- Actively maintained and widely used.
+- Built-in TypeScript API.
+- Redis-backed durability and distributed workers.
+- Built-in stalled-job recovery, retry attempts, fixed/exponential backoff, delays, priorities, FIFO/LIFO, auto-removal, QueueEvents, manual processing APIs, and job ID based dedupe.
+- BullMQ docs explicitly support manual job fetching with `Worker#getNextJob()`, `moveToCompleted()`, `moveToFailed()`, and lock extension. This matters because claude-mem's provider loop is closer to a stream consumer than a normal job processor.
+
+Costs and risks:
+
+- Redis becomes required for the queue backend. BullMQ docs require a Redis connection to use queues and recommend Redis compatibility 6.2+.
+- Redis must be configured like durable infrastructure, not cache: AOF persistence and `maxmemory-policy=noeviction` are recommended/required for correctness.
+- Connection count increases. BullMQ docs note each class consumes at least one Redis connection; `Worker` and `QueueEvents` need blocking/duplicated connections in some cases.
+- Jobs store data in Redis in clear text unless claude-mem encrypts or avoids sensitive payload fields. Tool input/output can be sensitive.
+- BullMQ job completion/failure semantics do not map directly to claude-mem's current "provider consumes many messages, parses one response, then clears the session" behavior.
+- Per-session FIFO with parallel sessions is not free in OSS BullMQ. A single global queue with worker concurrency > 1 can violate same-session ordering unless we add a scheduler. BullMQ Pro groups would address this, but claude-mem should not depend on Pro.
+- Custom `jobId` is useful for `tool_use_id` dedupe, but BullMQ custom job IDs must not contain `:`. Use a hash or safe delimiter.
+- Manual processing requires lock management. BullMQ docs call out that manually fetched jobs do not get automatic lock renewal like standard processors; claude-mem would need `extendLock()` for long provider calls or a large lock duration.
+
+Best BullMQ shape if adopted:
+
+- Prefer **one queue per active session** over one global queue initially:
+ - Queue name: `claude-mem:session:
{(e.inclusive?n.value<=e.value:n.value{(e.inclusive?n.value<=e.value:n.valueut(c.pid)).length!==0;)await new Promise(c=>setTimeout(c,100));let i=o.filter(a=>ut(a.pid));for(let a of i){S.warn("SYSTEM",`Session process PID ${a.pid} did not exit after SIGTERM, sending SIGKILL`,{pid:a.pid,pgid:a.pgid,sessionId:n});try{typeof a.pgid=="number"&&process.platform!=="win32"?process.kill(-a.pgid,"SIGKILL"):process.kill(a.pid,"SIGKILL")}catch(c){c instanceof Error?c.code!=="ESRCH"&&S.debug("SYSTEM",`Failed to SIGKILL session process PID ${a.pid}`,{pid:a.pid,pgid:a.pgid},c):S.warn("SYSTEM",`Failed to SIGKILL session process PID ${a.pid} (non-Error)`,{pid:a.pid,pgid:a.pgid,error:String(c)})}}if(i.length>0){let a=Date.now()+nx;for(;Date.now()ut(u.pid)).length!==0;)await new Promise(u=>setTimeout(u,100))}for(let a of r)this.entries.delete(a.id),this.runtimeProcesses.delete(a.id);this.persist();for(let a of r)a.type==="sdk"&&Fc();return S.info("SYSTEM",`Reaped ${r.length} process(es) for session ${e}`,{sessionId:n,reaped:r.length}),r.length}persist(){let e={processes:Object.fromEntries(this.entries.entries())};(0,lt.mkdirSync)(qc.default.dirname(this.registryPath),{recursive:!0}),(0,lt.writeFileSync)(this.registryPath,JSON.stringify(e,null,2))}},Uc=null;function vs(){return Uc||(Uc=new Hc),Uc}var sx=[];function Fc(){let t=sx.shift();t&&t()}var xg=require("child_process"),Pg=require("fs"),zg=require("util");var ix=(0,zg.promisify)(xg.execFile),ax=De.workerPid();async function Tg(t){let e=t.currentPid??process.pid,r=t.pidFilePath??ax,n=t.registry.getAll(),o=[...n].filter(i=>i.pid!==e).sort((i,a)=>Date.parse(a.startedAt)-Date.parse(i.startedAt));for(let i of o){if(!ut(i.pid)){t.registry.unregister(i.id);continue}try{await kg(i,"SIGTERM")}catch(a){a instanceof Error?S.debug("SYSTEM","Failed to send SIGTERM to child process",{pid:i.pid,pgid:i.pgid,type:i.type},a):S.warn("SYSTEM","Failed to send SIGTERM to child process (non-Error)",{pid:i.pid,pgid:i.pgid,type:i.type,error:String(a)})}}await $g(o,5e3);let s=o.filter(i=>ut(i.pid));for(let i of s)try{await kg(i,"SIGKILL")}catch(a){a instanceof Error?S.debug("SYSTEM","Failed to force kill child process",{pid:i.pid,pgid:i.pgid,type:i.type},a):S.warn("SYSTEM","Failed to force kill child process (non-Error)",{pid:i.pid,pgid:i.pgid,type:i.type,error:String(a)})}await $g(s,1e3);for(let i of o)t.registry.unregister(i.id);for(let i of n.filter(a=>a.pid===e))t.registry.unregister(i.id);try{(0,Pg.rmSync)(r,{force:!0})}catch(i){i instanceof Error?S.debug("SYSTEM","Failed to remove PID file during shutdown",{pidFilePath:r},i):S.warn("SYSTEM","Failed to remove PID file during shutdown (non-Error)",{pidFilePath:r,error:String(i)})}t.registry.pruneDeadEntries()}async function $g(t,e){let r=Date.now()+e;for(;Date.now()ct(c.pid)).length!==0;)await new Promise(c=>setTimeout(c,100));let i=o.filter(a=>ct(a.pid));for(let a of i){S.warn("SYSTEM",`Session process PID ${a.pid} did not exit after SIGTERM, sending SIGKILL`,{pid:a.pid,pgid:a.pgid,sessionId:n});try{typeof a.pgid=="number"&&process.platform!=="win32"?process.kill(-a.pgid,"SIGKILL"):process.kill(a.pid,"SIGKILL")}catch(c){c instanceof Error?c.code!=="ESRCH"&&S.debug("SYSTEM",`Failed to SIGKILL session process PID ${a.pid}`,{pid:a.pid,pgid:a.pgid},c):S.warn("SYSTEM",`Failed to SIGKILL session process PID ${a.pid} (non-Error)`,{pid:a.pid,pgid:a.pgid,error:String(c)})}}if(i.length>0){let a=Date.now()+fx;for(;Date.now()ct(u.pid)).length!==0;)await new Promise(u=>setTimeout(u,100))}for(let a of r)this.entries.delete(a.id),this.runtimeProcesses.delete(a.id);this.persist();for(let a of r)a.type==="sdk"&&Fc();return S.info("SYSTEM",`Reaped ${r.length} process(es) for session ${e}`,{sessionId:n,reaped:r.length}),r.length}persist(){let e={processes:Object.fromEntries(this.entries.entries())};(0,ut.mkdirSync)(qc.default.dirname(this.registryPath),{recursive:!0}),(0,ut.writeFileSync)(this.registryPath,JSON.stringify(e,null,2))}},Zc=null;function vs(){return Zc||(Zc=new Hc),Zc}var hx=[];function Fc(){let t=hx.shift();t&&t()}var Rg=require("child_process"),Og=require("fs"),Ig=require("util");var gx=(0,Ig.promisify)(Rg.execFile),_x=De.workerPid();async function Ag(t){let e=t.currentPid??process.pid,r=t.pidFilePath??_x,n=t.registry.getAll(),o=[...n].filter(i=>i.pid!==e).sort((i,a)=>Date.parse(a.startedAt)-Date.parse(i.startedAt));for(let i of o){if(!ct(i.pid)){t.registry.unregister(i.id);continue}try{await Tg(i,"SIGTERM")}catch(a){a instanceof Error?S.debug("SYSTEM","Failed to send SIGTERM to child process",{pid:i.pid,pgid:i.pgid,type:i.type},a):S.warn("SYSTEM","Failed to send SIGTERM to child process (non-Error)",{pid:i.pid,pgid:i.pgid,type:i.type,error:String(a)})}}await zg(o,5e3);let s=o.filter(i=>ct(i.pid));for(let i of s)try{await Tg(i,"SIGKILL")}catch(a){a instanceof Error?S.debug("SYSTEM","Failed to force kill child process",{pid:i.pid,pgid:i.pgid,type:i.type},a):S.warn("SYSTEM","Failed to force kill child process (non-Error)",{pid:i.pid,pgid:i.pgid,type:i.type,error:String(a)})}await zg(s,1e3);for(let i of o)t.registry.unregister(i.id);for(let i of n.filter(a=>a.pid===e))t.registry.unregister(i.id);try{(0,Og.rmSync)(r,{force:!0})}catch(i){i instanceof Error?S.debug("SYSTEM","Failed to remove PID file during shutdown",{pidFilePath:r},i):S.warn("SYSTEM","Failed to remove PID file during shutdown (non-Error)",{pidFilePath:r,error:String(i)})}t.registry.pruneDeadEntries()}async function zg(t,e){let r=Date.now()+e;for(;Date.now()
").replaceAll(" "," ");return`
+
+
+
+`+e+`
+
+
+`}C1.exports=FF;function FF(r,e,t){var n=t||{},i=n.env||process.env.NODE_ENV||"development",a=n.onerror;return function(s){var o,c,l;if(!s&&e.headersSent){ch("cannot 404 after headers sent");return}if(s?(l=GF(s),l===void 0?l=VF(e):o=JF(s),c=UF(s,l,i)):(l=404,c="Cannot "+r.method+" "+MF(BF(r))),ch("default %s",l),s&&a&&setImmediate(a,s,r,e),e.headersSent){ch("cannot %d after headers sent",l),r.socket&&r.socket.destroy();return}$F(r,e,l,o,c)}}function JF(r){if(!(!r.headers||typeof r.headers!="object"))return{...r.headers}}function UF(r,e,t){var n;return t!=="production"&&(n=r.stack,!n&&typeof r.toString=="function"&&(n=r.toString())),n||j1.message[e]}function GF(r){if(typeof r.status=="number"&&r.status>=400&&r.status<600)return r.status;if(typeof r.statusCode=="number"&&r.statusCode>=400&&r.statusCode<600)return r.statusCode}function BF(r){try{return NF.original(r).pathname}catch{return"resource"}}function VF(r){var e=r.statusCode;return(typeof e!="number"||e<400||e>599)&&(e=500),e}function $F(r,e,t,n,i){function a(){var s=qF(i);e.statusCode=t,r.httpVersionMajor<2&&(e.statusMessage=j1.message[t]),e.removeHeader("Content-Encoding"),e.removeHeader("Content-Language"),e.removeHeader("Content-Range");for(let[o,c]of Object.entries(n??{}))e.setHeader(o,c);if(e.setHeader("Content-Security-Policy","default-src 'none'"),e.setHeader("X-Content-Type-Options","nosniff"),e.setHeader("Content-Type","text/html; charset=utf-8"),e.setHeader("Content-Length",Buffer.byteLength(s,"utf8")),r.method==="HEAD"){e.end();return}e.end(s,"utf8")}if(LF(r)){a();return}r.unpipe(),R1(r,a),r.resume()}});var q1=h((dae,L1)=>{"use strict";var vc=Ot()("express:view"),Ss=require("node:path"),HF=require("node:fs"),zF=Ss.dirname,N1=Ss.basename,YF=Ss.extname,M1=Ss.join,WF=Ss.resolve;L1.exports=xc;function xc(r,e){var t=e||{};if(this.defaultEngine=t.defaultEngine,this.ext=YF(r),this.name=r,this.root=t.root,!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");var n=r;if(this.ext||(this.ext=this.defaultEngine[0]!=="."?"."+this.defaultEngine:this.defaultEngine,n+=this.ext),!t.engines[this.ext]){var i=this.ext.slice(1);vc('require "%s"',i);var a=require(i).__express;if(typeof a!="function")throw new Error('Module "'+i+'" does not provide a view engine.');t.engines[this.ext]=a}this.engine=t.engines[this.ext],this.path=this.lookup(n)}xc.prototype.lookup=function(e){var t,n=[].concat(this.root);vc('lookup "%s"',e);for(var i=0;i