@vpxa/kb 0.1.23 → 0.1.25
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 +3 -3
- package/package.json +9 -2
- package/packages/analyzers/dist/symbol-analyzer.js +5 -5
- package/packages/cli/dist/commands/init/adapters.js +1 -1
- package/packages/cli/dist/commands/init/constants.d.ts +4 -1
- package/packages/cli/dist/commands/init/constants.js +1 -1
- package/packages/cli/dist/commands/init/frontmatter.d.ts +54 -0
- package/packages/cli/dist/commands/init/frontmatter.js +2 -0
- package/packages/cli/dist/commands/init/index.js +4 -4
- package/packages/cli/dist/commands/init/manifest.d.ts +71 -0
- package/packages/cli/dist/commands/init/manifest.js +1 -0
- package/packages/cli/dist/commands/init/scaffold.d.ts +28 -5
- package/packages/cli/dist/commands/init/scaffold.js +1 -1
- package/packages/cli/dist/commands/init/templates.js +38 -9
- package/packages/cli/dist/commands/init/user.d.ts +1 -1
- package/packages/cli/dist/commands/init/user.js +4 -4
- package/packages/cli/dist/commands/system.js +2 -2
- package/packages/cli/dist/kb-init.js +1 -1
- package/packages/core/dist/errors.d.ts +2 -2
- package/packages/core/dist/errors.js +1 -1
- package/packages/core/dist/logger.d.ts +2 -1
- package/packages/core/dist/logger.js +1 -1
- package/packages/core/dist/types.d.ts +6 -0
- package/packages/dashboard/dist/assets/index-9ysCkze9.js +21 -0
- package/packages/dashboard/dist/assets/index-9ysCkze9.js.map +1 -0
- package/packages/dashboard/dist/assets/index-CHpVij2M.css +1 -0
- package/packages/dashboard/dist/index.html +18 -0
- package/packages/elicitation/dist/__tests__/build.test.d.ts +1 -0
- package/packages/elicitation/dist/__tests__/build.test.js +35 -0
- package/packages/elicitation/dist/__tests__/fields.test.d.ts +1 -0
- package/packages/elicitation/dist/__tests__/fields.test.js +81 -0
- package/packages/elicitation/dist/__tests__/normalize.test.d.ts +1 -0
- package/packages/elicitation/dist/__tests__/normalize.test.js +60 -0
- package/packages/elicitation/dist/build.d.ts +13 -0
- package/packages/elicitation/dist/build.js +23 -0
- package/packages/elicitation/dist/fields.d.ts +41 -0
- package/packages/elicitation/dist/fields.js +62 -0
- package/packages/elicitation/dist/index.d.ts +10 -0
- package/packages/elicitation/dist/index.js +12 -0
- package/packages/elicitation/dist/normalize.d.ts +15 -0
- package/packages/elicitation/dist/normalize.js +31 -0
- package/packages/elicitation/dist/types.d.ts +85 -0
- package/packages/elicitation/dist/types.js +8 -0
- package/packages/kb-client/dist/direct-client.d.ts +37 -0
- package/packages/kb-client/dist/direct-client.js +1 -0
- package/packages/kb-client/dist/index.d.ts +5 -0
- package/packages/kb-client/dist/index.js +1 -0
- package/packages/kb-client/dist/mcp-client.d.ts +19 -0
- package/packages/kb-client/dist/mcp-client.js +4 -0
- package/packages/kb-client/dist/parsers.d.ts +35 -0
- package/packages/kb-client/dist/parsers.js +2 -0
- package/packages/kb-client/dist/types.d.ts +62 -0
- package/packages/kb-client/dist/types.js +1 -0
- package/packages/present/dist/index.html +384 -0
- package/packages/server/dist/completions.d.ts +14 -0
- package/packages/server/dist/completions.js +1 -0
- package/packages/server/dist/config.js +1 -1
- package/packages/server/dist/dashboard-static.d.ts +27 -0
- package/packages/server/dist/dashboard-static.js +1 -0
- package/packages/server/dist/elicitor.d.ts +18 -0
- package/packages/server/dist/elicitor.js +1 -0
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/mcp-logging.js +1 -1
- package/packages/server/dist/output-schemas.d.ts +118 -1
- package/packages/server/dist/output-schemas.js +1 -1
- package/packages/server/dist/prompts.d.ts +9 -2
- package/packages/server/dist/prompts.js +13 -6
- package/packages/server/dist/resources/curated-resources.js +1 -1
- package/packages/server/dist/resources/resource-notifier.d.ts +45 -0
- package/packages/server/dist/resources/resource-notifier.js +1 -0
- package/packages/server/dist/sampling.d.ts +41 -0
- package/packages/server/dist/sampling.js +2 -0
- package/packages/server/dist/server.d.ts +5 -2
- package/packages/server/dist/server.js +3 -1
- package/packages/server/dist/task-manager.d.ts +40 -0
- package/packages/server/dist/task-manager.js +1 -0
- package/packages/server/dist/tool-metadata.js +1 -1
- package/packages/server/dist/tool-prefix.d.ts +12 -0
- package/packages/server/dist/tool-prefix.js +1 -0
- package/packages/server/dist/tools/analyze.tools.js +4 -4
- package/packages/server/dist/tools/audit.tool.js +1 -1
- package/packages/server/dist/tools/brainstorm.tool.d.ts +7 -0
- package/packages/server/dist/tools/brainstorm.tool.js +9 -0
- package/packages/server/dist/tools/bridge.tools.js +1 -1
- package/packages/server/dist/tools/context.tools.js +9 -9
- package/packages/server/dist/tools/execution.tools.d.ts +2 -1
- package/packages/server/dist/tools/execution.tools.js +4 -3
- package/packages/server/dist/tools/forge.tools.js +10 -10
- package/packages/server/dist/tools/forget.tool.d.ts +2 -1
- package/packages/server/dist/tools/forget.tool.js +1 -1
- package/packages/server/dist/tools/graph.tool.js +2 -2
- package/packages/server/dist/tools/infra.tools.js +2 -2
- package/packages/server/dist/tools/list.tool.js +2 -2
- package/packages/server/dist/tools/lookup.tool.js +1 -1
- package/packages/server/dist/tools/manipulation.tools.js +4 -4
- package/packages/server/dist/tools/onboard.tool.js +2 -2
- package/packages/server/dist/tools/persistence.tools.js +4 -4
- package/packages/server/dist/tools/policy.tools.js +3 -2
- package/packages/server/dist/tools/present-blocks.d.ts +46 -0
- package/packages/server/dist/tools/present-blocks.js +27 -0
- package/packages/server/dist/tools/present-charts.d.ts +31 -0
- package/packages/server/dist/tools/present-charts.js +34 -0
- package/packages/server/dist/tools/present-theme.d.ts +14 -0
- package/packages/server/dist/tools/present-theme.js +395 -0
- package/packages/server/dist/tools/present-utils.d.ts +11 -0
- package/packages/server/dist/tools/present-utils.js +1 -0
- package/packages/server/dist/tools/present.tool.d.ts +7 -0
- package/packages/server/dist/tools/present.tool.js +113 -0
- package/packages/server/dist/tools/produce.tool.js +2 -2
- package/packages/server/dist/tools/read.tool.js +1 -1
- package/packages/server/dist/tools/reindex.tool.d.ts +2 -1
- package/packages/server/dist/tools/reindex.tool.js +2 -2
- package/packages/server/dist/tools/remember.tool.d.ts +2 -1
- package/packages/server/dist/tools/remember.tool.js +2 -2
- package/packages/server/dist/tools/replay.tool.js +2 -2
- package/packages/server/dist/tools/search.tool.d.ts +2 -1
- package/packages/server/dist/tools/search.tool.js +5 -4
- package/packages/server/dist/tools/status.tool.js +2 -2
- package/packages/server/dist/tools/update.tool.d.ts +2 -1
- package/packages/server/dist/tools/update.tool.js +1 -1
- package/packages/server/dist/tools/utility.tools.js +8 -8
- package/packages/store/dist/lance-store.d.ts +1 -0
- package/packages/store/dist/lance-store.js +1 -1
- package/packages/tools/dist/audit.js +1 -1
- package/packages/tools/dist/batch.js +1 -1
- package/packages/tools/dist/check.js +1 -1
- package/packages/tools/dist/checkpoint.js +1 -1
- package/packages/tools/dist/compact.js +2 -2
- package/packages/tools/dist/config-extractor.d.ts +9 -0
- package/packages/tools/dist/config-extractor.js +7 -0
- package/packages/tools/dist/dead-symbols.js +2 -2
- package/packages/tools/dist/diagram-builder.d.ts +9 -0
- package/packages/tools/dist/diagram-builder.js +9 -0
- package/packages/tools/dist/eval.js +2 -2
- package/packages/tools/dist/evidence-map.d.ts +12 -1
- package/packages/tools/dist/evidence-map.js +2 -2
- package/packages/tools/dist/file-summary.js +2 -2
- package/packages/tools/dist/find-examples.js +2 -2
- package/packages/tools/dist/forge-classify.d.ts +4 -0
- package/packages/tools/dist/forge-classify.js +1 -1
- package/packages/tools/dist/git-context.d.ts +1 -0
- package/packages/tools/dist/git-context.js +3 -3
- package/packages/tools/dist/index.d.ts +3 -2
- package/packages/tools/dist/index.js +1 -1
- package/packages/tools/dist/onboard-utils.d.ts +12 -0
- package/packages/tools/dist/onboard-utils.js +1 -0
- package/packages/tools/dist/onboard.js +2 -21
- package/packages/tools/dist/queue.js +1 -1
- package/packages/tools/dist/regex-utils.d.ts +8 -0
- package/packages/tools/dist/regex-utils.js +1 -0
- package/packages/tools/dist/rename.js +2 -2
- package/packages/tools/dist/replay.d.ts +2 -1
- package/packages/tools/dist/replay.js +4 -4
- package/packages/tools/dist/symbol.js +3 -3
- package/packages/tools/dist/synthesis-engine.d.ts +13 -0
- package/packages/tools/dist/synthesis-engine.js +6 -0
- package/packages/tools/dist/test-run.d.ts +3 -1
- package/packages/tools/dist/test-run.js +1 -1
- package/packages/tools/dist/trace.js +2 -2
- package/packages/tui/dist/App-DXY0-tlW.js +2 -0
- package/packages/tui/dist/App.d.ts +3 -3
- package/packages/tui/dist/App.js +1 -1
- package/packages/tui/dist/CuratedPanel-BIamXLNy.js +2 -0
- package/packages/tui/dist/LogPanel-D6u6o84n.js +3 -0
- package/packages/tui/dist/SearchPanel-CpJGczAc.js +2 -0
- package/packages/tui/dist/StatusPanel-BAbUxyqQ.js +2 -0
- package/packages/tui/dist/hooks/useKBClient.d.ts +9 -0
- package/packages/tui/dist/hooks/useKBClient.js +2 -0
- package/packages/tui/dist/hooks/usePolling.d.ts +8 -0
- package/packages/tui/dist/hooks/usePolling.js +2 -0
- package/packages/tui/dist/index.d.ts +6 -2
- package/packages/tui/dist/index.js +1 -1
- package/packages/tui/dist/jsx-runtime-y6Gdq5PZ.js +294 -0
- package/packages/tui/dist/panels/CuratedPanel.d.ts +1 -7
- package/packages/tui/dist/panels/CuratedPanel.js +1 -1
- package/packages/tui/dist/panels/LogPanel.js +1 -1
- package/packages/tui/dist/panels/SearchPanel.d.ts +1 -10
- package/packages/tui/dist/panels/SearchPanel.js +1 -1
- package/packages/tui/dist/panels/StatusPanel.d.ts +1 -7
- package/packages/tui/dist/panels/StatusPanel.js +1 -1
- package/packages/tui/dist/react-D__J1GQe.js +24 -0
- package/packages/tui/dist/types-VcTHNV6s.d.ts +64 -0
- package/packages/tui/dist/useKBClient-C35iA4uG.js +2 -0
- package/packages/tui/dist/usePolling-BbjnRWgx.js +2 -0
- package/scaffold/adapters/copilot.mjs +9 -81
- package/scaffold/definitions/agents.mjs +12 -0
- package/scaffold/definitions/bodies.mjs +39 -14
- package/scaffold/definitions/protocols.mjs +149 -0
- package/scaffold/definitions/tools.mjs +40 -5
- package/scaffold/general/agents/Architect-Reviewer-Alpha.agent.md +1 -1
- package/scaffold/general/agents/Architect-Reviewer-Beta.agent.md +1 -1
- package/scaffold/general/agents/Code-Reviewer-Alpha.agent.md +1 -1
- package/scaffold/general/agents/Code-Reviewer-Beta.agent.md +1 -1
- package/scaffold/general/agents/Debugger.agent.md +2 -2
- package/scaffold/general/agents/Documenter.agent.md +2 -2
- package/scaffold/general/agents/Explorer.agent.md +4 -3
- package/scaffold/general/agents/Frontend.agent.md +1 -1
- package/scaffold/general/agents/Implementer.agent.md +1 -1
- package/scaffold/general/agents/Orchestrator.agent.md +16 -1
- package/scaffold/general/agents/Planner.agent.md +11 -4
- package/scaffold/general/agents/Refactor.agent.md +1 -1
- package/scaffold/general/agents/Researcher-Alpha.agent.md +1 -1
- package/scaffold/general/agents/Researcher-Beta.agent.md +1 -1
- package/scaffold/general/agents/Researcher-Delta.agent.md +1 -1
- package/scaffold/general/agents/Researcher-Gamma.agent.md +1 -1
- package/scaffold/general/agents/Security.agent.md +10 -8
- package/scaffold/general/agents/_shared/architect-reviewer-base.md +1 -0
- package/scaffold/general/agents/_shared/code-agent-base.md +28 -0
- package/scaffold/general/agents/_shared/code-reviewer-base.md +1 -0
- package/scaffold/general/agents/_shared/forge-protocol.md +44 -0
- package/scaffold/general/agents/_shared/researcher-base.md +14 -0
- package/scaffold/general/agents/templates/adr-template.md +1 -0
- package/scaffold/general/agents/templates/execution-state.md +1 -0
- package/skills/knowledge-base/SKILL.md +19 -6
- package/skills/present/SKILL.md +153 -0
- package/packages/server/dist/tools/toolkit.tools.d.ts +0 -36
- package/packages/server/dist/tools/toolkit.tools.js +0 -20
- package/packages/tui/dist/App-DE_tdOhs.js +0 -2
- package/packages/tui/dist/CuratedPanel-sYdZAICX.js +0 -2
- package/packages/tui/dist/LogPanel-Ce3jMQbH.js +0 -3
- package/packages/tui/dist/SearchPanel-DREo6zgt.js +0 -2
- package/packages/tui/dist/StatusPanel-2ex8fLOO.js +0 -2
- package/packages/tui/dist/embedder.interface-IFCBpOlX.d.ts +0 -28
- package/packages/tui/dist/index-C8NmOF18.d.ts +0 -13
- package/packages/tui/dist/jsx-runtime-Cof-kwFn.js +0 -316
- package/packages/tui/dist/store.interface-CnY6SPOH.d.ts +0 -150
- /package/packages/tui/dist/{devtools-DUyj952l.js → devtools-DMOZMn70.js} +0 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
const e=`<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">`;function t(){return`
|
|
2
|
+
/* ── Reset ────────────────────────────────────────────────────────── */
|
|
3
|
+
*{box-sizing:border-box;margin:0;padding:0}
|
|
4
|
+
|
|
5
|
+
/* ── Design Tokens ────────────────────────────────────────────────── */
|
|
6
|
+
:root{
|
|
7
|
+
/* Background hierarchy */
|
|
8
|
+
--background:#0f1419;
|
|
9
|
+
--background-subtle:#141b24;
|
|
10
|
+
--foreground:#e2e8f0;
|
|
11
|
+
--card:#1a2332;
|
|
12
|
+
--card-foreground:#e2e8f0;
|
|
13
|
+
|
|
14
|
+
/* Semantic colors */
|
|
15
|
+
--primary:#818cf8;
|
|
16
|
+
--primary-glow:rgba(129,140,248,.15);
|
|
17
|
+
--primary-foreground:#1e1b4b;
|
|
18
|
+
--secondary:#2a3549;
|
|
19
|
+
--secondary-foreground:#e2e8f0;
|
|
20
|
+
--muted:#2a3549;
|
|
21
|
+
--muted-foreground:#94a3b8;
|
|
22
|
+
--accent:#1e293b;
|
|
23
|
+
--accent-foreground:#a5b4fc;
|
|
24
|
+
--destructive:#f87171;
|
|
25
|
+
--border:rgba(148,163,184,.12);
|
|
26
|
+
--border-subtle:rgba(148,163,184,.06);
|
|
27
|
+
--input:#384766;
|
|
28
|
+
--ring:#6366f1;
|
|
29
|
+
|
|
30
|
+
/* Status colors */
|
|
31
|
+
--success:#10b981;
|
|
32
|
+
--success-light:#34d399;
|
|
33
|
+
--warning:#f59e0b;
|
|
34
|
+
--warning-light:#fbbf24;
|
|
35
|
+
--error:#ef4444;
|
|
36
|
+
--error-light:#f87171;
|
|
37
|
+
--info:#0ea5e9;
|
|
38
|
+
--info-light:#38bdf8;
|
|
39
|
+
|
|
40
|
+
/* Chart palette */
|
|
41
|
+
--chart-1:#818cf8;
|
|
42
|
+
--chart-2:#38bdf8;
|
|
43
|
+
--chart-3:#34d399;
|
|
44
|
+
--chart-4:#fbbf24;
|
|
45
|
+
--chart-5:#f87171;
|
|
46
|
+
--chart-6:#a78bfa;
|
|
47
|
+
--chart-7:#f472b6;
|
|
48
|
+
--chart-8:#2dd4bf;
|
|
49
|
+
--chart-9:#fb923c;
|
|
50
|
+
--chart-10:#22d3ee;
|
|
51
|
+
--chart-11:#c084fc;
|
|
52
|
+
--chart-12:#a3e635;
|
|
53
|
+
--chart-others:#a8a29e;
|
|
54
|
+
--chart-gradient-start:0.3;
|
|
55
|
+
--chart-gradient-end:0;
|
|
56
|
+
|
|
57
|
+
/* Layout */
|
|
58
|
+
--radius:0.625rem;
|
|
59
|
+
--shadow:0 4px 24px rgba(0,0,0,.25);
|
|
60
|
+
--shadow-sm:0 1px 3px rgba(0,0,0,.2);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* ── Base ─────────────────────────────────────────────────────────── */
|
|
64
|
+
body{
|
|
65
|
+
font-family:'Plus Jakarta Sans',ui-sans-serif,system-ui,-apple-system,sans-serif;
|
|
66
|
+
background:var(--background);color:var(--foreground);
|
|
67
|
+
min-height:100vh;padding:0;line-height:1.6;font-size:14px;
|
|
68
|
+
-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
|
|
69
|
+
background-image:radial-gradient(ellipse 80% 50% at 50% -20%,rgba(129,140,248,.08),transparent);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* ── Animations ───────────────────────────────────────────────────── */
|
|
73
|
+
@keyframes fadeInUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
|
|
74
|
+
@keyframes shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}
|
|
75
|
+
|
|
76
|
+
/* ── Layout ───────────────────────────────────────────────────────── */
|
|
77
|
+
.dashboard{max-width:1200px;margin:0 auto;padding:40px 28px}
|
|
78
|
+
|
|
79
|
+
/* ── Header ───────────────────────────────────────────────────────── */
|
|
80
|
+
.header{
|
|
81
|
+
padding:28px 0;margin-bottom:32px;
|
|
82
|
+
border-bottom:1px solid var(--border);
|
|
83
|
+
position:relative;
|
|
84
|
+
}
|
|
85
|
+
.header::after{
|
|
86
|
+
content:'';position:absolute;bottom:-1px;left:0;width:120px;height:2px;
|
|
87
|
+
background:linear-gradient(90deg,var(--primary),transparent);
|
|
88
|
+
}
|
|
89
|
+
.header h1{
|
|
90
|
+
font-size:1.75em;font-weight:700;color:var(--foreground);
|
|
91
|
+
letter-spacing:-0.03em;line-height:1.2;
|
|
92
|
+
}
|
|
93
|
+
.header .subtitle{
|
|
94
|
+
color:var(--muted-foreground);font-size:.88em;margin-top:6px;font-weight:400;
|
|
95
|
+
letter-spacing:.01em;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* ── Section headings ─────────────────────────────────────────────── */
|
|
99
|
+
h2{
|
|
100
|
+
font-size:1.1em;margin:32px 0 16px;color:var(--foreground);font-weight:600;
|
|
101
|
+
display:flex;align-items:center;gap:10px;letter-spacing:-0.01em;
|
|
102
|
+
animation:fadeInUp .4s ease both;
|
|
103
|
+
}
|
|
104
|
+
h2::before{
|
|
105
|
+
content:'';width:3px;height:16px;background:linear-gradient(180deg,var(--primary),rgba(129,140,248,.3));border-radius:2px;flex-shrink:0;
|
|
106
|
+
}
|
|
107
|
+
h3{font-size:1em;margin:16px 0 8px;color:var(--foreground);font-weight:600}
|
|
108
|
+
|
|
109
|
+
/* ── Rendered markdown content ────────────────────────────────────── */
|
|
110
|
+
.md-content{line-height:1.7;margin:12px 0}
|
|
111
|
+
.md-content h1{font-size:1.4em;font-weight:700;margin:24px 0 12px;color:var(--foreground);letter-spacing:-0.02em}
|
|
112
|
+
.md-content h2{font-size:1.2em;margin:20px 0 10px;color:var(--foreground);display:block}
|
|
113
|
+
.md-content h2::before{display:none}
|
|
114
|
+
.md-content h3{font-size:1.05em;margin:16px 0 8px;color:var(--foreground)}
|
|
115
|
+
.md-content h4{font-size:.95em;margin:12px 0 6px;color:var(--foreground);font-weight:600}
|
|
116
|
+
.md-content p{margin:8px 0;color:var(--foreground)}
|
|
117
|
+
.md-content strong{color:var(--foreground);font-weight:600}
|
|
118
|
+
.md-content em{color:var(--muted-foreground);font-style:italic}
|
|
119
|
+
.md-content a{color:var(--primary);text-decoration:underline;text-underline-offset:2px}
|
|
120
|
+
.md-content a:hover{color:var(--accent-foreground)}
|
|
121
|
+
.md-content ul,.md-content ol{padding-left:24px;margin:8px 0}
|
|
122
|
+
.md-content li{margin:4px 0;color:var(--foreground)}
|
|
123
|
+
.md-content li::marker{color:var(--muted-foreground)}
|
|
124
|
+
.md-content blockquote{
|
|
125
|
+
border-left:3px solid var(--primary);padding:10px 16px;margin:12px 0;
|
|
126
|
+
color:var(--muted-foreground);background:var(--card);border-radius:0 var(--radius) var(--radius) 0;
|
|
127
|
+
}
|
|
128
|
+
.md-content pre{
|
|
129
|
+
background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
|
|
130
|
+
padding:16px;overflow-x:auto;margin:12px 0;
|
|
131
|
+
}
|
|
132
|
+
.md-content code{font-family:'JetBrains Mono','Cascadia Code','Fira Code',monospace;font-size:.88em}
|
|
133
|
+
.md-content :not(pre)>code{background:var(--accent);padding:2px 6px;border-radius:4px;font-size:.85em;color:var(--accent-foreground)}
|
|
134
|
+
.md-content table{width:100%;border-collapse:collapse;margin:12px 0;font-size:13px}
|
|
135
|
+
.md-content th{
|
|
136
|
+
background:var(--accent);padding:10px 14px;text-align:left;font-weight:600;
|
|
137
|
+
color:var(--muted-foreground);border-bottom:2px solid var(--border);font-size:.8em;
|
|
138
|
+
text-transform:uppercase;letter-spacing:.5px;
|
|
139
|
+
}
|
|
140
|
+
.md-content td{padding:8px 14px;border-bottom:1px solid var(--border);color:var(--foreground)}
|
|
141
|
+
.md-content tr:hover td{background:rgba(129,140,248,.04)}
|
|
142
|
+
.md-content hr{border:none;border-top:1px solid var(--border);margin:24px 0}
|
|
143
|
+
.md-content img{max-width:100%;border-radius:var(--radius)}
|
|
144
|
+
|
|
145
|
+
/* ── Metrics grid ─────────────────────────────────────────────────── */
|
|
146
|
+
.metric-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:14px;margin:14px 0 28px}
|
|
147
|
+
.metric{
|
|
148
|
+
background:linear-gradient(135deg,var(--card),var(--accent));
|
|
149
|
+
border:1px solid var(--border);border-radius:var(--radius);
|
|
150
|
+
padding:22px 18px;text-align:center;transition:all .2s ease;position:relative;overflow:hidden;
|
|
151
|
+
animation:fadeInUp .4s ease both;
|
|
152
|
+
}
|
|
153
|
+
.metric::before{
|
|
154
|
+
content:'';position:absolute;top:0;left:0;right:0;height:2px;
|
|
155
|
+
background:linear-gradient(90deg,transparent,var(--primary),transparent);opacity:0;
|
|
156
|
+
transition:opacity .2s ease;
|
|
157
|
+
}
|
|
158
|
+
.metric:hover{border-color:rgba(129,140,248,.3);transform:translateY(-2px);box-shadow:0 8px 32px rgba(0,0,0,.2)}
|
|
159
|
+
.metric:hover::before{opacity:1}
|
|
160
|
+
.metric-value{
|
|
161
|
+
font-size:1.8em;font-weight:700;color:var(--primary);
|
|
162
|
+
font-variant-numeric:tabular-nums;letter-spacing:-0.02em;
|
|
163
|
+
}
|
|
164
|
+
.metric-label{
|
|
165
|
+
font-size:.75em;color:var(--muted-foreground);margin-top:6px;
|
|
166
|
+
text-transform:uppercase;letter-spacing:.6px;font-weight:500;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* ── Cards grid ───────────────────────────────────────────────────── */
|
|
170
|
+
.card-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px;margin:14px 0 28px}
|
|
171
|
+
.card{
|
|
172
|
+
background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
|
|
173
|
+
padding:20px;transition:all .2s ease;position:relative;overflow:hidden;
|
|
174
|
+
animation:fadeInUp .4s ease both;
|
|
175
|
+
}
|
|
176
|
+
.card::after{
|
|
177
|
+
content:'';position:absolute;top:0;left:0;width:3px;height:0;
|
|
178
|
+
background:var(--primary);transition:height .2s ease;border-radius:0 0 2px 0;
|
|
179
|
+
}
|
|
180
|
+
.card:hover{border-color:rgba(129,140,248,.2);box-shadow:0 4px 20px rgba(0,0,0,.15);transform:translateY(-1px)}
|
|
181
|
+
.card:hover::after{height:100%}
|
|
182
|
+
.card-title{font-weight:600;font-size:.98em;margin-bottom:8px;color:var(--foreground)}
|
|
183
|
+
.card-body{color:var(--muted-foreground);font-size:.88em;line-height:1.55}
|
|
184
|
+
.badge{
|
|
185
|
+
display:inline-flex;align-items:center;padding:3px 10px;border-radius:20px;
|
|
186
|
+
font-size:.75em;font-weight:600;margin-top:10px;
|
|
187
|
+
background:rgba(129,140,248,.1);color:var(--primary);border:1px solid rgba(129,140,248,.15);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* ── Table ─────────────────────────────────────────────────────────── */
|
|
191
|
+
.table-wrap{
|
|
192
|
+
overflow-x:auto;margin:14px 0 28px;border-radius:var(--radius);border:1px solid var(--border);
|
|
193
|
+
background:var(--card);animation:fadeInUp .4s ease both;
|
|
194
|
+
}
|
|
195
|
+
table{width:100%;border-collapse:collapse;font-size:13px}
|
|
196
|
+
thead{position:sticky;top:0;z-index:1}
|
|
197
|
+
th{
|
|
198
|
+
background:var(--accent);padding:12px 16px;text-align:left;font-weight:600;
|
|
199
|
+
color:var(--muted-foreground);text-transform:uppercase;letter-spacing:.5px;font-size:.72em;
|
|
200
|
+
border-bottom:1px solid var(--border);cursor:pointer;user-select:none;white-space:nowrap;
|
|
201
|
+
transition:color .15s;
|
|
202
|
+
}
|
|
203
|
+
th:hover{color:var(--primary)}
|
|
204
|
+
td{padding:10px 16px;border-bottom:1px solid var(--border-subtle);color:var(--foreground)}
|
|
205
|
+
tr:hover td{background:rgba(129,140,248,.04)}
|
|
206
|
+
.tool-name{font-family:'JetBrains Mono','Cascadia Code',monospace;font-size:.85em;color:var(--primary);font-weight:500}
|
|
207
|
+
.category-tag{
|
|
208
|
+
display:inline-flex;padding:2px 8px;border-radius:6px;font-size:.8em;font-weight:500;
|
|
209
|
+
background:var(--accent);color:var(--muted-foreground);border:1px solid var(--border);white-space:nowrap;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* ── Code blocks ──────────────────────────────────────────────────── */
|
|
213
|
+
pre{
|
|
214
|
+
background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
|
|
215
|
+
padding:16px;overflow-x:auto;font-size:13px;margin:12px 0;
|
|
216
|
+
}
|
|
217
|
+
code{font-family:'JetBrains Mono','Cascadia Code','Fira Code',monospace;font-size:.9em}
|
|
218
|
+
blockquote{
|
|
219
|
+
border-left:3px solid var(--primary);padding:10px 16px;color:var(--muted-foreground);
|
|
220
|
+
margin:12px 0;background:var(--card);border-radius:0 var(--radius) var(--radius) 0;
|
|
221
|
+
}
|
|
222
|
+
ul,ol{padding-left:24px;margin:8px 0}
|
|
223
|
+
li{margin:4px 0}
|
|
224
|
+
.tree-node{padding:3px 0}
|
|
225
|
+
.tree-key{font-weight:600;color:var(--primary)}
|
|
226
|
+
.tree-children{margin-left:20px;border-left:2px solid var(--border);padding-left:12px}
|
|
227
|
+
|
|
228
|
+
/* ── Mermaid ──────────────────────────────────────────────────────── */
|
|
229
|
+
.mermaid{background:transparent !important;border:none !important}
|
|
230
|
+
|
|
231
|
+
/* ── Charts ───────────────────────────────────────────────────────── */
|
|
232
|
+
.chart-container{
|
|
233
|
+
background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
|
|
234
|
+
padding:24px;margin:14px 0 28px;overflow:hidden;animation:fadeInUp .4s ease both;
|
|
235
|
+
}
|
|
236
|
+
.chart-title{font-size:.95em;font-weight:600;color:var(--foreground);margin-bottom:14px}
|
|
237
|
+
.chart-svg{width:100%;display:block}
|
|
238
|
+
.chart-legend{
|
|
239
|
+
display:flex;flex-wrap:wrap;gap:14px;margin-top:14px;padding-top:12px;
|
|
240
|
+
border-top:1px solid var(--border);
|
|
241
|
+
}
|
|
242
|
+
.chart-legend-item{display:flex;align-items:center;gap:6px;font-size:.8em;color:var(--muted-foreground)}
|
|
243
|
+
.chart-legend-swatch{width:10px;height:10px;border-radius:2px;flex-shrink:0}
|
|
244
|
+
.chart-tooltip{
|
|
245
|
+
position:absolute;background:var(--card);border:1px solid var(--border);
|
|
246
|
+
border-radius:6px;padding:8px 12px;font-size:.8em;pointer-events:none;
|
|
247
|
+
box-shadow:var(--shadow);z-index:10;display:none;color:var(--foreground);
|
|
248
|
+
}
|
|
249
|
+
.chart-axis-label{font-size:.7em;fill:var(--muted-foreground);font-family:inherit}
|
|
250
|
+
.chart-grid-line{stroke:var(--border);stroke-dasharray:3,3;stroke-width:0.5}
|
|
251
|
+
|
|
252
|
+
/* ── Timeline ─────────────────────────────────────────────────────── */
|
|
253
|
+
.timeline{margin:14px 0 28px;padding-left:28px;border-left:2px solid var(--border);position:relative;animation:fadeInUp .4s ease both}
|
|
254
|
+
.timeline-item{position:relative;padding:0 0 28px 22px}
|
|
255
|
+
.timeline-item:last-child{padding-bottom:0}
|
|
256
|
+
.timeline-dot{
|
|
257
|
+
position:absolute;left:-33px;top:4px;width:12px;height:12px;
|
|
258
|
+
border-radius:50%;border:2px solid var(--border);background:var(--background);
|
|
259
|
+
transition:all .2s ease;
|
|
260
|
+
}
|
|
261
|
+
.timeline-dot.done{background:var(--success);border-color:var(--success);box-shadow:0 0 8px rgba(16,185,129,.3)}
|
|
262
|
+
.timeline-dot.active{background:var(--primary);border-color:var(--primary);box-shadow:0 0 0 4px rgba(129,140,248,.15)}
|
|
263
|
+
.timeline-dot.pending{background:var(--muted);border-color:var(--muted-foreground)}
|
|
264
|
+
.timeline-dot.error{background:var(--error);border-color:var(--error);box-shadow:0 0 8px rgba(239,68,68,.3)}
|
|
265
|
+
.timeline-phase{font-size:.7em;color:var(--muted-foreground);text-transform:uppercase;letter-spacing:.5px;font-weight:600;margin-bottom:2px}
|
|
266
|
+
.timeline-title{font-weight:600;color:var(--foreground);font-size:.95em}
|
|
267
|
+
.timeline-desc{color:var(--muted-foreground);font-size:.85em;margin-top:4px;line-height:1.5}
|
|
268
|
+
|
|
269
|
+
/* ── Checklist ────────────────────────────────────────────────────── */
|
|
270
|
+
.checklist{margin:14px 0 28px}
|
|
271
|
+
.checklist-item{
|
|
272
|
+
display:flex;align-items:flex-start;gap:10px;padding:10px 14px;
|
|
273
|
+
border-radius:var(--radius);transition:background .1s;
|
|
274
|
+
}
|
|
275
|
+
.checklist-item:hover{background:var(--accent)}
|
|
276
|
+
.checklist-check{
|
|
277
|
+
width:18px;height:18px;border-radius:4px;border:2px solid var(--border);
|
|
278
|
+
flex-shrink:0;margin-top:1px;display:flex;align-items:center;justify-content:center;
|
|
279
|
+
font-size:11px;color:transparent;
|
|
280
|
+
}
|
|
281
|
+
.checklist-check.checked{background:var(--success);border-color:var(--success);color:#fff}
|
|
282
|
+
.checklist-label{color:var(--foreground);font-size:.9em;font-weight:500}
|
|
283
|
+
.checklist-item.checked .checklist-label{color:var(--muted-foreground);text-decoration:line-through}
|
|
284
|
+
.checklist-note{font-size:.8em;color:var(--muted-foreground);margin-top:2px}
|
|
285
|
+
|
|
286
|
+
/* ── Comparison grid ──────────────────────────────────────────────── */
|
|
287
|
+
.comparison-grid{
|
|
288
|
+
display:grid;gap:0;margin:14px 0 28px;border:1px solid var(--border);
|
|
289
|
+
border-radius:var(--radius);overflow:hidden;
|
|
290
|
+
}
|
|
291
|
+
.comparison-col{min-width:0}
|
|
292
|
+
.comparison-col:not(:last-child){border-right:1px solid var(--border)}
|
|
293
|
+
.comparison-header{
|
|
294
|
+
padding:14px 16px;font-weight:600;font-size:.9em;color:var(--foreground);
|
|
295
|
+
background:var(--accent);border-bottom:2px solid var(--border);text-align:center;
|
|
296
|
+
}
|
|
297
|
+
.comparison-item{
|
|
298
|
+
padding:10px 16px;border-bottom:1px solid var(--border);font-size:.88em;
|
|
299
|
+
color:var(--foreground);min-height:40px;display:flex;align-items:center;
|
|
300
|
+
}
|
|
301
|
+
.comparison-item:last-child{border-bottom:none}
|
|
302
|
+
|
|
303
|
+
/* ── Status board ─────────────────────────────────────────────────── */
|
|
304
|
+
.status-board{display:flex;flex-direction:column;gap:8px;margin:14px 0 28px}
|
|
305
|
+
.status-row{
|
|
306
|
+
display:flex;align-items:center;gap:12px;padding:10px 14px;
|
|
307
|
+
background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
|
|
308
|
+
}
|
|
309
|
+
.status-indicator{width:8px;height:8px;border-radius:50%;flex-shrink:0}
|
|
310
|
+
.status-indicator.success{background:var(--success)}
|
|
311
|
+
.status-indicator.warning{background:var(--warning)}
|
|
312
|
+
.status-indicator.error{background:var(--error)}
|
|
313
|
+
.status-indicator.info{background:var(--info)}
|
|
314
|
+
.status-indicator.pending{background:var(--muted-foreground)}
|
|
315
|
+
.status-label{font-weight:500;font-size:.9em;color:var(--foreground);flex:1}
|
|
316
|
+
.status-detail{font-size:.8em;color:var(--muted-foreground)}
|
|
317
|
+
|
|
318
|
+
/* ── Progress bars ────────────────────────────────────────────────── */
|
|
319
|
+
.progress-list{display:flex;flex-direction:column;gap:12px;margin:14px 0 28px}
|
|
320
|
+
.progress-item{display:flex;flex-direction:column;gap:4px}
|
|
321
|
+
.progress-header{display:flex;justify-content:space-between;align-items:baseline}
|
|
322
|
+
.progress-label{font-size:.88em;font-weight:500;color:var(--foreground)}
|
|
323
|
+
.progress-value{font-size:.8em;color:var(--muted-foreground);font-variant-numeric:tabular-nums}
|
|
324
|
+
.progress-track{
|
|
325
|
+
height:6px;background:var(--accent);border-radius:3px;overflow:hidden;
|
|
326
|
+
}
|
|
327
|
+
.progress-fill{
|
|
328
|
+
height:100%;border-radius:3px;transition:width .3s ease;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* ── Prompt / Question block ──────────────────────────────────────── */
|
|
332
|
+
.prompt-block{
|
|
333
|
+
background:var(--card);border:1px solid var(--primary);border-radius:var(--radius);
|
|
334
|
+
padding:20px;margin:14px 0 28px;
|
|
335
|
+
}
|
|
336
|
+
.prompt-question{font-size:1.05em;font-weight:600;color:var(--foreground);margin-bottom:8px}
|
|
337
|
+
.prompt-context{font-size:.88em;color:var(--muted-foreground);line-height:1.6;margin-bottom:12px}
|
|
338
|
+
.prompt-placeholder{
|
|
339
|
+
padding:10px 14px;background:var(--accent);border:1px dashed var(--border);
|
|
340
|
+
border-radius:var(--radius);color:var(--muted-foreground);font-size:.85em;font-style:italic;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/* ── Actions ──────────────────────────────────────────────────────── */
|
|
344
|
+
.actions-bar{margin:32px 0}
|
|
345
|
+
.actions-grid{display:flex;flex-wrap:wrap;gap:10px;margin-top:14px}
|
|
346
|
+
.action-group{display:flex;flex-direction:column;gap:6px}
|
|
347
|
+
.action-group label{font-size:.85em;color:var(--muted-foreground);font-weight:500}
|
|
348
|
+
.action-group select{
|
|
349
|
+
padding:9px 14px;background:var(--card);border:1px solid var(--border);
|
|
350
|
+
border-radius:var(--radius);color:var(--foreground);font-size:.9em;cursor:pointer;min-width:200px;
|
|
351
|
+
font-family:inherit;
|
|
352
|
+
}
|
|
353
|
+
.action-group select:hover{border-color:var(--primary)}
|
|
354
|
+
.action-btn{
|
|
355
|
+
padding:10px 22px;border:1px solid var(--border);border-radius:var(--radius);
|
|
356
|
+
font-size:.88em;font-weight:600;cursor:pointer;transition:all .2s ease;
|
|
357
|
+
background:var(--card);color:var(--foreground);font-family:inherit;
|
|
358
|
+
}
|
|
359
|
+
.action-btn:hover{transform:translateY(-1px);box-shadow:0 4px 16px rgba(0,0,0,.2)}
|
|
360
|
+
.action-primary{background:linear-gradient(135deg,var(--primary),#6366f1);color:var(--primary-foreground);border-color:transparent}
|
|
361
|
+
.action-primary:hover{opacity:.9;box-shadow:0 4px 20px rgba(129,140,248,.3)}
|
|
362
|
+
.action-danger{background:var(--error);color:#fff;border-color:var(--error)}
|
|
363
|
+
.action-danger:hover{opacity:.9}
|
|
364
|
+
.action-default:hover{border-color:var(--primary);color:var(--primary)}
|
|
365
|
+
.action-feedback{
|
|
366
|
+
margin-top:14px;padding:10px 16px;border-radius:var(--radius);
|
|
367
|
+
display:none;font-weight:500;font-size:.9em;
|
|
368
|
+
}
|
|
369
|
+
.action-feedback.sent{
|
|
370
|
+
display:block;background:rgba(16,185,129,.1);color:var(--success);
|
|
371
|
+
border:1px solid rgba(16,185,129,.2);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/* ── Footer ───────────────────────────────────────────────────────── */
|
|
375
|
+
.footer{
|
|
376
|
+
text-align:center;padding:24px;color:var(--muted-foreground);font-size:.75em;
|
|
377
|
+
border-top:1px solid var(--border);margin-top:48px;letter-spacing:.02em;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/* ── Search filter (injected for tables) ──────────────────────────── */
|
|
381
|
+
.search-bar{display:flex;gap:12px;margin-bottom:14px;align-items:center}
|
|
382
|
+
.search-bar input{
|
|
383
|
+
flex:1;padding:9px 14px;background:var(--card);border:1px solid var(--border);
|
|
384
|
+
border-radius:var(--radius);color:var(--foreground);font-size:.9em;outline:none;
|
|
385
|
+
transition:border-color .15s;font-family:inherit;
|
|
386
|
+
}
|
|
387
|
+
.search-bar input:focus{border-color:var(--primary)}
|
|
388
|
+
.search-bar .count{color:var(--muted-foreground);font-size:.85em;white-space:nowrap}
|
|
389
|
+
|
|
390
|
+
/* ── Scrollbar ────────────────────────────────────────────────────── */
|
|
391
|
+
::-webkit-scrollbar{width:6px;height:6px}
|
|
392
|
+
::-webkit-scrollbar-track{background:var(--card)}
|
|
393
|
+
::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}
|
|
394
|
+
::-webkit-scrollbar-thumb:hover{background:var(--muted-foreground)}
|
|
395
|
+
`}export{e as FONT_LINK,t as getDesignSystemCSS};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region packages/server/src/tools/present-utils.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shared HTML utility functions for the Present tool family.
|
|
4
|
+
*
|
|
5
|
+
* Used by present.tool.ts, present-charts.ts, and present-blocks.ts
|
|
6
|
+
* to avoid duplicating escape logic across modules.
|
|
7
|
+
*/
|
|
8
|
+
/** HTML-escape a string for safe insertion into HTML content and attributes. */
|
|
9
|
+
declare function escHtml(s: string): string;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { escHtml };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`)}export{e as escHtml};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { Elicitor } from "@kb/elicitation";
|
|
3
|
+
|
|
4
|
+
//#region packages/server/src/tools/present.tool.d.ts
|
|
5
|
+
declare function registerPresentTool(server: McpServer, elicitor?: Elicitor): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { registerPresentTool };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{escHtml as t}from"./present-utils.js";import{renderChecklistHtml as n,renderComparisonHtml as r,renderProgressHtml as i,renderPromptHtml as a,renderStatusBoardHtml as o,renderTimelineHtml as s}from"./present-blocks.js";import{renderChartAsHtml as c}from"./present-charts.js";import{FONT_LINK as l,getDesignSystemCSS as u}from"./present-theme.js";import{readFileSync as d}from"node:fs";import{dirname as f,join as p}from"node:path";import{fileURLToPath as m}from"node:url";import{z as h}from"zod";import{exec as g}from"node:child_process";import{createServer as _}from"node:http";import{createUIResource as v}from"@mcp-ui/server";import{RESOURCE_MIME_TYPE as y,registerAppResource as b,registerAppTool as x}from"@modelcontextprotocol/ext-apps/server";import{marked as S}from"marked";S.setOptions({async:!1,gfm:!0,breaks:!0}),S.use({renderer:{html(e){return t(e.text)}}});const C=import.meta.dirname??f(m(import.meta.url)),w=`ui://kb/present.html`;function T(){return p(C,`..`,`..`,`..`,`present`,`dist`,`index.html`)}let E;function D(){if(!E)try{E=d(T(),`utf-8`)}catch{E=``}return E}const O=h.object({type:h.enum([`button`,`select`]).describe(`Action type`),id:h.string().describe(`Unique action identifier`),label:h.string().describe(`Display label`),variant:h.enum([`primary`,`danger`,`default`]).optional().describe(`Button style variant`),options:h.array(h.union([h.string(),h.object({label:h.string(),value:h.string()})])).optional().describe(`Select options (for type=select)`)}),k={format:h.enum([`html`,`browser`]).default(`html`).describe(`Output format.
|
|
2
|
+
- "html" (default): Rich markdown in chat + embedded UIResource for MCP-UI hosts. Actions shown as numbered choices.
|
|
3
|
+
- "browser": Rich markdown in chat + opens beautiful themed dashboard in the browser. When actions are provided, the browser shows interactive buttons and the tool blocks until the user clicks, returning their selection.`),title:h.string().optional().describe(`Optional heading`),content:h.any().describe(`Content to present. Accepts: markdown string, array of objects (→ table), { nodes, edges } (→ mermaid graph), typed blocks [{ type, value }], or any JSON (→ tree).`),actions:h.array(O).optional().describe(`Interactive actions (buttons/selects). In html mode, shown as numbered choices. In browser mode, rendered as clickable buttons and the tool blocks until user clicks.`)};let A=!1;function j(t,n){let r=e(`present`);A||=(b(t,`KB Present App`,w,{description:`Rich interactive content viewer for KB tools`},async()=>({contents:[{uri:w,mimeType:y,text:D()}]})),!0),x(t,`present`,{title:r.title,description:`Present content to the user in the best format. Two modes:
|
|
4
|
+
- "html" (default): Rich markdown in chat + embedded UIResource. Actions shown as numbered choices for display.
|
|
5
|
+
- "browser": Rich markdown in chat + serves a themed dashboard on a local URL that auto-opens in your system browser. If openBrowserPage is available, also call it with the returned URL. When actions are provided, browser shows interactive buttons and the tool blocks until user clicks.
|
|
6
|
+
Use "html" for in-chat display. Use "browser" for visual dashboards and when you need interactive user input back.
|
|
7
|
+
After calling present with format "browser", extract the URL from the response and call openBrowserPage({ url }) to open it in VS Code.`,annotations:r.annotations,inputSchema:k,_meta:{ui:{resourceUri:w}}},async({format:e,title:t,content:r,actions:i})=>(e??`html`)===`browser`?await N(t,r,i,n):J(t,r,i))}let M=null;process.on(`exit`,()=>{if(M){try{M.close()}catch{}M=null}});async function N(e,t,n,r){let i=P(e,t),a=q(e,t,n),o,s,c=Array.isArray(n)?n:[],l=``;try{M&&=(M.close(),null),c.length>0&&(o=new Promise(e=>{s=e})),l=await new Promise((e,t)=>{let n=_((e,t)=>{if(e.method===`POST`&&e.url===`/callback`){let n=``;e.on(`data`,e=>{n+=e.toString()}),e.on(`end`,()=>{t.writeHead(200,{"Content-Type":`application/json`,"Access-Control-Allow-Origin":`*`}),t.end(`{"ok":true}`);try{let e=JSON.parse(n);s?.(e)}catch{}});return}if(e.method===`OPTIONS`){t.writeHead(204,{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`POST`,"Access-Control-Allow-Headers":`Content-Type`}),t.end();return}t.writeHead(200,{"Content-Type":`text/html; charset=utf-8`}),t.end(a)});n.listen(0,`127.0.0.1`,()=>{let r=n.address();typeof r==`object`&&r?(M=n,e(`http://127.0.0.1:${r.port}`)):t(Error(`Failed to start present server`))}),setTimeout(()=>{n.close(),M===n&&(M=null)},300*1e3).unref()});try{g(process.platform===`win32`?`start "" "${l}"`:process.platform===`darwin`?`open "${l}"`:`xdg-open "${l}"`)}catch{}}catch{}let u=v({uri:`ui://kb/present-static.html`,content:{type:`rawHtml`,htmlString:a},encoding:`text`,adapters:{mcpApps:{enabled:!0}}}),d=l?`${i}\n\n---\n🌐 **Dashboard opened in browser:** ${l}`:i;if(c.length>0&&r?.available&&o)try{let e=await Promise.race([o,new Promise((e,t)=>setTimeout(()=>t(Error(`timeout`)),300*1e3))]);return{content:[{type:`text`,text:`${d}\n\n✅ **Selected:** ${e.actionId} = \`${e.value}\``},u]}}catch{return{content:[{type:`text`,text:`${d}\n\n⚠️ *No selection received (timed out).*`},u]}}return{content:[{type:`text`,text:d},u]}}function P(e,t){let n=[];if(e&&n.push(`# ${e}\n`),typeof t==`string`)n.push(t);else if(Array.isArray(t))if(t.length===0)n.push(`*(empty)*`);else if(Z(t[0]))for(let e of t)n.push(F(e));else if(typeof t[0]==`object`&&t[0]!==null)n.push(I(t));else for(let e of t)n.push(`- ${String(e)}`);else if(typeof t==`object`&&t){let e=t;Array.isArray(e.nodes)&&Array.isArray(e.edges)?n.push(R(e)):Array.isArray(e.metrics)?n.push(L(e.metrics)):n.push(z(e))}else n.push(String(t));return n.join(`
|
|
8
|
+
`)}function F(e){let t=[];switch(e.title&&t.push(`## ${e.title}\n`),e.type){case`markdown`:t.push(String(e.value??``));break;case`code`:t.push(`\`\`\`${e.language??``}\n${String(e.value??``)}\n\`\`\``);break;case`mermaid`:t.push(`\`\`\`mermaid\n${String(e.value??``)}\n\`\`\``);break;case`table`:Array.isArray(e.value)&&t.push(I(e.value));break;case`metrics`:Array.isArray(e.value)&&t.push(L(e.value));break;case`graph`:e.value&&typeof e.value==`object`&&t.push(R(e.value));break;case`cards`:if(Array.isArray(e.value))for(let n of e.value)t.push(`### ${n.title??`Card`}`),(n.body||n.description)&&t.push(String(n.body??n.description)),(n.badge||n.status)&&t.push(`> **${n.badge??n.status}**`),t.push(``);break;case`tree`:e.value&&typeof e.value==`object`&&t.push(z(e.value));break;case`chart`:{let n=e.value;n?.data&&Array.isArray(n.data)&&t.push(`*${String(n.chartType??`chart`)} chart — ${n.data.length} data points*`);break}case`timeline`:{let n=e.value;if(n?.items)for(let e of n.items){let n=e.status===`done`?`✅`:e.status===`active`?`🔄`:e.status===`error`?`❌`:`⬜`;t.push(`${n} **${e.title}**${e.description?` — ${e.description}`:``}`)}break}case`checklist`:{let n=e.value;if(n?.items)for(let e of n.items)t.push(`- [${e.checked?`x`:` `}] ${e.label}${e.note?` — ${e.note}`:``}`);break}case`comparison`:{let n=e.value;if(n?.columns&&n.columns.length>0){let e=Math.max(...n.columns.map(e=>e.items?.length??0)),r=n.columns.map(e=>e.title);t.push(`| ${r.join(` | `)} |`),t.push(`| ${r.map(()=>`---`).join(` | `)} |`);for(let r=0;r<e;r++)t.push(`| ${n.columns.map(e=>e.items?.[r]??``).join(` | `)} |`)}break}case`status-board`:{let n=e.value;if(n?.items)for(let e of n.items){let n=e.status===`success`?`🟢`:e.status===`warning`?`🟡`:e.status===`error`?`🔴`:e.status===`info`?`🔵`:`⚪`;t.push(`${n} **${e.label}**${e.detail?` — ${e.detail}`:``}`)}break}case`prompt`:{let n=e.value;n?.question&&(t.push(`> **${n.question}**`),n.context&&t.push(`> ${n.context}`));break}case`progress`:{let n=e.value;if(n?.items)for(let e of n.items){let n=e.max??100,r=n>0?Math.round(e.value/n*100):0,i=`█`.repeat(Math.round(r/5))+`░`.repeat(20-Math.round(r/5));t.push(`${e.label}: ${i} ${r}%`)}break}default:t.push(JSON.stringify(e.value,null,2))}return t.push(``),t.join(`
|
|
9
|
+
`)}function I(e){if(e.length===0)return`*(empty table)*`;let t=Object.keys(e[0]),n=[];n.push(`| ${t.join(` | `)} |`),n.push(`| ${t.map(()=>`---`).join(` | `)} |`);for(let r of e)n.push(`| ${t.map(e=>String(r[e]??``)).join(` | `)} |`);return n.join(`
|
|
10
|
+
`)}function L(e){return e.map(e=>`- **${e.label}**: ${e.value}`).join(`
|
|
11
|
+
`)}function R(e){let t=["```mermaid",`graph LR`];for(let n of e.nodes){let e=X(String(n.id??n.name??``)),r=String(n.label??n.name??e);t.push(` ${e}["${r}"]`)}for(let n of e.edges){let e=X(String(n.source??n.from??``)),r=X(String(n.target??n.to??``)),i=n.label?`|${String(n.label)}|`:``;t.push(` ${e} -->${i} ${r}`)}return t.push("```"),t.join(`
|
|
12
|
+
`)}function z(e,t=0){let n=` `.repeat(t),r=[];for(let[i,a]of Object.entries(e))typeof a==`object`&&a&&!Array.isArray(a)?(r.push(`${n}- **${i}**:`),r.push(z(a,t+1))):r.push(`${n}- **${i}**: ${Y(a)}`);return r.join(`
|
|
13
|
+
`)}function B(e,n){let r=[];if(e&&r.push(`<h1>${t(e)}</h1>`),typeof n==`string`)r.push(`<div class="md-content">${S.parse(n)}</div>`);else if(Array.isArray(n))if(n.length===0)r.push(`<p><em>empty</em></p>`);else if(Z(n[0]))for(let e of n)r.push(V(e));else typeof n[0]==`object`&&n[0]!==null?r.push(H(n)):r.push(`<ul>${n.map(e=>`<li>${t(String(e))}</li>`).join(``)}</ul>`);else if(typeof n==`object`&&n){let e=n;Array.isArray(e.metrics)?r.push(U(e.metrics)):Array.isArray(e.nodes)&&Array.isArray(e.edges)?(r.push(`<pre class="mermaid">${t(K(e))}</pre>`),r.push(`<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"><\/script>`),r.push(`<script>mermaid.run();<\/script>`)):r.push(G(e))}else r.push(`<p>${t(String(n))}</p>`);return r.join(`
|
|
14
|
+
`)}function V(e){let l=[];switch(e.title&&l.push(`<h2>${t(e.title)}</h2>`),e.type){case`markdown`:l.push(`<div class="md-content">${S.parse(String(e.value??``))}</div>`);break;case`code`:l.push(`<pre><code>${t(String(e.value??``))}</code></pre>`);break;case`mermaid`:l.push(`<pre class="mermaid">${t(String(e.value??``))}</pre>`);break;case`table`:if(Array.isArray(e.value)){let t=e.value;if(t.length>0&&Array.isArray(t[0])){let e=t,n=e[0].map(String),r=e.slice(1).map(e=>Object.fromEntries(n.map((t,n)=>[t,e[n]])));l.push(H(r))}else l.push(H(t))}break;case`metrics`:{let t;Array.isArray(e.value)?t=e.value:e.value&&typeof e.value==`object`&&(t=Object.entries(e.value).map(([e,t])=>({label:e,value:String(t)}))),t&&l.push(U(t))}break;case`cards`:Array.isArray(e.value)&&l.push(W(e.value));break;case`tree`:e.value&&typeof e.value==`object`&&l.push(G(e.value));break;case`graph`:e.value&&typeof e.value==`object`&&l.push(`<pre class="mermaid">${t(K(e.value))}</pre>`);break;case`chart`:{let t=e.value;if(t&&!t.chartType&&t.type&&Array.isArray(t.labels)&&Array.isArray(t.datasets)){let n=t.labels,r=t.datasets,i=r.map((e,t)=>e.label??`series${t+1}`),a=n.map((e,t)=>{let n={_label:e};return r.forEach((e,r)=>{n[i[r]]=e.data[t]??0}),n}),o={type:`chart`,title:e.title,value:{chartType:String(t.type),data:a,xKey:`_label`,yKeys:i}};l.push(c(o))}else l.push(c(e));break}case`timeline`:{let t=e.value;Array.isArray(t)&&(t={items:t.map(e=>({title:String(e.event??e.title??``),phase:e.date==null?e.phase==null?void 0:String(e.phase):String(e.date),description:e.description==null?void 0:String(e.description),status:e.status??`done`}))}),t&&l.push(s(t));break}case`checklist`:e.value&&l.push(n(e.value));break;case`comparison`:e.value&&l.push(r(e.value));break;case`status-board`:e.value&&l.push(o(e.value));break;case`prompt`:e.value&&l.push(a(e.value));break;case`progress`:e.value&&l.push(i(e.value));break;default:l.push(`<pre>${t(JSON.stringify(e.value,null,2))}</pre>`)}return l.join(`
|
|
15
|
+
`)}function H(e){if(e.length===0)return`<p><em>empty table</em></p>`;let n=Object.keys(e[0]);return`<div class="table-wrap"><table><thead><tr>${n.map(e=>`<th>${t(e)}</th>`).join(``)}</tr></thead><tbody>${e.map(e=>`<tr>${n.map(n=>`<td>${t(String(e[n]??``))}</td>`).join(``)}</tr>`).join(`
|
|
16
|
+
`)}</tbody></table></div>`}function U(e){return`<div class="metric-grid">${e.map(e=>`<div class="metric"><div class="metric-value">${t(String(e.value))}</div><div class="metric-label">${t(e.label)}</div></div>`).join(``)}</div>`}function W(e){return`<div class="card-grid">${e.map(e=>{let n=[`<div class="card">`];return e.title&&n.push(`<div class="card-title">${t(String(e.title))}</div>`),(e.body||e.description)&&n.push(`<div class="card-body">${t(String(e.body??e.description))}</div>`),(e.badge||e.status)&&n.push(`<span class="badge">${t(String(e.badge??e.status))}</span>`),n.push(`</div>`),n.join(``)}).join(``)}</div>`}function G(e){let n=[];for(let[r,i]of Object.entries(e))typeof i==`object`&&i&&!Array.isArray(i)?n.push(`<div class="tree-node"><span class="tree-key">${t(r)}:</span><div class="tree-children">${G(i)}</div></div>`):n.push(`<div class="tree-node"><span class="tree-key">${t(r)}:</span> ${t(Y(i))}</div>`);return n.join(``)}function K(e){let t=[`graph LR`];for(let n of e.nodes){let e=X(String(n.id??n.name??``)),r=String(n.label??n.name??e);t.push(` ${e}["${r}"]`)}for(let n of e.edges){let e=X(String(n.source??n.from??``)),r=X(String(n.target??n.to??``)),i=n.label?`|${String(n.label)}|`:``;t.push(` ${e} -->${i} ${r}`)}return t.join(`
|
|
17
|
+
`)}function q(e,n,r){let i=B(e,n);return`<!DOCTYPE html>
|
|
18
|
+
<html lang="en">
|
|
19
|
+
<head>
|
|
20
|
+
<meta charset="UTF-8">
|
|
21
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
22
|
+
<title>${t(e??`KB Dashboard`)}</title>
|
|
23
|
+
${l}
|
|
24
|
+
<style>${u()}</style>
|
|
25
|
+
</head>
|
|
26
|
+
<body>
|
|
27
|
+
<div class="dashboard">
|
|
28
|
+
<div class="header">
|
|
29
|
+
<h1>${t(e??`KB Dashboard`)}</h1>
|
|
30
|
+
<div class="subtitle">Knowledge Base</div>
|
|
31
|
+
</div>
|
|
32
|
+
${i}
|
|
33
|
+
${(()=>{let e=Array.isArray(r)?r:[];return e.length===0?``:`
|
|
34
|
+
<div class="actions-bar">
|
|
35
|
+
<h2>Actions</h2>
|
|
36
|
+
<div class="actions-grid">${e.map(e=>{let n=String(e.id??``);if(e.type===`select`&&Array.isArray(e.options)){let r=e.options.map(e=>{let n=typeof e==`string`?e:e.label;return`<option value="${t(typeof e==`string`?e:e.value)}">${t(n)}</option>`}).join(``);return`<div class="action-group"><label>${t(String(e.label??``))}</label><select data-action-id="${t(n)}" onchange="sendCallback(${t(JSON.stringify(n))},this.value)">${r}</select></div>`}return`<button class="action-btn action-${String(e.variant??`default`)}" onclick="sendCallback(${t(JSON.stringify(n))},'clicked')">${t(String(e.label??``))}</button>`}).join(`
|
|
37
|
+
`)}</div>
|
|
38
|
+
<div id="action-feedback" class="action-feedback"></div>
|
|
39
|
+
</div>
|
|
40
|
+
<script>
|
|
41
|
+
let _cbSent=false;
|
|
42
|
+
function sendCallback(actionId,value){
|
|
43
|
+
if(_cbSent)return;
|
|
44
|
+
_cbSent=true;
|
|
45
|
+
document.querySelectorAll('.action-btn,.action-group select').forEach(el=>{el.disabled=true;el.style.opacity='0.5'});
|
|
46
|
+
const fb=document.getElementById('action-feedback');
|
|
47
|
+
fb.textContent='⏳ Sending selection: '+actionId+' = '+value;
|
|
48
|
+
fb.className='action-feedback sent';
|
|
49
|
+
fetch('/callback',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({actionId,value})})
|
|
50
|
+
.then(()=>{
|
|
51
|
+
fb.textContent='✓ Selection sent: '+actionId+' = '+value;
|
|
52
|
+
})
|
|
53
|
+
.catch(e=>{
|
|
54
|
+
fb.textContent='✗ Callback failed — '+e.message;
|
|
55
|
+
fb.style.color='var(--error)';
|
|
56
|
+
_cbSent=false;
|
|
57
|
+
document.querySelectorAll('.action-btn,.action-group select').forEach(el=>{el.disabled=false;el.style.opacity='1'});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
<\/script>`})()}
|
|
61
|
+
<div class="footer">KB MCP Server · Generated ${new Date().toLocaleString()}</div>
|
|
62
|
+
</div>
|
|
63
|
+
<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"><\/script>
|
|
64
|
+
<script>
|
|
65
|
+
// Mermaid initialization
|
|
66
|
+
if(document.querySelector('.mermaid'))mermaid.initialize({theme:'dark',startOnLoad:true});
|
|
67
|
+
|
|
68
|
+
// Table sorting
|
|
69
|
+
document.querySelectorAll('table').forEach(table=>{
|
|
70
|
+
const headers=table.querySelectorAll('th');
|
|
71
|
+
headers.forEach((th,i)=>{
|
|
72
|
+
let asc=true;
|
|
73
|
+
th.addEventListener('click',()=>{
|
|
74
|
+
const tbody=table.querySelector('tbody')||table;
|
|
75
|
+
const rows=[...tbody.querySelectorAll('tr')].filter(r=>r.querySelector('td'));
|
|
76
|
+
rows.sort((a,b)=>{
|
|
77
|
+
const at=(a.cells[i]?.textContent||'').trim();
|
|
78
|
+
const bt=(b.cells[i]?.textContent||'').trim();
|
|
79
|
+
return asc?at.localeCompare(bt,undefined,{numeric:true}):bt.localeCompare(at,undefined,{numeric:true});
|
|
80
|
+
});
|
|
81
|
+
rows.forEach(r=>tbody.appendChild(r));
|
|
82
|
+
asc=!asc;
|
|
83
|
+
headers.forEach(h=>h.style.color='');
|
|
84
|
+
th.style.color='var(--primary)';
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Table search/filter
|
|
90
|
+
document.querySelectorAll('.table-wrap').forEach(wrap=>{
|
|
91
|
+
const table=wrap.querySelector('table');
|
|
92
|
+
if(!table||table.querySelectorAll('tr').length<5)return;
|
|
93
|
+
const bar=document.createElement('div');
|
|
94
|
+
bar.className='search-bar';
|
|
95
|
+
const input=document.createElement('input');
|
|
96
|
+
input.placeholder='Filter rows...';
|
|
97
|
+
const count=document.createElement('span');
|
|
98
|
+
count.className='count';
|
|
99
|
+
bar.appendChild(input);bar.appendChild(count);
|
|
100
|
+
wrap.parentNode.insertBefore(bar,wrap);
|
|
101
|
+
const rows=[...table.querySelectorAll('tbody tr, tr')].filter(r=>r.querySelector('td'));
|
|
102
|
+
const updateCount=()=>{const v=rows.filter(r=>r.style.display!=='none').length;count.textContent=v+'/'+rows.length};
|
|
103
|
+
updateCount();
|
|
104
|
+
input.addEventListener('input',()=>{
|
|
105
|
+
const q=input.value.toLowerCase();
|
|
106
|
+
rows.forEach(r=>{r.style.display=r.textContent.toLowerCase().includes(q)?'':'none'});
|
|
107
|
+
updateCount();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
<\/script>
|
|
111
|
+
</body>
|
|
112
|
+
</html>`}function J(e,t,n){let r=Array.isArray(n)?n:[],i=[];if(e&&i.push(`## ${e}\n`),Array.isArray(t)){for(let e of t)if(e&&typeof e==`object`&&typeof e.type==`string`)if(e.type===`metrics`&&e.value&&typeof e.value==`object`){let t=e.value;i.push(Object.entries(t).map(([e,t])=>`**${e}**: ${String(t)}`).join(` · `))}else e.type===`text`&&typeof e.value==`string`?i.push(e.value):i.push(`*${e.type}${e.title?`: ${String(e.title)}`:``}*`)}else typeof t==`string`&&i.push(t);if(r.length>0){i.push(``);for(let e=0;e<r.length;e++){let t=r[e],n=typeof t.label==`string`?t.label:`Action ${e+1}`;if(t.type===`select`&&Array.isArray(t.options)){let r=t.options.map(e=>typeof e==`string`?e:e.label).join(`, `);i.push(`${e+1}. **${n}** — choose: ${r}`)}else i.push(`${e+1}. **${n}**`)}}let a={title:e,content:t};return r.length>0&&(a.actions=r),{content:[{type:`text`,text:i.join(`
|
|
113
|
+
`)}],structuredContent:a}}function Y(e){return e==null?`null`:Array.isArray(e)?`[${e.map(Y).join(`, `)}]`:String(e)}function X(e){return e.replace(/[^a-zA-Z0-9_]/g,`_`)}function Z(e){return typeof e==`object`&&!!e&&`type`in e&&`value`in e}export{j as registerPresentTool};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../tool-metadata.js";import{z as t}from"zod";import{
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{z as t}from"zod";import{createLogger as n,serializeError as r}from"../../../core/dist/index.js";import{DependencyAnalyzer as i,DiagramGenerator as a,EntryPointAnalyzer as o,KnowledgeProducer as s,PatternAnalyzer as c,StructureAnalyzer as l,SymbolAnalyzer as u}from"../../../analyzers/dist/index.js";const d=n(`tools`);function f(n){let f=new s({structure:new l,dependencies:new i,symbols:new u,patterns:new c,entryPoints:new o,diagrams:new a}),p=e(`produce_knowledge`);n.registerTool(`produce_knowledge`,{title:p.title,description:`Run automated codebase analysis and produce synthesis instructions. Executes Tier 1 deterministic analyzers, then returns structured baselines and instructions for you to synthesize knowledge using remember.`,inputSchema:{scope:t.string().optional().describe(`Root path to analyze (defaults to workspace root)`),aspects:t.array(t.enum([`all`,`structure`,`dependencies`,`symbols`,`patterns`,`entry-points`,`diagrams`])).default([`all`]).describe(`Which analysis aspects to run`)},annotations:p.annotations},async({scope:e,aspects:t})=>{try{let n=e??`.`;d.info(`Running knowledge production`,{rootPath:n,aspects:t});let r=await f.runExtraction(n,t);return{content:[{type:`text`,text:f.buildSynthesisInstructions(r,t)+`
|
|
2
2
|
|
|
3
3
|
---
|
|
4
|
-
_Next: Review the baselines above and use \`remember\` to store synthesized knowledge entries._`}]}}catch(e){return d.error(`Knowledge production failed`,
|
|
4
|
+
_Next: Review the baselines above and use \`remember\` to store synthesized knowledge entries._`}]}}catch(e){return d.error(`Knowledge production failed`,r(e)),{content:[{type:`text`,text:`Knowledge production failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{f as registerProduceKnowledgeTool};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{getToolMeta as e}from"../tool-metadata.js";import{curatedResourceLink as t}from"../resource-links.js";import{z as n}from"zod";import{createLogger as r,serializeError as i}from"../../../core/dist/index.js";const a=r(`tools`);function o(r,o){let s=e(`read`);r.registerTool(`read`,{title:s.title,description:`Read the full content of a specific curated knowledge entry by its path. Use list first to discover available entries.`,inputSchema:{path:n.string().describe(`Relative path within .ai/curated/ (e.g., "decisions/use-lancedb.md")`)},annotations:s.annotations},async({path:e})=>{try{let n=await o.read(e),r=[`## ${n.title}`,`- **Path**: .ai/curated/${e}`,`- **Category**: ${n.category}`,n.tags.length?`- **Tags**: ${n.tags.join(`, `)}`:null,`- **Version**: ${n.version}`,`- **Created**: ${n.created}`,n.updated===n.created?null:`- **Updated**: ${n.updated}`,``].filter(e=>e!==null).join(`
|
|
2
|
-
`),i=t(e,n.title,`[${n.category}]`);return{content:[{type:`text`,text:`${r}\n${n.content}\n\n---\n_Next: Use \`update\` to modify this entry, or \`search\` to find related entries._`},...i?[i]:[]]}}catch(e){return a.error(`Read failed`,i(e)),{content:[{type:`text`,text:`Read failed
|
|
2
|
+
`),i=t(e,n.title,`[${n.category}]`);return{content:[{type:`text`,text:`${r}\n${n.content}\n\n---\n_Next: Use \`update\` to modify this entry, or \`search\` to find related entries._`},...i?[i]:[]]}}catch(e){return a.error(`Read failed`,i(e)),{content:[{type:`text`,text:`Read failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{o as registerReadTool};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { CuratedKnowledgeManager } from "../curated-manager.js";
|
|
2
|
+
import { ResourceNotifier } from "../resources/resource-notifier.js";
|
|
2
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
4
|
import { KBConfig } from "@kb/core";
|
|
4
5
|
import { IncrementalIndexer } from "@kb/indexer";
|
|
5
6
|
import { IKnowledgeStore } from "@kb/store";
|
|
6
7
|
|
|
7
8
|
//#region packages/server/src/tools/reindex.tool.d.ts
|
|
8
|
-
declare function registerReindexTool(server: McpServer, indexer: IncrementalIndexer, config: KBConfig, curated: CuratedKnowledgeManager, store?: IKnowledgeStore): void;
|
|
9
|
+
declare function registerReindexTool(server: McpServer, indexer: IncrementalIndexer, config: KBConfig, curated: CuratedKnowledgeManager, store?: IKnowledgeStore, resourceNotifier?: ResourceNotifier): void;
|
|
9
10
|
//#endregion
|
|
10
11
|
export { registerReindexTool };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../tool-metadata.js";import{
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{createTaskRunner as t}from"../task-manager.js";import{z as n}from"zod";import{createLogger as r,serializeError as i}from"../../../core/dist/index.js";const a=r(`tools`);function o(r,o,s,c,l,u){let d=e(`reindex`);r.registerTool(`reindex`,{title:d.title,description:`Trigger re-indexing of the knowledge base. Can do incremental (only changed files) or full re-index.`,inputSchema:{full:n.boolean().default(!1).describe(`If true, force full re-index ignoring file hashes`)},annotations:d.annotations},async({full:e},n)=>{try{if(o.isIndexing)return{content:[{type:`text`,text:`## Reindex Already in Progress
|
|
2
2
|
|
|
3
|
-
A reindex operation is currently running. Search and other tools continue to work with existing data. Use \`status({})\` to check when it completes.`}]};
|
|
3
|
+
A reindex operation is currently running. Search and other tools continue to work with existing data. Use \`status({})\` to check when it completes.`}]};let r=t(n).createTask(`Reindex`,1);r.progress(0,`Starting ${e?`full`:`incremental`} reindex`),a.info(`Starting background re-index`,{mode:e?`full`:`incremental`});let d=e=>t=>{t.phase===`chunking`&&t.currentFile&&a.debug(`Re-index progress`,{prefix:e,current:t.filesProcessed+1,total:t.filesTotal,file:t.currentFile})};return(e?o.reindexAll(s,d(`Reindex`)):o.index(s,d(`Index`))).then(async e=>{if(a.info(`Background re-index complete`,{filesProcessed:e.filesProcessed,chunksCreated:e.chunksCreated,durationMs:e.durationMs}),r.complete(`Reindex complete: ${e.filesProcessed} files, ${e.chunksCreated} chunks in ${e.durationMs}ms`),l)try{await l.createFtsIndex(),a.info(`FTS index rebuilt after reindex`)}catch(e){a.warn(`FTS index rebuild failed`,i(e))}try{let e=await c.reindexAll();a.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){a.warn(`Curated re-index failed`,i(e))}if(u)try{await u.notifyAfterReindex()}catch(e){a.warn(`Post-reindex resource notification failed`,i(e))}}).catch(e=>{r.fail(`Reindex failed: ${e instanceof Error?e.message:String(e)}`),a.error(`Background reindex failed`,i(e))}),{content:[{type:`text`,text:`## Reindex Started (Background)\n\n- **Mode**: ${e?`Full`:`Incremental`}\n- Search and other tools continue to work with existing data during reindex.\n- Completion will be logged. Use \`status({})\` to check index stats afterward.\n\n---\n_Next: Continue working — the reindex runs in the background._`}]}}catch(e){return a.error(`Reindex failed`,i(e)),{content:[{type:`text`,text:`Reindex failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{o as registerReindexTool};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { CuratedKnowledgeManager } from "../curated-manager.js";
|
|
2
|
+
import { ResourceNotifier } from "../resources/resource-notifier.js";
|
|
2
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
4
|
import { EvolutionCollector, PolicyStore } from "@kb/enterprise-bridge";
|
|
4
5
|
|
|
5
6
|
//#region packages/server/src/tools/remember.tool.d.ts
|
|
6
|
-
declare function registerRememberTool(server: McpServer, curated: CuratedKnowledgeManager, policyStore?: PolicyStore, evolutionCollector?: EvolutionCollector): void;
|
|
7
|
+
declare function registerRememberTool(server: McpServer, curated: CuratedKnowledgeManager, policyStore?: PolicyStore, evolutionCollector?: EvolutionCollector, resourceNotifier?: ResourceNotifier): void;
|
|
7
8
|
//#endregion
|
|
8
9
|
export { registerRememberTool };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{getToolMeta as e}from"../tool-metadata.js";import{curatedResourceLink as t}from"../resource-links.js";import{z as n}from"zod";import{createLogger as r,serializeError as i}from"../../../core/dist/index.js";const a=r(`tools`);function o(r,o,s,c){let
|
|
1
|
+
import{getToolMeta as e}from"../tool-metadata.js";import{curatedResourceLink as t}from"../resource-links.js";import{z as n}from"zod";import{createLogger as r,serializeError as i}from"../../../core/dist/index.js";const a=r(`tools`);function o(r,o,s,c,l){let u=e(`remember`);r.registerTool(`remember`,{title:u.title,description:`Store a new piece of curated knowledge. Use this to persist decisions, patterns, conventions, or any insight worth remembering across sessions.`,inputSchema:{title:n.string().min(3).max(120).describe(`Short descriptive title for the knowledge entry`),content:n.string().min(10).max(1e5).describe(`The markdown content to store`),category:n.string().regex(/^[a-z][a-z0-9-]*$/).describe(`Category slug (e.g., "decisions", "patterns", "conventions", "api-contracts")`),tags:n.array(n.string()).default([]).describe(`Optional tags for filtering`)},annotations:u.annotations},async({title:e,content:n,category:r,tags:u})=>{try{let i=await o.remember(e,n,r,u),a=``;if(s){let t=s.classify(e,n,u);c&&c.recordClassification(e,t.matchingRules.map(e=>e.ruleId),t.pushRecommended),t.matchingRules.length>0&&(a=`\n\n### Classification Signals\n${t.matchingRules.map(e=>` - **${e.ruleId}** (${e.category}, weight: ${e.pushWeight}) — matched: ${e.matchedPatterns.join(`, `)}`).join(`
|
|
2
2
|
`)}\n- **Push recommended**: ${t.pushRecommended?`yes`:`no`} (max weight: ${t.maxPushWeight})`,t.pushRecommended&&(a+=`
|
|
3
3
|
|
|
4
|
-
> 💡 This entry matches push rules. Consider \`er_push\` to share with Enterprise RAG.`))}
|
|
4
|
+
> 💡 This entry matches push rules. Consider \`er_push\` to share with Enterprise RAG.`))}l&&l.notifyAfterCuratedWrite(i.path).catch(()=>{});let d=t(i.path,e,`[${r}]`);return{content:[{type:`text`,text:`Remembered: **${e}**\n\nStored at \`.ai/curated/${i.path}\` and indexed for semantic search.${a}\n\n---\n_Next: Use \`search\` to verify the entry is findable, or \`list\` to see all curated entries._`},...d?[d]:[]]}}catch(e){return a.error(`Remember failed`,i(e)),{content:[{type:`text`,text:`Remember failed: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}})}export{o as registerRememberTool};
|