claude-memory-layer 1.0.27 → 1.0.29
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.
- package/.env.example +7 -0
- package/AGENTS.md +11 -0
- package/README.md +374 -49
- package/benchmarks/replay/anonymized-real-sessions.json +48 -0
- package/dist/cli/index.js +10097 -6003
- package/dist/cli/index.js.map +4 -4
- package/dist/core/index.js +9745 -5587
- package/dist/core/index.js.map +4 -4
- package/dist/hooks/post-tool-use.js +6545 -5270
- package/dist/hooks/post-tool-use.js.map +4 -4
- package/dist/hooks/semantic-daemon.js +6646 -5354
- package/dist/hooks/semantic-daemon.js.map +4 -4
- package/dist/hooks/session-end.js +6618 -5347
- package/dist/hooks/session-end.js.map +4 -4
- package/dist/hooks/session-start.js +6619 -5354
- package/dist/hooks/session-start.js.map +4 -4
- package/dist/hooks/stop.js +6614 -5325
- package/dist/hooks/stop.js.map +4 -4
- package/dist/hooks/user-prompt-submit.js +6702 -5356
- package/dist/hooks/user-prompt-submit.js.map +4 -4
- package/dist/index.js +13537 -0
- package/dist/index.js.map +7 -0
- package/dist/mcp/index.js +20770 -0
- package/dist/mcp/index.js.map +7 -0
- package/dist/server/api/index.js +6632 -5319
- package/dist/server/api/index.js.map +4 -4
- package/dist/server/index.js +6667 -5340
- package/dist/server/index.js.map +4 -4
- package/dist/services/memory-service.js +6568 -5350
- package/dist/services/memory-service.js.map +4 -4
- package/dist/ui/assets/js/bootstrap.js +244 -0
- package/dist/ui/assets/js/chat.js +373 -0
- package/dist/ui/assets/js/disclosure.js +232 -0
- package/dist/ui/assets/js/modals.js +298 -0
- package/dist/ui/assets/js/overview.js +655 -0
- package/dist/ui/assets/js/state.js +72 -0
- package/dist/ui/assets/js/views.js +468 -0
- package/dist/ui/index.html +43 -1
- package/dist/ui/index.ts +3 -0
- package/dist/ui/style.css +222 -0
- package/docs/ARCHITECTURE_COMPARISON_AND_RECOMMENDATIONS.md +627 -0
- package/docs/HERMES_MEMORY_INGESTION_ANALYSIS.md +440 -0
- package/docs/MEMORY_USEFULNESS_AUDIT.md +371 -0
- package/docs/MEMORY_USEFULNESS_AUDIT_RAW.json +80 -0
- package/docs/MEMSEARCH_PROJECT_STRUCTURE_ANALYSIS.md +333 -0
- package/docs/PRODUCT_VALIDATION_MATRIX.md +82 -0
- package/docs/PROJECT_STRUCTURE_ANALYSIS.md +421 -0
- package/docs/REFACTORING_MILESTONES_AND_ISSUES.md +501 -0
- package/docs/REFACTORING_PLAN_THIN_CORE.md +414 -0
- package/docs/REFERENCE_PROJECT_ANALYSES.md +25 -0
- package/docs/SUPERLOCALMEMORY_PROJECT_STRUCTURE_ANALYSIS.md +452 -0
- package/docs/TARGET_ARCHITECTURE_AND_FOLDER_STRUCTURE.md +446 -0
- package/docs/architecture/comparison-index.md +47 -0
- package/docs/reports/codex-real-data-validation-20260505T040447Z.md +46 -0
- package/package.json +12 -5
- package/scripts/build.ts +25 -8
- package/scripts/generate-session-qrels.ts +126 -0
- package/scripts/postinstall-embedding-backend.cjs +142 -0
- package/scripts/replay-retrieval-benchmark.ts +69 -0
- package/specs/thin-core-refactor/context.md +275 -0
- package/specs/thin-core-refactor/plan.md +536 -0
- package/specs/thin-core-refactor/spec.md +465 -0
- package/src/adapters/claude/capture/index.ts +3 -0
- package/src/adapters/claude/context/index.ts +3 -0
- package/src/adapters/claude/hooks/index.ts +21 -0
- package/src/adapters/claude/hooks/post-tool-use.ts +239 -0
- package/src/adapters/claude/hooks/prompt-injection-policy.ts +104 -0
- package/src/adapters/claude/hooks/semantic-daemon-client.ts +209 -0
- package/src/adapters/claude/hooks/semantic-daemon.ts +283 -0
- package/src/adapters/claude/hooks/session-end.ts +59 -0
- package/src/adapters/claude/hooks/session-start.ts +73 -0
- package/src/adapters/claude/hooks/stop.ts +128 -0
- package/src/adapters/claude/hooks/user-prompt-submit.ts +361 -0
- package/src/adapters/claude/index.ts +4 -0
- package/src/adapters/claude/transcript/index.ts +4 -0
- package/src/adapters/claude/transcript/transcript-reader.ts +57 -0
- package/src/adapters/claude/transcript/turn-reconstructor.ts +65 -0
- package/src/apps/cli/claude-settings-hooks.ts +138 -0
- package/src/apps/cli/codex-import-runner.ts +125 -0
- package/src/apps/cli/codex-validation-output.ts +95 -0
- package/src/apps/cli/hermes-import-runner.ts +130 -0
- package/src/apps/cli/hermes-validation-output.ts +91 -0
- package/src/apps/cli/index.ts +1731 -0
- package/src/apps/cli/mcp-install.ts +106 -0
- package/src/apps/cli/retrieval-disclosure-output.ts +196 -0
- package/src/apps/dashboard/assets/js/bootstrap.js +244 -0
- package/src/apps/dashboard/assets/js/chat.js +373 -0
- package/src/apps/dashboard/assets/js/disclosure.js +232 -0
- package/src/apps/dashboard/assets/js/modals.js +298 -0
- package/src/apps/dashboard/assets/js/overview.js +655 -0
- package/src/apps/dashboard/assets/js/state.js +72 -0
- package/src/apps/dashboard/assets/js/views.js +468 -0
- package/src/{ui → apps/dashboard}/index.html +43 -1
- package/src/apps/dashboard/index.ts +3 -0
- package/src/{ui → apps/dashboard}/style.css +222 -0
- package/src/apps/index.ts +5 -0
- package/src/apps/server/api/chat.ts +244 -0
- package/src/apps/server/api/citations.ts +105 -0
- package/src/apps/server/api/events.ts +137 -0
- package/src/apps/server/api/health.ts +53 -0
- package/src/apps/server/api/index.ts +26 -0
- package/src/apps/server/api/projects.ts +74 -0
- package/src/apps/server/api/search.ts +184 -0
- package/src/apps/server/api/sessions.ts +115 -0
- package/src/apps/server/api/stats.ts +723 -0
- package/src/apps/server/api/turns.ts +143 -0
- package/src/apps/server/api/utils.ts +65 -0
- package/src/apps/server/index.ts +111 -0
- package/src/cli/index.ts +2 -1311
- package/src/cli/retrieval-disclosure-output.ts +2 -0
- package/src/compat/index.ts +5 -0
- package/src/core/derive/fact-deriver.ts +170 -0
- package/src/core/derive/index.ts +2 -0
- package/src/core/derive/summary-deriver.ts +76 -0
- package/src/core/embedder.ts +4 -152
- package/src/core/engine/embedding-maintenance-service.ts +187 -0
- package/src/core/engine/endless-memory-services.ts +4 -0
- package/src/core/engine/index.ts +19 -0
- package/src/core/engine/memory-engine-services.ts +170 -0
- package/src/core/engine/memory-ingest-service.ts +317 -0
- package/src/core/engine/memory-query-service.ts +173 -0
- package/src/core/engine/memory-runtime-service.ts +162 -0
- package/src/core/engine/memory-service-composition.ts +231 -0
- package/src/core/engine/retrieval-analytics-service.ts +181 -0
- package/src/core/engine/retrieval-disclosure-service.ts +420 -0
- package/src/core/engine/retrieval-orchestrator.ts +377 -0
- package/src/core/engine/retrieval-services.ts +176 -0
- package/src/core/engine/shared-memory-services.ts +4 -0
- package/src/core/entity-repo.ts +1 -3
- package/src/core/event-store.ts +3 -3
- package/src/core/evidence-aligner.ts +2 -2
- package/src/core/external-market-context.ts +582 -0
- package/src/core/graduation.ts +2 -3
- package/src/core/index.ts +21 -0
- package/src/core/matcher.ts +2 -4
- package/src/core/model/memory-fact.ts +30 -0
- package/src/core/model/memory-rule.ts +14 -0
- package/src/core/model/memory-summary.ts +21 -0
- package/src/core/model/raw-event.ts +28 -0
- package/src/core/model/retrieval-result.ts +35 -0
- package/src/core/privacy/filter.ts +21 -10
- package/src/core/product-validation-matrix.ts +314 -0
- package/src/core/progressive-retriever.ts +1 -2
- package/src/core/registry/project-path.ts +54 -0
- package/src/core/registry/session-registry.ts +69 -0
- package/src/core/replay-evaluator.ts +625 -0
- package/src/core/retrieval-benchmark.ts +117 -0
- package/src/core/retrieval-quality.ts +109 -0
- package/src/core/retriever.ts +53 -15
- package/src/core/session-qrels.ts +360 -0
- package/src/core/shared-event-store.ts +1 -1
- package/src/core/sqlite-event-store.ts +35 -11
- package/src/core/task/blocker-resolver.ts +2 -2
- package/src/core/task/task-resolver.ts +0 -1
- package/src/core/vector-outbox.ts +1 -10
- package/src/core/vector-worker.ts +1 -1
- package/src/extensions/endless-memory/endless-memory-services.ts +350 -0
- package/src/extensions/endless-memory/index.ts +1 -0
- package/src/extensions/index.ts +5 -0
- package/src/extensions/mcp/handlers.ts +960 -0
- package/src/extensions/mcp/index.ts +48 -0
- package/src/extensions/mcp/tools.ts +252 -0
- package/src/extensions/shared-memory/index.ts +1 -0
- package/src/extensions/shared-memory/shared-memory-services.ts +211 -0
- package/src/extensions/vector/embedder.ts +197 -0
- package/src/extensions/vector/index.ts +1 -0
- package/src/hooks/post-tool-use.ts +3 -236
- package/src/hooks/semantic-daemon-client.ts +1 -208
- package/src/hooks/semantic-daemon.ts +6 -271
- package/src/hooks/session-end.ts +4 -79
- package/src/hooks/session-start.ts +4 -73
- package/src/hooks/stop.ts +3 -173
- package/src/hooks/user-prompt-submit.ts +3 -338
- package/src/index.ts +13 -0
- package/src/mcp/handlers.ts +2 -212
- package/src/mcp/index.ts +3 -46
- package/src/mcp/tools.ts +2 -78
- package/src/server/api/chat.ts +2 -244
- package/src/server/api/citations.ts +2 -105
- package/src/server/api/events.ts +2 -137
- package/src/server/api/health.ts +2 -53
- package/src/server/api/index.ts +2 -26
- package/src/server/api/projects.ts +2 -74
- package/src/server/api/search.ts +2 -102
- package/src/server/api/sessions.ts +2 -115
- package/src/server/api/stats.ts +2 -724
- package/src/server/api/turns.ts +2 -143
- package/src/server/api/utils.ts +2 -46
- package/src/server/index.ts +2 -100
- package/src/services/bootstrap-organizer.ts +46 -26
- package/src/services/codex-session-history-importer.ts +521 -29
- package/src/services/hermes-session-history-importer.ts +733 -0
- package/src/services/memory-service-config.ts +36 -0
- package/src/services/memory-service-registry.ts +150 -0
- package/src/services/memory-service.ts +211 -1325
- package/src/services/session-history-importer.ts +58 -14
- package/tests/README.md +23 -0
- package/tests/adapters/claude/claude-semantic-daemon-adapter.test.ts +54 -0
- package/tests/adapters/claude/claude-transcript-reconstructor.test.ts +98 -0
- package/tests/adapters/claude-hook-prompt-injection-policy.test.ts +99 -0
- package/tests/apps/app-layer-boundary.test.ts +48 -0
- package/tests/apps/claude-settings-hooks.test.ts +107 -0
- package/tests/apps/cli-disclosure-output.test.ts +212 -0
- package/tests/apps/codex-import-runner.test.ts +99 -0
- package/tests/apps/codex-validation-output.test.ts +100 -0
- package/tests/apps/hermes-import-runner.test.ts +99 -0
- package/tests/apps/mcp-install-command.test.ts +59 -0
- package/tests/apps/package-build-entrypoints.test.ts +30 -0
- package/tests/apps/postinstall-embedding-backend.test.ts +167 -0
- package/tests/apps/search-api-disclosure.test.ts +162 -0
- package/tests/apps/stats-api-lightweight.test.ts +67 -0
- package/tests/apps/ui-disclosure-output.test.ts +140 -0
- package/tests/{bootstrap-organizer.test.ts → core/bootstrap-organizer.test.ts} +1 -1
- package/tests/{canonical-key.test.ts → core/canonical-key.test.ts} +1 -1
- package/tests/core/codex-session-history-importer-validation.test.ts +185 -0
- package/tests/{consolidation-worker.test.ts → core/consolidation-worker.test.ts} +2 -2
- package/tests/core/embedding-maintenance-service.test.ts +282 -0
- package/tests/{evidence-aligner.test.ts → core/evidence-aligner.test.ts} +1 -1
- package/tests/core/external-market-context.test.ts +209 -0
- package/tests/core/fact-deriver.test.ts +79 -0
- package/tests/core/hermes-session-history-importer-validation.test.ts +609 -0
- package/tests/{ingest-interceptor.test.ts → core/ingest-interceptor.test.ts} +1 -1
- package/tests/{markdown-mirror.test.ts → core/markdown-mirror.test.ts} +2 -2
- package/tests/{matcher.test.ts → core/matcher.test.ts} +1 -1
- package/tests/{md-mirror.test.ts → core/md-mirror.test.ts} +2 -2
- package/tests/core/memory-engine-services.test.ts +240 -0
- package/tests/core/memory-ingest-service.test.ts +296 -0
- package/tests/core/memory-query-service.test.ts +129 -0
- package/tests/core/memory-runtime-service.test.ts +201 -0
- package/tests/core/memory-service-composition.test.ts +192 -0
- package/tests/core/memory-service-config.test.ts +41 -0
- package/tests/core/memory-service-facade.test.ts +30 -0
- package/tests/core/memory-service-registry.test.ts +206 -0
- package/tests/core/product-validation-matrix.test.ts +61 -0
- package/tests/core/project-registry.test.ts +78 -0
- package/tests/core/replay-evaluator.test.ts +181 -0
- package/tests/core/retrieval-analytics-service.test.ts +210 -0
- package/tests/core/retrieval-benchmark.test.ts +93 -0
- package/tests/core/retrieval-disclosure-service.test.ts +264 -0
- package/tests/core/retrieval-orchestrator.test.ts +403 -0
- package/tests/core/retrieval-quality.test.ts +31 -0
- package/tests/core/retrieval-services.test.ts +185 -0
- package/tests/{retriever-fallback-chain.test.ts → core/retriever-fallback-chain.test.ts} +3 -3
- package/tests/{retriever-strategy-scope.test.ts → core/retriever-strategy-scope.test.ts} +70 -3
- package/tests/{retriever.memu-adoption.test.ts → core/retriever.memu-adoption.test.ts} +3 -3
- package/tests/core/session-history-importer-filter.test.ts +78 -0
- package/tests/core/session-qrels.test.ts +250 -0
- package/tests/{sqlite-event-store-replication.test.ts → core/sqlite-event-store-replication.test.ts} +36 -1
- package/tests/core/summary-deriver.test.ts +66 -0
- package/tests/extensions/embedder-warning-suppression.test.ts +53 -0
- package/tests/extensions/endless-memory-extension-boundary.test.ts +17 -0
- package/tests/extensions/endless-memory-services.test.ts +325 -0
- package/tests/extensions/mcp-context-tools.test.ts +905 -0
- package/tests/extensions/mcp-extension-boundary.test.ts +21 -0
- package/tests/extensions/mcp-package-build.test.ts +22 -0
- package/tests/extensions/mcp-project-aware-tools.test.ts +102 -0
- package/tests/extensions/shared-memory-extension-boundary.test.ts +24 -0
- package/tests/extensions/shared-memory-services.test.ts +309 -0
- package/tests/extensions/vector-extension-boundary.test.ts +21 -0
- package/.claude/settings.local.json +0 -25
- package/.npm-cache/_cacache/content-v2/sha512/04/76/c098f88dfe584a2b80870bff7421b05d17d3d9ee1027f77772332a22d3f93a9a57101a2855107f6ad82077a818bba912b2bc317f2361b5ddb09ad284d9ce +0 -0
- package/.npm-cache/_cacache/content-v2/sha512/60/25/d2ecd39cfc7cab58351162814be77f935c6d6491c10c3745d456da7ddb2117ffd90c10e53fe3c0f1ed16b403307841543634504398b16ee4e6b6dd8e0c45 +0 -0
- package/.npm-cache/_cacache/index-v5/2b/9a/7f8f40206ed8a2e0a84efaa953ccaed1f5d001e14b931083f2e7a0738007 +0 -2
- package/.npm-cache/_cacache/index-v5/2e/d9/fcfa5c6a6abdc2a3644ab84a95936047298c465a2f47ee03db8f7fe1e946 +0 -3
- package/.npm-cache/_cacache/index-v5/a9/42/e519633356d12d3d2f19da66a8301016d496c8f5c3e0554124aaa62dc043 +0 -2
- package/.npm-cache/_logs/2026-02-26T12_04_52_729Z-debug-0.log +0 -256
- package/.npm-cache/_logs/2026-02-26T12_05_36_835Z-debug-0.log +0 -18
- package/.npm-cache/_logs/2026-02-26T12_05_45_982Z-debug-0.log +0 -32
- package/.npm-cache/_logs/2026-02-26T12_05_48_515Z-debug-0.log +0 -260
- package/.npm-cache/_logs/2026-02-26T12_05_53_567Z-debug-0.log +0 -69
- package/.npm-cache/_update-notifier-last-checked +0 -0
- package/bootstrap-kb/decisions/decisions.md +0 -244
- package/bootstrap-kb/glossary/glossary.md +0 -46
- package/bootstrap-kb/modules/.claude-plugin.md +0 -22
- package/bootstrap-kb/modules/agents.md.md +0 -15
- package/bootstrap-kb/modules/claude.md.md +0 -15
- package/bootstrap-kb/modules/context.md.md +0 -15
- package/bootstrap-kb/modules/docs.md +0 -18
- package/bootstrap-kb/modules/handoff.md.md +0 -15
- package/bootstrap-kb/modules/package-lock.json.md +0 -15
- package/bootstrap-kb/modules/package.json.md +0 -15
- package/bootstrap-kb/modules/plan.md.md +0 -15
- package/bootstrap-kb/modules/readme.md.md +0 -15
- package/bootstrap-kb/modules/scripts.md +0 -26
- package/bootstrap-kb/modules/spec.md.md +0 -15
- package/bootstrap-kb/modules/specs.md +0 -20
- package/bootstrap-kb/modules/src.md +0 -51
- package/bootstrap-kb/modules/tests.md +0 -42
- package/bootstrap-kb/modules/tsconfig.json.md +0 -15
- package/bootstrap-kb/modules/vitest.config.ts.md +0 -15
- package/bootstrap-kb/overview/overview.md +0 -40
- package/bootstrap-kb/sources/manifest.json +0 -950
- package/bootstrap-kb/sources/manifest.md +0 -227
- package/bootstrap-kb/timeline/timeline.md +0 -57
- package/claude-memory-layer-1.0.14.tgz +0 -0
- package/d.sh +0 -3
- package/deploy.sh +0 -3
- package/dist/ui/app.js +0 -2101
- package/memory/.claude-plugin/commands/2026-02-25.md +0 -263
- package/memory/_index.md +0 -419
- package/memory/agent_response/uncategorized/2026-02-26.md +0 -176
- package/memory/agent_response/uncategorized/2026-03-03.md +0 -14
- package/memory/agent_response/uncategorized/2026-03-04.md +0 -1421
- package/memory/agent_response/uncategorized/2026-03-05.md +0 -157
- package/memory/default/uncategorized/2026-02-25.md +0 -4839
- package/memory/session_summary/uncategorized/2026-02-26.md +0 -13
- package/memory/session_summary/uncategorized/2026-03-03.md +0 -5
- package/memory/session_summary/uncategorized/2026-03-04.md +0 -50
- package/memory/specs/20260207-dashboard-upgrade/2026-02-25.md +0 -142
- package/memory/specs/citations-system/2026-02-25.md +0 -1121
- package/memory/specs/endless-mode/2026-02-25.md +0 -1392
- package/memory/specs/entity-edge-model/2026-02-25.md +0 -1263
- package/memory/specs/evidence-aligner-v2/2026-02-25.md +0 -1028
- package/memory/specs/mcp-desktop-integration/2026-02-25.md +0 -1334
- package/memory/specs/post-tool-use-hook/2026-02-25.md +0 -1164
- package/memory/specs/private-tags/2026-02-25.md +0 -1057
- package/memory/specs/progressive-disclosure/2026-02-25.md +0 -1436
- package/memory/specs/task-entity-system/2026-02-25.md +0 -924
- package/memory/specs/vector-outbox-v2/2026-02-25.md +0 -1510
- package/memory/specs/web-viewer-ui/2026-02-25.md +0 -1709
- package/memory/tool_observation/uncategorized/2026-02-26.md +0 -209
- package/memory/tool_observation/uncategorized/2026-03-03.md +0 -21
- package/memory/tool_observation/uncategorized/2026-03-04.md +0 -1033
- package/memory/tool_observation/uncategorized/2026-03-05.md +0 -33
- package/memory/user_prompt/uncategorized/2026-02-26.md +0 -25
- package/memory/user_prompt/uncategorized/2026-03-04.md +0 -634
- package/memory/user_prompt/uncategorized/2026-03-05.md +0 -6
- package/specs/optional-duckdb/context.md +0 -77
- package/specs/optional-duckdb/plan.md +0 -142
- package/specs/optional-duckdb/spec.md +0 -35
- package/src/ui/app.js +0 -2101
package/src/mcp/tools.ts
CHANGED
|
@@ -1,78 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
* Available tools for Claude Desktop
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
-
|
|
8
|
-
export const tools: Tool[] = [
|
|
9
|
-
{
|
|
10
|
-
name: 'mem-search',
|
|
11
|
-
description: 'Search claude-memory-layer for relevant past conversations and insights. Returns a compact index of results - use mem-details to get full content.',
|
|
12
|
-
inputSchema: {
|
|
13
|
-
type: 'object',
|
|
14
|
-
properties: {
|
|
15
|
-
query: {
|
|
16
|
-
type: 'string',
|
|
17
|
-
description: 'Natural language search query'
|
|
18
|
-
},
|
|
19
|
-
topK: {
|
|
20
|
-
type: 'number',
|
|
21
|
-
description: 'Maximum number of results (default: 5, max: 20)'
|
|
22
|
-
},
|
|
23
|
-
sessionId: {
|
|
24
|
-
type: 'string',
|
|
25
|
-
description: 'Optional: filter by specific session ID'
|
|
26
|
-
},
|
|
27
|
-
eventType: {
|
|
28
|
-
type: 'string',
|
|
29
|
-
enum: ['user_prompt', 'agent_response', 'tool_observation', 'session_summary'],
|
|
30
|
-
description: 'Optional: filter by event type'
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
required: ['query']
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
name: 'mem-timeline',
|
|
38
|
-
description: 'Get chronological context around specific memories. Useful for understanding the conversation flow.',
|
|
39
|
-
inputSchema: {
|
|
40
|
-
type: 'object',
|
|
41
|
-
properties: {
|
|
42
|
-
ids: {
|
|
43
|
-
type: 'array',
|
|
44
|
-
items: { type: 'string' },
|
|
45
|
-
description: 'Memory IDs (from mem-search) to get timeline for'
|
|
46
|
-
},
|
|
47
|
-
windowSize: {
|
|
48
|
-
type: 'number',
|
|
49
|
-
description: 'Number of items before/after each ID (default: 3)'
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
required: ['ids']
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
name: 'mem-details',
|
|
57
|
-
description: 'Get full content of specific memories. Use after mem-search to get complete information.',
|
|
58
|
-
inputSchema: {
|
|
59
|
-
type: 'object',
|
|
60
|
-
properties: {
|
|
61
|
-
ids: {
|
|
62
|
-
type: 'array',
|
|
63
|
-
items: { type: 'string' },
|
|
64
|
-
description: 'Memory IDs to fetch full details for'
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
required: ['ids']
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
name: 'mem-stats',
|
|
72
|
-
description: 'Get statistics about the memory storage (total events, sessions, etc.)',
|
|
73
|
-
inputSchema: {
|
|
74
|
-
type: 'object',
|
|
75
|
-
properties: {}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
];
|
|
1
|
+
// Compatibility re-export for the MCP extension tool definitions.
|
|
2
|
+
export * from '../extensions/mcp/tools.js';
|
package/src/server/api/chat.ts
CHANGED
|
@@ -1,244 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Endpoints for memory-aware chat using Claude CLI
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { Hono } from 'hono';
|
|
7
|
-
import { streamSSE } from 'hono/streaming';
|
|
8
|
-
import { spawn } from 'child_process';
|
|
9
|
-
import type { ChildProcess } from 'child_process';
|
|
10
|
-
import { getServiceFromQuery } from './utils.js';
|
|
11
|
-
|
|
12
|
-
export const chatRouter = new Hono();
|
|
13
|
-
|
|
14
|
-
interface ChatRequest {
|
|
15
|
-
message: string;
|
|
16
|
-
history?: Array<{ role: 'user' | 'assistant'; content: string }>;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const CLAUDE_TIMEOUT_MS = 120_000;
|
|
20
|
-
|
|
21
|
-
chatRouter.post('/', async (c) => {
|
|
22
|
-
let body: ChatRequest;
|
|
23
|
-
try {
|
|
24
|
-
body = await c.req.json<ChatRequest>();
|
|
25
|
-
} catch {
|
|
26
|
-
return c.json({ error: 'Invalid JSON body' }, 400);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (!body.message?.trim()) {
|
|
30
|
-
return c.json({ error: 'Message is required' }, 400);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const memoryService = getServiceFromQuery(c);
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
await memoryService.initialize();
|
|
37
|
-
|
|
38
|
-
// Retrieve relevant memories for context
|
|
39
|
-
let memoryContext = '';
|
|
40
|
-
let statsContext = '';
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
const result = await memoryService.retrieveMemories(body.message, {
|
|
44
|
-
topK: 8,
|
|
45
|
-
minScore: 0.5
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
if (result.memories.length > 0) {
|
|
49
|
-
const parts: string[] = ['## Relevant Memories\n'];
|
|
50
|
-
for (const m of result.memories) {
|
|
51
|
-
const date = new Date(m.event.timestamp).toISOString().split('T')[0];
|
|
52
|
-
const content = m.event.content.slice(0, 500);
|
|
53
|
-
parts.push(`### [${m.event.eventType}] ${date} (score: ${m.score.toFixed(2)})`);
|
|
54
|
-
parts.push(content);
|
|
55
|
-
if (m.sessionContext) {
|
|
56
|
-
parts.push(`_Context: ${m.sessionContext}_`);
|
|
57
|
-
}
|
|
58
|
-
parts.push('');
|
|
59
|
-
}
|
|
60
|
-
memoryContext = parts.join('\n');
|
|
61
|
-
}
|
|
62
|
-
} catch {
|
|
63
|
-
// Continue without memory context if retrieval fails
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const stats = await memoryService.getStats();
|
|
68
|
-
const levels = stats.levelStats.map(l => `${l.level}: ${l.count}`).join(', ');
|
|
69
|
-
statsContext = [
|
|
70
|
-
'## Memory Stats',
|
|
71
|
-
`- Total events: ${stats.totalEvents}`,
|
|
72
|
-
`- Vector nodes: ${stats.vectorCount}`,
|
|
73
|
-
`- By level: ${levels}`
|
|
74
|
-
].join('\n');
|
|
75
|
-
} catch {
|
|
76
|
-
// Continue without stats if it fails
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const fullPrompt = buildPrompt(
|
|
80
|
-
statsContext,
|
|
81
|
-
memoryContext,
|
|
82
|
-
body.history || [],
|
|
83
|
-
body.message
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
// Stream response via SSE
|
|
87
|
-
return streamSSE(c, async (stream) => {
|
|
88
|
-
try {
|
|
89
|
-
await streamClaudeResponse(fullPrompt, stream);
|
|
90
|
-
} catch (err) {
|
|
91
|
-
await stream.writeSSE({
|
|
92
|
-
event: 'error',
|
|
93
|
-
data: JSON.stringify({ error: (err as Error).message })
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
} catch (error) {
|
|
98
|
-
return c.json({ error: (error as Error).message }, 500);
|
|
99
|
-
} finally {
|
|
100
|
-
await memoryService.shutdown();
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
function buildPrompt(
|
|
105
|
-
statsContext: string,
|
|
106
|
-
memoryContext: string,
|
|
107
|
-
history: Array<{ role: string; content: string }>,
|
|
108
|
-
currentMessage: string
|
|
109
|
-
): string {
|
|
110
|
-
const parts: string[] = [];
|
|
111
|
-
|
|
112
|
-
parts.push('You are a helpful assistant that answers questions about the user\'s code memory data.');
|
|
113
|
-
parts.push('The memory system tracks coding sessions, tool usage, prompts, and responses.');
|
|
114
|
-
parts.push('Answer concisely based on the memory context below. If you don\'t have enough data, say so.');
|
|
115
|
-
parts.push('Use markdown formatting in your responses.\n');
|
|
116
|
-
|
|
117
|
-
if (statsContext) {
|
|
118
|
-
parts.push(statsContext);
|
|
119
|
-
parts.push('');
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (memoryContext) {
|
|
123
|
-
parts.push(memoryContext);
|
|
124
|
-
} else {
|
|
125
|
-
parts.push('No directly relevant memories found for this query.');
|
|
126
|
-
parts.push('Answer based on general knowledge or suggest the user rephrase.\n');
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
parts.push('---\n');
|
|
130
|
-
|
|
131
|
-
// Include recent history (last 10 turns)
|
|
132
|
-
const recentHistory = history.slice(-10);
|
|
133
|
-
if (recentHistory.length > 0) {
|
|
134
|
-
parts.push('## Conversation History\n');
|
|
135
|
-
for (const msg of recentHistory) {
|
|
136
|
-
const prefix = msg.role === 'user' ? 'User' : 'Assistant';
|
|
137
|
-
parts.push(`**${prefix}:** ${msg.content}\n`);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
parts.push(`**User:** ${currentMessage}`);
|
|
142
|
-
|
|
143
|
-
return parts.join('\n');
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function streamClaudeResponse(
|
|
147
|
-
prompt: string,
|
|
148
|
-
stream: { writeSSE: (msg: { event?: string; data: string }) => Promise<void> }
|
|
149
|
-
): Promise<void> {
|
|
150
|
-
return new Promise((resolve, reject) => {
|
|
151
|
-
const proc: ChildProcess = spawn('claude', [
|
|
152
|
-
'-p',
|
|
153
|
-
'--output-format', 'stream-json',
|
|
154
|
-
'--verbose'
|
|
155
|
-
], {
|
|
156
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
157
|
-
env: { ...process.env }
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
const timeout = setTimeout(() => {
|
|
161
|
-
proc.kill('SIGTERM');
|
|
162
|
-
reject(new Error('Chat response timed out after 2 minutes'));
|
|
163
|
-
}, CLAUDE_TIMEOUT_MS);
|
|
164
|
-
|
|
165
|
-
// Write prompt to stdin
|
|
166
|
-
proc.stdin!.write(prompt);
|
|
167
|
-
proc.stdin!.end();
|
|
168
|
-
|
|
169
|
-
let buffer = '';
|
|
170
|
-
let lastSentText = '';
|
|
171
|
-
|
|
172
|
-
proc.stdout!.on('data', async (chunk: Buffer) => {
|
|
173
|
-
buffer += chunk.toString();
|
|
174
|
-
const lines = buffer.split('\n');
|
|
175
|
-
buffer = lines.pop() || '';
|
|
176
|
-
|
|
177
|
-
for (const line of lines) {
|
|
178
|
-
if (!line.trim()) continue;
|
|
179
|
-
try {
|
|
180
|
-
const parsed = JSON.parse(line);
|
|
181
|
-
|
|
182
|
-
// Extract text from assistant messages
|
|
183
|
-
if (parsed.type === 'assistant' && parsed.message?.content) {
|
|
184
|
-
const textBlocks = parsed.message.content
|
|
185
|
-
.filter((b: { type: string }) => b.type === 'text')
|
|
186
|
-
.map((b: { text: string }) => b.text)
|
|
187
|
-
.join('');
|
|
188
|
-
|
|
189
|
-
if (textBlocks.length > lastSentText.length) {
|
|
190
|
-
const delta = textBlocks.slice(lastSentText.length);
|
|
191
|
-
lastSentText = textBlocks;
|
|
192
|
-
await stream.writeSSE({
|
|
193
|
-
event: 'message',
|
|
194
|
-
data: JSON.stringify({ content: delta })
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Handle completion
|
|
200
|
-
if (parsed.type === 'result') {
|
|
201
|
-
await stream.writeSSE({ event: 'done', data: '{}' });
|
|
202
|
-
}
|
|
203
|
-
} catch {
|
|
204
|
-
// Skip non-JSON lines
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
proc.stderr!.on('data', (chunk: Buffer) => {
|
|
210
|
-
if (process.env.CLAUDE_MEMORY_DEBUG) {
|
|
211
|
-
console.error('[chat] claude stderr:', chunk.toString());
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
proc.on('error', (err) => {
|
|
216
|
-
clearTimeout(timeout);
|
|
217
|
-
if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
218
|
-
reject(new Error('Claude CLI not found. Install with: npm install -g @anthropic-ai/claude-code'));
|
|
219
|
-
} else {
|
|
220
|
-
reject(err);
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
proc.on('close', async (code) => {
|
|
225
|
-
clearTimeout(timeout);
|
|
226
|
-
|
|
227
|
-
// Flush remaining buffer
|
|
228
|
-
if (buffer.trim()) {
|
|
229
|
-
try {
|
|
230
|
-
const parsed = JSON.parse(buffer);
|
|
231
|
-
if (parsed.type === 'result') {
|
|
232
|
-
await stream.writeSSE({ event: 'done', data: '{}' });
|
|
233
|
-
}
|
|
234
|
-
} catch { /* ignore */ }
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (code !== 0 && code !== null) {
|
|
238
|
-
reject(new Error(`Claude CLI exited with code ${code}`));
|
|
239
|
-
} else {
|
|
240
|
-
resolve();
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
}
|
|
1
|
+
/** Compatibility API module. Real app lives in src/apps/server/api. */
|
|
2
|
+
export * from '../../apps/server/api/chat.js';
|
|
@@ -1,105 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Endpoints for citation management
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { Hono } from 'hono';
|
|
7
|
-
import { getServiceFromQuery } from './utils.js';
|
|
8
|
-
import { generateCitationId, parseCitationId } from '../../core/citation-generator.js';
|
|
9
|
-
|
|
10
|
-
export const citationsRouter = new Hono();
|
|
11
|
-
|
|
12
|
-
// GET /api/citations/:id - Get citation by ID
|
|
13
|
-
citationsRouter.get('/:id', async (c) => {
|
|
14
|
-
const { id } = c.req.param();
|
|
15
|
-
|
|
16
|
-
// Support both formats: "a7Bc3x" or "mem:a7Bc3x"
|
|
17
|
-
const citationId = parseCitationId(id) || id;
|
|
18
|
-
const memoryService = getServiceFromQuery(c);
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
await memoryService.initialize();
|
|
22
|
-
|
|
23
|
-
// Search through recent events to find the one matching this citation ID
|
|
24
|
-
const recentEvents = await memoryService.getRecentEvents(10000);
|
|
25
|
-
|
|
26
|
-
const event = recentEvents.find(e => {
|
|
27
|
-
const eventCitationId = generateCitationId(e.id);
|
|
28
|
-
return eventCitationId === citationId;
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
if (!event) {
|
|
32
|
-
return c.json({ error: 'Citation not found' }, 404);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return c.json({
|
|
36
|
-
citation: {
|
|
37
|
-
id: citationId,
|
|
38
|
-
eventId: event.id
|
|
39
|
-
},
|
|
40
|
-
event: {
|
|
41
|
-
id: event.id,
|
|
42
|
-
eventType: event.eventType,
|
|
43
|
-
timestamp: event.timestamp,
|
|
44
|
-
sessionId: event.sessionId,
|
|
45
|
-
content: event.content,
|
|
46
|
-
metadata: event.metadata
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
} catch (error) {
|
|
50
|
-
return c.json({ error: (error as Error).message }, 500);
|
|
51
|
-
} finally {
|
|
52
|
-
await memoryService.shutdown();
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// GET /api/citations/:id/related - Get related citations
|
|
57
|
-
citationsRouter.get('/:id/related', async (c) => {
|
|
58
|
-
const { id } = c.req.param();
|
|
59
|
-
const citationId = parseCitationId(id) || id;
|
|
60
|
-
const memoryService = getServiceFromQuery(c);
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
await memoryService.initialize();
|
|
64
|
-
|
|
65
|
-
const recentEvents = await memoryService.getRecentEvents(10000);
|
|
66
|
-
|
|
67
|
-
// Find the main event
|
|
68
|
-
const event = recentEvents.find(e => {
|
|
69
|
-
const eventCitationId = generateCitationId(e.id);
|
|
70
|
-
return eventCitationId === citationId;
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
if (!event) {
|
|
74
|
-
return c.json({ error: 'Citation not found' }, 404);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Get surrounding events from same session
|
|
78
|
-
const sessionEvents = recentEvents
|
|
79
|
-
.filter(e => e.sessionId === event.sessionId)
|
|
80
|
-
.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
81
|
-
|
|
82
|
-
const eventIndex = sessionEvents.findIndex(e => e.id === event.id);
|
|
83
|
-
const prev = eventIndex > 0 ? sessionEvents[eventIndex - 1] : null;
|
|
84
|
-
const next = eventIndex < sessionEvents.length - 1 ? sessionEvents[eventIndex + 1] : null;
|
|
85
|
-
|
|
86
|
-
return c.json({
|
|
87
|
-
previous: prev ? {
|
|
88
|
-
citationId: generateCitationId(prev.id),
|
|
89
|
-
eventType: prev.eventType,
|
|
90
|
-
timestamp: prev.timestamp,
|
|
91
|
-
preview: prev.content.slice(0, 100) + (prev.content.length > 100 ? '...' : '')
|
|
92
|
-
} : null,
|
|
93
|
-
next: next ? {
|
|
94
|
-
citationId: generateCitationId(next.id),
|
|
95
|
-
eventType: next.eventType,
|
|
96
|
-
timestamp: next.timestamp,
|
|
97
|
-
preview: next.content.slice(0, 100) + (next.content.length > 100 ? '...' : '')
|
|
98
|
-
} : null
|
|
99
|
-
});
|
|
100
|
-
} catch (error) {
|
|
101
|
-
return c.json({ error: (error as Error).message }, 500);
|
|
102
|
-
} finally {
|
|
103
|
-
await memoryService.shutdown();
|
|
104
|
-
}
|
|
105
|
-
});
|
|
1
|
+
/** Compatibility API module. Real app lives in src/apps/server/api. */
|
|
2
|
+
export * from '../../apps/server/api/citations.js';
|
package/src/server/api/events.ts
CHANGED
|
@@ -1,137 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Endpoints for event management
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { Hono } from 'hono';
|
|
7
|
-
import { getServiceFromQuery } from './utils.js';
|
|
8
|
-
|
|
9
|
-
export const eventsRouter = new Hono();
|
|
10
|
-
|
|
11
|
-
// GET /api/events - List events with filters
|
|
12
|
-
eventsRouter.get('/', async (c) => {
|
|
13
|
-
const sessionId = c.req.query('sessionId');
|
|
14
|
-
const eventType = c.req.query('type');
|
|
15
|
-
const level = c.req.query('level');
|
|
16
|
-
const sort = c.req.query('sort') || 'recent'; // recent | accessed | oldest
|
|
17
|
-
const q = (c.req.query('q') || '').trim().toLowerCase();
|
|
18
|
-
const limit = parseInt(c.req.query('limit') || '100', 10);
|
|
19
|
-
const offset = parseInt(c.req.query('offset') || '0', 10);
|
|
20
|
-
const memoryService = getServiceFromQuery(c);
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
await memoryService.initialize();
|
|
24
|
-
|
|
25
|
-
let events: any[];
|
|
26
|
-
|
|
27
|
-
// Filter by level using the dedicated method
|
|
28
|
-
if (level) {
|
|
29
|
-
events = await memoryService.getEventsByLevel(level, { limit: limit + offset + 1000, offset: 0 });
|
|
30
|
-
} else {
|
|
31
|
-
events = await memoryService.getRecentEvents(limit + offset + 1000);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Filter by session
|
|
35
|
-
if (sessionId) {
|
|
36
|
-
events = events.filter(e => e.sessionId === sessionId);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Filter by type
|
|
40
|
-
if (eventType) {
|
|
41
|
-
events = events.filter(e => e.eventType === eventType);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Content query filter
|
|
45
|
-
if (q) {
|
|
46
|
-
events = events.filter(e => (e.content || '').toLowerCase().includes(q));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Sort
|
|
50
|
-
if (sort === 'accessed') {
|
|
51
|
-
events.sort((a: any, b: any) => {
|
|
52
|
-
const aTime = a.last_accessed_at || '';
|
|
53
|
-
const bTime = b.last_accessed_at || '';
|
|
54
|
-
return bTime.localeCompare(aTime);
|
|
55
|
-
});
|
|
56
|
-
} else if (sort === 'most-accessed') {
|
|
57
|
-
events.sort((a: any, b: any) => (b.access_count || 0) - (a.access_count || 0));
|
|
58
|
-
} else if (sort === 'oldest') {
|
|
59
|
-
events.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
60
|
-
}
|
|
61
|
-
// 'recent' is default (already sorted by timestamp DESC from the query)
|
|
62
|
-
|
|
63
|
-
// Pagination
|
|
64
|
-
const total = events.length;
|
|
65
|
-
events = events.slice(offset, offset + limit);
|
|
66
|
-
|
|
67
|
-
return c.json({
|
|
68
|
-
events: events.map(e => ({
|
|
69
|
-
id: e.id,
|
|
70
|
-
eventType: e.eventType,
|
|
71
|
-
timestamp: e.timestamp,
|
|
72
|
-
sessionId: e.sessionId,
|
|
73
|
-
preview: e.content.slice(0, 200) + (e.content.length > 200 ? '...' : ''),
|
|
74
|
-
contentLength: e.content.length,
|
|
75
|
-
metadata: e.metadata,
|
|
76
|
-
accessCount: (e as any).access_count || 0,
|
|
77
|
-
lastAccessedAt: (e as any).last_accessed_at || null
|
|
78
|
-
})),
|
|
79
|
-
total,
|
|
80
|
-
limit,
|
|
81
|
-
offset,
|
|
82
|
-
hasMore: offset + limit < total
|
|
83
|
-
});
|
|
84
|
-
} catch (error) {
|
|
85
|
-
return c.json({ error: (error as Error).message }, 500);
|
|
86
|
-
} finally {
|
|
87
|
-
await memoryService.shutdown();
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// GET /api/events/:id - Get event details
|
|
92
|
-
eventsRouter.get('/:id', async (c) => {
|
|
93
|
-
const { id } = c.req.param();
|
|
94
|
-
const memoryService = getServiceFromQuery(c);
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
await memoryService.initialize();
|
|
98
|
-
|
|
99
|
-
const recentEvents = await memoryService.getRecentEvents(10000);
|
|
100
|
-
const event = recentEvents.find(e => e.id === id);
|
|
101
|
-
|
|
102
|
-
if (!event) {
|
|
103
|
-
return c.json({ error: 'Event not found' }, 404);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Get surrounding events for context
|
|
107
|
-
const sessionEvents = recentEvents
|
|
108
|
-
.filter(e => e.sessionId === event.sessionId)
|
|
109
|
-
.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
110
|
-
|
|
111
|
-
const eventIndex = sessionEvents.findIndex(e => e.id === id);
|
|
112
|
-
const start = Math.max(0, eventIndex - 2);
|
|
113
|
-
const end = Math.min(sessionEvents.length, eventIndex + 3);
|
|
114
|
-
const context = sessionEvents.slice(start, end).filter(e => e.id !== id);
|
|
115
|
-
|
|
116
|
-
return c.json({
|
|
117
|
-
event: {
|
|
118
|
-
id: event.id,
|
|
119
|
-
eventType: event.eventType,
|
|
120
|
-
timestamp: event.timestamp,
|
|
121
|
-
sessionId: event.sessionId,
|
|
122
|
-
content: event.content,
|
|
123
|
-
metadata: event.metadata
|
|
124
|
-
},
|
|
125
|
-
context: context.map(e => ({
|
|
126
|
-
id: e.id,
|
|
127
|
-
eventType: e.eventType,
|
|
128
|
-
timestamp: e.timestamp,
|
|
129
|
-
preview: e.content.slice(0, 100) + (e.content.length > 100 ? '...' : '')
|
|
130
|
-
}))
|
|
131
|
-
});
|
|
132
|
-
} catch (error) {
|
|
133
|
-
return c.json({ error: (error as Error).message }, 500);
|
|
134
|
-
} finally {
|
|
135
|
-
await memoryService.shutdown();
|
|
136
|
-
}
|
|
137
|
-
});
|
|
1
|
+
/** Compatibility API module. Real app lives in src/apps/server/api. */
|
|
2
|
+
export * from '../../apps/server/api/events.js';
|
package/src/server/api/health.ts
CHANGED
|
@@ -1,53 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Operational health checks including outbox backlog/failures
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { Hono } from 'hono';
|
|
7
|
-
import { getServiceFromQuery } from './utils.js';
|
|
8
|
-
|
|
9
|
-
export const healthRouter = new Hono();
|
|
10
|
-
|
|
11
|
-
// GET /api/health
|
|
12
|
-
healthRouter.get('/', async (c) => {
|
|
13
|
-
const memoryService = getServiceFromQuery(c);
|
|
14
|
-
try {
|
|
15
|
-
await memoryService.initialize();
|
|
16
|
-
|
|
17
|
-
const [stats, outbox] = await Promise.all([
|
|
18
|
-
memoryService.getStats(),
|
|
19
|
-
memoryService.getOutboxStats()
|
|
20
|
-
]);
|
|
21
|
-
|
|
22
|
-
const outboxPending = outbox.embedding.pending + outbox.vector.pending;
|
|
23
|
-
const outboxFailed = outbox.embedding.failed + outbox.vector.failed;
|
|
24
|
-
|
|
25
|
-
const status = outboxFailed > 0 ? 'needs-attention' : 'ok';
|
|
26
|
-
|
|
27
|
-
return c.json({
|
|
28
|
-
status,
|
|
29
|
-
timestamp: new Date().toISOString(),
|
|
30
|
-
storage: {
|
|
31
|
-
totalEvents: stats.totalEvents,
|
|
32
|
-
vectorCount: stats.vectorCount
|
|
33
|
-
},
|
|
34
|
-
outbox: {
|
|
35
|
-
embedding: outbox.embedding,
|
|
36
|
-
vector: outbox.vector,
|
|
37
|
-
totals: {
|
|
38
|
-
pending: outboxPending,
|
|
39
|
-
failed: outboxFailed
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
levelStats: stats.levelStats
|
|
43
|
-
});
|
|
44
|
-
} catch (error) {
|
|
45
|
-
return c.json({
|
|
46
|
-
status: 'error',
|
|
47
|
-
timestamp: new Date().toISOString(),
|
|
48
|
-
error: (error as Error).message
|
|
49
|
-
}, 500);
|
|
50
|
-
} finally {
|
|
51
|
-
await memoryService.shutdown();
|
|
52
|
-
}
|
|
53
|
-
});
|
|
1
|
+
/** Compatibility API module. Real app lives in src/apps/server/api. */
|
|
2
|
+
export * from '../../apps/server/api/health.js';
|
package/src/server/api/index.ts
CHANGED
|
@@ -1,26 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Central router for all API endpoints
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { Hono } from 'hono';
|
|
7
|
-
import { sessionsRouter } from './sessions.js';
|
|
8
|
-
import { eventsRouter } from './events.js';
|
|
9
|
-
import { searchRouter } from './search.js';
|
|
10
|
-
import { statsRouter } from './stats.js';
|
|
11
|
-
import { citationsRouter } from './citations.js';
|
|
12
|
-
import { turnsRouter } from './turns.js';
|
|
13
|
-
import { projectsRouter } from './projects.js';
|
|
14
|
-
import { chatRouter } from './chat.js';
|
|
15
|
-
import { healthRouter } from './health.js';
|
|
16
|
-
|
|
17
|
-
export const apiRouter = new Hono()
|
|
18
|
-
.route('/sessions', sessionsRouter)
|
|
19
|
-
.route('/events', eventsRouter)
|
|
20
|
-
.route('/search', searchRouter)
|
|
21
|
-
.route('/stats', statsRouter)
|
|
22
|
-
.route('/citations', citationsRouter)
|
|
23
|
-
.route('/turns', turnsRouter)
|
|
24
|
-
.route('/projects', projectsRouter)
|
|
25
|
-
.route('/chat', chatRouter)
|
|
26
|
-
.route('/health', healthRouter);
|
|
1
|
+
/** Compatibility API router entrypoint. Real app lives in src/apps/server/api. */
|
|
2
|
+
export * from '../../apps/server/api/index.js';
|