@sanqianx/project-knowledge 5.0.8 → 5.0.9-rc.10
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +109 -0
- package/README.md +27 -4
- package/_modules/knowledge-engine/README.md +6 -1
- package/_modules/knowledge-engine/package.json +1 -1
- package/_modules/knowledge-engine/src/coordinator.js +68 -36
- package/_modules/knowledge-engine/src/diagnostics.js +1 -1
- package/_modules/knowledge-engine/src/headless-analyzer.js +3 -1
- package/_modules/knowledge-engine/src/index-request.js +49 -0
- package/_modules/knowledge-engine/src/knowledge-targets.js +46 -0
- package/_modules/knowledge-engine/src/retrieval.js +7 -5
- package/_modules/knowledge-engine/src/runtime/conversation-store.js +1 -1
- package/_modules/knowledge-engine/src/server.js +1 -1
- package/_modules/knowledge-engine/ui/app.js +1 -1
- package/_site/_test/candidate-release-contract-test.js +14 -0
- package/_site/_test/conversation-store-test.js +2 -0
- package/_site/_test/fixtures/make-git-repos.js +1 -9
- package/_site/_test/index-error-display-contract-test.js +10 -0
- package/_site/_test/knowledge-engine-client-test.js +105 -0
- package/_site/_test/product-brand-contract-test.js +25 -0
- package/_site/_test/release-version-sync-test.js +7 -1
- package/_site/_test/sessions-stream-test.js +3 -2
- package/_site/_test/shared-scope-root-binding-test.js +67 -0
- package/_site/_test/simple-import-test.js +3 -2
- package/_site/_test/team-knowledge-store-test.js +3 -2
- package/_site/_test/test-server-cleanup-test.js +31 -0
- package/_site/_test/vector-storage-root-test.js +52 -0
- package/_site/_test/workspace-ui-contract-test.js +1 -0
- package/_site/lib/contracts.js +5 -0
- package/_site/lib/conversation-store.js +1 -1
- package/_site/lib/engine-knowledge-client.js +72 -0
- package/_site/lib/knowledge-tool-runtime.js +7 -0
- package/_site/lib/module-bridge.js +44 -11
- package/_site/lib/server-app.js +3 -3
- package/_site/lib/settings-store.js +20 -0
- package/_site/lib/storage-layout.js +4 -0
- package/_site/scripts/pack-module-candidates.js +1 -1
- package/_site/scripts/sync-release-version.js +12 -10
- package/_site/scripts/verify-module-runtime.js +7 -2
- package/_site/scripts/verify-product-runtime.js +1 -0
- package/bin/project-knowledge-kb.js +4 -2
- package/bin/project-knowledge-mcp.js +7 -1
- package/module-runtime-manifest.json +41 -38
- package/package.json +6 -6
- package/plugins/project-knowledge/.claude-plugin/plugin.json +1 -1
- package/plugins/project-knowledge/.codex-plugin/plugin.json +1 -1
- package/plugins/project-knowledge/.mcp.json +1 -1
- package/ui/favicon.svg +5 -38
- package/ui/index.html +4 -4
- package/ui/product.css +2 -1
- package/ui/product.js +13 -2
- package/vendor-manifest.json +12 -10
package/ui/favicon.svg
CHANGED
|
@@ -1,38 +1,5 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<stop offset="1" stop-color="#06111f"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
<linearGradient id="core" x1="21" y1="16" x2="45" y2="44" gradientUnits="userSpaceOnUse">
|
|
9
|
-
<stop offset="0" stop-color="#dff8ff"/>
|
|
10
|
-
<stop offset=".48" stop-color="#7dd3fc"/>
|
|
11
|
-
<stop offset="1" stop-color="#2f7d64"/>
|
|
12
|
-
</linearGradient>
|
|
13
|
-
<linearGradient id="book" x1="18" y1="35" x2="48" y2="54" gradientUnits="userSpaceOnUse">
|
|
14
|
-
<stop offset="0" stop-color="#f8fafc"/>
|
|
15
|
-
<stop offset="1" stop-color="#b8c6d8"/>
|
|
16
|
-
</linearGradient>
|
|
17
|
-
<filter id="glow" x="-40%" y="-40%" width="180%" height="180%">
|
|
18
|
-
<feGaussianBlur stdDeviation="1.8" result="blur"/>
|
|
19
|
-
<feMerge>
|
|
20
|
-
<feMergeNode in="blur"/>
|
|
21
|
-
<feMergeNode in="SourceGraphic"/>
|
|
22
|
-
</feMerge>
|
|
23
|
-
</filter>
|
|
24
|
-
</defs>
|
|
25
|
-
<rect x="4" y="4" width="56" height="56" rx="15" fill="url(#bg)"/>
|
|
26
|
-
<path d="M16 42c-6-9-3-22 7-28 9-6 21-4 28 5" fill="none" stroke="#38bdf8" stroke-width="3.5" stroke-linecap="round" opacity=".82"/>
|
|
27
|
-
<path d="M48 18h-8l5 6" fill="none" stroke="#38bdf8" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" opacity=".82"/>
|
|
28
|
-
<path d="M50 25c4 10-1 23-12 27-9 4-20 1-25-8" fill="none" stroke="#75b798" stroke-width="3.5" stroke-linecap="round" opacity=".86"/>
|
|
29
|
-
<path d="M13 44h8l-5-6" fill="none" stroke="#75b798" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" opacity=".86"/>
|
|
30
|
-
<path d="M32 13 45 21v15l-13 8-13-8V21z" fill="url(#core)" filter="url(#glow)"/>
|
|
31
|
-
<path d="M32 18v21M23 24l9-6 9 6M23 33l9 6 9-6" fill="none" stroke="#0f1724" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" opacity=".9"/>
|
|
32
|
-
<circle cx="16" cy="20" r="4" fill="#c5a15d"/>
|
|
33
|
-
<circle cx="49" cy="43" r="4" fill="#38bdf8"/>
|
|
34
|
-
<path d="M20 42h25l5 5-6 6H19l-5-5z" fill="url(#book)"/>
|
|
35
|
-
<path d="M20 42 14 48l25 1 6-7" fill="#e2e8f0"/>
|
|
36
|
-
<path d="M19 53h25l6-6" fill="none" stroke="#64748b" stroke-width="2.7" stroke-linecap="round" stroke-linejoin="round"/>
|
|
37
|
-
<path d="M24 47h14" stroke="#4f6f8f" stroke-width="3" stroke-linecap="round"/>
|
|
38
|
-
</svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="Project Knowledge">
|
|
2
|
+
<title>Project Knowledge · 折页 K</title>
|
|
3
|
+
<rect width="64" height="64" rx="16" fill="#516f89"/>
|
|
4
|
+
<path d="M16 15h8v13l14-13h10L30 32l18 17H38L24 36v13h-8Z" fill="#fff"/>
|
|
5
|
+
</svg>
|
package/ui/index.html
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
<html lang="zh-CN" data-theme="light">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="color-scheme" content="light dark">
|
|
5
|
-
<title>Project Knowledge · 我的智脑</title><link rel="icon" href="/favicon.svg"><link rel="stylesheet" href="/product.css">
|
|
5
|
+
<title>Project Knowledge · 我的智脑</title><link rel="icon" type="image/svg+xml" href="/favicon.svg?v=folded-k-1"><link rel="stylesheet" href="/product.css">
|
|
6
6
|
</head>
|
|
7
7
|
<body>
|
|
8
8
|
<div class="app">
|
|
9
9
|
<aside class="sidebar">
|
|
10
|
-
<div class="brand"><
|
|
10
|
+
<div class="brand"><img class="brand-mark" src="/favicon.svg?v=folded-k-1" width="32" height="32" alt=""><div><strong>Project Knowledge</strong><small>个人工程智脑</small></div></div>
|
|
11
11
|
<div id="brainLabel" class="brain-label">我的智脑</div>
|
|
12
12
|
<nav aria-label="主要导航">
|
|
13
13
|
<button data-view="home"><svg viewBox="0 0 24 24"><path d="m3 11 9-7 9 7M5 10v10h14V10"/></svg>智脑首页</button>
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
<button id="openSystem" class="system-button"><span class="dot" id="systemDot"></span><span><b id="systemTitle">正在检查系统</b><small id="systemDetail">本机知识服务</small></span><svg viewBox="0 0 24 24"><path d="m9 6 6 6-6 6"/></svg></button>
|
|
21
21
|
</aside>
|
|
22
22
|
<main>
|
|
23
|
-
<header class="topbar"><div><small id="breadcrumb">我的智脑</small><h1 id="pageTitle">智脑首页</h1></div><div class="spacer"></div><select id="projectSelect" aria-label="当前项目"><option value="">尚未导入项目</option></select><button id="themeToggle" class="icon-button" title="切换浅色或深色主题" aria-label="切换主题"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="4"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/></svg></button></header>
|
|
23
|
+
<header class="topbar"><div><small id="breadcrumb">我的智脑</small><h1 id="pageTitle">智脑首页</h1></div><div class="spacer"></div><select id="projectSelect" aria-label="当前项目" disabled><option value="">尚未导入项目</option></select><button id="themeToggle" class="icon-button" title="切换浅色或深色主题" aria-label="切换主题"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="4"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/></svg></button></header>
|
|
24
24
|
<div class="content">
|
|
25
25
|
<section class="view" id="view-home"><div class="welcome"><div><small>工作概览</small><h2 id="homeTitle">我的智脑</h2><p>保存项目事实,连接相关经验。你的长期偏好,只在确认后使用。</p></div><div class="actions"><button class="primary" data-go="work">开始工作</button><button data-action="import">导入项目</button></div></div><div id="homeContent"></div></section>
|
|
26
26
|
<section class="view module-view" id="view-work"><div id="workEmpty" class="empty" hidden>导入项目后,就可以在这里开始工作。<button data-action="import">导入项目</button></div><div class="work-layout" id="workLayout"><div class="frame-container"><iframe id="workFrame" title="Agent 工作台" referrerpolicy="same-origin"></iframe></div><aside class="knowledge-context"><header><h2>本次知识引用</h2><small id="contextScope">任务发送前自动检索</small></header><div id="contextContent" class="empty small-empty">发送任务后显示实际检索到的项目事实、领域经验和已确认记忆。</div></aside></div></section>
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
<section id="agentCaptureSection"><div class="actions"><h3>外部 Agent 采集</h3><button id="refreshAgentCapture">检查状态</button></div><p class="muted">只接入你使用的工具。采集外部开发会话,不会重新安装 Agent,也不影响已有记录。</p><div id="agentCaptureList"></div><p id="agentCaptureFeedback" class="feedback" role="status"></p></section>
|
|
41
41
|
<section><h3>后台维护模型</h3><p class="muted">使用持久化默认模型,不跟随聊天中的临时切换。</p><select id="maintenanceModel" aria-label="后台维护默认模型"></select><div class="actions"><button id="saveMaintenance">保存默认模型</button><button id="configureProviders">管理模型供应商</button></div><p id="configurationStatus" class="muted"></p></section>
|
|
42
42
|
<section><h3>向量检索模型</h3><p id="embeddingStatus" class="muted">正在读取配置。</p><button id="openEmbedding">配置向量模型</button><p class="muted">凭据由工作台统一保存。未配置时仍可使用文本检索。</p></section>
|
|
43
|
-
<section><h3>智脑设置</h3><label>名称<input id="brainName" maxlength="100"></label><label>知识根目录<div class="input-with-action"><input id="knowledgeRoot"><button id="pickRoot">选择</button></div></label><p class="muted"
|
|
43
|
+
<section><h3>智脑设置</h3><label>名称<input id="brainName" maxlength="100"></label><label>知识根目录<div class="input-with-action"><input id="knowledgeRoot"><button id="pickRoot">选择</button></div></label><label>向量索引目录<output id="indexStoragePath" class="detail-path"></output></label><p id="indexStorageStatus" class="muted"></p><p class="muted">索引跟随知识根目录,可重新构建;切换时原索引保留,已有项目知识与共享知识不移动。</p><button id="saveBrainSettings">保存设置</button></section>
|
|
44
44
|
<section><div class="actions"><button id="openEngine">知识引擎诊断</button><button id="openLogs">系统诊断记录</button></div><p class="muted">诊断不影响正在进行的会话与维护。</p></section>
|
|
45
45
|
</div>
|
|
46
46
|
</aside>
|
package/ui/product.css
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
:root{--page:#f3f5f7;--surface:#fff;--surface2:#f8f9fb;--surface3:#edf1f4;--line:#dce2e8;--text:#202733;--muted:#687587;--faint:#8e99a7;--nav:#eef1f4;--accent:#516f89;--accent-soft:#e6edf3;--good:#397761;--bad:#a05252;--bad-soft:#fbeeee;color-scheme:light}
|
|
2
|
+
label>.detail-path{display:block;width:100%;margin:8px 0 0;color:var(--text)}
|
|
2
3
|
.agent-capture-row{display:flex;align-items:center;gap:16px;padding:16px 0;border-bottom:1px solid var(--line)}.agent-capture-row>div:first-child{flex:1;min-width:0}.agent-capture-row small{display:block;color:var(--muted);margin-top:8px;overflow-wrap:anywhere}.agent-capture-row .actions{flex-shrink:0}#agentCaptureFeedback{white-space:pre-wrap}
|
|
3
4
|
#logsDialog{display:flex;flex-direction:column;overflow:hidden}#logsDialog:not([open]){display:none}#logsContent{overflow:auto;min-height:0;flex:1;margin-top:16px}#logsContent .row{align-items:flex-start;cursor:pointer}#logsContent pre{flex:1;min-width:0;margin:0}#logsContent .log-entry{border-bottom:1px solid var(--line)}#logsContent .log-detail{padding:16px;background:var(--surface2);max-height:320px;overflow:auto}#logsContent [data-level=warn],#logsContent [data-level=error],#logsContent [data-level=fatal]{color:var(--bad)}#logsContent .row time,#logsContent .row pre{color:inherit}
|
|
4
5
|
@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;animation:none!important;transition:none!important}}
|
|
5
6
|
.knowledge-context{overflow-x:hidden}.reference{overflow-wrap:anywhere}.reference small{min-width:0;max-width:100%}
|
|
6
7
|
html[data-theme=dark]{--page:#171a1f;--surface:#20252d;--surface2:#252b34;--surface3:#2c333e;--line:#39424f;--text:#e6ebf0;--muted:#a0aaba;--faint:#788393;--nav:#1b2028;--accent:#8aa8cf;--accent-soft:#293748;--good:#81b29a;--bad:#d88b8b;--bad-soft:#39292d;color-scheme:dark}
|
|
7
8
|
*{box-sizing:border-box}[hidden]{display:none!important}html,body{height:100%}body{margin:0;overflow:hidden;background:var(--page);color:var(--text);font:13px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei",sans-serif}button,input,select,textarea{font:inherit;color:inherit}button{cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:34px;padding:6px 12px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}button:hover{background:var(--surface3)}button:disabled{opacity:.5;cursor:not-allowed}button.primary{background:var(--accent);color:#fff;border-color:var(--accent)}button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid var(--accent);outline-offset:3px}svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;flex:none}h1,h2,h3,p{margin:0}h1{font-size:18px;font-weight:650}h2{font-size:16px;font-weight:600}h3{font-size:13px;font-weight:600}small,.muted{color:var(--muted)}small{font-size:11px}p{color:var(--muted);margin-top:8px}input,select,textarea{background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:8px 12px;min-width:0}label{display:block;font-size:12px;margin:16px 0;color:var(--muted)}label>input,label>select,label>textarea{display:block;width:100%;margin-top:8px;color:var(--text)}pre{font:12px/1.8 Consolas,"Microsoft YaHei",monospace;white-space:pre-wrap;overflow-wrap:anywhere;color:var(--text)}
|
|
8
|
-
.app{height:100%;display:grid;grid-template-columns:232px minmax(0,1fr)}.sidebar{display:flex;flex-direction:column;border-right:1px solid var(--line);background:var(--nav);min-height:0}.brand{display:flex;align-items:center;gap:8px;padding:24px 20px 16px}.brand-mark{width:
|
|
9
|
+
.app{height:100%;display:grid;grid-template-columns:232px minmax(0,1fr)}.sidebar{display:flex;flex-direction:column;border-right:1px solid var(--line);background:var(--nav);min-height:0}.brand{display:flex;align-items:center;gap:8px;padding:24px 20px 16px}.brand-mark{width:32px;height:32px;display:block;flex:none;object-fit:contain}.brand strong{font-size:14px}.brand small{display:block}.brain-label{padding:0 20px 16px;color:var(--muted);overflow-wrap:anywhere}.sidebar nav{display:grid;gap:8px;padding:8px 12px}.sidebar nav button{justify-content:flex-start;min-height:40px;text-align:left;border-color:transparent;background:transparent;color:var(--muted)}.sidebar nav button.active{border-color:var(--line);background:var(--surface);color:var(--text)}.count{margin-left:auto;background:var(--surface3);padding:0 6px;border-radius:4px}.system-button{margin: auto 12px 16px;justify-content:flex-start;min-height:56px;background:transparent;border-color:transparent;padding:8px}.system-button>span:nth-child(2){flex:1;text-align:left}.system-button b,.system-button small{display:block;font-size:11px}.dot{width:7px;height:7px;border-radius:50%;background:var(--faint);flex:none}.dot.up{background:var(--good)}.dot.issue{background:var(--bad)}main{min-width:0;min-height:0;display:flex;flex-direction:column}.topbar{height:72px;flex:none;display:flex;align-items:center;gap:16px;padding:0 24px;background:var(--surface);border-bottom:1px solid var(--line)}.spacer{flex:1}.topbar select{width:240px}.icon-button{padding:8px;min-width:34px}.content{position:relative;flex:1;min-height:0}.view{display:none;height:100%;overflow:auto;padding:32px}.view.active{display:block}.view.module-view{padding:0;overflow:hidden}.module-view.active{display:flex;flex-direction:column}.frame-container{position:relative;flex:1;min-width:0;min-height:0;overflow:hidden;background:var(--surface)}iframe{display:block;width:100%;height:100%;border:0;background:var(--surface)}.work-layout{display:grid;grid-template-columns:minmax(0,1fr) 288px;height:100%;min-height:0}.knowledge-context{background:var(--surface2);border-left:1px solid var(--line);overflow:auto;padding:24px 16px}.knowledge-context header{margin-bottom:24px}.knowledge-context h2{font-size:13px}.module-toolbar{flex:none;min-height:56px;display:flex;justify-content:space-between;align-items:center;gap:16px;padding:8px 24px;border-bottom:1px solid var(--line);background:var(--surface)}.segmented{display:flex;gap:4px}.segmented button{background:transparent;border-color:transparent;color:var(--muted)}.segmented button.active{background:var(--surface);border-color:var(--line);color:var(--text)}
|
|
9
10
|
.welcome{display:flex;align-items:center;justify-content:space-between;gap:24px;margin-bottom:32px}.welcome h2{font-size:24px;margin-top:8px}.actions{display:flex;gap:8px;align-items:center}.grid2{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(320px,1fr);gap:24px}.stack{display:grid;gap:24px}.panel{border:1px solid var(--line);background:var(--surface);border-radius:8px;padding:24px;min-width:0}.panel h2{margin-bottom:16px}.section-heading{display:flex;align-items:center;justify-content:space-between;gap:24px;margin-bottom:24px}.section-heading p{font-size:12px}.row{display:flex;align-items:center;gap:16px;padding:16px 0;border-bottom:1px solid var(--line)}.row:last-child{border-bottom:0}.row>div{flex:1;min-width:0}.row b{font-weight:600}.row small{display:block;margin-top:4px;overflow-wrap:anywhere}.row time{color:var(--muted);font-size:11px;flex:none}.status{font-size:11px;border:1px solid var(--line);border-radius:4px;padding:2px 8px;white-space:nowrap;color:var(--muted)}.status.up{color:var(--good)}.status.issue{color:var(--bad);background:var(--bad-soft)}.empty{padding:64px 24px;text-align:center;color:var(--muted);background:var(--surface);border-radius:8px;line-height:1.9}.empty button{display:block;margin:16px auto 0}.small-empty{padding:16px 0;text-align:left;background:transparent;font-size:12px}.hierarchy{display:grid;grid-template-columns:296px minmax(0,1fr);gap:24px}.tree h3{margin:24px 0 8px;color:var(--muted);font-size:11px}.tree button{width:100%;justify-content:flex-start;text-align:left;background:transparent;border-color:transparent;margin-top:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tree button.active{background:var(--accent-soft);color:var(--accent)}.detail-path{padding:12px 16px;background:var(--surface2);border:1px solid var(--line);border-radius:8px;margin:8px 0 24px;font:12px/1.8 Consolas,"Microsoft YaHei",monospace;overflow-wrap:anywhere}.detail-label{color:var(--muted);font-size:11px}.memory-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px;margin-top:24px}.memory-card{padding:24px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}.memory-card p{color:var(--text);margin:0 0 16px;white-space:pre-wrap}.memory-card .actions{margin-top:16px}.reference{display:block;text-align:left;width:100%;background:transparent;border:0;border-bottom:1px solid var(--line);border-radius:0;padding:16px 0}.reference b,.reference small{display:block;text-align:left}.reference p{font-size:12px;text-align:left}.activity-updates{flex:1;overflow:auto;padding:24px 32px}.run{margin-bottom:16px;background:var(--surface);border:1px solid var(--line);border-radius:8px}.run summary{padding:16px 24px;cursor:pointer;display:flex;align-items:center;gap:16px}.run summary strong{flex:1}.run>div{padding:0 24px 24px}.run .error{color:var(--bad)}.operation{padding:8px 0;color:var(--muted)}
|
|
10
11
|
.drawer-backdrop{position:fixed;inset:0;background:rgba(10,18,25,.25);z-index:20}.drawer{position:fixed;right:0;top:0;height:100%;width:448px;background:var(--surface);border-left:1px solid var(--line);z-index:21;display:flex;flex-direction:column}.drawer>header{height:72px;display:flex;align-items:center;justify-content:space-between;padding:24px;border-bottom:1px solid var(--line)}.drawer-content{overflow:auto;flex:1;padding:24px}.drawer section{padding-bottom:24px;margin-bottom:24px;border-bottom:1px solid var(--line)}.drawer select{width:100%;margin:16px 0}.drawer .actions{flex-wrap:wrap}.drawer section:last-child{border-bottom:0}.input-with-action{display:flex;gap:8px;margin-top:8px}.input-with-action input{flex:1}.input-with-action button{flex:none}.checkbox{display:flex;align-items:center;gap:8px}.checkbox input{width:auto;margin:0}dialog{width:560px;max-width:90vw;max-height:90vh;overflow:auto;background:var(--surface);color:var(--text);border:1px solid var(--line);border-radius:12px;padding:24px}dialog::backdrop{background:rgba(10,18,25,.35)}.dialog-heading{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.dialog-heading>button{border:0;background:transparent;font-size:20px}.dialog-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:24px}.feedback{padding:12px 16px;background:var(--surface2);border:1px solid var(--line);border-radius:8px;color:var(--muted);white-space:pre-wrap}.feedback.issue{color:var(--bad)}.reference-dialog{width:880px}.reference-dialog pre{margin-top:24px;max-height:60vh;overflow:auto}.engine-dialog{width:calc(100vw - 96px);height:calc(100vh - 96px);padding:0;overflow:hidden}.engine-dialog .dialog-heading{height:64px;padding:16px 24px;border-bottom:1px solid var(--line);margin:0}.engine-dialog iframe{height:calc(100% - 64px)}.toast{position:fixed;bottom:24px;right:24px;z-index:50;background:var(--surface);padding:12px 16px;border:1px solid var(--line);border-radius:8px;max-width:480px;color:var(--text)}
|
package/ui/product.js
CHANGED
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
$('activityUpdates').hidden = state.activityTab !== 'updates'; $('activitySessions').hidden = state.activityTab !== 'sessions';
|
|
114
114
|
const runs = state.snapshot.runs.filter(r => r.projectId === state.projectId);
|
|
115
115
|
const open = new Set(all('.run[open]').map(d => d.dataset.runId));
|
|
116
|
-
$('activityUpdates').innerHTML = state.engineAvailable ? runs.map(r => `<details class="run" data-run-id="${esc(r.runId)}" ${open.has(r.runId) ? 'open' : ''}><summary><time>${time(r.startedAt)}</time><strong>${esc(projectName(r.projectId))} · ${esc(r.commitSha.slice(0, 8))}</strong>${badge(label(r), ['failed', 'index-pending'].includes(r.state) ? 'issue' : r.state === 'succeeded' ? 'up' : '')}</summary><div><p>提交:${esc(r.commitSha)}<br>阶段:${esc(r.phase)} · 入口:${esc(r.trigger)}<br>知识晋升:${time(r.promotedAt)} · 索引:${esc(r.indexState)}</p>${r.error ? `<p class="error">${esc(r.error.message)} (${esc(r.error.code)})</p>` : ''}${(r.staging?.operations || []).map(op => `<div class="operation">${esc(op.operation)} · ${esc(op.path)}<br>${esc(op.reason)}</div>`).join('')}${['failed', 'index-pending'].includes(r.state) ? `<button data-retry-run="${esc(r.runId)}">重试失败阶段</button>` : ''}</div></details>`).join('') || '<div class="empty">当前项目还没有知识维护记录。</div>' : '<div class="empty">知识引擎离线。记录仍保留在本机,连接恢复后自动读取。</div>';
|
|
116
|
+
$('activityUpdates').innerHTML = state.engineAvailable ? runs.map(r => `<details class="run" data-run-id="${esc(r.runId)}" ${open.has(r.runId) ? 'open' : ''}><summary><time>${time(r.startedAt)}</time><strong>${esc(projectName(r.projectId))} · ${esc(r.commitSha.slice(0, 8))}</strong>${badge(label(r), ['failed', 'index-pending'].includes(r.state) ? 'issue' : r.state === 'succeeded' ? 'up' : '')}</summary><div><p>提交:${esc(r.commitSha)}<br>阶段:${esc(r.phase)} · 入口:${esc(r.trigger)}<br>知识晋升:${time(r.promotedAt)} · 索引:${esc(r.indexState)}</p>${r.error ? `<p class="error">${esc(r.error.message)} (${esc(r.error.code)})</p>${r.error.details ? `<p>失败原因:${esc(r.error.details.upstreamMessage)}<br>类别:${esc(r.error.details.failureKind)} · HTTP:${esc(r.error.details.httpStatus ?? '—')} · 上游代码:${esc(r.error.details.upstreamCode)}<br>请求标识:${esc(r.error.details.requestId || '—')} · 尝试:${esc(r.error.details.attempt)} · 耗时:${esc(r.error.details.durationMs ?? '—')} ms</p>` : ''}` : ''}${(r.staging?.operations || []).map(op => `<div class="operation">${esc(op.operation)} · ${esc(op.path)}<br>${esc(op.reason)}</div>`).join('')}${['failed', 'index-pending'].includes(r.state) ? `<button data-retry-run="${esc(r.runId)}">重试失败阶段</button>` : ''}</div></details>`).join('') || '<div class="empty">当前项目还没有知识维护记录。</div>' : '<div class="empty">知识引擎离线。记录仍保留在本机,连接恢复后自动读取。</div>';
|
|
117
117
|
}
|
|
118
118
|
function renderContext() {
|
|
119
119
|
const saved = state.contexts.get(state.projectId);
|
|
@@ -159,6 +159,8 @@
|
|
|
159
159
|
const [brain, projects, health] = await Promise.all([api('/api/brain'), api('/api/projects/aggregated'), api('/api/modules/health')]);
|
|
160
160
|
if (epoch !== registryEpoch) return;
|
|
161
161
|
state.brain = brain.brain; state.root = brain.knowledgeRoot; state.projects = projects.projects; state.health = health.modules; state.ownership = health.ownership;
|
|
162
|
+
state.indexStorage = { path: brain.indexStoragePath, ...brain.configuration?.indexStorage };
|
|
163
|
+
state.scopeStatus = brain.configuration?.scopeStatus;
|
|
162
164
|
if (!activeProject()) { state.projectId = state.projects[0]?.projectId || ''; state.epoch++; Object.keys(frames).forEach(frameContext); }
|
|
163
165
|
renderProjectOptions(); renderSystem(); connectProgress(); await refreshSnapshot(); setView(state.view);
|
|
164
166
|
} catch (error) { toast(error.message); }
|
|
@@ -170,9 +172,13 @@
|
|
|
170
172
|
function renderSystem() {
|
|
171
173
|
const down = Object.keys(modules).filter(key => !state.health[key]?.up);
|
|
172
174
|
const pending = state.ownership?.owner === 'engine' && !state.ownership.ready;
|
|
175
|
+
const storagePending = !!state.indexStorage?.expectedPath && state.indexStorage.status !== 'ready';
|
|
176
|
+
renderStorageInfo();
|
|
173
177
|
$('systemDot').className = `dot ${down.length || pending ? 'issue' : 'up'}`;
|
|
174
178
|
$('systemTitle').textContent = pending ? '知识引擎连接待恢复' : down.length ? '部分服务需要处理' : '系统连接正常';
|
|
175
179
|
$('systemDetail').textContent = pending ? `${state.ownership.message || '服务恢复后自动重试。'}${state.ownership.error ? ` · ${state.ownership.error.step} (${state.ownership.error.code})` : ''}` : down.length ? down.map(k => modules[k]).join('、') : '本机知识服务已连接';
|
|
180
|
+
if (storagePending && !pending && !down.length) { $('systemDot').className = 'dot issue'; $('systemTitle').textContent = '索引目录接线待恢复'; $('systemDetail').textContent = `目标目录:${state.indexStorage.expectedPath}。请在系统状态中修复接线。`; }
|
|
181
|
+
if (state.root && state.scopeStatus?.status === 'pending' && !pending && !down.length) { $('systemDot').className = 'dot issue'; $('systemTitle').textContent = '共享知识接线待恢复'; $('systemDetail').textContent = '已有知识与长期记忆保留,请在系统状态中修复接线。'; }
|
|
176
182
|
$('moduleHealth').innerHTML = Object.entries(modules).map(([key, name]) => `<div class="row"><div><b>${esc(name)}</b><small>${esc(state.health[key]?.url || '')}</small></div>${badge(state.health[key]?.up ? '在线' : '离线', state.health[key]?.up ? 'up' : 'issue')}</div>`).join('');
|
|
177
183
|
if (!navigator.onLine) {
|
|
178
184
|
$('systemDot').className = 'dot issue'; $('systemTitle').textContent = '网页连接中断';
|
|
@@ -183,8 +189,13 @@
|
|
|
183
189
|
async function openSystem() {
|
|
184
190
|
$('systemDrawer').hidden = false; $('drawerBackdrop').hidden = false;
|
|
185
191
|
$('brainName').value = state.brain.name; $('knowledgeRoot').value = state.root;
|
|
192
|
+
renderStorageInfo();
|
|
186
193
|
await Promise.all([loadMaintenance(), loadAgentCapture()]);
|
|
187
194
|
}
|
|
195
|
+
function renderStorageInfo() {
|
|
196
|
+
$('indexStoragePath').textContent = state.indexStorage?.actualPath || state.indexStorage?.path || '设置知识根目录后自动确定';
|
|
197
|
+
$('indexStorageStatus').textContent = state.indexStorage?.status === 'ready' ? '索引目录已生效。' : `索引接线待恢复;目标目录:${state.indexStorage?.expectedPath || state.indexStorage?.path || '尚未设置'}`;
|
|
198
|
+
}
|
|
188
199
|
async function loadAgentCapture() {
|
|
189
200
|
const epoch = ++captureEpoch;
|
|
190
201
|
try {
|
|
@@ -376,7 +387,7 @@
|
|
|
376
387
|
on('embeddingForm', 'submit', async event => { event.preventDefault(); await saveEmbedding(); });
|
|
377
388
|
on('disableEmbedding', 'click', () => saveEmbedding(false));
|
|
378
389
|
on('embeddingDialog', 'close', () => { $('embeddingSecret').value = ''; });
|
|
379
|
-
on('saveBrainSettings', 'click', async () => { await api('/api/brain', { method: 'PATCH', body: { name: $('brainName').value } }); await api('/api/settings', { method: 'PATCH', body: { knowledge: { rootPath: $('knowledgeRoot').value } } }); toast('
|
|
390
|
+
on('saveBrainSettings', 'click', async () => { await api('/api/brain', { method: 'PATCH', body: { name: $('brainName').value } }); const saved = await api('/api/settings', { method: 'PATCH', body: { knowledge: { rootPath: $('knowledgeRoot').value } } }); toast(saved.configuration?.scopeStatus?.status === 'pending' ? '设置已保存,共享知识接线待恢复;已有知识保留。' : saved.configuration?.indexStorage?.status === 'ready' ? '设置已保存,索引目录已生效;已有知识未移动。' : '设置已保存,索引目录接线待恢复;已有知识保留。'); await refreshRegistry(true); if (resumeImport) closeSystem(); });
|
|
380
391
|
on('setupImportRoot', 'click', async () => { $('importDialog').close(); resumeImport = true; await openSystem(); $('knowledgeRoot').focus(); });
|
|
381
392
|
on('pickRoot', 'click', () => pick('knowledgeRoot')); on('pickCode', 'click', () => pick('importCode')); on('pickKnowledge', 'click', () => pick('importKnowledge'));
|
|
382
393
|
on('openEngine', 'click', () => { closeSystem(); initializeFrame('engine'); $('engineDialog').showModal(); post('engine', { type: 'kb:visibility', visible: true }); });
|
package/vendor-manifest.json
CHANGED
|
@@ -3,21 +3,23 @@
|
|
|
3
3
|
"modules": {
|
|
4
4
|
"knowledge-engine": {
|
|
5
5
|
"name": "@sanqianx/ai-coding-knowledge-engine",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.3-rc.4",
|
|
7
7
|
"root": "_modules/knowledge-engine",
|
|
8
8
|
"files": {
|
|
9
|
-
"README.md": "
|
|
10
|
-
"package.json": "
|
|
9
|
+
"README.md": "df15aafdfe833186c1f655a1847171435214b96ad168c5eb44774fec82d28cf6",
|
|
10
|
+
"package.json": "61e95ac2871a4e4e8964851161aac3c7fe4ef5015c8d03ec6ff1e9e53bbaa43f",
|
|
11
11
|
"src/analysis-contract.js": "fee063967d32eefc955cf0729f7dc8cb31bd690b85e22471c9059494a599c77a",
|
|
12
12
|
"src/analysis-output.js": "95a3c19dcc9ab85d1dba7fee5b9aec80f9c000dfba89da3fd0be25a81e2fb680",
|
|
13
13
|
"src/analysis-worker.js": "a105cabe6e1573b2d986b1e7a5aaf615e2fb53524156fc8e4e2c0a71f2c97e55",
|
|
14
14
|
"src/bin.js": "22208907431d0f3a971a669c7e5eb44b3b7af9bbb36fd7ba17c3b90c4288bd70",
|
|
15
15
|
"src/bridge-client.js": "ae0dba21e4286694bcd9e064ca36564ec997969ae1eb1ce4f8a6665e447cbffe",
|
|
16
|
-
"src/coordinator.js": "
|
|
17
|
-
"src/diagnostics.js": "
|
|
18
|
-
"src/headless-analyzer.js": "
|
|
16
|
+
"src/coordinator.js": "1df096060faa83245c49b65a861f32cdaeeb7a190b94abf2ad6477151d7ca2ff",
|
|
17
|
+
"src/diagnostics.js": "f7b516ace61a1e9faaa6876930b9e2e258499a25857d1203f4e53d28bfd0fa1a",
|
|
18
|
+
"src/headless-analyzer.js": "2f345adee332c003ecb9a1e01eac4fa69d8802b4e6dd9effb03ac3cb19aa3e48",
|
|
19
|
+
"src/index-request.js": "78f26b872299005499fff4f2d1f9e8f986784f2ff36a5cf2be2b1e7b7c7d9378",
|
|
20
|
+
"src/knowledge-targets.js": "aa44ec285d16d7b1c0b63bf084058a1d6f867fa9929c753b6b0cbb24f7b20ee2",
|
|
19
21
|
"src/memories.js": "0a8667e6daba99fa5022393951a28e96cdadf98af85b6af9a6be96c7f4e896fc",
|
|
20
|
-
"src/retrieval.js": "
|
|
22
|
+
"src/retrieval.js": "bbb09cefc3c6ed692a51edfeecf6ac50619b8a2afbdf2034e0fdb5e00f4cfa68",
|
|
21
23
|
"src/runtime/README.md": "9be676eca76a7857b34d7357194e6f0ee733c22e61d962d53984715dbec7f673",
|
|
22
24
|
"src/runtime/atomic-file.js": "9846b4b69db5ded811acf19a1181ef93615d93efaa542b858e552a7f3124ad23",
|
|
23
25
|
"src/runtime/automation-config.js": "6498c5397be12b155829740595a1553d4dcd6eaa7db6ced3ef88fdc60218f00e",
|
|
@@ -28,7 +30,7 @@
|
|
|
28
30
|
"src/runtime/content-hash.js": "201ee7dcc054310f14097a00058cf9b28fa913367eef616e0fdd8facbf3c6c41",
|
|
29
31
|
"src/runtime/contracts.js": "567fbace85ad0534fb0119f5c0e57d73acc0b76cc799af93d778c5ecbade53df",
|
|
30
32
|
"src/runtime/conversation-exclusions.js": "ef8545034b862d384fb460140490bb531b58d94992f5e2222ebaaa079b44fa63",
|
|
31
|
-
"src/runtime/conversation-store.js": "
|
|
33
|
+
"src/runtime/conversation-store.js": "644318f9c04376a3317ced240dd94afa99a79631f0ecc394c5aa298ae2bc0474",
|
|
32
34
|
"src/runtime/evidence-bundle.js": "33d4614849d5e1d69aba8b75c3a43c18b7b6f94e5c78654c82ef631331cc94cc",
|
|
33
35
|
"src/runtime/git-runner.js": "b74fe197bd4dcf3e70635ef7b1f2615edf965c1d9a3ffe5406aabd41b76d74a9",
|
|
34
36
|
"src/runtime/knowledge-promotion.js": "c24aba505caf11cdc8faba763beffc65956c1330ef28ed5fbd6ae16eac640fa6",
|
|
@@ -36,10 +38,10 @@
|
|
|
36
38
|
"src/runtime/layout.js": "c48fa1db62e5df1edefe13218e470c5ceea4ef2781293512c2c18e5c2ba0c7e9",
|
|
37
39
|
"src/runtime/markdown-knowledge-indexer.js": "44a76a9adefad07e78f77b1106b10d6c1cc7873d76362df4c546892b21f3939c",
|
|
38
40
|
"src/runtime/scanner.js": "d99fa8d74a6fbbaae75ca49f62127e14cf9e48b1404e4b4d597ef39df5441410",
|
|
39
|
-
"src/server.js": "
|
|
41
|
+
"src/server.js": "7deff466d28b94ec8975cd87ebd55c59d0aa6b49a8dfa447b552b1d32aa9c4b7",
|
|
40
42
|
"src/store.js": "71f0417c2c1e42b89429e3dee1adff7b2c09e86682cb3f4843ce6d9e5aafd7ec",
|
|
41
43
|
"ui/app.css": "7ad370c269e60a7b5ec907d81a607b2d16bd07b2d7c22a81f102dab51eeb2889",
|
|
42
|
-
"ui/app.js": "
|
|
44
|
+
"ui/app.js": "33a2ba38f0dafbbb2e30a1eb3fc93476bfcaf528e124e1a9b2edd2fb69221e9e",
|
|
43
45
|
"ui/index.html": "ce3565cfefd4838b11d37a91a906ef26ca5a1834844fe3f7c897b56851a3c418"
|
|
44
46
|
}
|
|
45
47
|
}
|