@tekmidian/pai 0.5.7 → 0.6.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/ARCHITECTURE.md +72 -1
- package/README.md +87 -1
- package/dist/{auto-route-BG6I_4B1.mjs → auto-route-C-DrW6BL.mjs} +3 -3
- package/dist/{auto-route-BG6I_4B1.mjs.map → auto-route-C-DrW6BL.mjs.map} +1 -1
- package/dist/cli/index.mjs +1482 -1628
- package/dist/cli/index.mjs.map +1 -1
- package/dist/clusters-JIDQW65f.mjs +201 -0
- package/dist/clusters-JIDQW65f.mjs.map +1 -0
- package/dist/{config-Cf92lGX_.mjs → config-BuhHWyOK.mjs} +21 -6
- package/dist/config-BuhHWyOK.mjs.map +1 -0
- package/dist/daemon/index.mjs +11 -8
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/{daemon-2ND5WO2j.mjs → daemon-D3hYb5_C.mjs} +669 -218
- package/dist/daemon-D3hYb5_C.mjs.map +1 -0
- package/dist/daemon-mcp/index.mjs +4597 -4
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/db-DdUperSl.mjs +110 -0
- package/dist/db-DdUperSl.mjs.map +1 -0
- package/dist/{detect-BU3Nx_2L.mjs → detect-CdaA48EI.mjs} +1 -1
- package/dist/{detect-BU3Nx_2L.mjs.map → detect-CdaA48EI.mjs.map} +1 -1
- package/dist/{detector-Bp-2SM3x.mjs → detector-jGBuYQJM.mjs} +2 -2
- package/dist/{detector-Bp-2SM3x.mjs.map → detector-jGBuYQJM.mjs.map} +1 -1
- package/dist/{factory-Bzcy70G9.mjs → factory-Ygqe_bVZ.mjs} +7 -5
- package/dist/{factory-Bzcy70G9.mjs.map → factory-Ygqe_bVZ.mjs.map} +1 -1
- package/dist/helpers-BEST-4Gx.mjs +420 -0
- package/dist/helpers-BEST-4Gx.mjs.map +1 -0
- package/dist/hooks/capture-all-events.mjs +2 -2
- package/dist/hooks/capture-all-events.mjs.map +3 -3
- package/dist/hooks/capture-session-summary.mjs +38 -0
- package/dist/hooks/capture-session-summary.mjs.map +3 -3
- package/dist/hooks/cleanup-session-files.mjs +6 -12
- package/dist/hooks/cleanup-session-files.mjs.map +4 -4
- package/dist/hooks/context-compression-hook.mjs +93 -104
- package/dist/hooks/context-compression-hook.mjs.map +4 -4
- package/dist/hooks/initialize-session.mjs +14 -11
- package/dist/hooks/initialize-session.mjs.map +4 -4
- package/dist/hooks/inject-observations.mjs +220 -0
- package/dist/hooks/inject-observations.mjs.map +7 -0
- package/dist/hooks/load-core-context.mjs +2 -2
- package/dist/hooks/load-core-context.mjs.map +3 -3
- package/dist/hooks/load-project-context.mjs +90 -91
- package/dist/hooks/load-project-context.mjs.map +4 -4
- package/dist/hooks/observe.mjs +354 -0
- package/dist/hooks/observe.mjs.map +7 -0
- package/dist/hooks/stop-hook.mjs +94 -107
- package/dist/hooks/stop-hook.mjs.map +4 -4
- package/dist/hooks/sync-todo-to-md.mjs +31 -33
- package/dist/hooks/sync-todo-to-md.mjs.map +4 -4
- package/dist/index.d.mts +30 -7
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +5 -8
- package/dist/indexer-D53l5d1U.mjs +1 -0
- package/dist/{indexer-backend-CIMXedqk.mjs → indexer-backend-jcJFsmB4.mjs} +37 -127
- package/dist/indexer-backend-jcJFsmB4.mjs.map +1 -0
- package/dist/{ipc-client-Bjg_a1dc.mjs → ipc-client-CoyUHPod.mjs} +2 -7
- package/dist/{ipc-client-Bjg_a1dc.mjs.map → ipc-client-CoyUHPod.mjs.map} +1 -1
- package/dist/latent-ideas-bTJo6Omd.mjs +191 -0
- package/dist/latent-ideas-bTJo6Omd.mjs.map +1 -0
- package/dist/neighborhood-BYYbEkUJ.mjs +135 -0
- package/dist/neighborhood-BYYbEkUJ.mjs.map +1 -0
- package/dist/note-context-BK24bX8Y.mjs +126 -0
- package/dist/note-context-BK24bX8Y.mjs.map +1 -0
- package/dist/postgres-CKf-EDtS.mjs +846 -0
- package/dist/postgres-CKf-EDtS.mjs.map +1 -0
- package/dist/{reranker-D7bRAHi6.mjs → reranker-CMNZcfVx.mjs} +1 -1
- package/dist/{reranker-D7bRAHi6.mjs.map → reranker-CMNZcfVx.mjs.map} +1 -1
- package/dist/{search-_oHfguA5.mjs → search-DC1qhkKn.mjs} +2 -58
- package/dist/search-DC1qhkKn.mjs.map +1 -0
- package/dist/{sqlite-WWBq7_2C.mjs → sqlite-l-s9xPjY.mjs} +160 -3
- package/dist/sqlite-l-s9xPjY.mjs.map +1 -0
- package/dist/state-C6_vqz7w.mjs +102 -0
- package/dist/state-C6_vqz7w.mjs.map +1 -0
- package/dist/stop-words-BaMEGVeY.mjs +326 -0
- package/dist/stop-words-BaMEGVeY.mjs.map +1 -0
- package/dist/{indexer-CMPOiY1r.mjs → sync-BOsnEj2-.mjs} +14 -216
- package/dist/sync-BOsnEj2-.mjs.map +1 -0
- package/dist/themes-BvYF0W8T.mjs +148 -0
- package/dist/themes-BvYF0W8T.mjs.map +1 -0
- package/dist/{tools-DV_lsiCc.mjs → tools-DcaJlYDN.mjs} +162 -273
- package/dist/tools-DcaJlYDN.mjs.map +1 -0
- package/dist/trace-CRx9lPuc.mjs +137 -0
- package/dist/trace-CRx9lPuc.mjs.map +1 -0
- package/dist/{vault-indexer-k-kUlaZ-.mjs → vault-indexer-Bi2cRmn7.mjs} +134 -132
- package/dist/vault-indexer-Bi2cRmn7.mjs.map +1 -0
- package/dist/zettelkasten-cdajbnPr.mjs +708 -0
- package/dist/zettelkasten-cdajbnPr.mjs.map +1 -0
- package/package.json +1 -2
- package/src/hooks/ts/lib/project-utils/index.ts +50 -0
- package/src/hooks/ts/lib/project-utils/notify.ts +75 -0
- package/src/hooks/ts/lib/project-utils/paths.ts +218 -0
- package/src/hooks/ts/lib/project-utils/session-notes.ts +363 -0
- package/src/hooks/ts/lib/project-utils/todo.ts +178 -0
- package/src/hooks/ts/lib/project-utils/tokens.ts +39 -0
- package/src/hooks/ts/lib/project-utils.ts +40 -1018
- package/src/hooks/ts/post-tool-use/observe.ts +327 -0
- package/src/hooks/ts/session-end/capture-session-summary.ts +41 -0
- package/src/hooks/ts/session-start/inject-observations.ts +254 -0
- package/dist/chunker-CbnBe0s0.mjs +0 -191
- package/dist/chunker-CbnBe0s0.mjs.map +0 -1
- package/dist/config-Cf92lGX_.mjs.map +0 -1
- package/dist/daemon-2ND5WO2j.mjs.map +0 -1
- package/dist/db-Dp8VXIMR.mjs +0 -212
- package/dist/db-Dp8VXIMR.mjs.map +0 -1
- package/dist/indexer-CMPOiY1r.mjs.map +0 -1
- package/dist/indexer-backend-CIMXedqk.mjs.map +0 -1
- package/dist/mcp/index.d.mts +0 -1
- package/dist/mcp/index.mjs +0 -500
- package/dist/mcp/index.mjs.map +0 -1
- package/dist/postgres-FXrHDPcE.mjs +0 -358
- package/dist/postgres-FXrHDPcE.mjs.map +0 -1
- package/dist/schemas-BFIgGntb.mjs +0 -3405
- package/dist/schemas-BFIgGntb.mjs.map +0 -1
- package/dist/search-_oHfguA5.mjs.map +0 -1
- package/dist/sqlite-WWBq7_2C.mjs.map +0 -1
- package/dist/tools-DV_lsiCc.mjs.map +0 -1
- package/dist/vault-indexer-k-kUlaZ-.mjs.map +0 -1
- package/dist/zettelkasten-e-a4rW_6.mjs +0 -901
- package/dist/zettelkasten-e-a4rW_6.mjs.map +0 -1
- package/templates/README.md +0 -181
- package/templates/skills/CORE/Aesthetic.md +0 -333
- package/templates/skills/CORE/CONSTITUTION.md +0 -1502
- package/templates/skills/CORE/HistorySystem.md +0 -427
- package/templates/skills/CORE/HookSystem.md +0 -1082
- package/templates/skills/CORE/Prompting.md +0 -509
- package/templates/skills/CORE/ProsodyAgentTemplate.md +0 -53
- package/templates/skills/CORE/ProsodyGuide.md +0 -416
- package/templates/skills/CORE/SKILL.md +0 -741
- package/templates/skills/CORE/SkillSystem.md +0 -213
- package/templates/skills/CORE/TerminalTabs.md +0 -119
- package/templates/skills/CORE/VOICE.md +0 -106
- package/templates/skills/createskill-skill.template.md +0 -78
- package/templates/skills/history-system.template.md +0 -371
- package/templates/skills/hook-system.template.md +0 -913
- package/templates/skills/sessions-skill.template.md +0 -102
- package/templates/skills/skill-system.template.md +0 -214
- package/templates/skills/terminal-tabs.template.md +0 -120
- package/templates/templates.md +0 -20
|
@@ -1,42 +1,13 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-95iHPtFO.mjs";
|
|
2
|
-
import { i as searchMemoryHybrid, n as populateSlugs } from "./search-
|
|
3
|
-
import { r as formatDetectionJson, t as detectProject } from "./detect-
|
|
2
|
+
import { i as searchMemoryHybrid, n as populateSlugs } from "./search-DC1qhkKn.mjs";
|
|
3
|
+
import { r as formatDetectionJson, t as detectProject } from "./detect-CdaA48EI.mjs";
|
|
4
4
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
5
5
|
import { isAbsolute, join, resolve } from "node:path";
|
|
6
6
|
|
|
7
|
-
//#region src/mcp/tools.ts
|
|
7
|
+
//#region src/mcp/tools/types.ts
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* Each function accepts pre-opened database handles and raw params, executes
|
|
12
|
-
* the tool logic, and returns an MCP-style content array.
|
|
13
|
-
*
|
|
14
|
-
* This module does NOT import indexAll() — indexing is handled by the daemon
|
|
15
|
-
* on its own schedule. The search hot path is pure DB read.
|
|
9
|
+
* Shared types and project-row helpers used across all MCP tool handler modules.
|
|
16
10
|
*/
|
|
17
|
-
var tools_exports = /* @__PURE__ */ __exportAll({
|
|
18
|
-
detectProjectFromPath: () => detectProjectFromPath,
|
|
19
|
-
formatProject: () => formatProject,
|
|
20
|
-
lookupProjectId: () => lookupProjectId,
|
|
21
|
-
toolMemoryGet: () => toolMemoryGet,
|
|
22
|
-
toolMemorySearch: () => toolMemorySearch,
|
|
23
|
-
toolNotificationConfig: () => toolNotificationConfig,
|
|
24
|
-
toolProjectDetect: () => toolProjectDetect,
|
|
25
|
-
toolProjectHealth: () => toolProjectHealth,
|
|
26
|
-
toolProjectInfo: () => toolProjectInfo,
|
|
27
|
-
toolProjectList: () => toolProjectList,
|
|
28
|
-
toolProjectTodo: () => toolProjectTodo,
|
|
29
|
-
toolRegistrySearch: () => toolRegistrySearch,
|
|
30
|
-
toolSessionList: () => toolSessionList,
|
|
31
|
-
toolSessionRoute: () => toolSessionRoute,
|
|
32
|
-
toolTopicDetect: () => toolTopicDetect,
|
|
33
|
-
toolZettelConverse: () => toolZettelConverse,
|
|
34
|
-
toolZettelExplore: () => toolZettelExplore,
|
|
35
|
-
toolZettelHealth: () => toolZettelHealth,
|
|
36
|
-
toolZettelSuggest: () => toolZettelSuggest,
|
|
37
|
-
toolZettelSurprise: () => toolZettelSurprise,
|
|
38
|
-
toolZettelThemes: () => toolZettelThemes
|
|
39
|
-
});
|
|
40
11
|
function lookupProjectId(registryDb, slug) {
|
|
41
12
|
const bySlug = registryDb.prepare("SELECT id FROM projects WHERE slug = ?").get(slug);
|
|
42
13
|
if (bySlug) return bySlug.id;
|
|
@@ -75,6 +46,12 @@ function formatProject(registryDb, project) {
|
|
|
75
46
|
if (project.archived_at) lines.push(`archived_at: ${new Date(project.archived_at).toISOString().slice(0, 10)}`);
|
|
76
47
|
return lines.join("\n");
|
|
77
48
|
}
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/mcp/tools/memory.ts
|
|
52
|
+
/**
|
|
53
|
+
* MCP tool handlers: memory_search, memory_get
|
|
54
|
+
*/
|
|
78
55
|
async function toolMemorySearch(registryDb, federation, params, searchDefaults) {
|
|
79
56
|
try {
|
|
80
57
|
const projectIds = params.project ? (() => {
|
|
@@ -114,7 +91,7 @@ async function toolMemorySearch(registryDb, federation, params, searchDefaults)
|
|
|
114
91
|
}
|
|
115
92
|
} else results = await federation.searchKeyword(params.query, searchOpts);
|
|
116
93
|
else {
|
|
117
|
-
const { searchMemory, searchMemorySemantic } = await import("./search-
|
|
94
|
+
const { searchMemory, searchMemorySemantic } = await import("./search-DC1qhkKn.mjs").then((n) => n.o);
|
|
118
95
|
if (mode === "keyword") results = searchMemory(federation, params.query, searchOpts);
|
|
119
96
|
else if (mode === "semantic" || mode === "hybrid") {
|
|
120
97
|
const { generateEmbedding } = await import("./embeddings-DGRAPAYb.mjs").then((n) => n.i);
|
|
@@ -125,12 +102,12 @@ async function toolMemorySearch(registryDb, federation, params, searchDefaults)
|
|
|
125
102
|
}
|
|
126
103
|
const shouldRerank = params.rerank ?? searchDefaults?.rerank ?? true;
|
|
127
104
|
if (shouldRerank && results.length > 0) {
|
|
128
|
-
const { rerankResults } = await import("./reranker-
|
|
105
|
+
const { rerankResults } = await import("./reranker-CMNZcfVx.mjs").then((n) => n.r);
|
|
129
106
|
results = await rerankResults(params.query, results, { topK: searchOpts.maxResults ?? 5 });
|
|
130
107
|
}
|
|
131
108
|
const recencyDays = params.recencyBoost ?? searchDefaults?.recencyBoostDays ?? 0;
|
|
132
109
|
if (recencyDays > 0 && results.length > 0) {
|
|
133
|
-
const { applyRecencyBoost } = await import("./search-
|
|
110
|
+
const { applyRecencyBoost } = await import("./search-DC1qhkKn.mjs").then((n) => n.o);
|
|
134
111
|
results = applyRecencyBoost(results, recencyDays);
|
|
135
112
|
}
|
|
136
113
|
const withSlugs = populateSlugs(results, registryDb);
|
|
@@ -224,6 +201,48 @@ function toolMemoryGet(registryDb, params) {
|
|
|
224
201
|
};
|
|
225
202
|
}
|
|
226
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Combine keyword + semantic results using min-max normalized scoring.
|
|
206
|
+
* Mirrors the logic in searchMemoryHybrid() from memory/search.ts,
|
|
207
|
+
* but works on pre-computed result arrays so it works for any backend.
|
|
208
|
+
*/
|
|
209
|
+
function combineHybridResults(keywordResults, semanticResults, maxResults, keywordWeight = .5, semanticWeight = .5) {
|
|
210
|
+
if (keywordResults.length === 0 && semanticResults.length === 0) return [];
|
|
211
|
+
const keyFor = (r) => `${r.projectId}:${r.path}:${r.startLine}:${r.endLine}`;
|
|
212
|
+
function minMaxNormalize(items) {
|
|
213
|
+
if (items.length === 0) return /* @__PURE__ */ new Map();
|
|
214
|
+
const min = Math.min(...items.map((r) => r.score));
|
|
215
|
+
const range = Math.max(...items.map((r) => r.score)) - min;
|
|
216
|
+
const m = /* @__PURE__ */ new Map();
|
|
217
|
+
for (const r of items) m.set(keyFor(r), range === 0 ? 1 : (r.score - min) / range);
|
|
218
|
+
return m;
|
|
219
|
+
}
|
|
220
|
+
const kwNorm = minMaxNormalize(keywordResults);
|
|
221
|
+
const semNorm = minMaxNormalize(semanticResults);
|
|
222
|
+
const allKeys = new Set([...keywordResults.map(keyFor), ...semanticResults.map(keyFor)]);
|
|
223
|
+
const metaMap = /* @__PURE__ */ new Map();
|
|
224
|
+
for (const r of [...keywordResults, ...semanticResults]) metaMap.set(keyFor(r), r);
|
|
225
|
+
const combined = [];
|
|
226
|
+
for (const key of allKeys) {
|
|
227
|
+
const meta = metaMap.get(key);
|
|
228
|
+
const kwScore = kwNorm.get(key) ?? 0;
|
|
229
|
+
const semScore = semNorm.get(key) ?? 0;
|
|
230
|
+
const combinedScore = keywordWeight * kwScore + semanticWeight * semScore;
|
|
231
|
+
combined.push({
|
|
232
|
+
...meta,
|
|
233
|
+
score: combinedScore,
|
|
234
|
+
combinedScore
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return combined.sort((a, b) => b.score - a.score).slice(0, maxResults).map(({ combinedScore: _unused, ...r }) => r);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
//#endregion
|
|
241
|
+
//#region src/mcp/tools/projects.ts
|
|
242
|
+
/**
|
|
243
|
+
* MCP tool handlers: project_info, project_list, project_detect,
|
|
244
|
+
* project_health, project_todo
|
|
245
|
+
*/
|
|
227
246
|
function toolProjectInfo(registryDb, params) {
|
|
228
247
|
try {
|
|
229
248
|
let project = null;
|
|
@@ -291,77 +310,6 @@ function toolProjectList(registryDb, params) {
|
|
|
291
310
|
};
|
|
292
311
|
}
|
|
293
312
|
}
|
|
294
|
-
function toolSessionList(registryDb, params) {
|
|
295
|
-
try {
|
|
296
|
-
const projectId = lookupProjectId(registryDb, params.project);
|
|
297
|
-
if (projectId == null) return {
|
|
298
|
-
content: [{
|
|
299
|
-
type: "text",
|
|
300
|
-
text: `Project not found: ${params.project}`
|
|
301
|
-
}],
|
|
302
|
-
isError: true
|
|
303
|
-
};
|
|
304
|
-
const conditions = ["project_id = ?"];
|
|
305
|
-
const queryParams = [projectId];
|
|
306
|
-
if (params.status) {
|
|
307
|
-
conditions.push("status = ?");
|
|
308
|
-
queryParams.push(params.status);
|
|
309
|
-
}
|
|
310
|
-
const limit = params.limit ?? 10;
|
|
311
|
-
queryParams.push(limit);
|
|
312
|
-
const sessions = registryDb.prepare(`SELECT number, date, title, filename, status
|
|
313
|
-
FROM sessions
|
|
314
|
-
WHERE ${conditions.join(" AND ")}
|
|
315
|
-
ORDER BY number DESC
|
|
316
|
-
LIMIT ?`).all(...queryParams);
|
|
317
|
-
if (sessions.length === 0) return { content: [{
|
|
318
|
-
type: "text",
|
|
319
|
-
text: `No sessions found for project: ${params.project}`
|
|
320
|
-
}] };
|
|
321
|
-
const lines = sessions.map((s) => `#${String(s.number).padStart(4, "0")} ${s.date} [${s.status}] ${s.title}\n file: Notes/${s.filename}`);
|
|
322
|
-
return { content: [{
|
|
323
|
-
type: "text",
|
|
324
|
-
text: `${sessions.length} session(s) for ${params.project}:\n\n${lines.join("\n\n")}`
|
|
325
|
-
}] };
|
|
326
|
-
} catch (e) {
|
|
327
|
-
return {
|
|
328
|
-
content: [{
|
|
329
|
-
type: "text",
|
|
330
|
-
text: `session_list error: ${String(e)}`
|
|
331
|
-
}],
|
|
332
|
-
isError: true
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
function toolRegistrySearch(registryDb, params) {
|
|
337
|
-
try {
|
|
338
|
-
const q = `%${params.query}%`;
|
|
339
|
-
const projects = registryDb.prepare(`SELECT id, slug, display_name, root_path, type, status, updated_at
|
|
340
|
-
FROM projects
|
|
341
|
-
WHERE slug LIKE ?
|
|
342
|
-
OR display_name LIKE ?
|
|
343
|
-
OR root_path LIKE ?
|
|
344
|
-
ORDER BY updated_at DESC
|
|
345
|
-
LIMIT 20`).all(q, q, q);
|
|
346
|
-
if (projects.length === 0) return { content: [{
|
|
347
|
-
type: "text",
|
|
348
|
-
text: `No projects found matching: "${params.query}"`
|
|
349
|
-
}] };
|
|
350
|
-
const lines = projects.map((p) => `${p.slug} [${p.status}] ${p.root_path}`);
|
|
351
|
-
return { content: [{
|
|
352
|
-
type: "text",
|
|
353
|
-
text: `${projects.length} match(es) for "${params.query}":\n\n${lines.join("\n")}`
|
|
354
|
-
}] };
|
|
355
|
-
} catch (e) {
|
|
356
|
-
return {
|
|
357
|
-
content: [{
|
|
358
|
-
type: "text",
|
|
359
|
-
text: `registry_search error: ${String(e)}`
|
|
360
|
-
}],
|
|
361
|
-
isError: true
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
313
|
function toolProjectDetect(registryDb, params) {
|
|
366
314
|
try {
|
|
367
315
|
const detection = detectProject(registryDb, params.cwd);
|
|
@@ -630,130 +578,46 @@ function toolProjectTodo(registryDb, params) {
|
|
|
630
578
|
};
|
|
631
579
|
}
|
|
632
580
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
async function toolNotificationConfig(params) {
|
|
581
|
+
|
|
582
|
+
//#endregion
|
|
583
|
+
//#region src/mcp/tools/sessions.ts
|
|
584
|
+
function toolSessionList(registryDb, params) {
|
|
638
585
|
try {
|
|
639
|
-
const
|
|
640
|
-
|
|
641
|
-
if (params.action === "get") {
|
|
642
|
-
const { config, activeChannels } = await client.getNotificationConfig();
|
|
643
|
-
return { content: [{
|
|
644
|
-
type: "text",
|
|
645
|
-
text: [
|
|
646
|
-
`mode: ${config.mode}`,
|
|
647
|
-
`active_channels: ${activeChannels.join(", ") || "(none)"}`,
|
|
648
|
-
"",
|
|
649
|
-
"channels:",
|
|
650
|
-
...Object.entries(config.channels).map(([ch, cfg]) => {
|
|
651
|
-
return ` ${ch}: ${cfg.enabled ? "enabled" : "disabled"}`;
|
|
652
|
-
}),
|
|
653
|
-
"",
|
|
654
|
-
"routing:",
|
|
655
|
-
...Object.entries(config.routing).map(([event, channels]) => ` ${event}: ${channels.join(", ") || "(none)"}`)
|
|
656
|
-
].join("\n")
|
|
657
|
-
}] };
|
|
658
|
-
}
|
|
659
|
-
if (params.action === "set") {
|
|
660
|
-
if (!params.mode && !params.channels && !params.routing) return {
|
|
661
|
-
content: [{
|
|
662
|
-
type: "text",
|
|
663
|
-
text: "notification_config set: provide at least one of mode, channels, or routing."
|
|
664
|
-
}],
|
|
665
|
-
isError: true
|
|
666
|
-
};
|
|
667
|
-
return { content: [{
|
|
668
|
-
type: "text",
|
|
669
|
-
text: `Notification config updated. Mode: ${(await client.setNotificationConfig({
|
|
670
|
-
mode: params.mode,
|
|
671
|
-
channels: params.channels,
|
|
672
|
-
routing: params.routing
|
|
673
|
-
})).config.mode}`
|
|
674
|
-
}] };
|
|
675
|
-
}
|
|
676
|
-
if (params.action === "send") {
|
|
677
|
-
if (!params.message) return {
|
|
678
|
-
content: [{
|
|
679
|
-
type: "text",
|
|
680
|
-
text: "notification_config send: message is required."
|
|
681
|
-
}],
|
|
682
|
-
isError: true
|
|
683
|
-
};
|
|
684
|
-
const result = await client.sendNotification({
|
|
685
|
-
event: params.event ?? "info",
|
|
686
|
-
message: params.message,
|
|
687
|
-
title: params.title
|
|
688
|
-
});
|
|
689
|
-
return { content: [{
|
|
690
|
-
type: "text",
|
|
691
|
-
text: [
|
|
692
|
-
`mode: ${result.mode}`,
|
|
693
|
-
`attempted: ${result.channelsAttempted.join(", ") || "(none)"}`,
|
|
694
|
-
`succeeded: ${result.channelsSucceeded.join(", ") || "(none)"}`,
|
|
695
|
-
...result.channelsFailed.length > 0 ? [`failed: ${result.channelsFailed.join(", ")}`] : []
|
|
696
|
-
].join("\n")
|
|
697
|
-
}] };
|
|
698
|
-
}
|
|
699
|
-
return {
|
|
700
|
-
content: [{
|
|
701
|
-
type: "text",
|
|
702
|
-
text: `Unknown action: ${String(params.action)}. Use "get", "set", or "send".`
|
|
703
|
-
}],
|
|
704
|
-
isError: true
|
|
705
|
-
};
|
|
706
|
-
} catch (e) {
|
|
707
|
-
return {
|
|
586
|
+
const projectId = lookupProjectId(registryDb, params.project);
|
|
587
|
+
if (projectId == null) return {
|
|
708
588
|
content: [{
|
|
709
589
|
type: "text",
|
|
710
|
-
text: `
|
|
590
|
+
text: `Project not found: ${params.project}`
|
|
711
591
|
}],
|
|
712
592
|
isError: true
|
|
713
593
|
};
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
* compares against the current project.
|
|
720
|
-
*
|
|
721
|
-
* Calls the daemon via IPC so it has access to the storage backend.
|
|
722
|
-
* Falls back gracefully if the daemon is not running.
|
|
723
|
-
*/
|
|
724
|
-
async function toolTopicDetect(params) {
|
|
725
|
-
try {
|
|
726
|
-
const { PaiClient } = await import("./ipc-client-Bjg_a1dc.mjs").then((n) => n.n);
|
|
727
|
-
const result = await new PaiClient().topicCheck({
|
|
728
|
-
context: params.context,
|
|
729
|
-
currentProject: params.current_project,
|
|
730
|
-
threshold: params.threshold
|
|
731
|
-
});
|
|
732
|
-
const lines = [
|
|
733
|
-
`shifted: ${result.shifted}`,
|
|
734
|
-
`current_project: ${result.currentProject ?? "(none)"}`,
|
|
735
|
-
`suggested_project: ${result.suggestedProject ?? "(none)"}`,
|
|
736
|
-
`confidence: ${result.confidence.toFixed(3)}`,
|
|
737
|
-
`chunks_scored: ${result.chunkCount}`
|
|
738
|
-
];
|
|
739
|
-
if (result.topProjects.length > 0) {
|
|
740
|
-
lines.push("");
|
|
741
|
-
lines.push("top_matches:");
|
|
742
|
-
for (const p of result.topProjects) lines.push(` ${p.slug}: ${(p.score * 100).toFixed(1)}%`);
|
|
743
|
-
}
|
|
744
|
-
if (result.shifted) {
|
|
745
|
-
lines.push("");
|
|
746
|
-
lines.push(`TOPIC SHIFT DETECTED: conversation appears to be about "${result.suggestedProject}" (confidence: ${(result.confidence * 100).toFixed(0)}%), not "${result.currentProject}".`);
|
|
594
|
+
const conditions = ["project_id = ?"];
|
|
595
|
+
const queryParams = [projectId];
|
|
596
|
+
if (params.status) {
|
|
597
|
+
conditions.push("status = ?");
|
|
598
|
+
queryParams.push(params.status);
|
|
747
599
|
}
|
|
600
|
+
const limit = params.limit ?? 10;
|
|
601
|
+
queryParams.push(limit);
|
|
602
|
+
const sessions = registryDb.prepare(`SELECT number, date, title, filename, status
|
|
603
|
+
FROM sessions
|
|
604
|
+
WHERE ${conditions.join(" AND ")}
|
|
605
|
+
ORDER BY number DESC
|
|
606
|
+
LIMIT ?`).all(...queryParams);
|
|
607
|
+
if (sessions.length === 0) return { content: [{
|
|
608
|
+
type: "text",
|
|
609
|
+
text: `No sessions found for project: ${params.project}`
|
|
610
|
+
}] };
|
|
611
|
+
const lines = sessions.map((s) => `#${String(s.number).padStart(4, "0")} ${s.date} [${s.status}] ${s.title}\n file: Notes/${s.filename}`);
|
|
748
612
|
return { content: [{
|
|
749
613
|
type: "text",
|
|
750
|
-
text: lines.join("\n")
|
|
614
|
+
text: `${sessions.length} session(s) for ${params.project}:\n\n${lines.join("\n\n")}`
|
|
751
615
|
}] };
|
|
752
616
|
} catch (e) {
|
|
753
617
|
return {
|
|
754
618
|
content: [{
|
|
755
619
|
type: "text",
|
|
756
|
-
text: `
|
|
620
|
+
text: `session_list error: ${String(e)}`
|
|
757
621
|
}],
|
|
758
622
|
isError: true
|
|
759
623
|
};
|
|
@@ -772,7 +636,7 @@ async function toolTopicDetect(params) {
|
|
|
772
636
|
*/
|
|
773
637
|
async function toolSessionRoute(registryDb, federation, params) {
|
|
774
638
|
try {
|
|
775
|
-
const { autoRoute, formatAutoRouteJson } = await import("./auto-route-
|
|
639
|
+
const { autoRoute, formatAutoRouteJson } = await import("./auto-route-C-DrW6BL.mjs");
|
|
776
640
|
const result = await autoRoute(registryDb, federation, params.cwd, params.context);
|
|
777
641
|
if (!result) return { content: [{
|
|
778
642
|
type: "text",
|
|
@@ -799,10 +663,45 @@ async function toolSessionRoute(registryDb, federation, params) {
|
|
|
799
663
|
};
|
|
800
664
|
}
|
|
801
665
|
}
|
|
802
|
-
|
|
666
|
+
|
|
667
|
+
//#endregion
|
|
668
|
+
//#region src/mcp/tools/registry.ts
|
|
669
|
+
function toolRegistrySearch(registryDb, params) {
|
|
803
670
|
try {
|
|
804
|
-
const
|
|
805
|
-
const
|
|
671
|
+
const q = `%${params.query}%`;
|
|
672
|
+
const projects = registryDb.prepare(`SELECT id, slug, display_name, root_path, type, status, updated_at
|
|
673
|
+
FROM projects
|
|
674
|
+
WHERE slug LIKE ?
|
|
675
|
+
OR display_name LIKE ?
|
|
676
|
+
OR root_path LIKE ?
|
|
677
|
+
ORDER BY updated_at DESC
|
|
678
|
+
LIMIT 20`).all(q, q, q);
|
|
679
|
+
if (projects.length === 0) return { content: [{
|
|
680
|
+
type: "text",
|
|
681
|
+
text: `No projects found matching: "${params.query}"`
|
|
682
|
+
}] };
|
|
683
|
+
const lines = projects.map((p) => `${p.slug} [${p.status}] ${p.root_path}`);
|
|
684
|
+
return { content: [{
|
|
685
|
+
type: "text",
|
|
686
|
+
text: `${projects.length} match(es) for "${params.query}":\n\n${lines.join("\n")}`
|
|
687
|
+
}] };
|
|
688
|
+
} catch (e) {
|
|
689
|
+
return {
|
|
690
|
+
content: [{
|
|
691
|
+
type: "text",
|
|
692
|
+
text: `registry_search error: ${String(e)}`
|
|
693
|
+
}],
|
|
694
|
+
isError: true
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
//#endregion
|
|
700
|
+
//#region src/mcp/tools/zettel.ts
|
|
701
|
+
async function toolZettelExplore(backend, params) {
|
|
702
|
+
try {
|
|
703
|
+
const { zettelExplore } = await import("./zettelkasten-cdajbnPr.mjs");
|
|
704
|
+
const result = await zettelExplore(backend, {
|
|
806
705
|
startNote: params.start_note,
|
|
807
706
|
depth: params.depth,
|
|
808
707
|
direction: params.direction,
|
|
@@ -822,10 +721,10 @@ async function toolZettelExplore(federationDb, params) {
|
|
|
822
721
|
};
|
|
823
722
|
}
|
|
824
723
|
}
|
|
825
|
-
async function toolZettelHealth(
|
|
724
|
+
async function toolZettelHealth(backend, params) {
|
|
826
725
|
try {
|
|
827
|
-
const { zettelHealth } = await import("./zettelkasten-
|
|
828
|
-
const result = zettelHealth(
|
|
726
|
+
const { zettelHealth } = await import("./zettelkasten-cdajbnPr.mjs");
|
|
727
|
+
const result = await zettelHealth(backend, {
|
|
829
728
|
scope: params.scope,
|
|
830
729
|
projectPath: params.project_path,
|
|
831
730
|
recentDays: params.recent_days,
|
|
@@ -845,10 +744,10 @@ async function toolZettelHealth(federationDb, params) {
|
|
|
845
744
|
};
|
|
846
745
|
}
|
|
847
746
|
}
|
|
848
|
-
async function toolZettelSurprise(
|
|
747
|
+
async function toolZettelSurprise(backend, params) {
|
|
849
748
|
try {
|
|
850
|
-
const { zettelSurprise } = await import("./zettelkasten-
|
|
851
|
-
const results = await zettelSurprise(
|
|
749
|
+
const { zettelSurprise } = await import("./zettelkasten-cdajbnPr.mjs");
|
|
750
|
+
const results = await zettelSurprise(backend, {
|
|
852
751
|
referencePath: params.reference_path,
|
|
853
752
|
vaultProjectId: params.vault_project_id,
|
|
854
753
|
limit: params.limit,
|
|
@@ -869,10 +768,10 @@ async function toolZettelSurprise(federationDb, params) {
|
|
|
869
768
|
};
|
|
870
769
|
}
|
|
871
770
|
}
|
|
872
|
-
async function toolZettelSuggest(
|
|
771
|
+
async function toolZettelSuggest(backend, params) {
|
|
873
772
|
try {
|
|
874
|
-
const { zettelSuggest } = await import("./zettelkasten-
|
|
875
|
-
const results = await zettelSuggest(
|
|
773
|
+
const { zettelSuggest } = await import("./zettelkasten-cdajbnPr.mjs");
|
|
774
|
+
const results = await zettelSuggest(backend, {
|
|
876
775
|
notePath: params.note_path,
|
|
877
776
|
vaultProjectId: params.vault_project_id,
|
|
878
777
|
limit: params.limit,
|
|
@@ -892,10 +791,10 @@ async function toolZettelSuggest(federationDb, params) {
|
|
|
892
791
|
};
|
|
893
792
|
}
|
|
894
793
|
}
|
|
895
|
-
async function toolZettelConverse(
|
|
794
|
+
async function toolZettelConverse(backend, params) {
|
|
896
795
|
try {
|
|
897
|
-
const { zettelConverse } = await import("./zettelkasten-
|
|
898
|
-
const result = await zettelConverse(
|
|
796
|
+
const { zettelConverse } = await import("./zettelkasten-cdajbnPr.mjs");
|
|
797
|
+
const result = await zettelConverse(backend, {
|
|
899
798
|
question: params.question,
|
|
900
799
|
vaultProjectId: params.vault_project_id,
|
|
901
800
|
depth: params.depth,
|
|
@@ -915,10 +814,10 @@ async function toolZettelConverse(federationDb, params) {
|
|
|
915
814
|
};
|
|
916
815
|
}
|
|
917
816
|
}
|
|
918
|
-
async function toolZettelThemes(
|
|
817
|
+
async function toolZettelThemes(backend, params) {
|
|
919
818
|
try {
|
|
920
|
-
const { zettelThemes } = await import("./zettelkasten-
|
|
921
|
-
const result = await zettelThemes(
|
|
819
|
+
const { zettelThemes } = await import("./zettelkasten-cdajbnPr.mjs");
|
|
820
|
+
const result = await zettelThemes(backend, {
|
|
922
821
|
vaultProjectId: params.vault_project_id,
|
|
923
822
|
lookbackDays: params.lookback_days,
|
|
924
823
|
minClusterSize: params.min_cluster_size,
|
|
@@ -939,42 +838,32 @@ async function toolZettelThemes(federationDb, params) {
|
|
|
939
838
|
};
|
|
940
839
|
}
|
|
941
840
|
}
|
|
942
|
-
/**
|
|
943
|
-
* Combine keyword + semantic results using min-max normalized scoring.
|
|
944
|
-
* Mirrors the logic in searchMemoryHybrid() from memory/search.ts,
|
|
945
|
-
* but works on pre-computed result arrays so it works for any backend.
|
|
946
|
-
*/
|
|
947
|
-
function combineHybridResults(keywordResults, semanticResults, maxResults, keywordWeight = .5, semanticWeight = .5) {
|
|
948
|
-
if (keywordResults.length === 0 && semanticResults.length === 0) return [];
|
|
949
|
-
const keyFor = (r) => `${r.projectId}:${r.path}:${r.startLine}:${r.endLine}`;
|
|
950
|
-
function minMaxNormalize(items) {
|
|
951
|
-
if (items.length === 0) return /* @__PURE__ */ new Map();
|
|
952
|
-
const min = Math.min(...items.map((r) => r.score));
|
|
953
|
-
const range = Math.max(...items.map((r) => r.score)) - min;
|
|
954
|
-
const m = /* @__PURE__ */ new Map();
|
|
955
|
-
for (const r of items) m.set(keyFor(r), range === 0 ? 1 : (r.score - min) / range);
|
|
956
|
-
return m;
|
|
957
|
-
}
|
|
958
|
-
const kwNorm = minMaxNormalize(keywordResults);
|
|
959
|
-
const semNorm = minMaxNormalize(semanticResults);
|
|
960
|
-
const allKeys = new Set([...keywordResults.map(keyFor), ...semanticResults.map(keyFor)]);
|
|
961
|
-
const metaMap = /* @__PURE__ */ new Map();
|
|
962
|
-
for (const r of [...keywordResults, ...semanticResults]) metaMap.set(keyFor(r), r);
|
|
963
|
-
const combined = [];
|
|
964
|
-
for (const key of allKeys) {
|
|
965
|
-
const meta = metaMap.get(key);
|
|
966
|
-
const kwScore = kwNorm.get(key) ?? 0;
|
|
967
|
-
const semScore = semNorm.get(key) ?? 0;
|
|
968
|
-
const combinedScore = keywordWeight * kwScore + semanticWeight * semScore;
|
|
969
|
-
combined.push({
|
|
970
|
-
...meta,
|
|
971
|
-
score: combinedScore,
|
|
972
|
-
combinedScore
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
return combined.sort((a, b) => b.score - a.score).slice(0, maxResults).map(({ combinedScore: _unused, ...r }) => r);
|
|
976
|
-
}
|
|
977
841
|
|
|
978
842
|
//#endregion
|
|
979
|
-
|
|
980
|
-
|
|
843
|
+
//#region src/mcp/tools.ts
|
|
844
|
+
var tools_exports = /* @__PURE__ */ __exportAll({
|
|
845
|
+
combineHybridResults: () => combineHybridResults,
|
|
846
|
+
detectProjectFromPath: () => detectProjectFromPath,
|
|
847
|
+
formatProject: () => formatProject,
|
|
848
|
+
lookupProjectId: () => lookupProjectId,
|
|
849
|
+
toolMemoryGet: () => toolMemoryGet,
|
|
850
|
+
toolMemorySearch: () => toolMemorySearch,
|
|
851
|
+
toolProjectDetect: () => toolProjectDetect,
|
|
852
|
+
toolProjectHealth: () => toolProjectHealth,
|
|
853
|
+
toolProjectInfo: () => toolProjectInfo,
|
|
854
|
+
toolProjectList: () => toolProjectList,
|
|
855
|
+
toolProjectTodo: () => toolProjectTodo,
|
|
856
|
+
toolRegistrySearch: () => toolRegistrySearch,
|
|
857
|
+
toolSessionList: () => toolSessionList,
|
|
858
|
+
toolSessionRoute: () => toolSessionRoute,
|
|
859
|
+
toolZettelConverse: () => toolZettelConverse,
|
|
860
|
+
toolZettelExplore: () => toolZettelExplore,
|
|
861
|
+
toolZettelHealth: () => toolZettelHealth,
|
|
862
|
+
toolZettelSuggest: () => toolZettelSuggest,
|
|
863
|
+
toolZettelSurprise: () => toolZettelSurprise,
|
|
864
|
+
toolZettelThemes: () => toolZettelThemes
|
|
865
|
+
});
|
|
866
|
+
|
|
867
|
+
//#endregion
|
|
868
|
+
export { toolProjectDetect as a, toolProjectList as c, toolMemorySearch as d, toolSessionRoute as i, toolProjectTodo as l, toolRegistrySearch as n, toolProjectHealth as o, toolSessionList as r, toolProjectInfo as s, tools_exports as t, toolMemoryGet as u };
|
|
869
|
+
//# sourceMappingURL=tools-DcaJlYDN.mjs.map
|