stellavault 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/core/dist/api/dashboard.d.ts +3 -0
- package/packages/core/{src/api/dashboard.ts → dist/api/dashboard.js} +8 -11
- package/packages/core/dist/api/graph-data.d.ts +11 -0
- package/packages/core/dist/api/graph-data.js +255 -0
- package/packages/core/dist/api/pwa.d.ts +3 -0
- package/packages/core/{src/api/pwa.ts → dist/api/pwa.js} +27 -32
- package/packages/core/dist/api/server.d.ts +16 -0
- package/packages/core/dist/api/server.js +647 -0
- package/packages/core/dist/capture/voice.d.ts +24 -0
- package/packages/core/dist/capture/voice.js +135 -0
- package/packages/core/{src/cloud/index.ts → dist/cloud/index.d.ts} +1 -0
- package/packages/core/dist/cloud/index.js +2 -0
- package/packages/core/dist/cloud/sync.d.ts +29 -0
- package/packages/core/dist/cloud/sync.js +137 -0
- package/packages/core/dist/config.d.ts +27 -0
- package/packages/core/dist/config.js +55 -0
- package/packages/core/dist/federation/credits.d.ts +26 -0
- package/packages/core/dist/federation/credits.js +56 -0
- package/packages/core/dist/federation/identity.d.ts +14 -0
- package/packages/core/dist/federation/identity.js +74 -0
- package/packages/core/{src/federation/index.ts → dist/federation/index.d.ts} +1 -2
- package/packages/core/dist/federation/index.js +5 -0
- package/packages/core/dist/federation/node.d.ts +31 -0
- package/packages/core/dist/federation/node.js +216 -0
- package/packages/core/dist/federation/privacy.d.ts +8 -0
- package/packages/core/dist/federation/privacy.js +40 -0
- package/packages/core/dist/federation/reputation.d.ts +37 -0
- package/packages/core/dist/federation/reputation.js +139 -0
- package/packages/core/dist/federation/search.d.ts +19 -0
- package/packages/core/dist/federation/search.js +101 -0
- package/packages/core/dist/federation/sharing.d.ts +72 -0
- package/packages/core/dist/federation/sharing.js +246 -0
- package/packages/core/dist/federation/trust.d.ts +15 -0
- package/packages/core/dist/federation/trust.js +60 -0
- package/packages/core/dist/federation/types.d.ts +40 -0
- package/packages/core/dist/federation/types.js +3 -0
- package/packages/core/dist/i18n/index.d.ts +6 -0
- package/packages/core/dist/i18n/index.js +81 -0
- package/packages/core/{src/index.ts → dist/index.d.ts} +46 -65
- package/packages/core/dist/index.js +69 -0
- package/packages/core/dist/indexer/chunker.d.ts +14 -0
- package/packages/core/dist/indexer/chunker.js +148 -0
- package/packages/core/dist/indexer/embedder.d.ts +8 -0
- package/packages/core/dist/indexer/embedder.js +3 -0
- package/packages/core/dist/indexer/index.d.ts +28 -0
- package/packages/core/dist/indexer/index.js +74 -0
- package/packages/core/dist/indexer/local-embedder.d.ts +3 -0
- package/packages/core/dist/indexer/local-embedder.js +29 -0
- package/packages/core/dist/indexer/scanner.d.ts +11 -0
- package/packages/core/dist/indexer/scanner.js +137 -0
- package/packages/core/dist/indexer/watcher.d.ts +19 -0
- package/packages/core/dist/indexer/watcher.js +49 -0
- package/packages/core/dist/intelligence/contradiction-detector.d.ts +20 -0
- package/packages/core/dist/intelligence/contradiction-detector.js +115 -0
- package/packages/core/dist/intelligence/decay-engine.d.ts +27 -0
- package/packages/core/dist/intelligence/decay-engine.js +190 -0
- package/packages/core/dist/intelligence/duplicate-detector.d.ts +20 -0
- package/packages/core/dist/intelligence/duplicate-detector.js +55 -0
- package/packages/core/dist/intelligence/fsrs.d.ts +43 -0
- package/packages/core/dist/intelligence/fsrs.js +70 -0
- package/packages/core/dist/intelligence/gap-detector.d.ts +25 -0
- package/packages/core/dist/intelligence/gap-detector.js +78 -0
- package/packages/core/dist/intelligence/learning-path.d.ts +31 -0
- package/packages/core/dist/intelligence/learning-path.js +53 -0
- package/packages/core/dist/intelligence/notifications.d.ts +31 -0
- package/packages/core/dist/intelligence/notifications.js +65 -0
- package/packages/core/dist/intelligence/predictive-gaps.d.ts +14 -0
- package/packages/core/dist/intelligence/predictive-gaps.js +74 -0
- package/packages/core/dist/intelligence/semantic-versioning.d.ts +37 -0
- package/packages/core/dist/intelligence/semantic-versioning.js +68 -0
- package/packages/core/dist/intelligence/types.d.ts +28 -0
- package/packages/core/dist/intelligence/types.js +3 -0
- package/packages/core/dist/mcp/custom-tools.d.ts +29 -0
- package/packages/core/dist/mcp/custom-tools.js +70 -0
- package/packages/core/{src/mcp/index.ts → dist/mcp/index.d.ts} +1 -0
- package/packages/core/dist/mcp/index.js +2 -0
- package/packages/core/dist/mcp/server.d.ts +49 -0
- package/packages/core/dist/mcp/server.js +133 -0
- package/packages/core/dist/mcp/tools/agentic-graph.d.ts +87 -0
- package/packages/core/dist/mcp/tools/agentic-graph.js +88 -0
- package/packages/core/dist/mcp/tools/brief.d.ts +31 -0
- package/packages/core/dist/mcp/tools/brief.js +39 -0
- package/packages/core/dist/mcp/tools/decay.d.ts +33 -0
- package/packages/core/dist/mcp/tools/decay.js +32 -0
- package/packages/core/dist/mcp/tools/decision-journal.d.ts +78 -0
- package/packages/core/dist/mcp/tools/decision-journal.js +79 -0
- package/packages/core/dist/mcp/tools/export.d.ts +29 -0
- package/packages/core/dist/mcp/tools/export.js +60 -0
- package/packages/core/dist/mcp/tools/federated-search.d.ts +29 -0
- package/packages/core/dist/mcp/tools/federated-search.js +36 -0
- package/packages/core/dist/mcp/tools/generate-claude-md.d.ts +35 -0
- package/packages/core/dist/mcp/tools/generate-claude-md.js +107 -0
- package/packages/core/dist/mcp/tools/get-document.d.ts +35 -0
- package/packages/core/dist/mcp/tools/get-document.js +25 -0
- package/packages/core/dist/mcp/tools/get-related.d.ts +32 -0
- package/packages/core/dist/mcp/tools/get-related.js +33 -0
- package/packages/core/dist/mcp/tools/learning-path.d.ts +23 -0
- package/packages/core/dist/mcp/tools/learning-path.js +45 -0
- package/packages/core/dist/mcp/tools/list-topics.d.ts +15 -0
- package/packages/core/dist/mcp/tools/list-topics.js +18 -0
- package/packages/core/dist/mcp/tools/search.d.ts +39 -0
- package/packages/core/dist/mcp/tools/search.js +29 -0
- package/packages/core/dist/mcp/tools/snapshot.d.ts +47 -0
- package/packages/core/dist/mcp/tools/snapshot.js +84 -0
- package/packages/core/dist/multi-vault/index.d.ts +26 -0
- package/packages/core/dist/multi-vault/index.js +80 -0
- package/packages/core/dist/pack/creator.d.ts +21 -0
- package/packages/core/dist/pack/creator.js +105 -0
- package/packages/core/dist/pack/exporter.d.ts +4 -0
- package/packages/core/dist/pack/exporter.js +18 -0
- package/packages/core/dist/pack/importer.d.ts +10 -0
- package/packages/core/dist/pack/importer.js +55 -0
- package/packages/core/{src/pack/index.ts → dist/pack/index.d.ts} +1 -0
- package/packages/core/dist/pack/index.js +5 -0
- package/packages/core/dist/pack/marketplace.d.ts +14 -0
- package/packages/core/dist/pack/marketplace.js +90 -0
- package/packages/core/dist/pack/pii-masker.d.ts +7 -0
- package/packages/core/dist/pack/pii-masker.js +29 -0
- package/packages/core/dist/pack/types.d.ts +36 -0
- package/packages/core/dist/pack/types.js +3 -0
- package/packages/core/dist/plugins/index.d.ts +35 -0
- package/packages/core/dist/plugins/index.js +57 -0
- package/packages/core/dist/plugins/webhooks.d.ts +30 -0
- package/packages/core/dist/plugins/webhooks.js +79 -0
- package/packages/core/dist/search/bm25.d.ts +4 -0
- package/packages/core/dist/search/bm25.js +10 -0
- package/packages/core/dist/search/index.d.ts +13 -0
- package/packages/core/dist/search/index.js +63 -0
- package/packages/core/dist/search/rrf.d.ts +7 -0
- package/packages/core/dist/search/rrf.js +21 -0
- package/packages/core/dist/search/semantic.d.ts +5 -0
- package/packages/core/dist/search/semantic.js +6 -0
- package/packages/core/{src/store/index.ts → dist/store/index.d.ts} +1 -0
- package/packages/core/dist/store/index.js +2 -0
- package/packages/core/dist/store/sqlite-vec.d.ts +6 -0
- package/packages/core/dist/store/sqlite-vec.js +251 -0
- package/packages/core/dist/store/types.d.ts +20 -0
- package/packages/core/dist/store/types.js +3 -0
- package/packages/core/dist/team/index.d.ts +25 -0
- package/packages/core/dist/team/index.js +97 -0
- package/packages/core/dist/types/chunk.d.ts +23 -0
- package/packages/core/dist/types/chunk.js +3 -0
- package/packages/core/dist/types/document.d.ts +23 -0
- package/packages/core/dist/types/document.js +3 -0
- package/packages/core/dist/types/graph.d.ts +39 -0
- package/packages/core/dist/types/graph.js +3 -0
- package/packages/core/dist/types/index.d.ts +5 -0
- package/packages/core/dist/types/index.js +2 -0
- package/packages/core/dist/types/search.d.ts +39 -0
- package/packages/core/dist/types/search.js +3 -0
- package/packages/core/dist/utils/retry.d.ts +25 -0
- package/packages/core/dist/utils/retry.js +59 -0
- package/.github/workflows/pages.yml +0 -37
- package/memory/MEMORY.md +0 -25
- package/packages/cli/dist/commands/brief-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/brief-cmd.js.map +0 -1
- package/packages/cli/dist/commands/capture-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/capture-cmd.js.map +0 -1
- package/packages/cli/dist/commands/card-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/card-cmd.js.map +0 -1
- package/packages/cli/dist/commands/clip-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/clip-cmd.js.map +0 -1
- package/packages/cli/dist/commands/cloud-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/cloud-cmd.js.map +0 -1
- package/packages/cli/dist/commands/contradictions-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/contradictions-cmd.js.map +0 -1
- package/packages/cli/dist/commands/decay-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/decay-cmd.js.map +0 -1
- package/packages/cli/dist/commands/digest-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/digest-cmd.js.map +0 -1
- package/packages/cli/dist/commands/duplicates-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/duplicates-cmd.js.map +0 -1
- package/packages/cli/dist/commands/federate-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/federate-cmd.js.map +0 -1
- package/packages/cli/dist/commands/gaps-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/gaps-cmd.js.map +0 -1
- package/packages/cli/dist/commands/graph-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/graph-cmd.js.map +0 -1
- package/packages/cli/dist/commands/index-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/index-cmd.js.map +0 -1
- package/packages/cli/dist/commands/init-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/init-cmd.js.map +0 -1
- package/packages/cli/dist/commands/learn-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/learn-cmd.js.map +0 -1
- package/packages/cli/dist/commands/pack-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/pack-cmd.js.map +0 -1
- package/packages/cli/dist/commands/review-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/review-cmd.js.map +0 -1
- package/packages/cli/dist/commands/search-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/search-cmd.js.map +0 -1
- package/packages/cli/dist/commands/serve-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/serve-cmd.js.map +0 -1
- package/packages/cli/dist/commands/status-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/status-cmd.js.map +0 -1
- package/packages/cli/dist/commands/sync-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/sync-cmd.js.map +0 -1
- package/packages/cli/dist/commands/vault-cmd.d.ts.map +0 -1
- package/packages/cli/dist/commands/vault-cmd.js.map +0 -1
- package/packages/cli/dist/index.d.ts.map +0 -1
- package/packages/cli/dist/index.js.map +0 -1
- package/packages/cli/src/commands/brief-cmd.ts +0 -87
- package/packages/cli/src/commands/capture-cmd.ts +0 -34
- package/packages/cli/src/commands/card-cmd.ts +0 -29
- package/packages/cli/src/commands/clip-cmd.ts +0 -172
- package/packages/cli/src/commands/cloud-cmd.ts +0 -75
- package/packages/cli/src/commands/contradictions-cmd.ts +0 -41
- package/packages/cli/src/commands/decay-cmd.ts +0 -57
- package/packages/cli/src/commands/digest-cmd.ts +0 -89
- package/packages/cli/src/commands/duplicates-cmd.ts +0 -38
- package/packages/cli/src/commands/federate-cmd.ts +0 -256
- package/packages/cli/src/commands/gaps-cmd.ts +0 -40
- package/packages/cli/src/commands/graph-cmd.ts +0 -88
- package/packages/cli/src/commands/index-cmd.ts +0 -65
- package/packages/cli/src/commands/init-cmd.ts +0 -145
- package/packages/cli/src/commands/learn-cmd.ts +0 -56
- package/packages/cli/src/commands/pack-cmd.ts +0 -121
- package/packages/cli/src/commands/review-cmd.ts +0 -125
- package/packages/cli/src/commands/search-cmd.ts +0 -45
- package/packages/cli/src/commands/serve-cmd.ts +0 -17
- package/packages/cli/src/commands/status-cmd.ts +0 -37
- package/packages/cli/src/commands/sync-cmd.ts +0 -68
- package/packages/cli/src/commands/vault-cmd.ts +0 -64
- package/packages/cli/src/index.ts +0 -187
- package/packages/core/src/api/graph-data.ts +0 -286
- package/packages/core/src/api/server.ts +0 -660
- package/packages/core/src/capture/voice.ts +0 -168
- package/packages/core/src/cloud/sync.ts +0 -167
- package/packages/core/src/config.ts +0 -82
- package/packages/core/src/federation/credits.ts +0 -80
- package/packages/core/src/federation/hyperswarm.d.ts +0 -19
- package/packages/core/src/federation/identity.ts +0 -90
- package/packages/core/src/federation/node.ts +0 -235
- package/packages/core/src/federation/privacy.ts +0 -52
- package/packages/core/src/federation/reputation.ts +0 -202
- package/packages/core/src/federation/search.ts +0 -129
- package/packages/core/src/federation/sharing.ts +0 -315
- package/packages/core/src/federation/trust.ts +0 -76
- package/packages/core/src/federation/types.ts +0 -25
- package/packages/core/src/i18n/index.ts +0 -85
- package/packages/core/src/indexer/chunker.ts +0 -180
- package/packages/core/src/indexer/embedder.ts +0 -9
- package/packages/core/src/indexer/index.ts +0 -113
- package/packages/core/src/indexer/local-embedder.ts +0 -35
- package/packages/core/src/indexer/scanner.ts +0 -142
- package/packages/core/src/indexer/watcher.ts +0 -62
- package/packages/core/src/intelligence/contradiction-detector.ts +0 -134
- package/packages/core/src/intelligence/decay-engine.ts +0 -229
- package/packages/core/src/intelligence/duplicate-detector.ts +0 -71
- package/packages/core/src/intelligence/fsrs.ts +0 -79
- package/packages/core/src/intelligence/gap-detector.ts +0 -109
- package/packages/core/src/intelligence/learning-path.ts +0 -86
- package/packages/core/src/intelligence/notifications.ts +0 -106
- package/packages/core/src/intelligence/predictive-gaps.ts +0 -94
- package/packages/core/src/intelligence/semantic-versioning.ts +0 -97
- package/packages/core/src/intelligence/types.ts +0 -28
- package/packages/core/src/mcp/custom-tools.ts +0 -97
- package/packages/core/src/mcp/server.ts +0 -142
- package/packages/core/src/mcp/tools/agentic-graph.ts +0 -96
- package/packages/core/src/mcp/tools/brief.ts +0 -49
- package/packages/core/src/mcp/tools/decay.ts +0 -40
- package/packages/core/src/mcp/tools/decision-journal.ts +0 -95
- package/packages/core/src/mcp/tools/export.ts +0 -72
- package/packages/core/src/mcp/tools/federated-search.ts +0 -43
- package/packages/core/src/mcp/tools/generate-claude-md.ts +0 -130
- package/packages/core/src/mcp/tools/get-document.ts +0 -26
- package/packages/core/src/mcp/tools/get-related.ts +0 -41
- package/packages/core/src/mcp/tools/learning-path.ts +0 -52
- package/packages/core/src/mcp/tools/list-topics.ts +0 -20
- package/packages/core/src/mcp/tools/search.ts +0 -35
- package/packages/core/src/mcp/tools/snapshot.ts +0 -98
- package/packages/core/src/multi-vault/index.ts +0 -118
- package/packages/core/src/pack/creator.ts +0 -127
- package/packages/core/src/pack/exporter.ts +0 -21
- package/packages/core/src/pack/importer.ts +0 -82
- package/packages/core/src/pack/marketplace.ts +0 -103
- package/packages/core/src/pack/pii-masker.ts +0 -38
- package/packages/core/src/pack/types.ts +0 -39
- package/packages/core/src/plugins/index.ts +0 -100
- package/packages/core/src/plugins/webhooks.ts +0 -110
- package/packages/core/src/search/bm25.ts +0 -16
- package/packages/core/src/search/index.ts +0 -83
- package/packages/core/src/search/rrf.ts +0 -31
- package/packages/core/src/search/semantic.ts +0 -15
- package/packages/core/src/store/sqlite-vec.ts +0 -290
- package/packages/core/src/store/types.ts +0 -22
- package/packages/core/src/team/index.ts +0 -126
- package/packages/core/src/types/chunk.ts +0 -25
- package/packages/core/src/types/document.ts +0 -24
- package/packages/core/src/types/graph.ts +0 -44
- package/packages/core/src/types/index.ts +0 -15
- package/packages/core/src/types/search.ts +0 -38
- package/packages/core/src/utils/retry.ts +0 -85
- package/packages/core/tests/api-card.test.ts +0 -60
- package/packages/core/tests/api-routes.test.ts +0 -98
- package/packages/core/tests/bm25.test.ts +0 -87
- package/packages/core/tests/chunker.test.ts +0 -48
- package/packages/core/tests/cluster.test.ts +0 -75
- package/packages/core/tests/constellation.test.ts +0 -77
- package/packages/core/tests/export-utils.test.ts +0 -97
- package/packages/core/tests/fsrs.test.ts +0 -96
- package/packages/core/tests/gesture-detector.test.ts +0 -45
- package/packages/core/tests/graph-data.test.ts +0 -87
- package/packages/core/tests/layout.test.ts +0 -83
- package/packages/core/tests/mcp.test.ts +0 -148
- package/packages/core/tests/pack.test.ts +0 -127
- package/packages/core/tests/pii-masker.test.ts +0 -42
- package/packages/core/tests/profile-card.test.ts +0 -62
- package/packages/core/tests/rrf.test.ts +0 -29
- package/packages/core/tests/search-integration.test.ts +0 -139
- package/packages/core/tests/store.test.ts +0 -80
- package/packages/graph/click-result.png +0 -0
- package/packages/graph/dist/assets/camera_utils-BMxqtvoZ.js +0 -1
- package/packages/graph/dist/assets/hands-DXA01_mx.js +0 -18
- package/packages/graph/dist/assets/index-DMEe2diW.js +0 -4192
- package/packages/graph/dist/assets/layout.worker-DbKCEFTz.js +0 -1
- package/packages/graph/dist/index.html +0 -17
- package/packages/graph/index.html +0 -17
- package/packages/graph/package.json +0 -32
- package/packages/graph/src/App.tsx +0 -7
- package/packages/graph/src/api/client.ts +0 -39
- package/packages/graph/src/components/ClusterFilter.tsx +0 -73
- package/packages/graph/src/components/ConstellationView.tsx +0 -232
- package/packages/graph/src/components/ExportPanel.tsx +0 -177
- package/packages/graph/src/components/Graph3D.tsx +0 -230
- package/packages/graph/src/components/GraphEdges.tsx +0 -100
- package/packages/graph/src/components/GraphNodes.tsx +0 -386
- package/packages/graph/src/components/HealthDashboard.tsx +0 -173
- package/packages/graph/src/components/Layout.tsx +0 -214
- package/packages/graph/src/components/MotionOverlay.tsx +0 -81
- package/packages/graph/src/components/MotionToggle.tsx +0 -33
- package/packages/graph/src/components/MultiverseView.tsx +0 -286
- package/packages/graph/src/components/NodeDetail.tsx +0 -232
- package/packages/graph/src/components/PulseParticle.tsx +0 -232
- package/packages/graph/src/components/SearchBar.tsx +0 -107
- package/packages/graph/src/components/StarField.tsx +0 -197
- package/packages/graph/src/components/StatusBar.tsx +0 -53
- package/packages/graph/src/components/Timeline.tsx +0 -148
- package/packages/graph/src/components/ToolsPanel.tsx +0 -512
- package/packages/graph/src/components/Tooltip.tsx +0 -100
- package/packages/graph/src/components/TypeFilter.tsx +0 -131
- package/packages/graph/src/embed/EmbedGraph.tsx +0 -144
- package/packages/graph/src/hooks/useConstellationLOD.ts +0 -76
- package/packages/graph/src/hooks/useDecay.ts +0 -37
- package/packages/graph/src/hooks/useExport.ts +0 -165
- package/packages/graph/src/hooks/useGraph.ts +0 -69
- package/packages/graph/src/hooks/useKeyboardNav.ts +0 -122
- package/packages/graph/src/hooks/useLayout.ts +0 -45
- package/packages/graph/src/hooks/useMotion.ts +0 -120
- package/packages/graph/src/hooks/usePulse.ts +0 -58
- package/packages/graph/src/hooks/useSearch.ts +0 -71
- package/packages/graph/src/lib/constellation.ts +0 -107
- package/packages/graph/src/lib/export-utils.ts +0 -48
- package/packages/graph/src/lib/gesture-detector.ts +0 -123
- package/packages/graph/src/lib/layout.worker.ts +0 -153
- package/packages/graph/src/lib/motion-controller.ts +0 -83
- package/packages/graph/src/lib/profile-card.ts +0 -122
- package/packages/graph/src/main.tsx +0 -4
- package/packages/graph/src/stores/graph-store.ts +0 -155
- package/packages/graph/success.png +0 -0
- package/packages/graph/test-click.mjs +0 -49
- package/packages/graph/test-explore.mjs +0 -102
- package/packages/graph/test-final.mjs +0 -61
- package/packages/graph/test-graph.mjs +0 -139
- package/packages/graph/test-hover.mjs +0 -48
- package/packages/graph/test-pulse.mjs +0 -68
- package/packages/graph/test-screenshot.mjs +0 -56
- package/packages/graph/test-v2.mjs +0 -97
- package/packages/graph/tsconfig.tsbuildinfo +0 -1
- package/packages/graph/vite.config.ts +0 -15
- package/packages/sync/.env.example +0 -11
- package/packages/sync/.sync-state.json +0 -317
- package/packages/sync/.upload-state.json +0 -1009
- package/packages/sync/create-stella-network-notion.mjs +0 -151
- package/packages/sync/create-stellavault-project-notion.mjs +0 -322
- package/packages/sync/logs/sync-2026-03-28.log +0 -6
- package/packages/sync/logs/sync-2026-03-29.log +0 -12
- package/packages/sync/logs/sync-2026-03-30.log +0 -6
- package/packages/sync/logs/sync-2026-03-31.log +0 -6
- package/packages/sync/logs/sync-2026-04-01.log +0 -6
- package/packages/sync/logs/sync-2026-04-02.log +0 -6
- package/packages/sync/package-lock.json +0 -373
- package/packages/sync/package.json +0 -16
- package/packages/sync/run-sync.bat +0 -18
- package/packages/sync/run-sync.mjs +0 -46
- package/packages/sync/setup-scheduler.mjs +0 -119
- package/packages/sync/structured-sync.mjs +0 -187
- package/packages/sync/sync-to-obsidian.mjs +0 -264
- package/packages/sync/upload-pdca-to-notion.mjs +0 -495
- package/tsconfig.base.json +0 -18
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// AI Learning Path Generator (F-A11)
|
|
2
|
+
// Analyzes decay + gaps + relationships to recommend what to review/learn next
|
|
3
|
+
export function generateLearningPath(input, limit = 15) {
|
|
4
|
+
const items = [];
|
|
5
|
+
// 1. Review: decaying notes (highest priority)
|
|
6
|
+
if (input.decayReport.topDecaying) {
|
|
7
|
+
for (const d of input.decayReport.topDecaying) {
|
|
8
|
+
const r = d.retrievability ?? 0;
|
|
9
|
+
const urgency = (1 - r) * 100;
|
|
10
|
+
items.push({
|
|
11
|
+
documentId: d.documentId,
|
|
12
|
+
title: d.title,
|
|
13
|
+
reason: r < 0.3
|
|
14
|
+
? `Critical: ${Math.round(r * 100)}% retrievability, ${d.daysSinceAccess}d since last access`
|
|
15
|
+
: `Fading: ${Math.round(r * 100)}% retrievability, review to strengthen memory`,
|
|
16
|
+
priority: r < 0.3 ? 'critical' : r < 0.5 ? 'important' : 'suggested',
|
|
17
|
+
score: Math.round(urgency),
|
|
18
|
+
category: 'review',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// 2. Bridge: knowledge gaps
|
|
23
|
+
if (input.gaps) {
|
|
24
|
+
for (const gap of input.gaps) {
|
|
25
|
+
const severityScore = gap.severity === 'high' ? 80 : gap.severity === 'medium' ? 60 : 40;
|
|
26
|
+
items.push({
|
|
27
|
+
documentId: '',
|
|
28
|
+
title: gap.suggestedTopic || `${gap.clusterA} × ${gap.clusterB}`,
|
|
29
|
+
reason: `Gap between "${gap.clusterA}" and "${gap.clusterB}" — creating a bridge note strengthens your knowledge network`,
|
|
30
|
+
priority: gap.severity === 'high' ? 'important' : 'suggested',
|
|
31
|
+
score: severityScore,
|
|
32
|
+
category: 'bridge',
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Sort by score descending
|
|
37
|
+
items.sort((a, b) => b.score - a.score);
|
|
38
|
+
const selected = items.slice(0, limit);
|
|
39
|
+
const reviewCount = selected.filter(i => i.category === 'review').length;
|
|
40
|
+
const exploreCount = selected.filter(i => i.category === 'explore').length;
|
|
41
|
+
const bridgeCount = selected.filter(i => i.category === 'bridge').length;
|
|
42
|
+
return {
|
|
43
|
+
items: selected,
|
|
44
|
+
summary: {
|
|
45
|
+
reviewCount,
|
|
46
|
+
exploreCount,
|
|
47
|
+
bridgeCount,
|
|
48
|
+
estimatedMinutes: reviewCount * 3 + exploreCount * 5 + bridgeCount * 8,
|
|
49
|
+
},
|
|
50
|
+
generatedAt: new Date().toISOString(),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=learning-path.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { DecayReport } from './types.js';
|
|
2
|
+
export interface NotificationConfig {
|
|
3
|
+
decay: {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
criticalThreshold: number;
|
|
6
|
+
warningThreshold: number;
|
|
7
|
+
};
|
|
8
|
+
gaps: {
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
minSeverity: 'low' | 'medium' | 'high';
|
|
11
|
+
};
|
|
12
|
+
digest: {
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
frequency: 'daily' | 'weekly' | 'off';
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface Notification {
|
|
18
|
+
id: string;
|
|
19
|
+
type: 'decay_critical' | 'decay_warning' | 'gap_detected' | 'digest';
|
|
20
|
+
title: string;
|
|
21
|
+
message: string;
|
|
22
|
+
timestamp: string;
|
|
23
|
+
priority: 'high' | 'medium' | 'low';
|
|
24
|
+
data?: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
export declare function checkNotifications(decayReport: DecayReport, gaps: Array<{
|
|
27
|
+
severity: string;
|
|
28
|
+
clusterA: string;
|
|
29
|
+
clusterB: string;
|
|
30
|
+
}>, config?: Partial<NotificationConfig>): Notification[];
|
|
31
|
+
//# sourceMappingURL=notifications.d.ts.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Notification Center (F-A05)
|
|
2
|
+
// Configurable alerts for decay thresholds, gap detection, weekly digest
|
|
3
|
+
const DEFAULT_CONFIG = {
|
|
4
|
+
decay: { enabled: true, criticalThreshold: 0.3, warningThreshold: 0.5 },
|
|
5
|
+
gaps: { enabled: true, minSeverity: 'medium' },
|
|
6
|
+
digest: { enabled: true, frequency: 'weekly' },
|
|
7
|
+
};
|
|
8
|
+
export function checkNotifications(decayReport, gaps, config = {}) {
|
|
9
|
+
const cfg = {
|
|
10
|
+
decay: { ...DEFAULT_CONFIG.decay, ...config.decay },
|
|
11
|
+
gaps: { ...DEFAULT_CONFIG.gaps, ...config.gaps },
|
|
12
|
+
digest: { ...DEFAULT_CONFIG.digest, ...config.digest },
|
|
13
|
+
};
|
|
14
|
+
const notifications = [];
|
|
15
|
+
const now = new Date().toISOString();
|
|
16
|
+
// Decay alerts
|
|
17
|
+
if (cfg.decay.enabled && decayReport.topDecaying) {
|
|
18
|
+
const criticals = decayReport.topDecaying.filter(d => d.retrievability < cfg.decay.criticalThreshold);
|
|
19
|
+
const warnings = decayReport.topDecaying.filter(d => d.retrievability >= cfg.decay.criticalThreshold && d.retrievability < cfg.decay.warningThreshold);
|
|
20
|
+
if (criticals.length > 0) {
|
|
21
|
+
notifications.push({
|
|
22
|
+
id: `decay-critical-${Date.now()}`,
|
|
23
|
+
type: 'decay_critical',
|
|
24
|
+
title: `${criticals.length} notes critically fading`,
|
|
25
|
+
message: criticals.slice(0, 3).map(d => `"${d.title}" (${Math.round(d.retrievability * 100)}%)`).join(', '),
|
|
26
|
+
timestamp: now,
|
|
27
|
+
priority: 'high',
|
|
28
|
+
data: { count: criticals.length, notes: criticals.slice(0, 5).map(d => d.title) },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (warnings.length > 0) {
|
|
32
|
+
notifications.push({
|
|
33
|
+
id: `decay-warning-${Date.now()}`,
|
|
34
|
+
type: 'decay_warning',
|
|
35
|
+
title: `${warnings.length} notes starting to fade`,
|
|
36
|
+
message: `Average retrievability: ${Math.round(decayReport.averageR * 100)}%`,
|
|
37
|
+
timestamp: now,
|
|
38
|
+
priority: 'medium',
|
|
39
|
+
data: { count: warnings.length },
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Gap alerts
|
|
44
|
+
if (cfg.gaps.enabled) {
|
|
45
|
+
const severityOrder = { high: 3, medium: 2, low: 1 };
|
|
46
|
+
const minLevel = severityOrder[cfg.gaps.minSeverity] ?? 2;
|
|
47
|
+
const significantGaps = gaps.filter(g => (severityOrder[g.severity] ?? 0) >= minLevel);
|
|
48
|
+
if (significantGaps.length > 0) {
|
|
49
|
+
notifications.push({
|
|
50
|
+
id: `gap-${Date.now()}`,
|
|
51
|
+
type: 'gap_detected',
|
|
52
|
+
title: `${significantGaps.length} knowledge gaps detected`,
|
|
53
|
+
message: significantGaps.slice(0, 2).map(g => `${g.clusterA} ↔ ${g.clusterB}`).join(', '),
|
|
54
|
+
timestamp: now,
|
|
55
|
+
priority: significantGaps.some(g => g.severity === 'high') ? 'high' : 'medium',
|
|
56
|
+
data: { count: significantGaps.length },
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return notifications.sort((a, b) => {
|
|
61
|
+
const p = { high: 3, medium: 2, low: 1 };
|
|
62
|
+
return (p[b.priority] ?? 0) - (p[a.priority] ?? 0);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=notifications.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { VectorStore } from '../store/types.js';
|
|
2
|
+
export interface PredictedGap {
|
|
3
|
+
topic: string;
|
|
4
|
+
reason: string;
|
|
5
|
+
confidence: number;
|
|
6
|
+
relatedTopics: string[];
|
|
7
|
+
category: 'adjacent' | 'bridging' | 'deepening';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Analyze graph topology to predict knowledge worth acquiring.
|
|
11
|
+
* Uses degree centrality, cluster density, and tag co-occurrence.
|
|
12
|
+
*/
|
|
13
|
+
export declare function predictKnowledgeGaps(store: VectorStore, limit?: number): Promise<PredictedGap[]>;
|
|
14
|
+
//# sourceMappingURL=predictive-gaps.d.ts.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Predictive Gap Analysis (F-A14)
|
|
2
|
+
// Based on graph topology, predict knowledge areas worth exploring
|
|
3
|
+
/**
|
|
4
|
+
* Analyze graph topology to predict knowledge worth acquiring.
|
|
5
|
+
* Uses degree centrality, cluster density, and tag co-occurrence.
|
|
6
|
+
*/
|
|
7
|
+
export async function predictKnowledgeGaps(store, limit = 10) {
|
|
8
|
+
const docs = await store.getAllDocuments();
|
|
9
|
+
const topics = await store.getTopics();
|
|
10
|
+
if (docs.length < 10)
|
|
11
|
+
return [];
|
|
12
|
+
const predictions = [];
|
|
13
|
+
// 1. Find isolated tags (topics that appear rarely and could be expanded)
|
|
14
|
+
const topicCounts = new Map(topics.map(t => [t.topic, t.count]));
|
|
15
|
+
const avgCount = topics.reduce((s, t) => s + t.count, 0) / (topics.length || 1);
|
|
16
|
+
// Tags that appear 1-2 times — potential deepening opportunities
|
|
17
|
+
const sparseTopics = topics.filter(t => t.count <= 2 && t.count > 0);
|
|
18
|
+
for (const t of sparseTopics.slice(0, 5)) {
|
|
19
|
+
predictions.push({
|
|
20
|
+
topic: t.topic,
|
|
21
|
+
reason: `Only ${t.count} note(s) on "${t.topic}" — deepening this area would strengthen your knowledge network`,
|
|
22
|
+
confidence: 0.6,
|
|
23
|
+
relatedTopics: findCoOccurring(t.topic, docs),
|
|
24
|
+
category: 'deepening',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// 2. Find tag pairs that never co-occur but are both frequent
|
|
28
|
+
const frequentTopics = topics.filter(t => t.count >= avgCount).slice(0, 20);
|
|
29
|
+
const coOccurrence = new Map();
|
|
30
|
+
for (const doc of docs) {
|
|
31
|
+
for (const tagA of doc.tags) {
|
|
32
|
+
if (!coOccurrence.has(tagA))
|
|
33
|
+
coOccurrence.set(tagA, new Set());
|
|
34
|
+
for (const tagB of doc.tags) {
|
|
35
|
+
if (tagA !== tagB)
|
|
36
|
+
coOccurrence.get(tagA).add(tagB);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (let i = 0; i < frequentTopics.length; i++) {
|
|
41
|
+
for (let j = i + 1; j < frequentTopics.length; j++) {
|
|
42
|
+
const a = frequentTopics[i].topic;
|
|
43
|
+
const b = frequentTopics[j].topic;
|
|
44
|
+
const aCoOccurs = coOccurrence.get(a) ?? new Set();
|
|
45
|
+
if (!aCoOccurs.has(b)) {
|
|
46
|
+
predictions.push({
|
|
47
|
+
topic: `${a} × ${b}`,
|
|
48
|
+
reason: `"${a}" (${frequentTopics[i].count} notes) and "${b}" (${frequentTopics[j].count} notes) are both well-known but never connected — bridging them could reveal insights`,
|
|
49
|
+
confidence: 0.7,
|
|
50
|
+
relatedTopics: [a, b],
|
|
51
|
+
category: 'bridging',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// 3. Adjacent topics — topics that co-occur with many of your topics but you don't have
|
|
57
|
+
// (This would ideally use external knowledge, but we approximate with tag patterns)
|
|
58
|
+
return predictions
|
|
59
|
+
.sort((a, b) => b.confidence - a.confidence)
|
|
60
|
+
.slice(0, limit);
|
|
61
|
+
}
|
|
62
|
+
function findCoOccurring(topic, docs) {
|
|
63
|
+
const coTopics = new Map();
|
|
64
|
+
for (const doc of docs) {
|
|
65
|
+
if (doc.tags.includes(topic)) {
|
|
66
|
+
for (const t of doc.tags) {
|
|
67
|
+
if (t !== topic)
|
|
68
|
+
coTopics.set(t, (coTopics.get(t) ?? 0) + 1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return [...coTopics.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([t]) => t);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=predictive-gaps.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface SemanticVersion {
|
|
2
|
+
documentId: string;
|
|
3
|
+
timestamp: string;
|
|
4
|
+
embeddingHash: string;
|
|
5
|
+
drift: number;
|
|
6
|
+
}
|
|
7
|
+
export interface SemanticChangelog {
|
|
8
|
+
documentId: string;
|
|
9
|
+
title: string;
|
|
10
|
+
versions: SemanticVersion[];
|
|
11
|
+
totalDrift: number;
|
|
12
|
+
stability: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Compute semantic drift between two embedding vectors.
|
|
16
|
+
* Returns cosine distance (0 = identical, 1 = orthogonal, 2 = opposite)
|
|
17
|
+
*/
|
|
18
|
+
export declare function computeSemanticDrift(vecA: number[], vecB: number[]): number;
|
|
19
|
+
/**
|
|
20
|
+
* Hash an embedding vector for quick comparison
|
|
21
|
+
*/
|
|
22
|
+
export declare function hashEmbedding(vec: number[]): string;
|
|
23
|
+
/**
|
|
24
|
+
* Analyze semantic stability of a document given its embedding history.
|
|
25
|
+
* In practice, we compare current embedding vs initial embedding to measure total drift.
|
|
26
|
+
*/
|
|
27
|
+
export declare function analyzeSemanticStability(currentVec: number[], title: string, documentId: string): SemanticChangelog;
|
|
28
|
+
/**
|
|
29
|
+
* Compare two sets of embeddings to find documents with the most semantic drift.
|
|
30
|
+
* Useful for "what changed the most since last index?"
|
|
31
|
+
*/
|
|
32
|
+
export declare function findMostDrifted(previousEmbeddings: Map<string, number[]>, currentEmbeddings: Map<string, number[]>, titles: Map<string, string>, limit?: number): Array<{
|
|
33
|
+
documentId: string;
|
|
34
|
+
title: string;
|
|
35
|
+
drift: number;
|
|
36
|
+
}>;
|
|
37
|
+
//# sourceMappingURL=semantic-versioning.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Knowledge Semantic Versioning (F-A13)
|
|
2
|
+
// Track how a note's MEANING changes over time via embedding drift
|
|
3
|
+
/**
|
|
4
|
+
* Compute semantic drift between two embedding vectors.
|
|
5
|
+
* Returns cosine distance (0 = identical, 1 = orthogonal, 2 = opposite)
|
|
6
|
+
*/
|
|
7
|
+
export function computeSemanticDrift(vecA, vecB) {
|
|
8
|
+
if (vecA.length !== vecB.length || vecA.length === 0)
|
|
9
|
+
return 0;
|
|
10
|
+
let dot = 0, na = 0, nb = 0;
|
|
11
|
+
for (let i = 0; i < vecA.length; i++) {
|
|
12
|
+
dot += vecA[i] * vecB[i];
|
|
13
|
+
na += vecA[i] * vecA[i];
|
|
14
|
+
nb += vecB[i] * vecB[i];
|
|
15
|
+
}
|
|
16
|
+
const denom = Math.sqrt(na) * Math.sqrt(nb);
|
|
17
|
+
const similarity = denom === 0 ? 0 : dot / denom;
|
|
18
|
+
return 1 - similarity; // cosine distance
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Hash an embedding vector for quick comparison
|
|
22
|
+
*/
|
|
23
|
+
export function hashEmbedding(vec) {
|
|
24
|
+
let hash = 0;
|
|
25
|
+
for (let i = 0; i < Math.min(vec.length, 50); i++) {
|
|
26
|
+
hash = ((hash << 5) - hash + Math.round(vec[i] * 10000)) | 0;
|
|
27
|
+
}
|
|
28
|
+
return Math.abs(hash).toString(36).slice(0, 8);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Analyze semantic stability of a document given its embedding history.
|
|
32
|
+
* In practice, we compare current embedding vs initial embedding to measure total drift.
|
|
33
|
+
*/
|
|
34
|
+
export function analyzeSemanticStability(currentVec, title, documentId) {
|
|
35
|
+
// Single-point analysis (no history yet — foundation for future multi-version tracking)
|
|
36
|
+
const now = new Date().toISOString();
|
|
37
|
+
const hash = hashEmbedding(currentVec);
|
|
38
|
+
return {
|
|
39
|
+
documentId,
|
|
40
|
+
title,
|
|
41
|
+
versions: [{
|
|
42
|
+
documentId,
|
|
43
|
+
timestamp: now,
|
|
44
|
+
embeddingHash: hash,
|
|
45
|
+
drift: 0,
|
|
46
|
+
}],
|
|
47
|
+
totalDrift: 0,
|
|
48
|
+
stability: 1.0,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Compare two sets of embeddings to find documents with the most semantic drift.
|
|
53
|
+
* Useful for "what changed the most since last index?"
|
|
54
|
+
*/
|
|
55
|
+
export function findMostDrifted(previousEmbeddings, currentEmbeddings, titles, limit = 10) {
|
|
56
|
+
const drifts = [];
|
|
57
|
+
for (const [docId, currentVec] of currentEmbeddings) {
|
|
58
|
+
const prevVec = previousEmbeddings.get(docId);
|
|
59
|
+
if (!prevVec)
|
|
60
|
+
continue;
|
|
61
|
+
const drift = computeSemanticDrift(prevVec, currentVec);
|
|
62
|
+
if (drift > 0.01) { // ignore trivial changes
|
|
63
|
+
drifts.push({ documentId: docId, title: titles.get(docId) ?? docId, drift: Math.round(drift * 1000) / 1000 });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return drifts.sort((a, b) => b.drift - a.drift).slice(0, limit);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=semantic-versioning.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface DecayState {
|
|
2
|
+
documentId: string;
|
|
3
|
+
stability: number;
|
|
4
|
+
difficulty: number;
|
|
5
|
+
lastAccess: string;
|
|
6
|
+
retrievability: number;
|
|
7
|
+
}
|
|
8
|
+
export interface AccessEvent {
|
|
9
|
+
documentId: string;
|
|
10
|
+
type: 'view' | 'search' | 'mcp_query';
|
|
11
|
+
timestamp: string;
|
|
12
|
+
}
|
|
13
|
+
export interface DecayReport {
|
|
14
|
+
totalDocuments: number;
|
|
15
|
+
decayingCount: number;
|
|
16
|
+
criticalCount: number;
|
|
17
|
+
averageR: number;
|
|
18
|
+
topDecaying: Array<DecayState & {
|
|
19
|
+
title: string;
|
|
20
|
+
daysSinceAccess: number;
|
|
21
|
+
}>;
|
|
22
|
+
clusterHealth: Array<{
|
|
23
|
+
label: string;
|
|
24
|
+
avgR: number;
|
|
25
|
+
count: number;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SearchEngine } from '../search/index.js';
|
|
2
|
+
export interface CustomToolDef {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
query_template: string;
|
|
6
|
+
output_format?: 'full' | 'titles' | 'snippets';
|
|
7
|
+
limit?: number;
|
|
8
|
+
filter_tags?: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface LoadedCustomTool {
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: 'object';
|
|
15
|
+
properties: Record<string, {
|
|
16
|
+
type: string;
|
|
17
|
+
description: string;
|
|
18
|
+
}>;
|
|
19
|
+
required?: string[];
|
|
20
|
+
};
|
|
21
|
+
handler: (args: Record<string, unknown>) => Promise<{
|
|
22
|
+
content: Array<{
|
|
23
|
+
type: 'text';
|
|
24
|
+
text: string;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
export declare function loadCustomTools(toolsDir: string, searchEngine: SearchEngine): LoadedCustomTool[];
|
|
29
|
+
//# sourceMappingURL=custom-tools.d.ts.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Custom MCP Tool Builder (F-A16)
|
|
2
|
+
// Load YAML/JSON tool definitions without coding
|
|
3
|
+
import { readFileSync, existsSync, readdirSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
export function loadCustomTools(toolsDir, searchEngine) {
|
|
6
|
+
if (!existsSync(toolsDir))
|
|
7
|
+
return [];
|
|
8
|
+
const tools = [];
|
|
9
|
+
const files = readdirSync(toolsDir).filter(f => f.endsWith('.json') || f.endsWith('.yaml') || f.endsWith('.yml'));
|
|
10
|
+
for (const file of files) {
|
|
11
|
+
try {
|
|
12
|
+
const raw = readFileSync(join(toolsDir, file), 'utf-8');
|
|
13
|
+
let def;
|
|
14
|
+
if (file.endsWith('.json')) {
|
|
15
|
+
def = JSON.parse(raw);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
// Simple YAML parser for basic key:value format
|
|
19
|
+
def = parseSimpleYaml(raw);
|
|
20
|
+
}
|
|
21
|
+
if (!def.name || !def.description || !def.query_template)
|
|
22
|
+
continue;
|
|
23
|
+
// Extract template variables ({{var}})
|
|
24
|
+
const vars = [...def.query_template.matchAll(/\{\{(\w+)\}\}/g)].map(m => m[1]);
|
|
25
|
+
tools.push({
|
|
26
|
+
name: def.name,
|
|
27
|
+
description: def.description,
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: Object.fromEntries(vars.map(v => [v, { type: 'string', description: `Value for ${v}` }])),
|
|
31
|
+
required: vars,
|
|
32
|
+
},
|
|
33
|
+
handler: async (args) => {
|
|
34
|
+
let query = def.query_template;
|
|
35
|
+
for (const [key, val] of Object.entries(args)) {
|
|
36
|
+
query = query.replace(`{{${key}}}`, String(val));
|
|
37
|
+
}
|
|
38
|
+
const results = await searchEngine.search({ query, limit: def.limit ?? 5 });
|
|
39
|
+
const format = def.output_format ?? 'snippets';
|
|
40
|
+
let text;
|
|
41
|
+
if (format === 'titles') {
|
|
42
|
+
text = results.map(r => `- ${r.document.title}`).join('\n');
|
|
43
|
+
}
|
|
44
|
+
else if (format === 'full') {
|
|
45
|
+
text = results.map(r => `## ${r.document.title}\n\n${r.document.content.slice(0, 1000)}`).join('\n\n---\n\n');
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
text = results.map(r => `**${r.document.title}** (${Math.round(r.score * 100)}%)\n${r.chunk.content.slice(0, 200)}...`).join('\n\n');
|
|
49
|
+
}
|
|
50
|
+
return { content: [{ type: 'text', text: text || 'No results found.' }] };
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Skip invalid tool files
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return tools;
|
|
59
|
+
}
|
|
60
|
+
function parseSimpleYaml(raw) {
|
|
61
|
+
const result = {};
|
|
62
|
+
for (const line of raw.split('\n')) {
|
|
63
|
+
const match = line.match(/^(\w[\w_]*)\s*:\s*(.+)$/);
|
|
64
|
+
if (match) {
|
|
65
|
+
result[match[1]] = match[2].replace(/^["']|["']$/g, '').trim();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=custom-tools.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import type { VectorStore } from '../store/types.js';
|
|
3
|
+
import type { SearchEngine } from '../search/index.js';
|
|
4
|
+
import type { DecayEngine } from '../intelligence/decay-engine.js';
|
|
5
|
+
export interface McpServerOptions {
|
|
6
|
+
store: VectorStore;
|
|
7
|
+
searchEngine: SearchEngine;
|
|
8
|
+
vaultPath?: string;
|
|
9
|
+
decayEngine?: DecayEngine;
|
|
10
|
+
}
|
|
11
|
+
export declare function createMcpServer(options: McpServerOptions): {
|
|
12
|
+
startStdio(): Promise<void>;
|
|
13
|
+
startHttp(port?: number): Promise<void>;
|
|
14
|
+
server: Server<{
|
|
15
|
+
method: string;
|
|
16
|
+
params?: {
|
|
17
|
+
[x: string]: unknown;
|
|
18
|
+
_meta?: {
|
|
19
|
+
[x: string]: unknown;
|
|
20
|
+
progressToken?: string | number | undefined;
|
|
21
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
22
|
+
taskId: string;
|
|
23
|
+
} | undefined;
|
|
24
|
+
} | undefined;
|
|
25
|
+
} | undefined;
|
|
26
|
+
}, {
|
|
27
|
+
method: string;
|
|
28
|
+
params?: {
|
|
29
|
+
[x: string]: unknown;
|
|
30
|
+
_meta?: {
|
|
31
|
+
[x: string]: unknown;
|
|
32
|
+
progressToken?: string | number | undefined;
|
|
33
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
34
|
+
taskId: string;
|
|
35
|
+
} | undefined;
|
|
36
|
+
} | undefined;
|
|
37
|
+
} | undefined;
|
|
38
|
+
}, {
|
|
39
|
+
[x: string]: unknown;
|
|
40
|
+
_meta?: {
|
|
41
|
+
[x: string]: unknown;
|
|
42
|
+
progressToken?: string | number | undefined;
|
|
43
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
44
|
+
taskId: string;
|
|
45
|
+
} | undefined;
|
|
46
|
+
} | undefined;
|
|
47
|
+
}>;
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Design Ref: §4.1 — MCP Server (stdio + SSE)
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
6
|
+
import { searchToolDef, handleSearch } from './tools/search.js';
|
|
7
|
+
import { getDocumentToolDef, handleGetDocument } from './tools/get-document.js';
|
|
8
|
+
import { listTopicsToolDef, handleListTopics } from './tools/list-topics.js';
|
|
9
|
+
import { getRelatedToolDef, handleGetRelated } from './tools/get-related.js';
|
|
10
|
+
import { generateClaudeMdToolDef, handleGenerateClaudeMd } from './tools/generate-claude-md.js';
|
|
11
|
+
import { createSnapshotToolDef, loadSnapshotToolDef, handleCreateSnapshot, handleLoadSnapshot } from './tools/snapshot.js';
|
|
12
|
+
import { logDecisionToolDef, findDecisionsToolDef, handleLogDecision, handleFindDecisions } from './tools/decision-journal.js';
|
|
13
|
+
import { exportToolDef, handleExport } from './tools/export.js';
|
|
14
|
+
import { getDecayStatusToolDef, handleGetDecayStatus } from './tools/decay.js';
|
|
15
|
+
import { getMorningBriefToolDef, handleGetMorningBrief } from './tools/brief.js';
|
|
16
|
+
import { createLearningPathTool } from './tools/learning-path.js';
|
|
17
|
+
export function createMcpServer(options) {
|
|
18
|
+
const { store, searchEngine, vaultPath = '', decayEngine } = options;
|
|
19
|
+
const learningPathTool = createLearningPathTool(store);
|
|
20
|
+
const server = new Server({ name: 'stellavault', version: '0.2.0' }, { capabilities: { tools: {} } });
|
|
21
|
+
// List tools
|
|
22
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
23
|
+
tools: [
|
|
24
|
+
searchToolDef, getDocumentToolDef, listTopicsToolDef, getRelatedToolDef,
|
|
25
|
+
generateClaudeMdToolDef, createSnapshotToolDef, loadSnapshotToolDef,
|
|
26
|
+
logDecisionToolDef, findDecisionsToolDef, exportToolDef,
|
|
27
|
+
...(decayEngine ? [getDecayStatusToolDef, getMorningBriefToolDef] : []),
|
|
28
|
+
{ name: learningPathTool.name, description: learningPathTool.description, inputSchema: learningPathTool.inputSchema },
|
|
29
|
+
],
|
|
30
|
+
}));
|
|
31
|
+
// Call tool
|
|
32
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
33
|
+
const { name, arguments: args } = request.params;
|
|
34
|
+
try {
|
|
35
|
+
let result;
|
|
36
|
+
switch (name) {
|
|
37
|
+
case 'search':
|
|
38
|
+
result = await handleSearch(searchEngine, args);
|
|
39
|
+
// MCP 검색 이벤트 기록
|
|
40
|
+
if (decayEngine && result && typeof result === 'object' && 'results' in result) {
|
|
41
|
+
const now = new Date().toISOString();
|
|
42
|
+
for (const r of result.results ?? []) {
|
|
43
|
+
if (r.documentId)
|
|
44
|
+
decayEngine.recordAccess({ documentId: r.documentId, type: 'mcp_query', timestamp: now }).catch(() => { });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
case 'get-document':
|
|
49
|
+
result = await handleGetDocument(store, args);
|
|
50
|
+
// MCP 문서 조회 이벤트 기록
|
|
51
|
+
if (decayEngine && result && typeof result === 'object' && 'id' in result) {
|
|
52
|
+
decayEngine.recordAccess({ documentId: result.id, type: 'mcp_query', timestamp: new Date().toISOString() }).catch(() => { });
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
case 'list-topics':
|
|
56
|
+
result = await handleListTopics(store);
|
|
57
|
+
break;
|
|
58
|
+
case 'get-related':
|
|
59
|
+
result = await handleGetRelated(store, searchEngine, args);
|
|
60
|
+
break;
|
|
61
|
+
case 'generate-claude-md':
|
|
62
|
+
result = await handleGenerateClaudeMd(searchEngine, store, args);
|
|
63
|
+
break;
|
|
64
|
+
case 'create-snapshot':
|
|
65
|
+
result = await handleCreateSnapshot(searchEngine, args);
|
|
66
|
+
break;
|
|
67
|
+
case 'load-snapshot':
|
|
68
|
+
result = await handleLoadSnapshot(args);
|
|
69
|
+
break;
|
|
70
|
+
case 'log-decision':
|
|
71
|
+
result = await handleLogDecision(vaultPath, args);
|
|
72
|
+
break;
|
|
73
|
+
case 'find-decisions':
|
|
74
|
+
result = await handleFindDecisions(vaultPath, args);
|
|
75
|
+
break;
|
|
76
|
+
case 'export':
|
|
77
|
+
result = await handleExport(store, args);
|
|
78
|
+
break;
|
|
79
|
+
case 'get-decay-status':
|
|
80
|
+
if (!decayEngine) {
|
|
81
|
+
result = { error: 'Decay engine not available' };
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
result = await handleGetDecayStatus(decayEngine, args);
|
|
85
|
+
break;
|
|
86
|
+
case 'get-morning-brief':
|
|
87
|
+
if (!decayEngine) {
|
|
88
|
+
result = { error: 'Decay engine not available' };
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
result = await handleGetMorningBrief(decayEngine, store);
|
|
92
|
+
break;
|
|
93
|
+
case 'get-learning-path':
|
|
94
|
+
result = await learningPathTool.handler(args);
|
|
95
|
+
return result;
|
|
96
|
+
default:
|
|
97
|
+
return { content: [{ type: 'text', text: `Unknown tool: ${name}` }], isError: true };
|
|
98
|
+
}
|
|
99
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
103
|
+
return { content: [{ type: 'text', text: `Error: ${msg}` }], isError: true };
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return {
|
|
107
|
+
async startStdio() {
|
|
108
|
+
const transport = new StdioServerTransport();
|
|
109
|
+
await server.connect(transport);
|
|
110
|
+
},
|
|
111
|
+
async startHttp(port = 3334) {
|
|
112
|
+
const { createServer } = await import('node:http');
|
|
113
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => `sv-${Date.now()}` });
|
|
114
|
+
await server.connect(transport);
|
|
115
|
+
const httpServer = createServer(async (req, res) => {
|
|
116
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
117
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
118
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
119
|
+
if (req.method === 'OPTIONS') {
|
|
120
|
+
res.writeHead(204);
|
|
121
|
+
res.end();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
await transport.handleRequest(req, res);
|
|
125
|
+
});
|
|
126
|
+
httpServer.listen(port, '127.0.0.1', () => {
|
|
127
|
+
console.error(`🔌 MCP HTTP server running at http://127.0.0.1:${port}/mcp`);
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
server,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=server.js.map
|