synabun 1.3.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/CHANGELOG.md +665 -0
- package/LICENSE +191 -0
- package/README.md +853 -0
- package/hooks/claude-code/post-plan.mjs +391 -0
- package/hooks/claude-code/post-remember.mjs +239 -0
- package/hooks/claude-code/pre-compact.mjs +241 -0
- package/hooks/claude-code/pre-websearch.mjs +90 -0
- package/hooks/claude-code/prompt-submit.mjs +861 -0
- package/hooks/claude-code/session-start.mjs +494 -0
- package/hooks/claude-code/shared.mjs +368 -0
- package/hooks/claude-code/stop.mjs +646 -0
- package/hooks/claude-code/test-user-learning.mjs +531 -0
- package/mcp-server/package.json +38 -0
- package/mcp-server/run.mjs +10 -0
- package/mcp-server/src/config.ts +70 -0
- package/mcp-server/src/http.ts +93 -0
- package/mcp-server/src/index.ts +203 -0
- package/mcp-server/src/preload-http.ts +25 -0
- package/mcp-server/src/preload.ts +29 -0
- package/mcp-server/src/scripts/migrate-qdrant-to-sqlite.ts +506 -0
- package/mcp-server/src/services/categories.ts +429 -0
- package/mcp-server/src/services/discord.ts +702 -0
- package/mcp-server/src/services/file-checksums.ts +33 -0
- package/mcp-server/src/services/local-embeddings.ts +77 -0
- package/mcp-server/src/services/neural-interface.ts +344 -0
- package/mcp-server/src/services/sqlite.ts +823 -0
- package/mcp-server/src/tools/browser-advanced.ts +123 -0
- package/mcp-server/src/tools/browser-interact.ts +255 -0
- package/mcp-server/src/tools/browser-navigate.ts +77 -0
- package/mcp-server/src/tools/browser-observe.ts +1330 -0
- package/mcp-server/src/tools/browser.ts +107 -0
- package/mcp-server/src/tools/card-tools.ts +193 -0
- package/mcp-server/src/tools/card.ts +22 -0
- package/mcp-server/src/tools/category.ts +379 -0
- package/mcp-server/src/tools/discord-channel.ts +274 -0
- package/mcp-server/src/tools/discord-guild.ts +188 -0
- package/mcp-server/src/tools/discord-member.ts +158 -0
- package/mcp-server/src/tools/discord-message.ts +231 -0
- package/mcp-server/src/tools/discord-onboarding.ts +228 -0
- package/mcp-server/src/tools/discord-role.ts +209 -0
- package/mcp-server/src/tools/discord-thread.ts +110 -0
- package/mcp-server/src/tools/discord-webhook.ts +176 -0
- package/mcp-server/src/tools/discord.ts +40 -0
- package/mcp-server/src/tools/forget.ts +38 -0
- package/mcp-server/src/tools/git-tools.ts +141 -0
- package/mcp-server/src/tools/git.ts +13 -0
- package/mcp-server/src/tools/image-tools.ts +98 -0
- package/mcp-server/src/tools/image.ts +17 -0
- package/mcp-server/src/tools/leonardo-browser-tools.ts +281 -0
- package/mcp-server/src/tools/leonardo.ts +28 -0
- package/mcp-server/src/tools/loop.ts +348 -0
- package/mcp-server/src/tools/memories.ts +118 -0
- package/mcp-server/src/tools/recall.ts +323 -0
- package/mcp-server/src/tools/reflect.ts +145 -0
- package/mcp-server/src/tools/remember.ts +115 -0
- package/mcp-server/src/tools/response.ts +26 -0
- package/mcp-server/src/tools/restore.ts +34 -0
- package/mcp-server/src/tools/sync.ts +114 -0
- package/mcp-server/src/tools/tictactoe-tools.ts +98 -0
- package/mcp-server/src/tools/tictactoe.ts +13 -0
- package/mcp-server/src/tools/utils.ts +25 -0
- package/mcp-server/src/tools/whiteboard-tools.ts +260 -0
- package/mcp-server/src/tools/whiteboard.ts +22 -0
- package/mcp-server/src/tui.ts +940 -0
- package/mcp-server/src/types.ts +85 -0
- package/mcp-server/tsconfig.json +19 -0
- package/neural-interface/package.json +27 -0
- package/neural-interface/public/apple-touch-icon.png +0 -0
- package/neural-interface/public/category-logos/claude.svg +1 -0
- package/neural-interface/public/category-logos/gemini-color.svg +1 -0
- package/neural-interface/public/category-logos/openai.svg +1 -0
- package/neural-interface/public/category-logos/synabun.png +0 -0
- package/neural-interface/public/claude-chat.css +878 -0
- package/neural-interface/public/claude-chat.html +92 -0
- package/neural-interface/public/claude-chat.js +1168 -0
- package/neural-interface/public/favicon-16x16.png +0 -0
- package/neural-interface/public/favicon-32x32.png +0 -0
- package/neural-interface/public/gallery.svg +6 -0
- package/neural-interface/public/icon-192.png +0 -0
- package/neural-interface/public/icon-512.png +0 -0
- package/neural-interface/public/index-legacy.html +14677 -0
- package/neural-interface/public/index.html +212 -0
- package/neural-interface/public/index2d-legacy.html +8193 -0
- package/neural-interface/public/index2d.html +127 -0
- package/neural-interface/public/invite.html +351 -0
- package/neural-interface/public/leonardoai.svg +1 -0
- package/neural-interface/public/logo-synabun.png +0 -0
- package/neural-interface/public/logoHD.png +0 -0
- package/neural-interface/public/manifest.json +14 -0
- package/neural-interface/public/offline.html +299 -0
- package/neural-interface/public/onboarding.html +2335 -0
- package/neural-interface/public/openclaw-logo-text.png +0 -0
- package/neural-interface/public/pin-svgrepo-com.svg +25 -0
- package/neural-interface/public/sessionicon.svg +8 -0
- package/neural-interface/public/shared/ansi-parser.js +305 -0
- package/neural-interface/public/shared/api.js +1043 -0
- package/neural-interface/public/shared/colors.js +153 -0
- package/neural-interface/public/shared/constants.js +141 -0
- package/neural-interface/public/shared/html-shell.js +777 -0
- package/neural-interface/public/shared/html-term-renderer.js +1022 -0
- package/neural-interface/public/shared/i18n.js +147 -0
- package/neural-interface/public/shared/registry.js +82 -0
- package/neural-interface/public/shared/state.js +86 -0
- package/neural-interface/public/shared/storage.js +150 -0
- package/neural-interface/public/shared/styles.css +21212 -0
- package/neural-interface/public/shared/ui-automation-studio.js +3573 -0
- package/neural-interface/public/shared/ui-bookmarks.js +231 -0
- package/neural-interface/public/shared/ui-claude-panel.js +6333 -0
- package/neural-interface/public/shared/ui-command-runner.js +534 -0
- package/neural-interface/public/shared/ui-cost-widget.js +602 -0
- package/neural-interface/public/shared/ui-detail.js +1454 -0
- package/neural-interface/public/shared/ui-explorer.js +1356 -0
- package/neural-interface/public/shared/ui-file-explorer.js +2750 -0
- package/neural-interface/public/shared/ui-games.js +411 -0
- package/neural-interface/public/shared/ui-help.js +107 -0
- package/neural-interface/public/shared/ui-image-gallery.js +461 -0
- package/neural-interface/public/shared/ui-invite.js +519 -0
- package/neural-interface/public/shared/ui-keybinds.js +452 -0
- package/neural-interface/public/shared/ui-layouts.js +297 -0
- package/neural-interface/public/shared/ui-link.js +731 -0
- package/neural-interface/public/shared/ui-loading.js +255 -0
- package/neural-interface/public/shared/ui-menubar.js +499 -0
- package/neural-interface/public/shared/ui-multiselect.js +93 -0
- package/neural-interface/public/shared/ui-navbar.js +222 -0
- package/neural-interface/public/shared/ui-notifications.js +287 -0
- package/neural-interface/public/shared/ui-panels.js +309 -0
- package/neural-interface/public/shared/ui-resume.js +653 -0
- package/neural-interface/public/shared/ui-search.js +145 -0
- package/neural-interface/public/shared/ui-sessions.js +531 -0
- package/neural-interface/public/shared/ui-settings.js +5987 -0
- package/neural-interface/public/shared/ui-sidebar.js +1905 -0
- package/neural-interface/public/shared/ui-skills.js +2805 -0
- package/neural-interface/public/shared/ui-stats.js +38 -0
- package/neural-interface/public/shared/ui-sync.js +201 -0
- package/neural-interface/public/shared/ui-terminal.js +6385 -0
- package/neural-interface/public/shared/ui-tooltip.js +123 -0
- package/neural-interface/public/shared/ui-trash.js +439 -0
- package/neural-interface/public/shared/ui-tutorial-draw.js +875 -0
- package/neural-interface/public/shared/ui-tutorial-steps.js +2276 -0
- package/neural-interface/public/shared/ui-tutorial.js +1117 -0
- package/neural-interface/public/shared/ui-update.js +244 -0
- package/neural-interface/public/shared/ui-whiteboard.js +3262 -0
- package/neural-interface/public/shared/ui-workspaces.js +722 -0
- package/neural-interface/public/shared/utils.js +360 -0
- package/neural-interface/public/shared/vterm-buffer.js +1102 -0
- package/neural-interface/public/sw.js +52 -0
- package/neural-interface/public/synabun.png +0 -0
- package/neural-interface/public/toolbar-album.svg +8 -0
- package/neural-interface/public/toolbar-question.svg +6 -0
- package/neural-interface/public/toolbar-sessions.svg +6 -0
- package/neural-interface/public/variant/2d/background.js +113 -0
- package/neural-interface/public/variant/2d/context-menu.js +133 -0
- package/neural-interface/public/variant/2d/gfx.js +45 -0
- package/neural-interface/public/variant/2d/graph.js +1635 -0
- package/neural-interface/public/variant/2d/hulls.js +207 -0
- package/neural-interface/public/variant/2d/lasso.js +135 -0
- package/neural-interface/public/variant/2d/layout.js +594 -0
- package/neural-interface/public/variant/2d/main.js +521 -0
- package/neural-interface/public/variant/2d/minimap.js +312 -0
- package/neural-interface/public/variant/2d/settings-gfx.js +98 -0
- package/neural-interface/public/variant/3d/background.js +884 -0
- package/neural-interface/public/variant/3d/camera.js +661 -0
- package/neural-interface/public/variant/3d/gfx.js +116 -0
- package/neural-interface/public/variant/3d/graph.js +2399 -0
- package/neural-interface/public/variant/3d/main.js +500 -0
- package/neural-interface/public/variant/3d/settings-gfx.js +228 -0
- package/neural-interface/scripts/rebuild-pty.js +100 -0
- package/neural-interface/server.js +15000 -0
- package/neural-interface/templates/CLAUDE-template.md +211 -0
- package/package.json +53 -0
- package/postinstall.js +135 -0
- package/setup.js +260 -0
- package/skills/leonardo/SKILL.md +159 -0
- package/skills/leonardo/icon.svg +1 -0
- package/skills/leonardo/modules/browser-guide.md +378 -0
- package/skills/leonardo/modules/image-prompter.md +277 -0
- package/skills/leonardo/modules/model-advisor.md +100 -0
- package/skills/leonardo/modules/prompt-library.md +110 -0
- package/skills/leonardo/modules/style-guide.md +186 -0
- package/skills/leonardo/modules/video-prompter.md +311 -0
- package/skills/synabun/SKILL.md +185 -0
- package/skills/synabun/icon.png +0 -0
- package/skills/synabun/modules/audit.md +374 -0
- package/skills/synabun/modules/changelog.md +194 -0
- package/skills/synabun/modules/idea.md +144 -0
- package/skills/synabun/modules/memorize.md +188 -0
- package/skills/synabun/synabunicon.png +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* HTTP transport for SynaBun MCP server.
|
|
5
|
+
* Stateless — creates a fresh McpServer per request (same tools, no session state).
|
|
6
|
+
* Mount on any Express app or run standalone.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import express from 'express';
|
|
10
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
11
|
+
import { ensureDatabase } from './services/sqlite.js';
|
|
12
|
+
import { initCategoryCache } from './services/categories.js';
|
|
13
|
+
import { createMcpServer } from './index.js';
|
|
14
|
+
|
|
15
|
+
let initialized = false;
|
|
16
|
+
|
|
17
|
+
async function ensureInit() {
|
|
18
|
+
if (initialized) return;
|
|
19
|
+
try { await ensureDatabase(); } catch {}
|
|
20
|
+
await initCategoryCache();
|
|
21
|
+
initialized = true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create Express routes for the MCP HTTP endpoint.
|
|
26
|
+
* Auth is handled externally (URL-embedded key in server.js).
|
|
27
|
+
* Can be mounted on an existing Express app: app.use('/mcp', createMcpRoutes());
|
|
28
|
+
*/
|
|
29
|
+
export function createMcpRoutes() {
|
|
30
|
+
const router = express.Router();
|
|
31
|
+
router.use(express.json());
|
|
32
|
+
|
|
33
|
+
router.post('/', async (req, res) => {
|
|
34
|
+
await ensureInit();
|
|
35
|
+
const server = createMcpServer();
|
|
36
|
+
try {
|
|
37
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
38
|
+
await server.connect(transport);
|
|
39
|
+
await transport.handleRequest(req, res, req.body);
|
|
40
|
+
res.on('close', () => {
|
|
41
|
+
transport.close();
|
|
42
|
+
server.close();
|
|
43
|
+
});
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error('MCP HTTP error:', error);
|
|
46
|
+
if (!res.headersSent) {
|
|
47
|
+
res.status(500).json({
|
|
48
|
+
jsonrpc: '2.0',
|
|
49
|
+
error: { code: -32603, message: 'Internal server error' },
|
|
50
|
+
id: null,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Stateless — no GET (SSE) or DELETE (session close) needed
|
|
57
|
+
router.get('/', (_req, res) => {
|
|
58
|
+
res.writeHead(405).end(JSON.stringify({
|
|
59
|
+
jsonrpc: '2.0',
|
|
60
|
+
error: { code: -32000, message: 'Method not allowed.' },
|
|
61
|
+
id: null,
|
|
62
|
+
}));
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
router.delete('/', (_req, res) => {
|
|
66
|
+
res.writeHead(405).end(JSON.stringify({
|
|
67
|
+
jsonrpc: '2.0',
|
|
68
|
+
error: { code: -32000, message: 'Method not allowed.' },
|
|
69
|
+
id: null,
|
|
70
|
+
}));
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return router;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// If run directly, start a standalone HTTP server
|
|
77
|
+
const isMain = process.argv[1]?.replace(/\\/g, '/').endsWith('/http.js')
|
|
78
|
+
|| process.argv[1]?.replace(/\\/g, '/').endsWith('/http.ts');
|
|
79
|
+
|
|
80
|
+
if (isMain) {
|
|
81
|
+
const PORT = parseInt(process.env.MCP_HTTP_PORT || '3345', 10);
|
|
82
|
+
const app = express();
|
|
83
|
+
app.use('/mcp', createMcpRoutes());
|
|
84
|
+
|
|
85
|
+
app.get('/', (_req, res) => {
|
|
86
|
+
res.json({ name: 'SynaBun MCP (HTTP)', status: 'ok', endpoint: '/mcp' });
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
app.listen(PORT, () => {
|
|
90
|
+
console.log(`SynaBun MCP HTTP server listening on port ${PORT}`);
|
|
91
|
+
console.log(`Endpoint: http://localhost:${PORT}/mcp`);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { ensureDatabase, closeDatabase, reopenDatabase } from './services/sqlite.js';
|
|
4
|
+
|
|
5
|
+
import { rememberSchema, rememberDescription, handleRemember, buildRememberSchema } from './tools/remember.js';
|
|
6
|
+
import { recallSchema, recallDescription, handleRecall, buildRecallSchema } from './tools/recall.js';
|
|
7
|
+
import { forgetSchema, forgetDescription, handleForget } from './tools/forget.js';
|
|
8
|
+
import { restoreSchema, restoreDescription, handleRestore } from './tools/restore.js';
|
|
9
|
+
import { reflectSchema, reflectDescription, handleReflect, buildReflectSchema } from './tools/reflect.js';
|
|
10
|
+
import { memoriesSchema, memoriesDescription, handleMemories, buildMemoriesSchema } from './tools/memories.js';
|
|
11
|
+
import { categorySchema, categoryDescription, handleCategory } from './tools/category.js';
|
|
12
|
+
import { syncSchema, syncDescription, handleSync } from './tools/sync.js';
|
|
13
|
+
import { loopSchema, loopDescription, handleLoop } from './tools/loop.js';
|
|
14
|
+
import { registerBrowserTools } from './tools/browser.js';
|
|
15
|
+
import { registerWhiteboardTools } from './tools/whiteboard.js';
|
|
16
|
+
import { registerCardTools } from './tools/card.js';
|
|
17
|
+
import { registerTicTacToeTools } from './tools/tictactoe.js';
|
|
18
|
+
import { registerDiscordTools } from './tools/discord.js';
|
|
19
|
+
import { registerGitTools } from './tools/git.js';
|
|
20
|
+
import { registerLeonardoTools } from './tools/leonardo.js';
|
|
21
|
+
import { registerImageTools } from './tools/image.js';
|
|
22
|
+
import { invalidateCategoryCache, setOnExternalChange, startWatchingCategories, stopWatchingCategories, initCategoryCache } from './services/categories.js';
|
|
23
|
+
import { getEnvPath } from './config.js';
|
|
24
|
+
import { readFileSync, watch, existsSync } from 'fs';
|
|
25
|
+
|
|
26
|
+
function buildServerInstructions(): string {
|
|
27
|
+
return `SynaBun — persistent vector memory system for Claude Code sessions.
|
|
28
|
+
|
|
29
|
+
Tool groups:
|
|
30
|
+
- Memory: remember, recall, reflect, forget, restore, memories
|
|
31
|
+
- Categories: category (action: create/update/delete/list)
|
|
32
|
+
- Browser: browser_navigate, browser_click, browser_type, browser_fill, browser_hover, browser_select, browser_press, browser_scroll, browser_upload, browser_go_back, browser_go_forward, browser_reload, browser_snapshot, browser_content, browser_screenshot, browser_evaluate, browser_wait, browser_session, browser_extract_tweets, browser_extract_fb_posts, browser_extract_tiktok_videos, browser_extract_tiktok_search, browser_extract_tiktok_studio, browser_extract_tiktok_profile, browser_extract_wa_chats, browser_extract_wa_messages, browser_extract_ig_feed, browser_extract_ig_profile, browser_extract_ig_post, browser_extract_ig_reels, browser_extract_ig_search, browser_extract_li_feed, browser_extract_li_profile, browser_extract_li_post, browser_extract_li_notifications, browser_extract_li_messages, browser_extract_li_search_people, browser_extract_li_network, browser_extract_li_jobs
|
|
33
|
+
- Whiteboard: whiteboard_read, whiteboard_add, whiteboard_update, whiteboard_remove, whiteboard_screenshot
|
|
34
|
+
- Cards: card_list, card_open, card_close, card_update, card_screenshot
|
|
35
|
+
- TicTacToe: tictactoe (action: start/move/state/end)
|
|
36
|
+
- Sync: sync
|
|
37
|
+
- Loop: loop (action: start/stop/status)
|
|
38
|
+
- Git: git (action: status/diff/commit/log/branches)
|
|
39
|
+
- Discord: discord_guild, discord_channel, discord_role, discord_message, discord_member, discord_onboarding, discord_webhook, discord_thread
|
|
40
|
+
- Images: image_staged (action: list/clear/remove)
|
|
41
|
+
- Leonardo (browser-based): leonardo_browser_navigate, leonardo_browser_generate, leonardo_browser_library, leonardo_browser_download, leonardo_browser_reference
|
|
42
|
+
|
|
43
|
+
Use "category" with action "list" to see valid category names before using remember/recall/reflect.
|
|
44
|
+
|
|
45
|
+
Discord tools require DISCORD_BOT_TOKEN in .env. Set DISCORD_GUILD_ID for default guild. Each tool uses an "action" parameter to select the operation.
|
|
46
|
+
|
|
47
|
+
Leonardo tools are 100% browser-based — no API key needed. Use leonardo_browser_navigate to go to the right page, then use generic browser tools (browser_click, browser_fill, browser_snapshot) to configure settings (model, style, dimensions, motion controls), and leonardo_browser_generate to fill the prompt and click Generate. Use the /leonardo skill for the full guided creation experience.`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Register all tools on a given McpServer instance.
|
|
51
|
+
// Returns references needed for dynamic schema refresh.
|
|
52
|
+
export function registerTools(server: McpServer) {
|
|
53
|
+
const rememberTool = server.tool('remember', rememberDescription, rememberSchema, handleRemember);
|
|
54
|
+
const recallTool = server.tool('recall', recallDescription, recallSchema, handleRecall);
|
|
55
|
+
server.tool('forget', forgetDescription, forgetSchema, handleForget);
|
|
56
|
+
server.tool('restore', restoreDescription, restoreSchema, handleRestore);
|
|
57
|
+
const reflectTool = server.tool('reflect', reflectDescription, reflectSchema, handleReflect);
|
|
58
|
+
const memoriesTool = server.tool('memories', memoriesDescription, memoriesSchema, handleMemories);
|
|
59
|
+
server.tool('category', categoryDescription, categorySchema, handleCategory);
|
|
60
|
+
server.tool('sync', syncDescription, syncSchema, handleSync);
|
|
61
|
+
server.tool('loop', loopDescription, loopSchema, handleLoop);
|
|
62
|
+
registerBrowserTools(server);
|
|
63
|
+
registerWhiteboardTools(server);
|
|
64
|
+
registerCardTools(server);
|
|
65
|
+
registerTicTacToeTools(server);
|
|
66
|
+
registerDiscordTools(server);
|
|
67
|
+
registerGitTools(server);
|
|
68
|
+
registerLeonardoTools(server);
|
|
69
|
+
registerImageTools(server);
|
|
70
|
+
return { rememberTool, recallTool, reflectTool, memoriesTool };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Create a fully configured McpServer with all tools registered.
|
|
74
|
+
export function createMcpServer() {
|
|
75
|
+
const server = new McpServer(
|
|
76
|
+
{ name: 'claude-memory', version: '1.1.0' },
|
|
77
|
+
{ instructions: buildServerInstructions() }
|
|
78
|
+
);
|
|
79
|
+
registerTools(server);
|
|
80
|
+
return server;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const server = new McpServer(
|
|
84
|
+
{ name: 'claude-memory', version: '1.1.0' },
|
|
85
|
+
{ instructions: buildServerInstructions() }
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const { rememberTool, recallTool, reflectTool, memoriesTool } = registerTools(server);
|
|
89
|
+
|
|
90
|
+
// Refresh all tool schemas that reference category descriptions.
|
|
91
|
+
// Called after any category change so Claude sees updated guidelines.
|
|
92
|
+
export function refreshCategorySchemas() {
|
|
93
|
+
invalidateCategoryCache();
|
|
94
|
+
rememberTool.update({ paramsSchema: buildRememberSchema() });
|
|
95
|
+
recallTool.update({ paramsSchema: buildRecallSchema() });
|
|
96
|
+
reflectTool.update({ paramsSchema: buildReflectSchema() });
|
|
97
|
+
memoriesTool.update({ paramsSchema: buildMemoriesSchema() });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function main() {
|
|
101
|
+
try {
|
|
102
|
+
await ensureDatabase();
|
|
103
|
+
} catch (err) {
|
|
104
|
+
console.error(
|
|
105
|
+
'Warning: Could not initialize SQLite database on startup.',
|
|
106
|
+
err instanceof Error ? err.message : err
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Initialize category cache (loads from SQLite or starts empty)
|
|
111
|
+
await initCategoryCache();
|
|
112
|
+
|
|
113
|
+
// Set up file watcher for external category changes
|
|
114
|
+
setOnExternalChange(() => {
|
|
115
|
+
console.error('Categories changed externally, refreshing schemas...');
|
|
116
|
+
refreshCategorySchemas();
|
|
117
|
+
// Notify Claude Code that tool schemas have changed
|
|
118
|
+
server.server.notification({
|
|
119
|
+
method: 'notifications/tools/list_changed',
|
|
120
|
+
}).catch((err) => {
|
|
121
|
+
console.error('Failed to send tools/list_changed notification:', err);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
startWatchingCategories();
|
|
125
|
+
|
|
126
|
+
// Watch .env for SQLITE_DB_PATH changes (e.g. from onboarding or settings)
|
|
127
|
+
const envPath = getEnvPath();
|
|
128
|
+
let envWatcher: ReturnType<typeof watch> | null = null;
|
|
129
|
+
if (existsSync(envPath)) {
|
|
130
|
+
startEnvWatcher();
|
|
131
|
+
} else {
|
|
132
|
+
// .env doesn't exist yet — poll until it appears, then start watching
|
|
133
|
+
const envPollInterval = setInterval(() => {
|
|
134
|
+
if (existsSync(envPath)) {
|
|
135
|
+
clearInterval(envPollInterval);
|
|
136
|
+
startEnvWatcher();
|
|
137
|
+
}
|
|
138
|
+
}, 5000);
|
|
139
|
+
envPollInterval.unref();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function startEnvWatcher() {
|
|
143
|
+
try {
|
|
144
|
+
let debounce: ReturnType<typeof setTimeout> | null = null;
|
|
145
|
+
envWatcher = watch(envPath, () => {
|
|
146
|
+
if (debounce) clearTimeout(debounce);
|
|
147
|
+
debounce = setTimeout(() => {
|
|
148
|
+
try {
|
|
149
|
+
const content = readFileSync(envPath, 'utf-8');
|
|
150
|
+
const vars: Record<string, string> = {};
|
|
151
|
+
for (const line of content.split('\n')) {
|
|
152
|
+
const trimmed = line.trim();
|
|
153
|
+
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
154
|
+
const eq = trimmed.indexOf('=');
|
|
155
|
+
if (eq === -1) continue;
|
|
156
|
+
vars[trimmed.slice(0, eq)] = trimmed.slice(eq + 1);
|
|
157
|
+
}
|
|
158
|
+
const newDbPath = vars['SQLITE_DB_PATH'];
|
|
159
|
+
const currentDbPath = process.env.SQLITE_DB_PATH || '';
|
|
160
|
+
if (newDbPath && newDbPath !== currentDbPath) {
|
|
161
|
+
console.error(`SQLITE_DB_PATH changed: ${currentDbPath || '(default)'} → ${newDbPath}`);
|
|
162
|
+
process.env.SQLITE_DB_PATH = newDbPath;
|
|
163
|
+
reopenDatabase().catch((err) => {
|
|
164
|
+
console.error('Failed to reopen database at new path:', err);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
} catch (err) {
|
|
168
|
+
console.error('.env reload error:', err);
|
|
169
|
+
}
|
|
170
|
+
}, 500);
|
|
171
|
+
});
|
|
172
|
+
} catch (err) {
|
|
173
|
+
console.error('Failed to watch .env:', err);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Clean up on exit
|
|
178
|
+
process.on('SIGINT', () => {
|
|
179
|
+
if (envWatcher) envWatcher.close();
|
|
180
|
+
stopWatchingCategories();
|
|
181
|
+
closeDatabase();
|
|
182
|
+
process.exit(0);
|
|
183
|
+
});
|
|
184
|
+
process.on('SIGTERM', () => {
|
|
185
|
+
if (envWatcher) envWatcher.close();
|
|
186
|
+
stopWatchingCategories();
|
|
187
|
+
closeDatabase();
|
|
188
|
+
process.exit(0);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const transport = new StdioServerTransport();
|
|
192
|
+
await server.connect(transport);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Only start stdio transport when run directly (not when imported by http.ts)
|
|
196
|
+
const isMain = process.argv[1]?.replace(/\\/g, '/').endsWith('/index.js')
|
|
197
|
+
|| process.argv[1]?.replace(/\\/g, '/').endsWith('/preload.js');
|
|
198
|
+
if (isMain) {
|
|
199
|
+
main().catch((err) => {
|
|
200
|
+
console.error('Fatal error starting memory server:', err);
|
|
201
|
+
process.exit(1);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Preload script for HTTP transport — loads .env then starts the HTTP server.
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync } from 'fs';
|
|
7
|
+
import { resolve, dirname } from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const envPath = process.env.DOTENV_PATH || resolve(__dirname, '..', '..', '.env');
|
|
12
|
+
try {
|
|
13
|
+
const content = readFileSync(envPath, 'utf-8');
|
|
14
|
+
for (const line of content.split('\n')) {
|
|
15
|
+
const trimmed = line.trim();
|
|
16
|
+
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
17
|
+
const eq = trimmed.indexOf('=');
|
|
18
|
+
if (eq === -1) continue;
|
|
19
|
+
const key = trimmed.slice(0, eq);
|
|
20
|
+
const val = trimmed.slice(eq + 1);
|
|
21
|
+
process.env[key] = val;
|
|
22
|
+
}
|
|
23
|
+
} catch { /* .env not found, rely on existing env vars */ }
|
|
24
|
+
|
|
25
|
+
await import('./http.js');
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Preload script — loads .env into process.env BEFORE any other module evaluates.
|
|
5
|
+
* This avoids the ESM hoisting issue where static imports (like config.ts) would
|
|
6
|
+
* read empty env vars because import statements execute before module body code.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync } from 'fs';
|
|
9
|
+
import { resolve, dirname } from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const envPath = process.env.DOTENV_PATH || resolve(__dirname, '..', '..', '.env');
|
|
14
|
+
try {
|
|
15
|
+
const content = readFileSync(envPath, 'utf-8');
|
|
16
|
+
for (const line of content.split('\n')) {
|
|
17
|
+
const trimmed = line.trim();
|
|
18
|
+
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
19
|
+
const eq = trimmed.indexOf('=');
|
|
20
|
+
if (eq === -1) continue;
|
|
21
|
+
const key = trimmed.slice(0, eq);
|
|
22
|
+
const val = trimmed.slice(eq + 1);
|
|
23
|
+
process.env[key] = val;
|
|
24
|
+
}
|
|
25
|
+
} catch { /* .env not found, rely on existing env vars */ }
|
|
26
|
+
|
|
27
|
+
// Now that env is loaded, dynamically import the main entry point.
|
|
28
|
+
// Dynamic import ensures all static imports in index.ts see the populated env.
|
|
29
|
+
await import('./index.js');
|