gnosys 5.10.0 → 5.11.0
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/README.md +66 -0
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +289 -137
- package/dist/index.d.ts +3 -1
- package/dist/index.js +427 -348
- package/dist/lib/archive.d.ts +3 -4
- package/dist/lib/archive.js +0 -1
- package/dist/lib/ask.d.ts +3 -4
- package/dist/lib/ask.js +0 -1
- package/dist/lib/atomicWrite.d.ts +7 -0
- package/dist/lib/atomicWrite.js +46 -0
- package/dist/lib/attachments.d.ts +0 -1
- package/dist/lib/attachments.js +0 -1
- package/dist/lib/audioExtract.d.ts +0 -1
- package/dist/lib/audioExtract.js +0 -1
- package/dist/lib/audit.d.ts +0 -1
- package/dist/lib/audit.js +0 -1
- package/dist/lib/bootstrap.d.ts +1 -2
- package/dist/lib/bootstrap.js +0 -1
- package/dist/lib/centralize.d.ts +20 -0
- package/dist/lib/centralize.js +34 -0
- package/dist/lib/chat/SlashPalette.d.ts +2 -3
- package/dist/lib/chat/SlashPalette.js +0 -1
- package/dist/lib/chat/boot-splash.d.ts +1 -2
- package/dist/lib/chat/boot-splash.js +0 -1
- package/dist/lib/chat/choose.d.ts +0 -1
- package/dist/lib/chat/choose.js +0 -2
- package/dist/lib/chat/commands.d.ts +1 -2
- package/dist/lib/chat/commands.js +0 -1
- package/dist/lib/chat/components/CitationText.d.ts +1 -2
- package/dist/lib/chat/components/CitationText.js +0 -1
- package/dist/lib/chat/components/MarkdownRenderer.d.ts +0 -1
- package/dist/lib/chat/components/MarkdownRenderer.js +0 -1
- package/dist/lib/chat/components/ToolCallCard.d.ts +1 -2
- package/dist/lib/chat/components/ToolCallCard.js +0 -1
- package/dist/lib/chat/focus.d.ts +3 -3
- package/dist/lib/chat/focus.js +0 -1
- package/dist/lib/chat/index.d.ts +3 -4
- package/dist/lib/chat/index.js +2 -2
- package/dist/lib/chat/intent.d.ts +1 -17
- package/dist/lib/chat/intent.js +2 -3
- package/dist/lib/chat/llmTurn.d.ts +5 -6
- package/dist/lib/chat/llmTurn.js +0 -1
- package/dist/lib/chat/recall.d.ts +2 -3
- package/dist/lib/chat/recall.js +1 -2
- package/dist/lib/chat/render.d.ts +2 -3
- package/dist/lib/chat/render.js +0 -1
- package/dist/lib/chat/session.d.ts +0 -1
- package/dist/lib/chat/session.js +0 -1
- package/dist/lib/chat/theme.d.ts +0 -1
- package/dist/lib/chat/theme.js +0 -1
- package/dist/lib/chat/toolFence.d.ts +2 -2
- package/dist/lib/chat/toolFence.js +0 -1
- package/dist/lib/chat/tools.d.ts +0 -1
- package/dist/lib/chat/tools.js +0 -1
- package/dist/lib/chat/types.d.ts +0 -1
- package/dist/lib/chat/types.js +0 -1
- package/dist/lib/chat/write.d.ts +5 -5
- package/dist/lib/chat/write.js +0 -1
- package/dist/lib/chunkSplitter.d.ts +0 -1
- package/dist/lib/chunkSplitter.js +0 -1
- package/dist/lib/cleanup.d.ts +0 -1
- package/dist/lib/cleanup.js +0 -1
- package/dist/lib/config.d.ts +0 -1
- package/dist/lib/config.js +3 -3
- package/dist/lib/dashboard.d.ts +3 -4
- package/dist/lib/dashboard.js +0 -1
- package/dist/lib/db.d.ts +0 -1
- package/dist/lib/db.js +40 -8
- package/dist/lib/dbSearch.d.ts +3 -4
- package/dist/lib/dbSearch.js +0 -1
- package/dist/lib/dbWrite.d.ts +2 -3
- package/dist/lib/dbWrite.js +0 -1
- package/dist/lib/desktopNotify.d.ts +0 -1
- package/dist/lib/desktopNotify.js +0 -1
- package/dist/lib/docxExtract.d.ts +0 -1
- package/dist/lib/docxExtract.js +22 -1
- package/dist/lib/dream.d.ts +2 -3
- package/dist/lib/dream.js +2 -2
- package/dist/lib/embeddings.d.ts +0 -3
- package/dist/lib/embeddings.js +7 -3
- package/dist/lib/export.d.ts +6 -2
- package/dist/lib/export.js +24 -2
- package/dist/lib/exportProject.d.ts +4 -3
- package/dist/lib/exportProject.js +3 -1
- package/dist/lib/federated.d.ts +1 -2
- package/dist/lib/federated.js +0 -1
- package/dist/lib/fileDetect.d.ts +0 -1
- package/dist/lib/fileDetect.js +0 -1
- package/dist/lib/graph.d.ts +4 -4
- package/dist/lib/graph.js +0 -1
- package/dist/lib/heartbeat.d.ts +0 -13
- package/dist/lib/heartbeat.js +1 -2
- package/dist/lib/hybridSearch.d.ts +5 -21
- package/dist/lib/hybridSearch.js +0 -1
- package/dist/lib/idFormat.d.ts +0 -2
- package/dist/lib/idFormat.js +1 -2
- package/dist/lib/imageExtract.d.ts +0 -1
- package/dist/lib/imageExtract.js +0 -1
- package/dist/lib/import.d.ts +6 -5
- package/dist/lib/import.js +3 -33
- package/dist/lib/importProject.d.ts +4 -4
- package/dist/lib/importProject.js +1 -2
- package/dist/lib/ingest.d.ts +3 -4
- package/dist/lib/ingest.js +0 -1
- package/dist/lib/lensing.d.ts +1 -2
- package/dist/lib/lensing.js +0 -1
- package/dist/lib/llm.d.ts +6 -45
- package/dist/lib/llm.js +27 -9
- package/dist/lib/lock.d.ts +0 -1
- package/dist/lib/lock.js +0 -1
- package/dist/lib/log.d.ts +4 -0
- package/dist/lib/log.js +85 -0
- package/dist/lib/machineConfig.d.ts +2 -3
- package/dist/lib/machineConfig.js +14 -3
- package/dist/lib/machineMigrate.d.ts +0 -1
- package/dist/lib/machineMigrate.js +0 -1
- package/dist/lib/maintenance.d.ts +4 -5
- package/dist/lib/maintenance.js +0 -1
- package/dist/lib/mcpClientConfig.d.ts +20 -0
- package/dist/lib/mcpClientConfig.js +62 -0
- package/dist/lib/mcpHttp.d.ts +52 -0
- package/dist/lib/mcpHttp.js +227 -0
- package/dist/lib/migrate.d.ts +1 -2
- package/dist/lib/migrate.js +1 -1
- package/dist/lib/modelValidation.d.ts +0 -1
- package/dist/lib/modelValidation.js +0 -1
- package/dist/lib/multimodalIngest.d.ts +1 -2
- package/dist/lib/multimodalIngest.js +0 -1
- package/dist/lib/packageManager.d.ts +5 -0
- package/dist/lib/packageManager.js +30 -0
- package/dist/lib/paths.d.ts +0 -7
- package/dist/lib/paths.js +1 -2
- package/dist/lib/pdfExtract.d.ts +0 -1
- package/dist/lib/pdfExtract.js +0 -1
- package/dist/lib/portfolio.d.ts +1 -2
- package/dist/lib/portfolio.js +0 -1
- package/dist/lib/portfolioHtml.d.ts +1 -2
- package/dist/lib/portfolioHtml.js +0 -1
- package/dist/lib/preferences.d.ts +6 -2
- package/dist/lib/preferences.js +19 -1
- package/dist/lib/progress.d.ts +2 -2
- package/dist/lib/progress.js +0 -1
- package/dist/lib/projectIdentity.d.ts +1 -2
- package/dist/lib/projectIdentity.js +5 -5
- package/dist/lib/projectPaths.d.ts +2 -2
- package/dist/lib/projectPaths.js +0 -1
- package/dist/lib/projectScan.d.ts +2 -2
- package/dist/lib/projectScan.js +0 -1
- package/dist/lib/recall.d.ts +6 -6
- package/dist/lib/recall.js +0 -1
- package/dist/lib/remote.d.ts +3 -20
- package/dist/lib/remote.js +37 -2
- package/dist/lib/remoteWizard.d.ts +2 -3
- package/dist/lib/remoteWizard.js +0 -1
- package/dist/lib/resolver.d.ts +1 -2
- package/dist/lib/resolver.js +2 -3
- package/dist/lib/retry.d.ts +0 -1
- package/dist/lib/retry.js +1 -2
- package/dist/lib/rulesGen.d.ts +2 -8
- package/dist/lib/rulesGen.js +1 -2
- package/dist/lib/search.d.ts +1 -2
- package/dist/lib/search.js +1 -1
- package/dist/lib/searchTypes.d.ts +18 -0
- package/dist/lib/searchTypes.js +2 -0
- package/dist/lib/setup/coldStart.d.ts +0 -1
- package/dist/lib/setup/coldStart.js +0 -1
- package/dist/lib/setup/configSetRender.d.ts +0 -1
- package/dist/lib/setup/configSetRender.js +0 -1
- package/dist/lib/setup/dreamRender.d.ts +0 -1
- package/dist/lib/setup/dreamRender.js +0 -1
- package/dist/lib/setup/dreamState.d.ts +2 -2
- package/dist/lib/setup/dreamState.js +0 -1
- package/dist/lib/setup/modelsRender.d.ts +0 -1
- package/dist/lib/setup/modelsRender.js +0 -1
- package/dist/lib/setup/remoteRender.d.ts +0 -1
- package/dist/lib/setup/remoteRender.js +0 -1
- package/dist/lib/setup/routingRender.d.ts +0 -1
- package/dist/lib/setup/routingRender.js +0 -1
- package/dist/lib/setup/sections/ides.d.ts +1 -2
- package/dist/lib/setup/sections/ides.js +3 -2
- package/dist/lib/setup/sections/preferences.d.ts +1 -2
- package/dist/lib/setup/sections/preferences.js +3 -2
- package/dist/lib/setup/sections/routing.d.ts +1 -2
- package/dist/lib/setup/sections/routing.js +0 -1
- package/dist/lib/setup/storePath.d.ts +0 -1
- package/dist/lib/setup/storePath.js +0 -1
- package/dist/lib/setup/summary.d.ts +1 -2
- package/dist/lib/setup/summary.js +0 -1
- package/dist/lib/setup/syncProjectsRender.d.ts +0 -1
- package/dist/lib/setup/syncProjectsRender.js +0 -1
- package/dist/lib/setup/ui/diff.d.ts +0 -1
- package/dist/lib/setup/ui/diff.js +0 -1
- package/dist/lib/setup/ui/footer.d.ts +0 -1
- package/dist/lib/setup/ui/footer.js +0 -1
- package/dist/lib/setup/ui/header.d.ts +0 -1
- package/dist/lib/setup/ui/header.js +0 -1
- package/dist/lib/setup/ui/index.d.ts +0 -1
- package/dist/lib/setup/ui/index.js +0 -1
- package/dist/lib/setup/ui/menu.d.ts +0 -1
- package/dist/lib/setup/ui/menu.js +0 -1
- package/dist/lib/setup/ui/panel.d.ts +0 -1
- package/dist/lib/setup/ui/panel.js +0 -1
- package/dist/lib/setup/ui/prompt.d.ts +0 -1
- package/dist/lib/setup/ui/prompt.js +0 -1
- package/dist/lib/setup/ui/safePrompt.d.ts +0 -1
- package/dist/lib/setup/ui/safePrompt.js +0 -1
- package/dist/lib/setup/ui/spinner.d.ts +0 -1
- package/dist/lib/setup/ui/spinner.js +0 -1
- package/dist/lib/setup/ui/status.d.ts +0 -1
- package/dist/lib/setup/ui/status.js +0 -1
- package/dist/lib/setup/ui/table.d.ts +0 -1
- package/dist/lib/setup/ui/table.js +0 -1
- package/dist/lib/setup/ui/title.d.ts +0 -1
- package/dist/lib/setup/ui/title.js +0 -1
- package/dist/lib/setup/ui/tokens.d.ts +0 -1
- package/dist/lib/setup/ui/tokens.js +0 -1
- package/dist/lib/setup.d.ts +2 -31
- package/dist/lib/setup.js +13 -9
- package/dist/lib/staticSearch.d.ts +0 -1
- package/dist/lib/staticSearch.js +0 -1
- package/dist/lib/store.d.ts +0 -1
- package/dist/lib/store.js +0 -1
- package/dist/lib/structuredIngest.d.ts +0 -1
- package/dist/lib/structuredIngest.js +0 -1
- package/dist/lib/tags.d.ts +0 -1
- package/dist/lib/tags.js +0 -1
- package/dist/lib/timeline.d.ts +2 -3
- package/dist/lib/timeline.js +3 -4
- package/dist/lib/trace.d.ts +1 -16
- package/dist/lib/trace.js +0 -1
- package/dist/lib/upgrade.d.ts +0 -1
- package/dist/lib/upgrade.js +0 -1
- package/dist/lib/videoExtract.d.ts +0 -1
- package/dist/lib/videoExtract.js +0 -1
- package/dist/lib/webIndex.d.ts +1 -3
- package/dist/lib/webIndex.js +0 -1
- package/dist/lib/webIngest.d.ts +13 -1
- package/dist/lib/webIngest.js +98 -24
- package/dist/lib/wikilinks.d.ts +3 -3
- package/dist/lib/wikilinks.js +0 -1
- package/dist/postinstall.d.ts +0 -1
- package/dist/postinstall.js +0 -1
- package/dist/sandbox/client.d.ts +0 -1
- package/dist/sandbox/client.js +0 -1
- package/dist/sandbox/helper-template.d.ts +0 -1
- package/dist/sandbox/helper-template.js +0 -1
- package/dist/sandbox/manager.d.ts +0 -9
- package/dist/sandbox/manager.js +2 -3
- package/dist/sandbox/server.d.ts +2 -3
- package/dist/sandbox/server.js +7 -7
- package/docs/logo.svg +25 -0
- package/package.json +18 -6
- package/prompts/synthesize.md +2 -0
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/archive.d.ts.map +0 -1
- package/dist/lib/archive.js.map +0 -1
- package/dist/lib/ask.d.ts.map +0 -1
- package/dist/lib/ask.js.map +0 -1
- package/dist/lib/attachments.d.ts.map +0 -1
- package/dist/lib/attachments.js.map +0 -1
- package/dist/lib/audioExtract.d.ts.map +0 -1
- package/dist/lib/audioExtract.js.map +0 -1
- package/dist/lib/audit.d.ts.map +0 -1
- package/dist/lib/audit.js.map +0 -1
- package/dist/lib/bootstrap.d.ts.map +0 -1
- package/dist/lib/bootstrap.js.map +0 -1
- package/dist/lib/chat/SlashPalette.d.ts.map +0 -1
- package/dist/lib/chat/SlashPalette.js.map +0 -1
- package/dist/lib/chat/boot-splash.d.ts.map +0 -1
- package/dist/lib/chat/boot-splash.js.map +0 -1
- package/dist/lib/chat/choose.d.ts.map +0 -1
- package/dist/lib/chat/choose.js.map +0 -1
- package/dist/lib/chat/commands.d.ts.map +0 -1
- package/dist/lib/chat/commands.js.map +0 -1
- package/dist/lib/chat/components/CitationText.d.ts.map +0 -1
- package/dist/lib/chat/components/CitationText.js.map +0 -1
- package/dist/lib/chat/components/MarkdownRenderer.d.ts.map +0 -1
- package/dist/lib/chat/components/MarkdownRenderer.js.map +0 -1
- package/dist/lib/chat/components/ToolCallCard.d.ts.map +0 -1
- package/dist/lib/chat/components/ToolCallCard.js.map +0 -1
- package/dist/lib/chat/focus.d.ts.map +0 -1
- package/dist/lib/chat/focus.js.map +0 -1
- package/dist/lib/chat/index.d.ts.map +0 -1
- package/dist/lib/chat/index.js.map +0 -1
- package/dist/lib/chat/intent.d.ts.map +0 -1
- package/dist/lib/chat/intent.js.map +0 -1
- package/dist/lib/chat/llmTurn.d.ts.map +0 -1
- package/dist/lib/chat/llmTurn.js.map +0 -1
- package/dist/lib/chat/recall.d.ts.map +0 -1
- package/dist/lib/chat/recall.js.map +0 -1
- package/dist/lib/chat/render.d.ts.map +0 -1
- package/dist/lib/chat/render.js.map +0 -1
- package/dist/lib/chat/session.d.ts.map +0 -1
- package/dist/lib/chat/session.js.map +0 -1
- package/dist/lib/chat/theme.d.ts.map +0 -1
- package/dist/lib/chat/theme.js.map +0 -1
- package/dist/lib/chat/toolFence.d.ts.map +0 -1
- package/dist/lib/chat/toolFence.js.map +0 -1
- package/dist/lib/chat/tools.d.ts.map +0 -1
- package/dist/lib/chat/tools.js.map +0 -1
- package/dist/lib/chat/types.d.ts.map +0 -1
- package/dist/lib/chat/types.js.map +0 -1
- package/dist/lib/chat/write.d.ts.map +0 -1
- package/dist/lib/chat/write.js.map +0 -1
- package/dist/lib/chunkSplitter.d.ts.map +0 -1
- package/dist/lib/chunkSplitter.js.map +0 -1
- package/dist/lib/cleanup.d.ts.map +0 -1
- package/dist/lib/cleanup.js.map +0 -1
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/dashboard.d.ts.map +0 -1
- package/dist/lib/dashboard.js.map +0 -1
- package/dist/lib/db.d.ts.map +0 -1
- package/dist/lib/db.js.map +0 -1
- package/dist/lib/dbSearch.d.ts.map +0 -1
- package/dist/lib/dbSearch.js.map +0 -1
- package/dist/lib/dbWrite.d.ts.map +0 -1
- package/dist/lib/dbWrite.js.map +0 -1
- package/dist/lib/desktopNotify.d.ts.map +0 -1
- package/dist/lib/desktopNotify.js.map +0 -1
- package/dist/lib/docxExtract.d.ts.map +0 -1
- package/dist/lib/docxExtract.js.map +0 -1
- package/dist/lib/dream.d.ts.map +0 -1
- package/dist/lib/dream.js.map +0 -1
- package/dist/lib/embeddings.d.ts.map +0 -1
- package/dist/lib/embeddings.js.map +0 -1
- package/dist/lib/export.d.ts.map +0 -1
- package/dist/lib/export.js.map +0 -1
- package/dist/lib/exportProject.d.ts.map +0 -1
- package/dist/lib/exportProject.js.map +0 -1
- package/dist/lib/federated.d.ts.map +0 -1
- package/dist/lib/federated.js.map +0 -1
- package/dist/lib/fileDetect.d.ts.map +0 -1
- package/dist/lib/fileDetect.js.map +0 -1
- package/dist/lib/graph.d.ts.map +0 -1
- package/dist/lib/graph.js.map +0 -1
- package/dist/lib/heartbeat.d.ts.map +0 -1
- package/dist/lib/heartbeat.js.map +0 -1
- package/dist/lib/history.d.ts +0 -39
- package/dist/lib/history.d.ts.map +0 -1
- package/dist/lib/history.js +0 -112
- package/dist/lib/history.js.map +0 -1
- package/dist/lib/hybridSearch.d.ts.map +0 -1
- package/dist/lib/hybridSearch.js.map +0 -1
- package/dist/lib/idFormat.d.ts.map +0 -1
- package/dist/lib/idFormat.js.map +0 -1
- package/dist/lib/imageExtract.d.ts.map +0 -1
- package/dist/lib/imageExtract.js.map +0 -1
- package/dist/lib/import.d.ts.map +0 -1
- package/dist/lib/import.js.map +0 -1
- package/dist/lib/importProject.d.ts.map +0 -1
- package/dist/lib/importProject.js.map +0 -1
- package/dist/lib/ingest.d.ts.map +0 -1
- package/dist/lib/ingest.js.map +0 -1
- package/dist/lib/lensing.d.ts.map +0 -1
- package/dist/lib/lensing.js.map +0 -1
- package/dist/lib/llm.d.ts.map +0 -1
- package/dist/lib/llm.js.map +0 -1
- package/dist/lib/lock.d.ts.map +0 -1
- package/dist/lib/lock.js.map +0 -1
- package/dist/lib/machineConfig.d.ts.map +0 -1
- package/dist/lib/machineConfig.js.map +0 -1
- package/dist/lib/machineMigrate.d.ts.map +0 -1
- package/dist/lib/machineMigrate.js.map +0 -1
- package/dist/lib/maintenance.d.ts.map +0 -1
- package/dist/lib/maintenance.js.map +0 -1
- package/dist/lib/migrate.d.ts.map +0 -1
- package/dist/lib/migrate.js.map +0 -1
- package/dist/lib/modelValidation.d.ts.map +0 -1
- package/dist/lib/modelValidation.js.map +0 -1
- package/dist/lib/multimodalIngest.d.ts.map +0 -1
- package/dist/lib/multimodalIngest.js.map +0 -1
- package/dist/lib/paths.d.ts.map +0 -1
- package/dist/lib/paths.js.map +0 -1
- package/dist/lib/pdfExtract.d.ts.map +0 -1
- package/dist/lib/pdfExtract.js.map +0 -1
- package/dist/lib/portfolio.d.ts.map +0 -1
- package/dist/lib/portfolio.js.map +0 -1
- package/dist/lib/portfolioHtml.d.ts.map +0 -1
- package/dist/lib/portfolioHtml.js.map +0 -1
- package/dist/lib/preferences.d.ts.map +0 -1
- package/dist/lib/preferences.js.map +0 -1
- package/dist/lib/progress.d.ts.map +0 -1
- package/dist/lib/progress.js.map +0 -1
- package/dist/lib/projectIdentity.d.ts.map +0 -1
- package/dist/lib/projectIdentity.js.map +0 -1
- package/dist/lib/projectPaths.d.ts.map +0 -1
- package/dist/lib/projectPaths.js.map +0 -1
- package/dist/lib/projectScan.d.ts.map +0 -1
- package/dist/lib/projectScan.js.map +0 -1
- package/dist/lib/recall.d.ts.map +0 -1
- package/dist/lib/recall.js.map +0 -1
- package/dist/lib/remote.d.ts.map +0 -1
- package/dist/lib/remote.js.map +0 -1
- package/dist/lib/remoteWizard.d.ts.map +0 -1
- package/dist/lib/remoteWizard.js.map +0 -1
- package/dist/lib/resolver.d.ts.map +0 -1
- package/dist/lib/resolver.js.map +0 -1
- package/dist/lib/retry.d.ts.map +0 -1
- package/dist/lib/retry.js.map +0 -1
- package/dist/lib/rulesGen.d.ts.map +0 -1
- package/dist/lib/rulesGen.js.map +0 -1
- package/dist/lib/search.d.ts.map +0 -1
- package/dist/lib/search.js.map +0 -1
- package/dist/lib/setup/coldStart.d.ts.map +0 -1
- package/dist/lib/setup/coldStart.js.map +0 -1
- package/dist/lib/setup/configSetRender.d.ts.map +0 -1
- package/dist/lib/setup/configSetRender.js.map +0 -1
- package/dist/lib/setup/dreamRender.d.ts.map +0 -1
- package/dist/lib/setup/dreamRender.js.map +0 -1
- package/dist/lib/setup/dreamState.d.ts.map +0 -1
- package/dist/lib/setup/dreamState.js.map +0 -1
- package/dist/lib/setup/modelsRender.d.ts.map +0 -1
- package/dist/lib/setup/modelsRender.js.map +0 -1
- package/dist/lib/setup/remoteRender.d.ts.map +0 -1
- package/dist/lib/setup/remoteRender.js.map +0 -1
- package/dist/lib/setup/routingRender.d.ts.map +0 -1
- package/dist/lib/setup/routingRender.js.map +0 -1
- package/dist/lib/setup/sections/ides.d.ts.map +0 -1
- package/dist/lib/setup/sections/ides.js.map +0 -1
- package/dist/lib/setup/sections/preferences.d.ts.map +0 -1
- package/dist/lib/setup/sections/preferences.js.map +0 -1
- package/dist/lib/setup/sections/routing.d.ts.map +0 -1
- package/dist/lib/setup/sections/routing.js.map +0 -1
- package/dist/lib/setup/storePath.d.ts.map +0 -1
- package/dist/lib/setup/storePath.js.map +0 -1
- package/dist/lib/setup/summary.d.ts.map +0 -1
- package/dist/lib/setup/summary.js.map +0 -1
- package/dist/lib/setup/syncProjectsRender.d.ts.map +0 -1
- package/dist/lib/setup/syncProjectsRender.js.map +0 -1
- package/dist/lib/setup/ui/diff.d.ts.map +0 -1
- package/dist/lib/setup/ui/diff.js.map +0 -1
- package/dist/lib/setup/ui/footer.d.ts.map +0 -1
- package/dist/lib/setup/ui/footer.js.map +0 -1
- package/dist/lib/setup/ui/header.d.ts.map +0 -1
- package/dist/lib/setup/ui/header.js.map +0 -1
- package/dist/lib/setup/ui/index.d.ts.map +0 -1
- package/dist/lib/setup/ui/index.js.map +0 -1
- package/dist/lib/setup/ui/menu.d.ts.map +0 -1
- package/dist/lib/setup/ui/menu.js.map +0 -1
- package/dist/lib/setup/ui/panel.d.ts.map +0 -1
- package/dist/lib/setup/ui/panel.js.map +0 -1
- package/dist/lib/setup/ui/prompt.d.ts.map +0 -1
- package/dist/lib/setup/ui/prompt.js.map +0 -1
- package/dist/lib/setup/ui/safePrompt.d.ts.map +0 -1
- package/dist/lib/setup/ui/safePrompt.js.map +0 -1
- package/dist/lib/setup/ui/spinner.d.ts.map +0 -1
- package/dist/lib/setup/ui/spinner.js.map +0 -1
- package/dist/lib/setup/ui/status.d.ts.map +0 -1
- package/dist/lib/setup/ui/status.js.map +0 -1
- package/dist/lib/setup/ui/table.d.ts.map +0 -1
- package/dist/lib/setup/ui/table.js.map +0 -1
- package/dist/lib/setup/ui/title.d.ts.map +0 -1
- package/dist/lib/setup/ui/title.js.map +0 -1
- package/dist/lib/setup/ui/tokens.d.ts.map +0 -1
- package/dist/lib/setup/ui/tokens.js.map +0 -1
- package/dist/lib/setup.d.ts.map +0 -1
- package/dist/lib/setup.js.map +0 -1
- package/dist/lib/staticSearch.d.ts.map +0 -1
- package/dist/lib/staticSearch.js.map +0 -1
- package/dist/lib/store.d.ts.map +0 -1
- package/dist/lib/store.js.map +0 -1
- package/dist/lib/structuredIngest.d.ts.map +0 -1
- package/dist/lib/structuredIngest.js.map +0 -1
- package/dist/lib/tags.d.ts.map +0 -1
- package/dist/lib/tags.js.map +0 -1
- package/dist/lib/timeline.d.ts.map +0 -1
- package/dist/lib/timeline.js.map +0 -1
- package/dist/lib/trace.d.ts.map +0 -1
- package/dist/lib/trace.js.map +0 -1
- package/dist/lib/upgrade.d.ts.map +0 -1
- package/dist/lib/upgrade.js.map +0 -1
- package/dist/lib/videoExtract.d.ts.map +0 -1
- package/dist/lib/videoExtract.js.map +0 -1
- package/dist/lib/webIndex.d.ts.map +0 -1
- package/dist/lib/webIndex.js.map +0 -1
- package/dist/lib/webIngest.d.ts.map +0 -1
- package/dist/lib/webIngest.js.map +0 -1
- package/dist/lib/wikilinks.d.ts.map +0 -1
- package/dist/lib/wikilinks.js.map +0 -1
- package/dist/postinstall.d.ts.map +0 -1
- package/dist/postinstall.js.map +0 -1
- package/dist/sandbox/client.d.ts.map +0 -1
- package/dist/sandbox/client.js.map +0 -1
- package/dist/sandbox/helper-template.d.ts.map +0 -1
- package/dist/sandbox/helper-template.js.map +0 -1
- package/dist/sandbox/index.d.ts +0 -10
- package/dist/sandbox/index.d.ts.map +0 -1
- package/dist/sandbox/index.js +0 -10
- package/dist/sandbox/index.js.map +0 -1
- package/dist/sandbox/manager.d.ts.map +0 -1
- package/dist/sandbox/manager.js.map +0 -1
- package/dist/sandbox/server.d.ts.map +0 -1
- package/dist/sandbox/server.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -45,7 +45,6 @@ import { GnosysSearch } from "./lib/search.js";
|
|
|
45
45
|
import { GnosysTagRegistry } from "./lib/tags.js";
|
|
46
46
|
import { GnosysResolver } from "./lib/resolver.js";
|
|
47
47
|
import { applyLens } from "./lib/lensing.js";
|
|
48
|
-
import { getFileHistory, rollbackToCommit, hasGitHistory } from "./lib/history.js";
|
|
49
48
|
import { groupByPeriod, computeStats } from "./lib/timeline.js";
|
|
50
49
|
import { buildLinkGraph, getBacklinks, getOutgoingLinks, formatGraphSummary } from "./lib/wikilinks.js";
|
|
51
50
|
import { loadConfig, DEFAULT_CONFIG } from "./lib/config.js";
|
|
@@ -55,7 +54,7 @@ import { initAudit, readAuditLog, formatAuditTimeline } from "./lib/audit.js";
|
|
|
55
54
|
import { GnosysDB } from "./lib/db.js";
|
|
56
55
|
import { syncMemoryToDb, syncUpdateToDb, syncDearchiveToDb, syncReinforcementToDb, auditToDb } from "./lib/dbWrite.js";
|
|
57
56
|
import { createProjectIdentity, readProjectIdentity } from "./lib/projectIdentity.js";
|
|
58
|
-
import { setPreference, getPreference, getAllPreferences, deletePreference } from "./lib/preferences.js";
|
|
57
|
+
import { setPreference, getPreference, getAllPreferences, deletePreference, KNOWN_PREFERENCE_KEYS, suggestPreferenceKey } from "./lib/preferences.js";
|
|
59
58
|
import { syncRules, generateRulesBlock } from "./lib/rulesGen.js";
|
|
60
59
|
import { federatedSearch, detectAmbiguity, generateBriefing, generateAllBriefings, getWorkingSet, formatWorkingSet, detectCurrentProject } from "./lib/federated.js";
|
|
61
60
|
import { generatePortfolio, formatPortfolioCompact, formatPortfolioMarkdown, generateStatusPrompt } from "./lib/portfolio.js";
|
|
@@ -67,6 +66,23 @@ const server = new McpServer({
|
|
|
67
66
|
name: "gnosys",
|
|
68
67
|
version: "2.0.0",
|
|
69
68
|
});
|
|
69
|
+
const _registrations = [];
|
|
70
|
+
// Typed to the McpServer methods so call-site generic inference (Zod schema →
|
|
71
|
+
// handler arg types) is preserved; the body just collects a replay thunk.
|
|
72
|
+
const regTool = ((...args) => {
|
|
73
|
+
_registrations.push((s) => s.tool(...args));
|
|
74
|
+
});
|
|
75
|
+
const regPrompt = ((...args) => {
|
|
76
|
+
_registrations.push((s) => s.prompt(...args));
|
|
77
|
+
});
|
|
78
|
+
const regResource = ((...args) => {
|
|
79
|
+
_registrations.push((s) => s.resource(...args));
|
|
80
|
+
});
|
|
81
|
+
/** Replay all collected capability registrations onto a server instance. */
|
|
82
|
+
export function registerCapabilities(s) {
|
|
83
|
+
for (const r of _registrations)
|
|
84
|
+
r(s);
|
|
85
|
+
}
|
|
70
86
|
/**
|
|
71
87
|
* v5.4.1: Format MCP errors. Detects DB corruption and replaces the raw
|
|
72
88
|
* "database disk image is malformed" with actionable recovery instructions.
|
|
@@ -155,7 +171,7 @@ async function resolveToolContext(projectRoot) {
|
|
|
155
171
|
const scopedWriteTarget = scopedResolver.getWriteTarget();
|
|
156
172
|
const scopedStorePath = scopedWriteTarget?.store.getStorePath() || "";
|
|
157
173
|
let scopedConfig = DEFAULT_CONFIG;
|
|
158
|
-
|
|
174
|
+
const scopedDb = null;
|
|
159
175
|
let scopedSearch = null;
|
|
160
176
|
// v3.0: Read project identity
|
|
161
177
|
const identity = await readProjectIdentity(path.resolve(projectRoot));
|
|
@@ -220,7 +236,7 @@ function resolveWriteScope(ctx, targetStore) {
|
|
|
220
236
|
return { ok: true, scope: "project", projectId: ctx.projectId };
|
|
221
237
|
}
|
|
222
238
|
// ─── Tool: gnosys_discover ──────────────────────────────────────────────
|
|
223
|
-
|
|
239
|
+
regTool("gnosys_discover", "Discover relevant memories by describing what you're working on. Searches relevance keyword clouds across all stores. Returns lightweight metadata (title, path, relevance keywords) — NO file contents. Use gnosys_read to load specific memories you need. Call this FIRST when starting a task to find what Gnosys knows.", {
|
|
224
240
|
query: z
|
|
225
241
|
.string()
|
|
226
242
|
.describe("Describe what you're working on or looking for. Use keywords, not sentences. Example: 'auth JWT session tokens' or 'deployment CI/CD pipeline'"),
|
|
@@ -274,7 +290,7 @@ server.tool("gnosys_discover", "Discover relevant memories by describing what yo
|
|
|
274
290
|
};
|
|
275
291
|
});
|
|
276
292
|
// ─── Tool: gnosys_read ───────────────────────────────────────────────────
|
|
277
|
-
|
|
293
|
+
regTool("gnosys_read", "Read a specific memory. Accepts a memory ID (e.g., 'arch-012') or layer-prefixed path (e.g., 'project:decisions/why-not-rag.md'). Without a prefix, searches all stores in precedence order.", {
|
|
278
294
|
path: z.string().describe("Memory ID or path, optionally prefixed with store layer"),
|
|
279
295
|
projectRoot: projectRootParam,
|
|
280
296
|
}, async ({ path: memPath, projectRoot }) => {
|
|
@@ -284,7 +300,7 @@ server.tool("gnosys_read", "Read a specific memory. Accepts a memory ID (e.g., '
|
|
|
284
300
|
const dbMem = ctx.centralDb.getMemory(memPath);
|
|
285
301
|
if (dbMem) {
|
|
286
302
|
const tags = dbMem.tags || "[]";
|
|
287
|
-
const
|
|
303
|
+
const headerLines = [
|
|
288
304
|
`---`,
|
|
289
305
|
`id: ${dbMem.id}`,
|
|
290
306
|
`title: '${dbMem.title}'`,
|
|
@@ -298,8 +314,14 @@ server.tool("gnosys_read", "Read a specific memory. Accepts a memory ID (e.g., '
|
|
|
298
314
|
`tier: ${dbMem.tier}`,
|
|
299
315
|
`created: '${dbMem.created}'`,
|
|
300
316
|
`modified: '${dbMem.modified}'`,
|
|
301
|
-
|
|
302
|
-
|
|
317
|
+
];
|
|
318
|
+
if (dbMem.source_file) {
|
|
319
|
+
headerLines.push(`source_file: ${dbMem.source_file}${dbMem.source_page != null ? ` (page ${Number(dbMem.source_page)})` : ""}`);
|
|
320
|
+
}
|
|
321
|
+
if (dbMem.source_path)
|
|
322
|
+
headerLines.push(`source_path: ${dbMem.source_path}`);
|
|
323
|
+
headerLines.push(`---`);
|
|
324
|
+
const header = headerLines.join("\n");
|
|
303
325
|
return {
|
|
304
326
|
content: [{ type: "text", text: `[Source: gnosys.db]\n\n${header}\n\n${dbMem.content}` }],
|
|
305
327
|
};
|
|
@@ -314,7 +336,13 @@ server.tool("gnosys_read", "Read a specific memory. Accepts a memory ID (e.g., '
|
|
|
314
336
|
isError: true,
|
|
315
337
|
};
|
|
316
338
|
}
|
|
317
|
-
|
|
339
|
+
let raw;
|
|
340
|
+
try {
|
|
341
|
+
raw = await fs.readFile(memory.filePath, "utf-8");
|
|
342
|
+
}
|
|
343
|
+
catch (err) {
|
|
344
|
+
return { content: [{ type: "text", text: formatMcpError("reading memory", err) }], isError: true };
|
|
345
|
+
}
|
|
318
346
|
return {
|
|
319
347
|
content: [
|
|
320
348
|
{
|
|
@@ -325,7 +353,7 @@ server.tool("gnosys_read", "Read a specific memory. Accepts a memory ID (e.g., '
|
|
|
325
353
|
};
|
|
326
354
|
});
|
|
327
355
|
// ─── Tool: gnosys_search ─────────────────────────────────────────────────
|
|
328
|
-
|
|
356
|
+
regTool("gnosys_search", "Search memories by keyword across all stores. Returns matching file paths with relevance snippets.", {
|
|
329
357
|
query: z.string().describe("Search query (keywords)"),
|
|
330
358
|
limit: z.number().optional().describe("Max results (default 20)"),
|
|
331
359
|
projectRoot: projectRootParam,
|
|
@@ -377,7 +405,7 @@ server.tool("gnosys_search", "Search memories by keyword across all stores. Retu
|
|
|
377
405
|
};
|
|
378
406
|
});
|
|
379
407
|
// ─── Tool: gnosys_list ───────────────────────────────────────────────────
|
|
380
|
-
|
|
408
|
+
regTool("gnosys_list", "List memories across all stores, optionally filtered by category, tag, or store layer.", {
|
|
381
409
|
category: z.string().optional().describe("Filter by category"),
|
|
382
410
|
tag: z.string().optional().describe("Filter by tag"),
|
|
383
411
|
store: z.string().optional().describe("Filter by store layer (project/personal/global/optional)"),
|
|
@@ -463,7 +491,7 @@ server.tool("gnosys_list", "List memories across all stores, optionally filtered
|
|
|
463
491
|
};
|
|
464
492
|
});
|
|
465
493
|
// ─── Tool: gnosys_add ────────────────────────────────────────────────────
|
|
466
|
-
|
|
494
|
+
regTool("gnosys_add", "Add a new memory. Accepts raw text — an LLM structures it into an atomic memory. Writes to the project store by default. Use store='personal' for cross-project knowledge, or store='global' to explicitly write to shared org knowledge.", {
|
|
467
495
|
input: z
|
|
468
496
|
.string()
|
|
469
497
|
.describe("Raw text input. Can be a decision, concept, fact, observation, or any knowledge."),
|
|
@@ -577,7 +605,7 @@ server.tool("gnosys_add", "Add a new memory. Accepts raw text — an LLM structu
|
|
|
577
605
|
}
|
|
578
606
|
});
|
|
579
607
|
// ─── Tool: gnosys_add_structured ─────────────────────────────────────────
|
|
580
|
-
|
|
608
|
+
regTool("gnosys_add_structured", "Add a memory with structured input (no LLM needed). Writes to the project store by default. Use store='global' to explicitly write to shared org knowledge.", {
|
|
581
609
|
title: z.string().describe("Memory title"),
|
|
582
610
|
category: z.string().describe("Category directory name"),
|
|
583
611
|
tags: z
|
|
@@ -656,7 +684,7 @@ server.tool("gnosys_add_structured", "Add a memory with structured input (no LLM
|
|
|
656
684
|
}
|
|
657
685
|
});
|
|
658
686
|
// ─── Tool: gnosys_tags ───────────────────────────────────────────────────
|
|
659
|
-
|
|
687
|
+
regTool("gnosys_tags", "List all tags in the registry, grouped by category.", { projectRoot: projectRootParam }, async ({ projectRoot }) => {
|
|
660
688
|
// Tag registry is module-level and shared across projects, projectRoot is for API consistency
|
|
661
689
|
if (!tagRegistry) {
|
|
662
690
|
return { content: [{ type: "text", text: "Tag registry not loaded." }], isError: true };
|
|
@@ -671,7 +699,7 @@ server.tool("gnosys_tags", "List all tags in the registry, grouped by category."
|
|
|
671
699
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
672
700
|
});
|
|
673
701
|
// ─── Tool: gnosys_tags_add ───────────────────────────────────────────────
|
|
674
|
-
|
|
702
|
+
regTool("gnosys_tags_add", "Add a new tag to the registry.", {
|
|
675
703
|
category: z.string().describe("Tag category (domain, type, concern, status_tag)"),
|
|
676
704
|
tag: z.string().describe("The new tag to add"),
|
|
677
705
|
projectRoot: projectRootParam,
|
|
@@ -691,7 +719,7 @@ server.tool("gnosys_tags_add", "Add a new tag to the registry.", {
|
|
|
691
719
|
};
|
|
692
720
|
});
|
|
693
721
|
// ─── Tool: gnosys_reinforce ──────────────────────────────────────────────
|
|
694
|
-
|
|
722
|
+
regTool("gnosys_reinforce", "Signal whether a memory was useful. 'useful' reinforces it (resets decay). 'not_relevant' means routing was wrong, not the memory (memory unchanged). 'outdated' flags for review.", {
|
|
695
723
|
memory_id: z.string().describe("The memory ID (from frontmatter)"),
|
|
696
724
|
signal: z
|
|
697
725
|
.enum(["useful", "not_relevant", "outdated"])
|
|
@@ -699,46 +727,51 @@ server.tool("gnosys_reinforce", "Signal whether a memory was useful. 'useful' re
|
|
|
699
727
|
context: z.string().optional().describe("Why this signal was given"),
|
|
700
728
|
projectRoot: projectRootParam,
|
|
701
729
|
}, async ({ memory_id, signal, context, projectRoot }) => {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
.
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
730
|
+
try {
|
|
731
|
+
const ctx = await resolveToolContext(projectRoot);
|
|
732
|
+
// Log to the first writable store's .config directory
|
|
733
|
+
const writeTarget = ctx.resolver.getWriteTarget();
|
|
734
|
+
if (writeTarget) {
|
|
735
|
+
const logPath = path.join(writeTarget.store.getStorePath(), ".config", "reinforcement.log");
|
|
736
|
+
const entry = JSON.stringify({
|
|
737
|
+
memory_id,
|
|
738
|
+
signal,
|
|
739
|
+
context,
|
|
740
|
+
timestamp: new Date().toISOString(),
|
|
741
|
+
});
|
|
742
|
+
await fs.appendFile(logPath, entry + "\n", "utf-8");
|
|
743
|
+
}
|
|
744
|
+
// If 'useful', find the memory across all stores and update if writable
|
|
745
|
+
if (signal === "useful") {
|
|
746
|
+
const allMemories = await ctx.resolver.getAllMemories();
|
|
747
|
+
const memory = allMemories.find((m) => m.frontmatter.id === memory_id);
|
|
748
|
+
if (memory) {
|
|
749
|
+
const sourceStore = ctx.resolver
|
|
750
|
+
.getStores()
|
|
751
|
+
.find((s) => s.label === memory.sourceLabel);
|
|
752
|
+
if (sourceStore) {
|
|
753
|
+
const count = (memory.frontmatter.reinforcement_count || 0) + 1;
|
|
754
|
+
// Write reinforcement to DB only (SQLite is sole source of truth)
|
|
755
|
+
if (ctx.centralDb?.isAvailable()) {
|
|
756
|
+
syncReinforcementToDb(ctx.centralDb, memory_id, count);
|
|
757
|
+
auditToDb(ctx.centralDb, "reinforce", memory_id, { signal, context });
|
|
758
|
+
}
|
|
729
759
|
}
|
|
730
760
|
}
|
|
731
761
|
}
|
|
762
|
+
const messages = {
|
|
763
|
+
useful: `Memory ${memory_id} reinforced. Decay clock reset.`,
|
|
764
|
+
not_relevant: `Routing feedback logged for ${memory_id}. Memory unchanged — consider reviewing its relevance keywords or tags.`,
|
|
765
|
+
outdated: `Memory ${memory_id} flagged for review as outdated.`,
|
|
766
|
+
};
|
|
767
|
+
return { content: [{ type: "text", text: messages[signal] }] };
|
|
768
|
+
}
|
|
769
|
+
catch (err) {
|
|
770
|
+
return { content: [{ type: "text", text: formatMcpError("reinforcing memory", err) }], isError: true };
|
|
732
771
|
}
|
|
733
|
-
const messages = {
|
|
734
|
-
useful: `Memory ${memory_id} reinforced. Decay clock reset.`,
|
|
735
|
-
not_relevant: `Routing feedback logged for ${memory_id}. Memory unchanged — consider reviewing its relevance keywords or tags.`,
|
|
736
|
-
outdated: `Memory ${memory_id} flagged for review as outdated.`,
|
|
737
|
-
};
|
|
738
|
-
return { content: [{ type: "text", text: messages[signal] }] };
|
|
739
772
|
});
|
|
740
773
|
// ─── Tool: gnosys_init ───────────────────────────────────────────────────
|
|
741
|
-
|
|
774
|
+
regTool("gnosys_init", "Initialize Gnosys in a project directory. Creates .gnosys/ with project identity (gnosys.json), registers the project in the central DB (~/.gnosys/gnosys.db), and sets up tag registry. You MUST run this before any other Gnosys tool in a new project. Pass the full absolute path to the project root.", {
|
|
742
775
|
directory: z
|
|
743
776
|
.string()
|
|
744
777
|
.describe("Absolute path to the project directory to initialize. Required."),
|
|
@@ -812,7 +845,7 @@ server.tool("gnosys_init", "Initialize Gnosys in a project directory. Creates .g
|
|
|
812
845
|
};
|
|
813
846
|
});
|
|
814
847
|
// ─── Tool: gnosys_migrate ────────────────────────────────────────────────
|
|
815
|
-
|
|
848
|
+
regTool("gnosys_migrate", "Migrate a Gnosys store (.gnosys/) from one directory to another. Updates the project name, working directory, and central DB registration. Use this when a project has moved or you want to consolidate stores.", {
|
|
816
849
|
sourcePath: z.string().describe("Directory that currently contains .gnosys/ (absolute path)"),
|
|
817
850
|
targetPath: z.string().describe("Directory to move .gnosys/ into (absolute path)"),
|
|
818
851
|
newName: z.string().optional().describe("New project name (default: basename of target directory)"),
|
|
@@ -884,7 +917,7 @@ server.tool("gnosys_migrate", "Migrate a Gnosys store (.gnosys/) from one direct
|
|
|
884
917
|
}
|
|
885
918
|
});
|
|
886
919
|
// ─── Tool: gnosys_update ─────────────────────────────────────────────────
|
|
887
|
-
|
|
920
|
+
regTool("gnosys_update", "Update an existing memory's frontmatter and/or content. Specify the memory path and the fields to change.", {
|
|
888
921
|
path: z
|
|
889
922
|
.string()
|
|
890
923
|
.describe("Path to memory, optionally prefixed with store layer (e.g., 'project:decisions/auth.md')"),
|
|
@@ -990,7 +1023,7 @@ server.tool("gnosys_update", "Update an existing memory's frontmatter and/or con
|
|
|
990
1023
|
};
|
|
991
1024
|
});
|
|
992
1025
|
// ─── Tool: gnosys_stale ─────────────────────────────────────────────────
|
|
993
|
-
|
|
1026
|
+
regTool("gnosys_stale", "Find memories that haven't been modified or reviewed within a given number of days. Useful for identifying knowledge that may be outdated.", {
|
|
994
1027
|
days: z
|
|
995
1028
|
.number()
|
|
996
1029
|
.optional()
|
|
@@ -998,46 +1031,51 @@ server.tool("gnosys_stale", "Find memories that haven't been modified or reviewe
|
|
|
998
1031
|
limit: z.number().optional().describe("Max results (default 20)"),
|
|
999
1032
|
projectRoot: projectRootParam,
|
|
1000
1033
|
}, async ({ days, limit, projectRoot }) => {
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1034
|
+
try {
|
|
1035
|
+
const ctx = await resolveToolContext(projectRoot);
|
|
1036
|
+
const threshold = days || 90;
|
|
1037
|
+
const maxResults = limit || 20;
|
|
1038
|
+
const cutoff = new Date();
|
|
1039
|
+
cutoff.setDate(cutoff.getDate() - threshold);
|
|
1040
|
+
const cutoffStr = cutoff.toISOString().split("T")[0];
|
|
1041
|
+
const allMemories = await ctx.resolver.getAllMemories();
|
|
1042
|
+
const stale = allMemories
|
|
1043
|
+
.filter((m) => {
|
|
1044
|
+
const lastTouched = m.frontmatter.last_reviewed || m.frontmatter.modified;
|
|
1045
|
+
return lastTouched && lastTouched < cutoffStr;
|
|
1046
|
+
})
|
|
1047
|
+
.sort((a, b) => {
|
|
1048
|
+
const aDate = a.frontmatter.last_reviewed || a.frontmatter.modified;
|
|
1049
|
+
const bDate = b.frontmatter.last_reviewed || b.frontmatter.modified;
|
|
1050
|
+
return (aDate || "").localeCompare(bDate || "");
|
|
1051
|
+
})
|
|
1052
|
+
.slice(0, maxResults);
|
|
1053
|
+
if (stale.length === 0) {
|
|
1054
|
+
return {
|
|
1055
|
+
content: [
|
|
1056
|
+
{
|
|
1057
|
+
type: "text",
|
|
1058
|
+
text: `No memories older than ${threshold} days found. Everything is fresh.`,
|
|
1059
|
+
},
|
|
1060
|
+
],
|
|
1061
|
+
};
|
|
1062
|
+
}
|
|
1063
|
+
const lines = stale.map((m) => `- **${m.frontmatter.title}** (${m.sourceLabel}:${m.relativePath})\n Last modified: ${m.frontmatter.modified}${m.frontmatter.last_reviewed ? `, Last reviewed: ${m.frontmatter.last_reviewed}` : ""}`);
|
|
1020
1064
|
return {
|
|
1021
1065
|
content: [
|
|
1022
1066
|
{
|
|
1023
1067
|
type: "text",
|
|
1024
|
-
text: `
|
|
1068
|
+
text: `Found ${stale.length} memories not touched in ${threshold}+ days:\n\n${lines.join("\n\n")}\n\nUse gnosys_read to review, then gnosys_update or gnosys_reinforce as needed.`,
|
|
1025
1069
|
},
|
|
1026
1070
|
],
|
|
1027
1071
|
};
|
|
1028
1072
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
{
|
|
1033
|
-
type: "text",
|
|
1034
|
-
text: `Found ${stale.length} memories not touched in ${threshold}+ days:\n\n${lines.join("\n\n")}\n\nUse gnosys_read to review, then gnosys_update or gnosys_reinforce as needed.`,
|
|
1035
|
-
},
|
|
1036
|
-
],
|
|
1037
|
-
};
|
|
1073
|
+
catch (err) {
|
|
1074
|
+
return { content: [{ type: "text", text: formatMcpError("finding stale memories", err) }], isError: true };
|
|
1075
|
+
}
|
|
1038
1076
|
});
|
|
1039
1077
|
// ─── Tool: gnosys_commit_context ────────────────────────────────────────
|
|
1040
|
-
|
|
1078
|
+
regTool("gnosys_commit_context", "Pre-compaction memory sweep. Call this before context is lost (e.g., before a long conversation compacts). Extracts important decisions, facts, and insights from the conversation and commits novel ones to memory. Checks existing memories to avoid duplicates — only adds what's genuinely new or augments what's changed.", {
|
|
1041
1079
|
context: z
|
|
1042
1080
|
.string()
|
|
1043
1081
|
.describe("Summary of the conversation or context to extract memories from. Include key decisions, facts, insights, and observations."),
|
|
@@ -1199,17 +1237,15 @@ Output ONLY the JSON array, no markdown fences.`,
|
|
|
1199
1237
|
};
|
|
1200
1238
|
});
|
|
1201
1239
|
// ─── Tool: gnosys_history ────────────────────────────────────────────────
|
|
1202
|
-
|
|
1240
|
+
regTool("gnosys_history", "View audit history for a memory. Shows what changed and when based on the audit log.", {
|
|
1203
1241
|
path: z.string().describe("Path to memory, optionally layer-prefixed"),
|
|
1204
1242
|
limit: z.number().optional().describe("Max history entries (default 20)"),
|
|
1205
1243
|
projectRoot: projectRootParam,
|
|
1206
1244
|
}, async ({ path: memPath, limit, projectRoot }) => {
|
|
1207
1245
|
const ctx = await resolveToolContext(projectRoot);
|
|
1208
|
-
// DB-first: resolve memory ID and show timestamps
|
|
1209
1246
|
if (ctx.centralDb?.isAvailable()) {
|
|
1210
1247
|
const dbMem = ctx.centralDb.getMemory(memPath);
|
|
1211
1248
|
if (dbMem) {
|
|
1212
|
-
// Query audit_log for this memory
|
|
1213
1249
|
const audits = ctx.centralDb.getAuditLog(dbMem.id, limit || 20);
|
|
1214
1250
|
if (audits.length > 0) {
|
|
1215
1251
|
const lines = audits.map((e) => `- ${e.timestamp.split("T")[0]} — ${e.operation}${e.details ? ` (${e.details})` : ""}`);
|
|
@@ -1228,60 +1264,10 @@ server.tool("gnosys_history", "View version history for a memory. Shows what cha
|
|
|
1228
1264
|
};
|
|
1229
1265
|
}
|
|
1230
1266
|
}
|
|
1231
|
-
|
|
1232
|
-
const memory = await ctx.resolver.readMemory(memPath);
|
|
1233
|
-
if (!memory) {
|
|
1234
|
-
return { content: [{ type: "text", text: `Memory not found: ${memPath}` }], isError: true };
|
|
1235
|
-
}
|
|
1236
|
-
const sourceStore = ctx.resolver.getStores().find((s) => s.label === memory.sourceLabel);
|
|
1237
|
-
if (!sourceStore || !hasGitHistory(sourceStore.path)) {
|
|
1238
|
-
return { content: [{ type: "text", text: "No git history available for this store." }], isError: true };
|
|
1239
|
-
}
|
|
1240
|
-
const history = getFileHistory(sourceStore.path, memory.relativePath, limit || 20);
|
|
1241
|
-
if (history.length === 0) {
|
|
1242
|
-
return { content: [{ type: "text", text: "No history found for this memory." }] };
|
|
1243
|
-
}
|
|
1244
|
-
const lines = history.map((e) => `- \`${e.commitHash.substring(0, 7)}\` ${e.date} — ${e.message}`);
|
|
1245
|
-
return {
|
|
1246
|
-
content: [{
|
|
1247
|
-
type: "text",
|
|
1248
|
-
text: `History for **${memory.frontmatter.title}** (${history.length} entries):\n\n${lines.join("\n")}\n\nUse gnosys_rollback with a commit hash to revert to a prior version.`,
|
|
1249
|
-
}],
|
|
1250
|
-
};
|
|
1251
|
-
});
|
|
1252
|
-
// ─── Tool: gnosys_rollback ──────────────────────────────────────────────
|
|
1253
|
-
server.tool("gnosys_rollback", "Rollback a memory to its state at a specific commit. Non-destructive: creates a new commit with the reverted content. Use gnosys_history first to find the target commit hash.", {
|
|
1254
|
-
path: z.string().describe("Path to memory, optionally layer-prefixed"),
|
|
1255
|
-
commitHash: z.string().describe("Git commit hash to revert to (full or abbreviated)"),
|
|
1256
|
-
projectRoot: projectRootParam,
|
|
1257
|
-
}, async ({ path: memPath, commitHash, projectRoot }) => {
|
|
1258
|
-
const ctx = await resolveToolContext(projectRoot);
|
|
1259
|
-
const memory = await ctx.resolver.readMemory(memPath);
|
|
1260
|
-
if (!memory) {
|
|
1261
|
-
return { content: [{ type: "text", text: `Memory not found: ${memPath}` }], isError: true };
|
|
1262
|
-
}
|
|
1263
|
-
const sourceStore = ctx.resolver.getStores().find((s) => s.label === memory.sourceLabel);
|
|
1264
|
-
if (!sourceStore?.writable) {
|
|
1265
|
-
return { content: [{ type: "text", text: "Cannot rollback: store is read-only." }], isError: true };
|
|
1266
|
-
}
|
|
1267
|
-
const success = rollbackToCommit(sourceStore.path, memory.relativePath, commitHash);
|
|
1268
|
-
if (!success) {
|
|
1269
|
-
return { content: [{ type: "text", text: `Rollback failed. Verify the commit hash with gnosys_history.` }], isError: true };
|
|
1270
|
-
}
|
|
1271
|
-
// Reindex after rollback
|
|
1272
|
-
if (ctx.search)
|
|
1273
|
-
await reindexAllStores();
|
|
1274
|
-
// Read the reverted memory
|
|
1275
|
-
const reverted = await ctx.resolver.readMemory(memPath);
|
|
1276
|
-
return {
|
|
1277
|
-
content: [{
|
|
1278
|
-
type: "text",
|
|
1279
|
-
text: `Rolled back **${memory.frontmatter.title}** to commit ${commitHash.substring(0, 7)}.\n\nCurrent state: ${reverted?.frontmatter.title} [${reverted?.frontmatter.status}] (confidence: ${reverted?.frontmatter.confidence})`,
|
|
1280
|
-
}],
|
|
1281
|
-
};
|
|
1267
|
+
return { content: [{ type: "text", text: `Memory not found: ${memPath}` }], isError: true };
|
|
1282
1268
|
});
|
|
1283
1269
|
// ─── Tool: gnosys_lens ──────────────────────────────────────────────────
|
|
1284
|
-
|
|
1270
|
+
regTool("gnosys_lens", "Filtered view of memories. Combine criteria to focus on specific subsets — e.g., 'active decisions about auth with confidence > 0.8'. Use AND (default) to require all criteria, or OR to match any.", {
|
|
1285
1271
|
category: z.string().optional().describe("Filter by category"),
|
|
1286
1272
|
tags: z.array(z.string()).optional().describe("Filter by tags"),
|
|
1287
1273
|
tagMatchMode: z.enum(["any", "all"]).optional().describe("'any' = has any listed tag (default), 'all' = must have every listed tag"),
|
|
@@ -1297,71 +1283,82 @@ server.tool("gnosys_lens", "Filtered view of memories. Combine criteria to focus
|
|
|
1297
1283
|
operator: z.enum(["AND", "OR"]).optional().describe("Compound operator when multiple filter groups are provided (default: AND)"),
|
|
1298
1284
|
projectRoot: projectRootParam,
|
|
1299
1285
|
}, async ({ category, tags, tagMatchMode, status, author, authority, minConfidence, maxConfidence, createdAfter, createdBefore, modifiedAfter, modifiedBefore, projectRoot }) => {
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1286
|
+
try {
|
|
1287
|
+
const ctx = await resolveToolContext(projectRoot);
|
|
1288
|
+
const allMemories = await ctx.resolver.getAllMemories();
|
|
1289
|
+
const lens = {};
|
|
1290
|
+
if (category)
|
|
1291
|
+
lens.category = category;
|
|
1292
|
+
if (tags) {
|
|
1293
|
+
lens.tags = tags;
|
|
1294
|
+
lens.tagMatchMode = tagMatchMode || "any";
|
|
1295
|
+
}
|
|
1296
|
+
if (status)
|
|
1297
|
+
lens.status = status;
|
|
1298
|
+
if (author)
|
|
1299
|
+
lens.author = author;
|
|
1300
|
+
if (authority)
|
|
1301
|
+
lens.authority = authority;
|
|
1302
|
+
if (minConfidence !== undefined)
|
|
1303
|
+
lens.minConfidence = minConfidence;
|
|
1304
|
+
if (maxConfidence !== undefined)
|
|
1305
|
+
lens.maxConfidence = maxConfidence;
|
|
1306
|
+
if (createdAfter)
|
|
1307
|
+
lens.createdAfter = createdAfter;
|
|
1308
|
+
if (createdBefore)
|
|
1309
|
+
lens.createdBefore = createdBefore;
|
|
1310
|
+
if (modifiedAfter)
|
|
1311
|
+
lens.modifiedAfter = modifiedAfter;
|
|
1312
|
+
if (modifiedBefore)
|
|
1313
|
+
lens.modifiedBefore = modifiedBefore;
|
|
1314
|
+
const result = applyLens(allMemories, lens);
|
|
1315
|
+
if (result.length === 0) {
|
|
1316
|
+
return { content: [{ type: "text", text: "No memories match the lens filter." }] };
|
|
1317
|
+
}
|
|
1318
|
+
const lines = result.map((m) => `- **${m.frontmatter.title}** [${m.frontmatter.status}] (${m.frontmatter.confidence})\n ${m.sourceLabel ? m.sourceLabel + ":" : ""}${m.relativePath}`);
|
|
1319
|
+
return {
|
|
1320
|
+
content: [{ type: "text", text: `${result.length} memories match:\n\n${lines.join("\n\n")}` }],
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
catch (err) {
|
|
1324
|
+
return { content: [{ type: "text", text: formatMcpError("applying memory lens", err) }], isError: true };
|
|
1325
|
+
}
|
|
1335
1326
|
});
|
|
1336
1327
|
// ─── Tool: gnosys_timeline ───────────────────────────────────────────────
|
|
1337
|
-
|
|
1328
|
+
regTool("gnosys_timeline", "View memory creation and modification activity over time. Shows how knowledge evolves by grouping memories into time periods.", {
|
|
1338
1329
|
period: z.enum(["day", "week", "month", "year"]).optional().describe("Grouping period (default: month)"),
|
|
1339
1330
|
projectRoot: projectRootParam,
|
|
1340
1331
|
}, async ({ period, projectRoot }) => {
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1332
|
+
try {
|
|
1333
|
+
const ctx = await resolveToolContext(projectRoot);
|
|
1334
|
+
const allMemories = await ctx.resolver.getAllMemories();
|
|
1335
|
+
const entries = groupByPeriod(allMemories, period || "month");
|
|
1336
|
+
if (entries.length === 0) {
|
|
1337
|
+
return { content: [{ type: "text", text: "No memories found for timeline." }] };
|
|
1338
|
+
}
|
|
1339
|
+
const lines = entries.map((e) => `**${e.period}** — ${e.created} created, ${e.modified} modified\n ${e.titles.slice(0, 5).join(", ")}${e.titles.length > 5 ? ` (+${e.titles.length - 5} more)` : ""}`);
|
|
1340
|
+
return {
|
|
1341
|
+
content: [{ type: "text", text: `Knowledge Timeline (by ${period || "month"}):\n\n${lines.join("\n\n")}` }],
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
catch (err) {
|
|
1345
|
+
return { content: [{ type: "text", text: formatMcpError("building timeline", err) }], isError: true };
|
|
1346
1346
|
}
|
|
1347
|
-
const lines = entries.map((e) => `**${e.period}** — ${e.created} created, ${e.modified} modified\n ${e.titles.slice(0, 5).join(", ")}${e.titles.length > 5 ? ` (+${e.titles.length - 5} more)` : ""}`);
|
|
1348
|
-
return {
|
|
1349
|
-
content: [{ type: "text", text: `Knowledge Timeline (by ${period || "month"}):\n\n${lines.join("\n\n")}` }],
|
|
1350
|
-
};
|
|
1351
1347
|
});
|
|
1352
1348
|
// ─── Tool: gnosys_stats ─────────────────────────────────────────────────
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1349
|
+
regTool("gnosys_stats", "Summary statistics across all memories — totals by category, status, author, authority, average confidence, and date ranges.", { projectRoot: projectRootParam }, async ({ projectRoot }) => {
|
|
1350
|
+
try {
|
|
1351
|
+
const ctx = await resolveToolContext(projectRoot);
|
|
1352
|
+
const allMemories = await ctx.resolver.getAllMemories();
|
|
1353
|
+
const stats = computeStats(allMemories);
|
|
1354
|
+
if (stats.totalCount === 0) {
|
|
1355
|
+
return { content: [{ type: "text", text: "No memories found." }] };
|
|
1356
|
+
}
|
|
1357
|
+
const catLines = Object.entries(stats.byCategory).map(([k, v]) => ` ${k}: ${v}`).join("\n");
|
|
1358
|
+
const statusLines = Object.entries(stats.byStatus).map(([k, v]) => ` ${k}: ${v}`).join("\n");
|
|
1359
|
+
const authorLines = Object.entries(stats.byAuthor).map(([k, v]) => ` ${k}: ${v}`).join("\n");
|
|
1360
|
+
const authLines = Object.entries(stats.byAuthority).map(([k, v]) => ` ${k}: ${v}`).join("\n");
|
|
1361
|
+
const text = `Gnosys Memory Statistics
|
|
1365
1362
|
Total: ${stats.totalCount} memories
|
|
1366
1363
|
|
|
1367
1364
|
By Category:
|
|
@@ -1380,10 +1377,14 @@ Average Confidence: ${stats.averageConfidence.toFixed(2)}
|
|
|
1380
1377
|
Oldest: ${stats.oldestCreated || "—"}
|
|
1381
1378
|
Newest: ${stats.newestCreated || "—"}
|
|
1382
1379
|
Last Modified: ${stats.lastModified || "—"}`;
|
|
1383
|
-
|
|
1380
|
+
return { content: [{ type: "text", text }] };
|
|
1381
|
+
}
|
|
1382
|
+
catch (err) {
|
|
1383
|
+
return { content: [{ type: "text", text: formatMcpError("computing statistics", err) }], isError: true };
|
|
1384
|
+
}
|
|
1384
1385
|
});
|
|
1385
1386
|
// ─── Tool: gnosys_links ─────────────────────────────────────────────────
|
|
1386
|
-
|
|
1387
|
+
regTool("gnosys_links", "Show wikilinks for a specific memory — outgoing [[links]] and backlinks from other memories. Obsidian-compatible [[Title]] and [[path|display]] syntax.", {
|
|
1387
1388
|
path: z.string().describe("Path to memory, optionally layer-prefixed"),
|
|
1388
1389
|
projectRoot: projectRootParam,
|
|
1389
1390
|
}, async ({ path: memPath, projectRoot }) => {
|
|
@@ -1447,17 +1448,22 @@ server.tool("gnosys_links", "Show wikilinks for a specific memory — outgoing [
|
|
|
1447
1448
|
return { content: [{ type: "text", text: parts.join("\n") }] };
|
|
1448
1449
|
});
|
|
1449
1450
|
// ─── Tool: gnosys_graph ─────────────────────────────────────────────────
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1451
|
+
regTool("gnosys_graph", "Show the full cross-reference graph across all memories. Reveals clusters, orphaned links, and the most-connected memories.", { projectRoot: projectRootParam }, async ({ projectRoot }) => {
|
|
1452
|
+
try {
|
|
1453
|
+
const ctx = await resolveToolContext(projectRoot);
|
|
1454
|
+
const allMemories = await ctx.resolver.getAllMemories();
|
|
1455
|
+
if (allMemories.length === 0) {
|
|
1456
|
+
return { content: [{ type: "text", text: "No memories found." }] };
|
|
1457
|
+
}
|
|
1458
|
+
const graph = buildLinkGraph(allMemories);
|
|
1459
|
+
return { content: [{ type: "text", text: formatGraphSummary(graph) }] };
|
|
1460
|
+
}
|
|
1461
|
+
catch (err) {
|
|
1462
|
+
return { content: [{ type: "text", text: formatMcpError("building graph", err) }], isError: true };
|
|
1455
1463
|
}
|
|
1456
|
-
const graph = buildLinkGraph(allMemories);
|
|
1457
|
-
return { content: [{ type: "text", text: formatGraphSummary(graph) }] };
|
|
1458
1464
|
});
|
|
1459
1465
|
// ─── Tool: gnosys_bootstrap ─────────────────────────────────────────────
|
|
1460
|
-
|
|
1466
|
+
regTool("gnosys_bootstrap", "Batch-import existing documents from a directory into the memory store. Scans for markdown files and creates memories. Use dry_run=true to preview.", {
|
|
1461
1467
|
sourceDir: z.string().describe("Absolute path to directory containing documents to import"),
|
|
1462
1468
|
patterns: z.array(z.string()).optional().describe("File glob patterns (default: ['**/*.md'])"),
|
|
1463
1469
|
skipExisting: z.boolean().optional().describe("Skip files whose titles already exist (default: false)"),
|
|
@@ -1516,7 +1522,7 @@ server.tool("gnosys_bootstrap", "Batch-import existing documents from a director
|
|
|
1516
1522
|
}
|
|
1517
1523
|
});
|
|
1518
1524
|
// ─── Tool: gnosys_import ─────────────────────────────────────────────────
|
|
1519
|
-
|
|
1525
|
+
regTool("gnosys_import", "Bulk import structured data (CSV, JSON, JSONL) into Gnosys memories. Map source fields to title/category/content/tags/relevance. Use mode='llm' for smart ingestion with keyword clouds, or 'structured' for fast direct mapping. For large datasets (>100 records with LLM), the CLI is recommended: gnosys import <file>", {
|
|
1520
1526
|
format: z.enum(["csv", "json", "jsonl"]).describe("Data format"),
|
|
1521
1527
|
data: z.string().describe("File path, URL, or inline data"),
|
|
1522
1528
|
mapping: z
|
|
@@ -1597,7 +1603,7 @@ server.tool("gnosys_import", "Bulk import structured data (CSV, JSON, JSONL) int
|
|
|
1597
1603
|
}
|
|
1598
1604
|
});
|
|
1599
1605
|
// ─── Tool: gnosys_hybrid_search ──────────────────────────────────────────
|
|
1600
|
-
|
|
1606
|
+
regTool("gnosys_hybrid_search", "Search memories using hybrid keyword + semantic search with Reciprocal Rank Fusion. Combines FTS5 keyword matching with embedding-based semantic similarity for best results. Run gnosys_reindex first if embeddings don't exist yet.", {
|
|
1601
1607
|
query: z.string().describe("Natural language search query"),
|
|
1602
1608
|
limit: z.number().optional().describe("Max results (default 15)"),
|
|
1603
1609
|
mode: z.enum(["keyword", "semantic", "hybrid"]).optional().describe("Search mode (default: hybrid)"),
|
|
@@ -1649,7 +1655,7 @@ server.tool("gnosys_hybrid_search", "Search memories using hybrid keyword + sema
|
|
|
1649
1655
|
}
|
|
1650
1656
|
});
|
|
1651
1657
|
// ─── Tool: gnosys_semantic_search ────────────────────────────────────────
|
|
1652
|
-
|
|
1658
|
+
regTool("gnosys_semantic_search", "Search memories using semantic similarity only (no keyword matching). Finds conceptually related memories even without exact keyword matches. Requires embeddings — run gnosys_reindex first.", {
|
|
1653
1659
|
query: z.string().describe("Natural language search query"),
|
|
1654
1660
|
limit: z.number().optional().describe("Max results (default 15)"),
|
|
1655
1661
|
projectRoot: projectRootParam,
|
|
@@ -1685,7 +1691,7 @@ server.tool("gnosys_semantic_search", "Search memories using semantic similarity
|
|
|
1685
1691
|
}
|
|
1686
1692
|
});
|
|
1687
1693
|
// ─── Tool: gnosys_reindex ────────────────────────────────────────────────
|
|
1688
|
-
|
|
1694
|
+
regTool("gnosys_reindex", "Rebuild all semantic embeddings from every memory file. Downloads the embedding model (~80 MB) on first run. Required before hybrid/semantic search can be used. Safe to re-run — fully regenerates the index.", { projectRoot: projectRootParam }, async ({ projectRoot }) => {
|
|
1689
1695
|
// Note: reindex operates on all stores, projectRoot is for API consistency
|
|
1690
1696
|
(projectRoot); // quiets unused warning if any
|
|
1691
1697
|
await ensureHeavyDeps();
|
|
@@ -1716,7 +1722,7 @@ server.tool("gnosys_reindex", "Rebuild all semantic embeddings from every memory
|
|
|
1716
1722
|
}
|
|
1717
1723
|
});
|
|
1718
1724
|
// ─── Tool: gnosys_ask ────────────────────────────────────────────────────
|
|
1719
|
-
|
|
1725
|
+
regTool("gnosys_ask", "Ask a natural-language question and get a synthesized answer with citations from the entire vault. Uses hybrid search to find relevant memories, then LLM to synthesize a cited response. Citations are Obsidian wikilinks [[filename.md]]. Requires an LLM provider (Anthropic or Ollama) and embeddings (run gnosys_reindex first).", {
|
|
1720
1726
|
question: z.string().describe("Natural language question to answer from the vault"),
|
|
1721
1727
|
limit: z.number().optional().describe("Max memories to retrieve (default 15)"),
|
|
1722
1728
|
mode: z.enum(["keyword", "semantic", "hybrid"]).optional().describe("Search mode (default: hybrid)"),
|
|
@@ -1773,7 +1779,7 @@ server.tool("gnosys_ask", "Ask a natural-language question and get a synthesized
|
|
|
1773
1779
|
}
|
|
1774
1780
|
});
|
|
1775
1781
|
// ─── Tool: gnosys_maintain ────────────────────────────────────────────────
|
|
1776
|
-
|
|
1782
|
+
regTool("gnosys_maintain", "Run vault maintenance: detect duplicate memories, apply confidence decay, consolidate similar memories. Use --dry-run mode first to see what would change. Requires embeddings (run gnosys_reindex first).", {
|
|
1777
1783
|
dryRun: z.boolean().optional().describe("Show what would change without modifying anything (default: true)"),
|
|
1778
1784
|
autoApply: z.boolean().optional().describe("Automatically apply all changes (default: false)"),
|
|
1779
1785
|
projectRoot: projectRootParam,
|
|
@@ -1808,7 +1814,7 @@ server.tool("gnosys_maintain", "Run vault maintenance: detect duplicate memories
|
|
|
1808
1814
|
}
|
|
1809
1815
|
});
|
|
1810
1816
|
// ─── Tool: gnosys_dearchive ──────────────────────────────────────────────
|
|
1811
|
-
|
|
1817
|
+
regTool("gnosys_dearchive", "Force-dearchive memories from archive.db back to active. Search the archive for memories matching a query, then restore them to the active layer. Used when you need specific archived knowledge that wasn't auto-dearchived by search/ask.", {
|
|
1812
1818
|
query: z.string().describe("Search query to find archived memories to restore"),
|
|
1813
1819
|
limit: z.number().optional().describe("Max memories to dearchive (default 5)"),
|
|
1814
1820
|
projectRoot: projectRootParam,
|
|
@@ -1826,7 +1832,7 @@ server.tool("gnosys_dearchive", "Force-dearchive memories from archive.db back t
|
|
|
1826
1832
|
const archive = new GnosysArchive(writeTarget.path);
|
|
1827
1833
|
if (!archive.isAvailable()) {
|
|
1828
1834
|
return {
|
|
1829
|
-
content: [{ type: "text", text: "Archive not available.
|
|
1835
|
+
content: [{ type: "text", text: "Archive not available. Install it with: npm install better-sqlite3" }],
|
|
1830
1836
|
isError: true,
|
|
1831
1837
|
};
|
|
1832
1838
|
}
|
|
@@ -1863,7 +1869,7 @@ server.tool("gnosys_dearchive", "Force-dearchive memories from archive.db back t
|
|
|
1863
1869
|
}
|
|
1864
1870
|
});
|
|
1865
1871
|
// ─── Tool: gnosys_reindex_graph ──────────────────────────────────────────
|
|
1866
|
-
|
|
1872
|
+
regTool("gnosys_reindex_graph", "Build or rebuild the wikilink graph (.gnosys/graph.json). Parses all [[wikilinks]] across memories and generates a persistent JSON graph with nodes, edges, and stats.", { projectRoot: projectRootParam }, async ({ projectRoot }) => {
|
|
1867
1873
|
const ctx = await resolveToolContext(projectRoot);
|
|
1868
1874
|
try {
|
|
1869
1875
|
const { reindexGraph, formatGraphStats } = await import("./lib/graph.js");
|
|
@@ -1880,54 +1886,59 @@ server.tool("gnosys_reindex_graph", "Build or rebuild the wikilink graph (.gnosy
|
|
|
1880
1886
|
}
|
|
1881
1887
|
});
|
|
1882
1888
|
// ─── Tool: gnosys_dream ──────────────────────────────────────────────────
|
|
1883
|
-
|
|
1889
|
+
regTool("gnosys_dream", "Run a Dream Mode cycle — idle-time consolidation that decays confidence, generates category summaries, discovers relationships, and creates review suggestions. NEVER deletes memories. Safe to run anytime.", {
|
|
1884
1890
|
maxRuntimeMinutes: z.number().int().min(1).max(120).default(30).optional().describe("Max runtime in minutes"),
|
|
1885
1891
|
selfCritique: z.boolean().default(true).optional().describe("Enable self-critique scoring"),
|
|
1886
1892
|
generateSummaries: z.boolean().default(true).optional().describe("Generate category summaries"),
|
|
1887
1893
|
discoverRelationships: z.boolean().default(true).optional().describe("Discover relationships between memories"),
|
|
1888
1894
|
projectRoot: projectRootParam,
|
|
1889
1895
|
}, async (params) => {
|
|
1890
|
-
|
|
1891
|
-
|
|
1896
|
+
try {
|
|
1897
|
+
const ctx = await resolveToolContext(params.projectRoot);
|
|
1898
|
+
if (!ctx.centralDb || !ctx.centralDb.isAvailable() || !ctx.centralDb.isMigrated()) {
|
|
1899
|
+
return {
|
|
1900
|
+
content: [
|
|
1901
|
+
{
|
|
1902
|
+
type: "text",
|
|
1903
|
+
text: "Dream Mode requires gnosys.db (v2.0). Run `gnosys migrate` first.",
|
|
1904
|
+
},
|
|
1905
|
+
],
|
|
1906
|
+
};
|
|
1907
|
+
}
|
|
1908
|
+
// Record activity to reset idle timer (if scheduler is running)
|
|
1909
|
+
dreamScheduler?.recordActivity();
|
|
1910
|
+
const dreamConfig = {
|
|
1911
|
+
enabled: true,
|
|
1912
|
+
idleMinutes: 0, // Run immediately (manual trigger)
|
|
1913
|
+
maxRuntimeMinutes: params.maxRuntimeMinutes ?? 30,
|
|
1914
|
+
selfCritique: params.selfCritique ?? true,
|
|
1915
|
+
generateSummaries: params.generateSummaries ?? true,
|
|
1916
|
+
discoverRelationships: params.discoverRelationships ?? true,
|
|
1917
|
+
minMemories: 1, // No minimum for manual trigger
|
|
1918
|
+
provider: ctx.config?.dream?.provider || "ollama",
|
|
1919
|
+
model: ctx.config?.dream?.model,
|
|
1920
|
+
};
|
|
1921
|
+
// v5.9.1 (#100): dream engine pulls LLM provider machinery — load lazily.
|
|
1922
|
+
const { GnosysDreamEngine, formatDreamReport } = await import("./lib/dream.js");
|
|
1923
|
+
const engine = new GnosysDreamEngine(ctx.centralDb, ctx.config || DEFAULT_CONFIG, dreamConfig);
|
|
1924
|
+
const report = await engine.dream((phase, detail) => {
|
|
1925
|
+
console.error(`[dream:${phase}] ${detail}`);
|
|
1926
|
+
});
|
|
1892
1927
|
return {
|
|
1893
1928
|
content: [
|
|
1894
1929
|
{
|
|
1895
1930
|
type: "text",
|
|
1896
|
-
text:
|
|
1931
|
+
text: formatDreamReport(report),
|
|
1897
1932
|
},
|
|
1898
1933
|
],
|
|
1899
1934
|
};
|
|
1900
1935
|
}
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
enabled: true,
|
|
1905
|
-
idleMinutes: 0, // Run immediately (manual trigger)
|
|
1906
|
-
maxRuntimeMinutes: params.maxRuntimeMinutes ?? 30,
|
|
1907
|
-
selfCritique: params.selfCritique ?? true,
|
|
1908
|
-
generateSummaries: params.generateSummaries ?? true,
|
|
1909
|
-
discoverRelationships: params.discoverRelationships ?? true,
|
|
1910
|
-
minMemories: 1, // No minimum for manual trigger
|
|
1911
|
-
provider: ctx.config?.dream?.provider || "ollama",
|
|
1912
|
-
model: ctx.config?.dream?.model,
|
|
1913
|
-
};
|
|
1914
|
-
// v5.9.1 (#100): dream engine pulls LLM provider machinery — load lazily.
|
|
1915
|
-
const { GnosysDreamEngine, formatDreamReport } = await import("./lib/dream.js");
|
|
1916
|
-
const engine = new GnosysDreamEngine(ctx.centralDb, ctx.config || DEFAULT_CONFIG, dreamConfig);
|
|
1917
|
-
const report = await engine.dream((phase, detail) => {
|
|
1918
|
-
console.error(`[dream:${phase}] ${detail}`);
|
|
1919
|
-
});
|
|
1920
|
-
return {
|
|
1921
|
-
content: [
|
|
1922
|
-
{
|
|
1923
|
-
type: "text",
|
|
1924
|
-
text: formatDreamReport(report),
|
|
1925
|
-
},
|
|
1926
|
-
],
|
|
1927
|
-
};
|
|
1936
|
+
catch (err) {
|
|
1937
|
+
return { content: [{ type: "text", text: formatMcpError("running dream mode", err) }], isError: true };
|
|
1938
|
+
}
|
|
1928
1939
|
});
|
|
1929
1940
|
// ─── Tool: gnosys_export ─────────────────────────────────────────────────
|
|
1930
|
-
|
|
1941
|
+
regTool("gnosys_export", "Export gnosys.db to Obsidian-compatible vault — atomic Markdown files with YAML frontmatter, [[wikilinks]], category summaries, and relationship graph. One-way export, never modifies gnosys.db.", {
|
|
1931
1942
|
targetDir: z.string().describe("Target directory path for export"),
|
|
1932
1943
|
activeOnly: z.boolean().default(true).optional().describe("Only export active memories (default: true)"),
|
|
1933
1944
|
overwrite: z.boolean().default(false).optional().describe("Overwrite existing files"),
|
|
@@ -1936,39 +1947,44 @@ server.tool("gnosys_export", "Export gnosys.db to Obsidian-compatible vault —
|
|
|
1936
1947
|
includeGraph: z.boolean().default(true).optional().describe("Include relationship graph"),
|
|
1937
1948
|
projectRoot: projectRootParam,
|
|
1938
1949
|
}, async (params) => {
|
|
1939
|
-
|
|
1940
|
-
|
|
1950
|
+
try {
|
|
1951
|
+
const ctx = await resolveToolContext(params.projectRoot);
|
|
1952
|
+
if (!ctx.centralDb || !ctx.centralDb.isAvailable() || !ctx.centralDb.isMigrated()) {
|
|
1953
|
+
return {
|
|
1954
|
+
content: [
|
|
1955
|
+
{
|
|
1956
|
+
type: "text",
|
|
1957
|
+
text: "Export requires gnosys.db (v2.0). Run `gnosys migrate` first.",
|
|
1958
|
+
},
|
|
1959
|
+
],
|
|
1960
|
+
};
|
|
1961
|
+
}
|
|
1962
|
+
// v5.9.1 (#100): exporter pulls obsidian-flavored markdown gen — lazy.
|
|
1963
|
+
const { GnosysExporter, formatExportReport } = await import("./lib/export.js");
|
|
1964
|
+
const exporter = new GnosysExporter(ctx.centralDb);
|
|
1965
|
+
const report = await exporter.export({
|
|
1966
|
+
targetDir: params.targetDir,
|
|
1967
|
+
activeOnly: params.activeOnly ?? true,
|
|
1968
|
+
overwrite: params.overwrite ?? false,
|
|
1969
|
+
includeSummaries: params.includeSummaries ?? true,
|
|
1970
|
+
includeReviews: params.includeReviews ?? true,
|
|
1971
|
+
includeGraph: params.includeGraph ?? true,
|
|
1972
|
+
});
|
|
1941
1973
|
return {
|
|
1942
1974
|
content: [
|
|
1943
1975
|
{
|
|
1944
1976
|
type: "text",
|
|
1945
|
-
text:
|
|
1977
|
+
text: formatExportReport(report),
|
|
1946
1978
|
},
|
|
1947
1979
|
],
|
|
1948
1980
|
};
|
|
1949
1981
|
}
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
const report = await exporter.export({
|
|
1954
|
-
targetDir: params.targetDir,
|
|
1955
|
-
activeOnly: params.activeOnly ?? true,
|
|
1956
|
-
overwrite: params.overwrite ?? false,
|
|
1957
|
-
includeSummaries: params.includeSummaries ?? true,
|
|
1958
|
-
includeReviews: params.includeReviews ?? true,
|
|
1959
|
-
includeGraph: params.includeGraph ?? true,
|
|
1960
|
-
});
|
|
1961
|
-
return {
|
|
1962
|
-
content: [
|
|
1963
|
-
{
|
|
1964
|
-
type: "text",
|
|
1965
|
-
text: formatExportReport(report),
|
|
1966
|
-
},
|
|
1967
|
-
],
|
|
1968
|
-
};
|
|
1982
|
+
catch (err) {
|
|
1983
|
+
return { content: [{ type: "text", text: formatMcpError("exporting vault", err) }], isError: true };
|
|
1984
|
+
}
|
|
1969
1985
|
});
|
|
1970
1986
|
// ─── Tool: gnosys_dashboard ──────────────────────────────────────────────
|
|
1971
|
-
|
|
1987
|
+
regTool("gnosys_dashboard", "Show the Gnosys system dashboard: memory counts, maintenance health, graph stats, LLM provider status. Returns structured JSON.", { projectRoot: projectRootParam }, async ({ projectRoot }) => {
|
|
1972
1988
|
const ctx = await resolveToolContext(projectRoot);
|
|
1973
1989
|
try {
|
|
1974
1990
|
const { collectDashboardData, formatDashboardJSON } = await import("./lib/dashboard.js");
|
|
@@ -1985,40 +2001,45 @@ server.tool("gnosys_dashboard", "Show the Gnosys system dashboard: memory counts
|
|
|
1985
2001
|
}
|
|
1986
2002
|
});
|
|
1987
2003
|
// ─── Tool: gnosys_stores ─────────────────────────────────────────────────
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2004
|
+
regTool("gnosys_stores", "Debug tool — lists all detected Gnosys stores across registered projects, MCP workspace roots, cwd, and environment variables. Shows which store is active and helps diagnose multi-project routing.", {}, async () => {
|
|
2005
|
+
try {
|
|
2006
|
+
const lines = [];
|
|
2007
|
+
lines.push("GNOSYS STORES — Multi-Project Overview");
|
|
2008
|
+
lines.push("=".repeat(45));
|
|
2009
|
+
lines.push("");
|
|
2010
|
+
// Active stores
|
|
2011
|
+
lines.push("ACTIVE STORES:");
|
|
2012
|
+
lines.push(resolver.getSummary());
|
|
2013
|
+
lines.push("");
|
|
2014
|
+
// MCP roots
|
|
2015
|
+
const mcpRoots = GnosysResolver.getMcpRoots();
|
|
2016
|
+
lines.push(`MCP WORKSPACE ROOTS (${mcpRoots.length}):`);
|
|
2017
|
+
if (mcpRoots.length === 0) {
|
|
2018
|
+
lines.push(" (none — host may not support roots/list)");
|
|
2019
|
+
}
|
|
2020
|
+
else {
|
|
2021
|
+
for (const root of mcpRoots) {
|
|
2022
|
+
lines.push(` ${root}`);
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
lines.push("");
|
|
2026
|
+
// All detected stores
|
|
2027
|
+
const detected = await resolver.detectAllStores();
|
|
2028
|
+
lines.push(`ALL DETECTED STORES (${detected.length}):`);
|
|
2029
|
+
for (const d of detected) {
|
|
2030
|
+
const status = d.isActive ? "✓ ACTIVE" : d.hasGnosys ? "available" : "no .gnosys";
|
|
2031
|
+
lines.push(` [${d.source}] ${d.path} — ${status}`);
|
|
2032
|
+
}
|
|
2033
|
+
lines.push("");
|
|
2034
|
+
// Usage hint
|
|
2035
|
+
lines.push("USAGE:");
|
|
2036
|
+
lines.push(" Pass projectRoot to any tool to target a specific project:");
|
|
2037
|
+
lines.push(' e.g. gnosys_add({ projectRoot: "/path/to/my-project", ... })');
|
|
2038
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
2039
|
+
}
|
|
2040
|
+
catch (err) {
|
|
2041
|
+
return { content: [{ type: "text", text: formatMcpError("listing stores", err) }], isError: true };
|
|
2002
2042
|
}
|
|
2003
|
-
else {
|
|
2004
|
-
for (const root of mcpRoots) {
|
|
2005
|
-
lines.push(` ${root}`);
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
lines.push("");
|
|
2009
|
-
// All detected stores
|
|
2010
|
-
const detected = await resolver.detectAllStores();
|
|
2011
|
-
lines.push(`ALL DETECTED STORES (${detected.length}):`);
|
|
2012
|
-
for (const d of detected) {
|
|
2013
|
-
const status = d.isActive ? "✓ ACTIVE" : d.hasGnosys ? "available" : "no .gnosys";
|
|
2014
|
-
lines.push(` [${d.source}] ${d.path} — ${status}`);
|
|
2015
|
-
}
|
|
2016
|
-
lines.push("");
|
|
2017
|
-
// Usage hint
|
|
2018
|
-
lines.push("USAGE:");
|
|
2019
|
-
lines.push(" Pass projectRoot to any tool to target a specific project:");
|
|
2020
|
-
lines.push(' e.g. gnosys_add({ projectRoot: "/path/to/my-project", ... })');
|
|
2021
|
-
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
2022
2043
|
});
|
|
2023
2044
|
// ─── Helper: reindex search across all stores ────────────────────────────
|
|
2024
2045
|
async function reindexAllStores() {
|
|
@@ -2043,7 +2064,7 @@ async function reindexAllStores() {
|
|
|
2043
2064
|
// injecting relevant memories into the model context — no tool call needed.
|
|
2044
2065
|
//
|
|
2045
2066
|
// Priority 1 + audience: assistant = hosts inject this before every message.
|
|
2046
|
-
|
|
2067
|
+
regResource("gnosys_recall", "gnosys://recall", {
|
|
2047
2068
|
description: "Automatic memory injection. Hosts read this resource on every turn to inject the most relevant memories as context. Returns a <gnosys-recall> block with [[wikilinks]] and relevance scores. Priority 1 (highest) — designed for always-on context injection without any tool call. Configure aggressiveness in gnosys.json: recall.aggressive (default: true).",
|
|
2048
2069
|
mimeType: "text/markdown",
|
|
2049
2070
|
annotations: {
|
|
@@ -2086,7 +2107,7 @@ server.resource("gnosys_recall", "gnosys://recall", {
|
|
|
2086
2107
|
// ─── Tool: gnosys_recall (query-specific fallback) ──────────────────────
|
|
2087
2108
|
// For hosts that don't support MCP Resources, or when the agent wants to
|
|
2088
2109
|
// recall memories for a specific query. The resource above is preferred.
|
|
2089
|
-
|
|
2110
|
+
regTool("gnosys_recall", "Fast memory recall — inject relevant memories as context. Returns <gnosys-recall> block. In aggressive mode (default), always returns top memories even at medium relevance. Prefer the gnosys://recall MCP Resource for automatic injection (no tool call needed).", {
|
|
2090
2111
|
query: z
|
|
2091
2112
|
.string()
|
|
2092
2113
|
.describe("What the agent is currently working on. Use keywords. Example: 'auth JWT middleware' or 'database migration schema'"),
|
|
@@ -2095,32 +2116,37 @@ server.tool("gnosys_recall", "Fast memory recall — inject relevant memories as
|
|
|
2095
2116
|
aggressive: z.boolean().optional().describe("Override aggressive mode for this call. Default: from gnosys.json (true)"),
|
|
2096
2117
|
projectRoot: projectRootParam,
|
|
2097
2118
|
}, async ({ query, limit, traceId, aggressive, projectRoot }) => {
|
|
2098
|
-
|
|
2099
|
-
|
|
2119
|
+
try {
|
|
2120
|
+
const ctx = await resolveToolContext(projectRoot);
|
|
2121
|
+
if (!ctx.search) {
|
|
2122
|
+
return {
|
|
2123
|
+
content: [{ type: "text", text: "<gnosys: no-strong-recall-needed>" }],
|
|
2124
|
+
};
|
|
2125
|
+
}
|
|
2126
|
+
const storePath = ctx.resolver.getWriteTarget()?.store.getStorePath() || "";
|
|
2127
|
+
const recallConfig = {
|
|
2128
|
+
...ctx.config.recall,
|
|
2129
|
+
...(aggressive !== undefined ? { aggressive } : {}),
|
|
2130
|
+
};
|
|
2131
|
+
const result = await recall(query, {
|
|
2132
|
+
limit: Math.min(limit || recallConfig.maxMemories, 15),
|
|
2133
|
+
search: ctx.search,
|
|
2134
|
+
resolver: ctx.resolver,
|
|
2135
|
+
storePath,
|
|
2136
|
+
traceId,
|
|
2137
|
+
recallConfig,
|
|
2138
|
+
gnosysDb: ctx.centralDb || undefined,
|
|
2139
|
+
});
|
|
2100
2140
|
return {
|
|
2101
|
-
content: [{ type: "text", text:
|
|
2141
|
+
content: [{ type: "text", text: formatRecall(result) }],
|
|
2102
2142
|
};
|
|
2103
2143
|
}
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
...(aggressive !== undefined ? { aggressive } : {}),
|
|
2108
|
-
};
|
|
2109
|
-
const result = await recall(query, {
|
|
2110
|
-
limit: Math.min(limit || recallConfig.maxMemories, 15),
|
|
2111
|
-
search: ctx.search,
|
|
2112
|
-
resolver: ctx.resolver,
|
|
2113
|
-
storePath,
|
|
2114
|
-
traceId,
|
|
2115
|
-
recallConfig,
|
|
2116
|
-
gnosysDb: ctx.centralDb || undefined,
|
|
2117
|
-
});
|
|
2118
|
-
return {
|
|
2119
|
-
content: [{ type: "text", text: formatRecall(result) }],
|
|
2120
|
-
};
|
|
2144
|
+
catch (err) {
|
|
2145
|
+
return { content: [{ type: "text", text: formatMcpError("recalling memories", err) }], isError: true };
|
|
2146
|
+
}
|
|
2121
2147
|
});
|
|
2122
2148
|
// ─── Tool: gnosys_audit ──────────────────────────────────────────────────
|
|
2123
|
-
|
|
2149
|
+
regTool("gnosys_audit", "View the audit trail of all memory operations (reads, writes, reinforcements, dearchives, maintenance). Shows a timeline of what happened and when. Useful for debugging 'why did the agent forget X?'", {
|
|
2124
2150
|
days: z.number().optional().describe("Number of days to look back (default 7)"),
|
|
2125
2151
|
operation: z.string().optional().describe("Filter by operation type: read, write, reinforce, dearchive, archive, maintain, search, ask, recall"),
|
|
2126
2152
|
limit: z.number().optional().describe("Max entries to return (default 100)"),
|
|
@@ -2144,7 +2170,7 @@ server.tool("gnosys_audit", "View the audit trail of all memory operations (read
|
|
|
2144
2170
|
};
|
|
2145
2171
|
});
|
|
2146
2172
|
// ─── Tool: gnosys_preference_set ─────────────────────────────────────────
|
|
2147
|
-
|
|
2173
|
+
regTool("gnosys_preference_set", "Set a user preference. Preferences are stored in the central DB as user-scoped memories. They persist across all projects and are injected into agent rules files on `gnosys sync`. Use this to record workflow conventions, coding standards, tool preferences, etc.", {
|
|
2148
2174
|
key: z.string().describe("Preference key, kebab-case. Examples: 'commit-convention', 'code-style', 'llm-provider', 'testing-approach', 'naming-convention'"),
|
|
2149
2175
|
value: z.string().describe("The preference value. Can be a sentence or paragraph describing the convention."),
|
|
2150
2176
|
title: z.string().optional().describe("Human-readable title. Auto-generated from key if omitted."),
|
|
@@ -2158,6 +2184,18 @@ server.tool("gnosys_preference_set", "Set a user preference. Preferences are sto
|
|
|
2158
2184
|
};
|
|
2159
2185
|
}
|
|
2160
2186
|
try {
|
|
2187
|
+
if (!KNOWN_PREFERENCE_KEYS.includes(key)) {
|
|
2188
|
+
const suggestion = suggestPreferenceKey(key);
|
|
2189
|
+
if (suggestion) {
|
|
2190
|
+
return {
|
|
2191
|
+
isError: true,
|
|
2192
|
+
content: [{
|
|
2193
|
+
type: "text",
|
|
2194
|
+
text: `Unknown preference key \`${key}\` — did you mean \`${suggestion}\`?`,
|
|
2195
|
+
}],
|
|
2196
|
+
};
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2161
2199
|
const pref = setPreference(centralDb, key, value, { title, tags });
|
|
2162
2200
|
return {
|
|
2163
2201
|
content: [{
|
|
@@ -2178,7 +2216,7 @@ server.tool("gnosys_preference_set", "Set a user preference. Preferences are sto
|
|
|
2178
2216
|
}
|
|
2179
2217
|
});
|
|
2180
2218
|
// ─── Tool: gnosys_preference_get ─────────────────────────────────────────
|
|
2181
|
-
|
|
2219
|
+
regTool("gnosys_preference_get", "Get a user preference by key, or list all preferences.", {
|
|
2182
2220
|
key: z.string().optional().describe("Preference key to retrieve. Omit to list all preferences."),
|
|
2183
2221
|
projectRoot: projectRootParam,
|
|
2184
2222
|
}, async ({ key }) => {
|
|
@@ -2220,7 +2258,7 @@ server.tool("gnosys_preference_get", "Get a user preference by key, or list all
|
|
|
2220
2258
|
};
|
|
2221
2259
|
});
|
|
2222
2260
|
// ─── Tool: gnosys_preference_delete ──────────────────────────────────────
|
|
2223
|
-
|
|
2261
|
+
regTool("gnosys_preference_delete", "Delete a user preference by key.", {
|
|
2224
2262
|
key: z.string().describe("Preference key to delete."),
|
|
2225
2263
|
projectRoot: projectRootParam,
|
|
2226
2264
|
}, async ({ key }) => {
|
|
@@ -2257,7 +2295,7 @@ server.tool("gnosys_preference_delete", "Delete a user preference by key.", {
|
|
|
2257
2295
|
//
|
|
2258
2296
|
// Routine in-session context flows through the SessionStart hook
|
|
2259
2297
|
// (`gnosys recall`), not through this tool.
|
|
2260
|
-
|
|
2298
|
+
regTool("gnosys_sync", "Get the current user preferences + project conventions formatted as a GNOSYS:START/GNOSYS:END block. By default returns the block as text only (no disk write). Pass commit_to_disk=true to write it into the detected agent rules file (CLAUDE.md, .cursor/rules/gnosys.mdc) — only do this if the user has explicitly asked to refresh the rules file. Routine session context is already injected via the SessionStart hook (`gnosys recall`); do NOT call this tool after every preference change.", {
|
|
2261
2299
|
projectRoot: projectRootParam,
|
|
2262
2300
|
commit_to_disk: z
|
|
2263
2301
|
.boolean()
|
|
@@ -2339,7 +2377,7 @@ server.tool("gnosys_sync", "Get the current user preferences + project conventio
|
|
|
2339
2377
|
};
|
|
2340
2378
|
});
|
|
2341
2379
|
// ─── Tool: gnosys_federated_search ───────────────────────────────────────
|
|
2342
|
-
|
|
2380
|
+
regTool("gnosys_federated_search", "Search across all scopes (project → user → global) with tier boosting. Results from the current project rank highest. Returns score breakdown showing which boosts were applied.", {
|
|
2343
2381
|
query: z.string().describe("Search query"),
|
|
2344
2382
|
limit: z.number().optional().describe("Max results (default: 20)"),
|
|
2345
2383
|
projectRoot: z.string().optional().describe("Project root directory for context detection"),
|
|
@@ -2369,7 +2407,7 @@ server.tool("gnosys_federated_search", "Search across all scopes (project → us
|
|
|
2369
2407
|
};
|
|
2370
2408
|
});
|
|
2371
2409
|
// ─── Tool: gnosys_detect_ambiguity ──────────────────────────────────────
|
|
2372
|
-
|
|
2410
|
+
regTool("gnosys_detect_ambiguity", "Check if a query matches memories in multiple projects. Use before write operations to confirm the target project when ambiguity exists.", {
|
|
2373
2411
|
query: z.string().describe("Query to check for cross-project ambiguity"),
|
|
2374
2412
|
}, async ({ query }) => {
|
|
2375
2413
|
if (!centralDb?.isAvailable()) {
|
|
@@ -2388,7 +2426,7 @@ server.tool("gnosys_detect_ambiguity", "Check if a query matches memories in mul
|
|
|
2388
2426
|
};
|
|
2389
2427
|
});
|
|
2390
2428
|
// ─── Tool: gnosys_briefing ──────────────────────────────────────────────
|
|
2391
|
-
|
|
2429
|
+
regTool("gnosys_briefing", "Generate a project briefing — a summary of memory state, categories, recent activity, and top tags. Use for dream mode pre-computation or quick project status.", {
|
|
2392
2430
|
projectId: z.string().optional().describe("Project ID (auto-detects from cwd if omitted)"),
|
|
2393
2431
|
all: z.boolean().optional().describe("Generate briefings for ALL projects"),
|
|
2394
2432
|
projectRoot: z.string().optional().describe("Project root for auto-detection"),
|
|
@@ -2439,7 +2477,7 @@ server.tool("gnosys_briefing", "Generate a project briefing — a summary of mem
|
|
|
2439
2477
|
return { content: [{ type: "text", text }] };
|
|
2440
2478
|
});
|
|
2441
2479
|
// ─── Tool: gnosys_portfolio ─────────────────────────────────────────────
|
|
2442
|
-
|
|
2480
|
+
regTool("gnosys_portfolio", "Portfolio dashboard — shows all registered projects with memory counts, categories, status snapshots, roadmap items, and recent activity. Use for cross-project status overview.", {
|
|
2443
2481
|
format: z.enum(["compact", "full"]).optional().describe("Output format: compact (default) or full markdown"),
|
|
2444
2482
|
}, async ({ format }) => {
|
|
2445
2483
|
if (!centralDb?.isAvailable()) {
|
|
@@ -2455,7 +2493,7 @@ server.tool("gnosys_portfolio", "Portfolio dashboard — shows all registered pr
|
|
|
2455
2493
|
return { content: [{ type: "text", text }] };
|
|
2456
2494
|
});
|
|
2457
2495
|
// ─── Remote sync tools (v5.3.0) ─────────────────────────────────────────
|
|
2458
|
-
|
|
2496
|
+
regTool("gnosys_remote_status", "Check the status of remote sync (multi-machine). Returns pending pushes, pulls, conflicts, and reachability. Agents should surface this to the user when there are pending changes or conflicts.", {}, async () => {
|
|
2459
2497
|
// Sync operations need explicit local DB access (not auto-routed remote).
|
|
2460
2498
|
const localDb = GnosysDB.openLocal();
|
|
2461
2499
|
try {
|
|
@@ -2483,7 +2521,7 @@ server.tool("gnosys_remote_status", "Check the status of remote sync (multi-mach
|
|
|
2483
2521
|
localDb.close();
|
|
2484
2522
|
}
|
|
2485
2523
|
});
|
|
2486
|
-
|
|
2524
|
+
regTool("gnosys_remote_push", "Push local memory changes to the remote (NAS) database. Uses skip-and-flag for conflicts by default. Call this when the user has approved pushing local changes.", {
|
|
2487
2525
|
newerWins: z.boolean().optional().describe("Auto-resolve conflicts by taking the newer version"),
|
|
2488
2526
|
}, async ({ newerWins }) => {
|
|
2489
2527
|
const localDb = GnosysDB.openLocal();
|
|
@@ -2507,7 +2545,7 @@ server.tool("gnosys_remote_push", "Push local memory changes to the remote (NAS)
|
|
|
2507
2545
|
localDb.close();
|
|
2508
2546
|
}
|
|
2509
2547
|
});
|
|
2510
|
-
|
|
2548
|
+
regTool("gnosys_remote_pull", "Pull remote memory changes to the local database. Uses skip-and-flag for conflicts by default. Call this when the user wants the latest from the remote.", {
|
|
2511
2549
|
newerWins: z.boolean().optional().describe("Auto-resolve conflicts by taking the newer version"),
|
|
2512
2550
|
}, async ({ newerWins }) => {
|
|
2513
2551
|
const localDb = GnosysDB.openLocal();
|
|
@@ -2531,7 +2569,7 @@ server.tool("gnosys_remote_pull", "Pull remote memory changes to the local datab
|
|
|
2531
2569
|
localDb.close();
|
|
2532
2570
|
}
|
|
2533
2571
|
});
|
|
2534
|
-
|
|
2572
|
+
regTool("gnosys_remote_resolve", "Resolve a sync conflict by choosing which version to keep. Use after gnosys_remote_status reveals conflicts. The agent should present the local and remote versions to the user and call this with their choice.", {
|
|
2535
2573
|
memoryId: z.string().describe("Memory ID with the conflict"),
|
|
2536
2574
|
choice: z.enum(["local", "remote"]).describe("Which version to keep"),
|
|
2537
2575
|
}, async ({ memoryId, choice }) => {
|
|
@@ -2558,7 +2596,7 @@ server.tool("gnosys_remote_resolve", "Resolve a sync conflict by choosing which
|
|
|
2558
2596
|
}
|
|
2559
2597
|
});
|
|
2560
2598
|
// ─── Tool: gnosys_update_status ─────────────────────────────────────────
|
|
2561
|
-
|
|
2599
|
+
regTool("gnosys_update_status", "Get the prompt/template for writing a dashboard-compatible status memory for this project. Returns instructions for creating a landscape memory with the correct heading format so the portfolio dashboard can parse it. Run this, then follow the instructions to analyze and write the status.", {
|
|
2562
2600
|
projectRoot: z.string().optional().describe("Project root for auto-detection"),
|
|
2563
2601
|
}, async ({ projectRoot }) => {
|
|
2564
2602
|
if (!centralDb?.isAvailable()) {
|
|
@@ -2576,7 +2614,7 @@ server.tool("gnosys_update_status", "Get the prompt/template for writing a dashb
|
|
|
2576
2614
|
return { content: [{ type: "text", text: prompt }] };
|
|
2577
2615
|
});
|
|
2578
2616
|
// ─── Tool: gnosys_working_set ───────────────────────────────────────────
|
|
2579
|
-
|
|
2617
|
+
regTool("gnosys_working_set", "Get the implicit working set — recently modified memories for the current project. These represent the active context and get boosted in federated search.", {
|
|
2580
2618
|
projectRoot: z.string().optional().describe("Project root for auto-detection"),
|
|
2581
2619
|
windowHours: z.number().optional().describe("Lookback window in hours (default: 24)"),
|
|
2582
2620
|
}, async ({ projectRoot, windowHours }) => {
|
|
@@ -2594,7 +2632,7 @@ server.tool("gnosys_working_set", "Get the implicit working set — recently mod
|
|
|
2594
2632
|
return { content: [{ type: "text", text: formatted }] };
|
|
2595
2633
|
});
|
|
2596
2634
|
// ─── Tool: gnosys_ingest_file ────────────────────────────────────────────
|
|
2597
|
-
|
|
2635
|
+
regTool("gnosys_ingest_file", "Ingest a file (PDF, DOCX, TXT, MD) into Gnosys memory. Extracts text, splits into chunks, and creates atomic memories. Supports LLM-powered structuring or fast structured mode.", {
|
|
2598
2636
|
filePath: z.string().describe("Absolute path to the file to ingest"),
|
|
2599
2637
|
mode: z.enum(["llm", "structured"]).default("llm").optional()
|
|
2600
2638
|
.describe("Ingestion mode: 'llm' uses AI to structure each chunk, 'structured' uses keyword extraction (faster, no LLM needed)"),
|
|
@@ -2644,6 +2682,13 @@ server.tool("gnosys_ingest_file", "Ingest a file (PDF, DOCX, TXT, MD) into Gnosy
|
|
|
2644
2682
|
lines.push(`- Chunk ${e.chunk}: ${e.error}`);
|
|
2645
2683
|
}
|
|
2646
2684
|
}
|
|
2685
|
+
if (!dryRun && ctx.centralDb?.isAvailable()) {
|
|
2686
|
+
auditToDb(ctx.centralDb, "ingest", undefined, {
|
|
2687
|
+
source_file: result.attachment.originalName,
|
|
2688
|
+
fileType: result.fileType,
|
|
2689
|
+
count: result.memories.length,
|
|
2690
|
+
}, result.duration);
|
|
2691
|
+
}
|
|
2647
2692
|
if (dryRun) {
|
|
2648
2693
|
lines.unshift("(dry run — no files were written)\n");
|
|
2649
2694
|
}
|
|
@@ -2661,7 +2706,7 @@ server.tool("gnosys_ingest_file", "Ingest a file (PDF, DOCX, TXT, MD) into Gnosy
|
|
|
2661
2706
|
// ─── MCP Prompts (slash commands) ────────────────────────────────────────
|
|
2662
2707
|
// These appear as /gnosys-recall, /gnosys-discover, /gnosys-memorize in
|
|
2663
2708
|
// Cursor, Claude Code, and Codex.
|
|
2664
|
-
|
|
2709
|
+
regPrompt("gnosys-recall", "Inject top Gnosys memories for the current project into context. Use this at the start of any task to load relevant knowledge.", async () => {
|
|
2665
2710
|
if (!centralDb?.isAvailable()) {
|
|
2666
2711
|
return {
|
|
2667
2712
|
messages: [
|
|
@@ -2706,7 +2751,7 @@ server.prompt("gnosys-recall", "Inject top Gnosys memories for the current proje
|
|
|
2706
2751
|
],
|
|
2707
2752
|
};
|
|
2708
2753
|
});
|
|
2709
|
-
|
|
2754
|
+
regPrompt("gnosys-discover", "Search Gnosys memories on a specific topic and inject results into context.", { topic: z.string().describe("Topic or keywords to search for") }, async ({ topic }) => {
|
|
2710
2755
|
if (!centralDb?.isAvailable() || !centralDb?.isMigrated()) {
|
|
2711
2756
|
return {
|
|
2712
2757
|
messages: [
|
|
@@ -2745,7 +2790,7 @@ server.prompt("gnosys-discover", "Search Gnosys memories on a specific topic and
|
|
|
2745
2790
|
],
|
|
2746
2791
|
};
|
|
2747
2792
|
});
|
|
2748
|
-
|
|
2793
|
+
regPrompt("gnosys-memorize", "Analyze the current conversation and save new decisions, findings, and context as Gnosys memories. Checks for duplicates automatically.", async () => {
|
|
2749
2794
|
// Check for last memorized timestamp from preferences
|
|
2750
2795
|
let lastMemorizedInfo = "This is the first time /gnosys-memorize has been run — analyze all conversation content.";
|
|
2751
2796
|
if (centralDb?.isAvailable()) {
|
|
@@ -2971,6 +3016,38 @@ async function main() {
|
|
|
2971
3016
|
// heavy module initialization in the background. Handlers that use the
|
|
2972
3017
|
// module-level `ingestion` / `hybridSearch` / `askEngine` vars guard
|
|
2973
3018
|
// against null and either await readiness or surface a clear error.
|
|
3019
|
+
// v5.12: HTTP transport (central-server topology) — opt-in via env, set by
|
|
3020
|
+
// `gnosys serve --transport http`. Each session gets its own McpServer
|
|
3021
|
+
// (registrations replayed); all share the module-global brain/search.
|
|
3022
|
+
if (process.env.GNOSYS_TRANSPORT === "http") {
|
|
3023
|
+
const { startMcpHttpServer } = await import("./lib/mcpHttp.js");
|
|
3024
|
+
const host = process.env.GNOSYS_HTTP_HOST || "127.0.0.1";
|
|
3025
|
+
const port = parseInt(process.env.GNOSYS_HTTP_PORT || "7777", 10);
|
|
3026
|
+
const authToken = process.env.GNOSYS_SERVE_TOKEN || undefined;
|
|
3027
|
+
try {
|
|
3028
|
+
await startMcpHttpServer({
|
|
3029
|
+
host,
|
|
3030
|
+
port,
|
|
3031
|
+
authToken,
|
|
3032
|
+
log: (m) => console.error(`Gnosys MCP[http]: ${m}`),
|
|
3033
|
+
makeServer: () => {
|
|
3034
|
+
const s = new McpServer({ name: "gnosys", version: "2.0.0" });
|
|
3035
|
+
registerCapabilities(s);
|
|
3036
|
+
return s;
|
|
3037
|
+
},
|
|
3038
|
+
});
|
|
3039
|
+
}
|
|
3040
|
+
catch (err) {
|
|
3041
|
+
console.error(`Gnosys MCP: ${err instanceof Error ? err.message : String(err)}`);
|
|
3042
|
+
process.exit(1);
|
|
3043
|
+
}
|
|
3044
|
+
console.error(`Gnosys MCP: HTTP transport ready on http://${host}:${port}/mcp${authToken ? " (bearer auth required)" : ""}`);
|
|
3045
|
+
void initHeavyDeps().catch((err) => {
|
|
3046
|
+
console.error(`Gnosys MCP: heavy-init failed — ${err instanceof Error ? err.message : err}`);
|
|
3047
|
+
});
|
|
3048
|
+
return;
|
|
3049
|
+
}
|
|
3050
|
+
registerCapabilities(server);
|
|
2974
3051
|
const transport = new StdioServerTransport();
|
|
2975
3052
|
await server.connect(transport);
|
|
2976
3053
|
console.error("Gnosys MCP: handshake ready (heavy modules still loading)");
|
|
@@ -3014,8 +3091,10 @@ async function main() {
|
|
|
3014
3091
|
// Notification handler setup failed — non-critical
|
|
3015
3092
|
}
|
|
3016
3093
|
}
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3094
|
+
const invokedAsScript = !!process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
|
|
3095
|
+
if (invokedAsScript) {
|
|
3096
|
+
main().catch((err) => {
|
|
3097
|
+
console.error("Fatal error:", err);
|
|
3098
|
+
process.exit(1);
|
|
3099
|
+
});
|
|
3100
|
+
}
|