kimi-code-memory-mcp-server 0.1.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/AGENTS.md +144 -0
- package/CHANGELOG.md +26 -0
- package/LICENSE +21 -0
- package/README.md +227 -0
- package/README.zh-CN.md +227 -0
- package/dist/config.d.ts +36 -0
- package/dist/config.js +63 -0
- package/dist/config.js.map +1 -0
- package/dist/context/wire-context.d.ts +171 -0
- package/dist/context/wire-context.js +586 -0
- package/dist/context/wire-context.js.map +1 -0
- package/dist/dao/index.d.ts +76 -0
- package/dist/dao/index.js +490 -0
- package/dist/dao/index.js.map +1 -0
- package/dist/dao/memory-store.d.ts +24 -0
- package/dist/dao/memory-store.js +112 -0
- package/dist/dao/memory-store.js.map +1 -0
- package/dist/refined-manager.d.ts +70 -0
- package/dist/refined-manager.js +369 -0
- package/dist/refined-manager.js.map +1 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.js +71 -0
- package/dist/server.js.map +1 -0
- package/dist/theme-manager.d.ts +40 -0
- package/dist/theme-manager.js +88 -0
- package/dist/theme-manager.js.map +1 -0
- package/dist/tools/context-tools.d.ts +56 -0
- package/dist/tools/context-tools.js +332 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/index.d.ts +835 -0
- package/dist/tools/index.js +370 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/memory-tools.d.ts +62 -0
- package/dist/tools/memory-tools.js +292 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/system-tools.d.ts +37 -0
- package/dist/tools/system-tools.js +195 -0
- package/dist/tools/system-tools.js.map +1 -0
- package/dist/tools/theme-tools.d.ts +34 -0
- package/dist/tools/theme-tools.js +186 -0
- package/dist/tools/theme-tools.js.map +1 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +10 -0
- package/dist/utils/frontmatter.js +61 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/mutex.d.ts +11 -0
- package/dist/utils/mutex.js +17 -0
- package/dist/utils/mutex.js.map +1 -0
- package/dist/utils/paths.d.ts +19 -0
- package/dist/utils/paths.js +54 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/validation.d.ts +15 -0
- package/dist/utils/validation.js +40 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.js +10 -0
- package/dist/version.js.map +1 -0
- package/docs/ARCHITECTURE.md +144 -0
- package/docs/CONTRIBUTING.md +83 -0
- package/docs/CONTRIBUTING.zh-CN.md +83 -0
- package/docs/search-logic.md +157 -0
- package/docs/search-logic.zh-CN.md +157 -0
- package/examples/README.md +34 -0
- package/examples/sample-workspace/essence/essence.md +26 -0
- package/examples/sample-workspace/index.json +36 -0
- package/examples/sample-workspace/memory/decisions/sample-decision.md +30 -0
- package/examples/sample-workspace/memory/knowledge/sample-knowledge.md +24 -0
- package/examples/sample-workspace/memory/reference/sample-reference.md +20 -0
- package/examples/sample-workspace/memory/rules/sample-rule.md +31 -0
- package/examples/sample-workspace/themes/cache-design.json +15 -0
- package/package.json +72 -0
- package/skills/memory-manage/SKILL.md +43 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme tracing tools: tag_theme, trace_theme, list_themes, refine_session_turns.
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { sanitizeFolder, sanitizeKey, toTitle } from '../utils/validation.js';
|
|
7
|
+
import { parseFrontmatter } from '../utils/frontmatter.js';
|
|
8
|
+
import { findAllWorkspaceSessions, parseWireFile } from '../context/wire-context.js';
|
|
9
|
+
function toolResult(data, isError = false) {
|
|
10
|
+
return {
|
|
11
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
12
|
+
isError,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function safeParseFile(filePath) {
|
|
16
|
+
try {
|
|
17
|
+
const text = fs.readFileSync(filePath, 'utf8');
|
|
18
|
+
return parseFrontmatter(text) || { frontmatter: {}, body: text };
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function createThemeTools(ctx) {
|
|
25
|
+
const { storeRoot, themeManager, refinedManager } = ctx;
|
|
26
|
+
async function handleTagTheme(args) {
|
|
27
|
+
const theme = args.theme;
|
|
28
|
+
if (!theme || typeof theme !== 'string') {
|
|
29
|
+
return toolResult({ success: false, error: 'Missing or invalid "theme"' }, true);
|
|
30
|
+
}
|
|
31
|
+
const ref = {};
|
|
32
|
+
if (args.sessionId && typeof args.turnId === 'number') {
|
|
33
|
+
const allSessions = findAllWorkspaceSessions();
|
|
34
|
+
const session = allSessions.find((s) => s.sessionId === args.sessionId);
|
|
35
|
+
if (!session) {
|
|
36
|
+
return toolResult({ success: false, error: 'Session not found' }, true);
|
|
37
|
+
}
|
|
38
|
+
const { turns } = await parseWireFile(session.wire);
|
|
39
|
+
const turnExists = turns.some((t) => String(t.turnId) === String(args.turnId));
|
|
40
|
+
if (!turnExists) {
|
|
41
|
+
return toolResult({ success: false, error: 'Turn not found' }, true);
|
|
42
|
+
}
|
|
43
|
+
ref.sessionId = args.sessionId;
|
|
44
|
+
ref.turnId = args.turnId;
|
|
45
|
+
}
|
|
46
|
+
if (args.memoryKey) {
|
|
47
|
+
const memoryFolderRaw = typeof args.memoryFolder === 'string' ? args.memoryFolder : 'memory';
|
|
48
|
+
const memoryFolder = sanitizeFolder(memoryFolderRaw);
|
|
49
|
+
if (!memoryFolder) {
|
|
50
|
+
return toolResult({ success: false, error: 'Invalid memoryFolder path' }, true);
|
|
51
|
+
}
|
|
52
|
+
const sanitizedMemoryKey = sanitizeKey(args.memoryKey);
|
|
53
|
+
const memoryFilePath = path.join(storeRoot, memoryFolder, `${sanitizedMemoryKey}.md`);
|
|
54
|
+
if (!fs.existsSync(memoryFilePath)) {
|
|
55
|
+
return toolResult({ success: false, error: 'Memory not found' }, true);
|
|
56
|
+
}
|
|
57
|
+
const parsed = safeParseFile(memoryFilePath);
|
|
58
|
+
ref.memoryKey = sanitizedMemoryKey;
|
|
59
|
+
ref.folder = memoryFolder;
|
|
60
|
+
ref.title =
|
|
61
|
+
typeof args.memoryTitle === 'string'
|
|
62
|
+
? args.memoryTitle
|
|
63
|
+
: String(parsed?.frontmatter?.title || toTitle(sanitizedMemoryKey));
|
|
64
|
+
}
|
|
65
|
+
if (!ref.sessionId && !ref.memoryKey) {
|
|
66
|
+
return toolResult({ success: false, error: 'Provide either sessionId+turnId or memoryKey' }, true);
|
|
67
|
+
}
|
|
68
|
+
await themeManager.addThemeAssociation(theme, ref);
|
|
69
|
+
return toolResult({ success: true, theme: sanitizeKey(theme), ref });
|
|
70
|
+
}
|
|
71
|
+
async function handleTraceTheme(args) {
|
|
72
|
+
const theme = args.theme;
|
|
73
|
+
if (!theme || typeof theme !== 'string') {
|
|
74
|
+
return toolResult({ found: false, error: 'Missing or invalid "theme"' }, true);
|
|
75
|
+
}
|
|
76
|
+
const association = themeManager.loadTheme(theme);
|
|
77
|
+
if (!association) {
|
|
78
|
+
return toolResult({ found: false, theme });
|
|
79
|
+
}
|
|
80
|
+
association.turns.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
81
|
+
association.memories.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
82
|
+
const includeContent = args.includeTurnContent === true;
|
|
83
|
+
const result = {
|
|
84
|
+
found: true,
|
|
85
|
+
theme: association.theme,
|
|
86
|
+
displayName: association.displayName || association.theme,
|
|
87
|
+
createdAt: association.createdAt,
|
|
88
|
+
updatedAt: association.updatedAt,
|
|
89
|
+
turnCount: association.turns.length,
|
|
90
|
+
memoryCount: association.memories.length,
|
|
91
|
+
turns: association.turns,
|
|
92
|
+
memories: association.memories,
|
|
93
|
+
};
|
|
94
|
+
if (includeContent && association.turns.length > 0) {
|
|
95
|
+
const loadedTurns = [];
|
|
96
|
+
const allSessions = findAllWorkspaceSessions();
|
|
97
|
+
const sessionById = new Map(allSessions.map((s) => [s.sessionId, s]));
|
|
98
|
+
for (const ref of association.turns) {
|
|
99
|
+
if (!ref.sessionId || ref.turnId === undefined)
|
|
100
|
+
continue;
|
|
101
|
+
try {
|
|
102
|
+
const refinedTurns = refinedManager.loadRefinedTurns(ref.sessionId);
|
|
103
|
+
const refined = refinedTurns.find((t) => String(t.turnId) === String(ref.turnId));
|
|
104
|
+
const session = sessionById.get(ref.sessionId);
|
|
105
|
+
let fullTurn = null;
|
|
106
|
+
if (session) {
|
|
107
|
+
const { turns } = await parseWireFile(session.wire);
|
|
108
|
+
fullTurn = turns.find((t) => String(t.turnId) === String(ref.turnId));
|
|
109
|
+
}
|
|
110
|
+
loadedTurns.push({
|
|
111
|
+
...ref,
|
|
112
|
+
refined: refined || null,
|
|
113
|
+
content: fullTurn
|
|
114
|
+
? {
|
|
115
|
+
user: fullTurn.user,
|
|
116
|
+
agent: fullTurn.agentText || fullTurn.agent,
|
|
117
|
+
timestamp: fullTurn.timestamp,
|
|
118
|
+
actions: fullTurn.actions,
|
|
119
|
+
}
|
|
120
|
+
: null,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
loadedTurns.push({
|
|
125
|
+
...ref,
|
|
126
|
+
content: null,
|
|
127
|
+
refined: null,
|
|
128
|
+
error: err instanceof Error ? err.message : String(err),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
result.turns = loadedTurns;
|
|
133
|
+
}
|
|
134
|
+
return toolResult(result);
|
|
135
|
+
}
|
|
136
|
+
function handleListThemes() {
|
|
137
|
+
return toolResult({ themes: themeManager.listThemes() });
|
|
138
|
+
}
|
|
139
|
+
async function handleRefineSessionTurns(args) {
|
|
140
|
+
let session = null;
|
|
141
|
+
const requestedSessionId = args.sessionId || args.session_id;
|
|
142
|
+
if (requestedSessionId) {
|
|
143
|
+
const allSessions = findAllWorkspaceSessions();
|
|
144
|
+
session = allSessions.find((s) => s.sessionId === requestedSessionId);
|
|
145
|
+
if (!session) {
|
|
146
|
+
return toolResult({ success: false, error: 'Session not found' }, true);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (!session) {
|
|
150
|
+
const { getCurrentSessionWirePath } = await import('../context/wire-context.js');
|
|
151
|
+
session = getCurrentSessionWirePath();
|
|
152
|
+
}
|
|
153
|
+
if (!session) {
|
|
154
|
+
return toolResult({ success: false, error: 'No session wire found' }, true);
|
|
155
|
+
}
|
|
156
|
+
const { turns } = await parseWireFile(session.wire);
|
|
157
|
+
let targetTurnIds = null;
|
|
158
|
+
if (Array.isArray(args.turnIds) && args.turnIds.length > 0) {
|
|
159
|
+
targetTurnIds = new Set(args.turnIds.map((id) => parseInt(String(id), 10)));
|
|
160
|
+
}
|
|
161
|
+
let targetTurns = turns;
|
|
162
|
+
if (targetTurnIds) {
|
|
163
|
+
targetTurns = turns.filter((t) => targetTurnIds.has(parseInt(t.turnId, 10)));
|
|
164
|
+
}
|
|
165
|
+
const limit = typeof args.limit === 'number' ? Math.max(0, Math.floor(args.limit)) : null;
|
|
166
|
+
if (limit !== null && targetTurns.length > limit) {
|
|
167
|
+
targetTurns = limit === 0 ? [] : targetTurns.slice(-limit);
|
|
168
|
+
}
|
|
169
|
+
const refinedTurns = targetTurns.map((turn) => refinedManager.refineTurn({ ...turn, timestamp: turn.timestamp || undefined }, session.sessionId));
|
|
170
|
+
await refinedManager.saveRefinedTurns(session.sessionId, refinedTurns);
|
|
171
|
+
return toolResult({
|
|
172
|
+
success: true,
|
|
173
|
+
sessionId: session.sessionId,
|
|
174
|
+
refinedCount: refinedTurns.length,
|
|
175
|
+
outputPath: refinedManager.getDbPath(),
|
|
176
|
+
sample: refinedTurns.slice(0, 2),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
handleTagTheme,
|
|
181
|
+
handleTraceTheme,
|
|
182
|
+
handleListThemes,
|
|
183
|
+
handleRefineSessionTurns,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=theme-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-tools.js","sourceRoot":"","sources":["../../src/tools/theme-tools.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared context and argument types used across tools.
|
|
3
|
+
*/
|
|
4
|
+
import type { IndexDao } from './dao/index.js';
|
|
5
|
+
import type { MemoryStore } from './dao/memory-store.js';
|
|
6
|
+
import type { ThemeManager } from './theme-manager.js';
|
|
7
|
+
import type { RefinedManager } from './refined-manager.js';
|
|
8
|
+
export interface Ctx {
|
|
9
|
+
cwd: string;
|
|
10
|
+
workspaceId: string;
|
|
11
|
+
storeRoot: string;
|
|
12
|
+
indexDao: IndexDao;
|
|
13
|
+
memoryStore: MemoryStore;
|
|
14
|
+
themeManager: ThemeManager;
|
|
15
|
+
refinedManager: RefinedManager;
|
|
16
|
+
}
|
|
17
|
+
export interface RememberArgs {
|
|
18
|
+
key: string;
|
|
19
|
+
content?: string;
|
|
20
|
+
folder?: string;
|
|
21
|
+
tags?: unknown[];
|
|
22
|
+
themes?: unknown[];
|
|
23
|
+
}
|
|
24
|
+
export interface RecallArgs {
|
|
25
|
+
key: string;
|
|
26
|
+
folder?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface RecallRecentArgs {
|
|
29
|
+
n?: number;
|
|
30
|
+
folder?: string;
|
|
31
|
+
tag?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface SearchArgs {
|
|
34
|
+
query: string;
|
|
35
|
+
folder?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface DeleteArgs {
|
|
38
|
+
key: string;
|
|
39
|
+
folder?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface MoveArgs {
|
|
42
|
+
key: string;
|
|
43
|
+
folder?: string;
|
|
44
|
+
toFolder: string;
|
|
45
|
+
newKey?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface LoadWorkspaceContextArgs {
|
|
48
|
+
detailed_rounds?: number;
|
|
49
|
+
summary_rounds?: number;
|
|
50
|
+
}
|
|
51
|
+
export interface LoadMoreContextArgs {
|
|
52
|
+
before_turn_id?: number;
|
|
53
|
+
limit?: number;
|
|
54
|
+
}
|
|
55
|
+
export interface SearchContextArgs {
|
|
56
|
+
query: string;
|
|
57
|
+
date_from?: string;
|
|
58
|
+
date_to?: string;
|
|
59
|
+
limit?: number;
|
|
60
|
+
cluster_gap_seconds?: number;
|
|
61
|
+
max_cluster_size?: number;
|
|
62
|
+
}
|
|
63
|
+
export interface ListSearchViewsArgs {
|
|
64
|
+
limit?: number;
|
|
65
|
+
}
|
|
66
|
+
export interface LoadTurnContextArgs {
|
|
67
|
+
references: unknown[];
|
|
68
|
+
}
|
|
69
|
+
export interface TagThemeArgs {
|
|
70
|
+
theme: string;
|
|
71
|
+
sessionId?: string;
|
|
72
|
+
turnId?: number;
|
|
73
|
+
memoryKey?: string;
|
|
74
|
+
memoryFolder?: string;
|
|
75
|
+
memoryTitle?: string;
|
|
76
|
+
}
|
|
77
|
+
export interface TraceThemeArgs {
|
|
78
|
+
theme: string;
|
|
79
|
+
includeTurnContent?: boolean;
|
|
80
|
+
}
|
|
81
|
+
export interface RefineSessionTurnsArgs {
|
|
82
|
+
sessionId?: string;
|
|
83
|
+
session_id?: string;
|
|
84
|
+
turnIds?: unknown[];
|
|
85
|
+
limit?: number;
|
|
86
|
+
}
|
|
87
|
+
export interface OrganizeArgs {
|
|
88
|
+
content?: string;
|
|
89
|
+
sources?: unknown[];
|
|
90
|
+
}
|
|
91
|
+
export interface SyncWorkspaceIndexArgs {
|
|
92
|
+
folderComments?: Record<string, string>;
|
|
93
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal YAML frontmatter parser/stringifier for Markdown memory files.
|
|
3
|
+
*/
|
|
4
|
+
export type Frontmatter = Record<string, string | string[]>;
|
|
5
|
+
export interface ParsedFrontmatter {
|
|
6
|
+
frontmatter: Frontmatter;
|
|
7
|
+
body: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function parseFrontmatter(fileContent: string): ParsedFrontmatter | null;
|
|
10
|
+
export declare function stringifyFrontmatter(frontmatter: Frontmatter): string;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal YAML frontmatter parser/stringifier for Markdown memory files.
|
|
3
|
+
*/
|
|
4
|
+
function stripQuotes(value) {
|
|
5
|
+
return value.replace(/^['"]|['"]$/g, '');
|
|
6
|
+
}
|
|
7
|
+
export function parseFrontmatter(fileContent) {
|
|
8
|
+
const normalized = fileContent.replace(/\r\n/g, '\n');
|
|
9
|
+
if (!normalized.startsWith('---\n'))
|
|
10
|
+
return null;
|
|
11
|
+
const end = normalized.indexOf('\n---', 4);
|
|
12
|
+
if (end === -1)
|
|
13
|
+
return null;
|
|
14
|
+
const fmText = normalized.slice(4, end);
|
|
15
|
+
const body = normalized.slice(end + 4).replace(/^\n+/, '');
|
|
16
|
+
const frontmatter = {};
|
|
17
|
+
let currentKey = null;
|
|
18
|
+
for (const rawLine of fmText.split('\n')) {
|
|
19
|
+
const line = rawLine.trimEnd();
|
|
20
|
+
if (!line.trim())
|
|
21
|
+
continue;
|
|
22
|
+
const listMatch = line.match(/^(\s+)-\s*(.*)$/);
|
|
23
|
+
if (listMatch && currentKey) {
|
|
24
|
+
const current = frontmatter[currentKey];
|
|
25
|
+
if (Array.isArray(current)) {
|
|
26
|
+
current.push(stripQuotes(listMatch[2].trim()));
|
|
27
|
+
}
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const kvMatch = line.match(/^([^:]+):\s*(.*)$/);
|
|
31
|
+
if (kvMatch) {
|
|
32
|
+
currentKey = kvMatch[1].trim();
|
|
33
|
+
const value = kvMatch[2].trim();
|
|
34
|
+
if (value === '') {
|
|
35
|
+
frontmatter[currentKey] = [];
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
frontmatter[currentKey] = stripQuotes(value);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return { frontmatter, body };
|
|
43
|
+
}
|
|
44
|
+
export function stringifyFrontmatter(frontmatter) {
|
|
45
|
+
let out = '---\n';
|
|
46
|
+
for (const [k, v] of Object.entries(frontmatter)) {
|
|
47
|
+
if (Array.isArray(v)) {
|
|
48
|
+
out += `${k}:\n`;
|
|
49
|
+
for (const item of v) {
|
|
50
|
+
out += ` - ${item}\n`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const safe = String(v).replace(/'/g, "''");
|
|
55
|
+
out += `${k}: '${safe}'\n`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
out += '---\n\n';
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A simple per-instance promise mutex.
|
|
3
|
+
*
|
|
4
|
+
* Operations queued through `runExclusive` are serialized: each waits for the
|
|
5
|
+
* previous one to complete before starting. This prevents read-modify-write
|
|
6
|
+
* races on shared files such as index.json, theme JSON, and refined JSONL.
|
|
7
|
+
*/
|
|
8
|
+
export declare class Mutex {
|
|
9
|
+
private queue;
|
|
10
|
+
runExclusive<T>(fn: () => Promise<T> | T): Promise<T>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A simple per-instance promise mutex.
|
|
3
|
+
*
|
|
4
|
+
* Operations queued through `runExclusive` are serialized: each waits for the
|
|
5
|
+
* previous one to complete before starting. This prevents read-modify-write
|
|
6
|
+
* races on shared files such as index.json, theme JSON, and refined JSONL.
|
|
7
|
+
*/
|
|
8
|
+
export class Mutex {
|
|
9
|
+
queue = Promise.resolve();
|
|
10
|
+
runExclusive(fn) {
|
|
11
|
+
const task = this.queue.then(() => fn(), () => fn());
|
|
12
|
+
// Keep a non-rejecting reference so one failed operation does not block the queue.
|
|
13
|
+
this.queue = task.then(() => { }, () => { });
|
|
14
|
+
return task;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=mutex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutex.js","sourceRoot":"","sources":["../../src/utils/mutex.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,OAAO,KAAK;IACR,KAAK,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEpD,YAAY,CAAI,EAAwB;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAC1B,GAAG,EAAE,CAAC,EAAE,EAAE,EACV,GAAG,EAAE,CAAC,EAAE,EAAE,CACX,CAAC;QACF,mFAAmF;QACnF,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CACpB,GAAG,EAAE,GAAE,CAAC,EACR,GAAG,EAAE,GAAE,CAAC,CACT,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path and workspace hashing helpers.
|
|
3
|
+
*/
|
|
4
|
+
export declare const homedir: string;
|
|
5
|
+
export declare function computeWorkspaceHash(cwd: string): string;
|
|
6
|
+
export declare function computeWorkspaceId(cwd: string): string;
|
|
7
|
+
export declare function getProjectRoot(): string;
|
|
8
|
+
export declare function relativeStorePath(storeRoot: string, filePath: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve path segments under a base directory and verify the result does not
|
|
11
|
+
* escape the base directory (path traversal protection).
|
|
12
|
+
*/
|
|
13
|
+
export declare function safeResolve(base: string, ...segments: string[]): string;
|
|
14
|
+
export declare function isPathInside(parent: string, child: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Atomically write a file by writing to a temp file and renaming it into place.
|
|
17
|
+
* The target directory is created if it does not exist.
|
|
18
|
+
*/
|
|
19
|
+
export declare function atomicWriteFile(filePath: string, content: string, encoding?: BufferEncoding): void;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path and workspace hashing helpers.
|
|
3
|
+
*/
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import crypto from 'crypto';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
export const homedir = os.homedir();
|
|
11
|
+
export function computeWorkspaceHash(cwd) {
|
|
12
|
+
const normalized = String(cwd).replace(/\\/g, '/');
|
|
13
|
+
return crypto.createHash('sha256').update(normalized).digest('hex').slice(0, 12);
|
|
14
|
+
}
|
|
15
|
+
export function computeWorkspaceId(cwd) {
|
|
16
|
+
if (!cwd || cwd === homedir) {
|
|
17
|
+
return 'workspace-default';
|
|
18
|
+
}
|
|
19
|
+
return `workspace-${computeWorkspaceHash(cwd)}`;
|
|
20
|
+
}
|
|
21
|
+
export function getProjectRoot() {
|
|
22
|
+
return path.resolve(__dirname, '..', '..');
|
|
23
|
+
}
|
|
24
|
+
export function relativeStorePath(storeRoot, filePath) {
|
|
25
|
+
return path.relative(storeRoot, filePath).replace(/\\/g, '/');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve path segments under a base directory and verify the result does not
|
|
29
|
+
* escape the base directory (path traversal protection).
|
|
30
|
+
*/
|
|
31
|
+
export function safeResolve(base, ...segments) {
|
|
32
|
+
const resolvedBase = path.resolve(base);
|
|
33
|
+
const resolved = path.resolve(resolvedBase, ...segments);
|
|
34
|
+
const relative = path.relative(resolvedBase, resolved);
|
|
35
|
+
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
36
|
+
throw new Error(`Path escapes base directory: ${segments.join('/')}`);
|
|
37
|
+
}
|
|
38
|
+
return resolved;
|
|
39
|
+
}
|
|
40
|
+
export function isPathInside(parent, child) {
|
|
41
|
+
const relative = path.relative(path.resolve(parent), path.resolve(child));
|
|
42
|
+
return !relative.startsWith('..') && !path.isAbsolute(relative);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Atomically write a file by writing to a temp file and renaming it into place.
|
|
46
|
+
* The target directory is created if it does not exist.
|
|
47
|
+
*/
|
|
48
|
+
export function atomicWriteFile(filePath, content, encoding = 'utf8') {
|
|
49
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
50
|
+
const tmpPath = filePath + '.tmp';
|
|
51
|
+
fs.writeFileSync(tmpPath, content, encoding);
|
|
52
|
+
fs.renameSync(tmpPath, filePath);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input sanitization helpers.
|
|
3
|
+
*/
|
|
4
|
+
export declare function sanitizeKey(key: unknown): string;
|
|
5
|
+
/**
|
|
6
|
+
* Sanitize and validate a folder path.
|
|
7
|
+
*
|
|
8
|
+
* Rules:
|
|
9
|
+
* - Backslashes are normalized to forward slashes.
|
|
10
|
+
* - Absolute paths, parent traversal, or characters outside [a-zA-Z0-9_\-/] are rejected.
|
|
11
|
+
* - Leading/trailing slashes are trimmed.
|
|
12
|
+
* - An empty or missing value defaults to 'memory'.
|
|
13
|
+
*/
|
|
14
|
+
export declare function sanitizeFolder(folder: unknown): string | null;
|
|
15
|
+
export declare function toTitle(key: unknown): string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input sanitization helpers.
|
|
3
|
+
*/
|
|
4
|
+
export function sanitizeKey(key) {
|
|
5
|
+
return (String(key)
|
|
6
|
+
.trim()
|
|
7
|
+
.replace(/[\\/:*?"<>|]/g, '_')
|
|
8
|
+
.replace(/\s+/g, '_')
|
|
9
|
+
.slice(0, 120) || 'untitled');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Sanitize and validate a folder path.
|
|
13
|
+
*
|
|
14
|
+
* Rules:
|
|
15
|
+
* - Backslashes are normalized to forward slashes.
|
|
16
|
+
* - Absolute paths, parent traversal, or characters outside [a-zA-Z0-9_\-/] are rejected.
|
|
17
|
+
* - Leading/trailing slashes are trimmed.
|
|
18
|
+
* - An empty or missing value defaults to 'memory'.
|
|
19
|
+
*/
|
|
20
|
+
export function sanitizeFolder(folder) {
|
|
21
|
+
let normalized = String(folder).replace(/\\/g, '/');
|
|
22
|
+
if (normalized.startsWith('/'))
|
|
23
|
+
return null;
|
|
24
|
+
if (normalized.includes('..'))
|
|
25
|
+
return null;
|
|
26
|
+
if (/[^a-zA-Z0-9_\-/]/.test(normalized))
|
|
27
|
+
return null;
|
|
28
|
+
normalized = normalized.replace(/^\/+|\/+$/g, '');
|
|
29
|
+
return normalized || 'memory';
|
|
30
|
+
}
|
|
31
|
+
export function toTitle(key) {
|
|
32
|
+
return String(key)
|
|
33
|
+
.replace(/[-_]+/g, ' ')
|
|
34
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
35
|
+
.split(' ')
|
|
36
|
+
.filter(Boolean)
|
|
37
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
|
|
38
|
+
.join(' ');
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,OAAO,CACL,MAAM,CAAC,GAAG,CAAC;SACR,IAAI,EAAE;SACN,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC;SAC7B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,UAAU,CAC/B,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,IAAI,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACpD,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACrD,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAClD,OAAO,UAAU,IAAI,QAAQ,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAY;IAClC,OAAO,MAAM,CAAC,GAAG,CAAC;SACf,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAChE,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the MCP server runtime version.
|
|
3
|
+
*
|
|
4
|
+
* This value is kept in sync with `package.json` by `scripts/sync-version.mjs`
|
|
5
|
+
* during the build/publish flow. The runtime version is reported to MCP clients
|
|
6
|
+
* during protocol initialization and must match the repository (package)
|
|
7
|
+
* version unless explicitly noted otherwise.
|
|
8
|
+
*/
|
|
9
|
+
export declare const VERSION = "0.1.0";
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the MCP server runtime version.
|
|
3
|
+
*
|
|
4
|
+
* This value is kept in sync with `package.json` by `scripts/sync-version.mjs`
|
|
5
|
+
* during the build/publish flow. The runtime version is reported to MCP clients
|
|
6
|
+
* during protocol initialization and must match the repository (package)
|
|
7
|
+
* version unless explicitly noted otherwise.
|
|
8
|
+
*/
|
|
9
|
+
export const VERSION = '0.1.0';
|
|
10
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|