chainlesschain 0.162.2 → 0.162.7
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/package.json +2 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-D69_XwQf.js → AIOps-BXQ92dvI.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-COVVHNnK.js → ActionButton-DjmolmAS.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-m0Cuoraq.js → Analytics-LUUOS78B.js} +2 -2
- package/src/assets/web-panel/assets/{AppLayout-BEZq_CS0.css → AppLayout-BLCe1k8m.css} +1 -1
- package/src/assets/web-panel/assets/AppLayout-DeAq-Waa.js +3 -0
- package/src/assets/web-panel/assets/{Audit-DB5RNs9K.js → Audit-De_86BpN.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DD9SgVtq.js → Backup-CAqIbrb5.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CS2Y4V0O.js → BaseInput-CwTVDavS.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-Cvw48zqw.js → Chat-BnihAKiI.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-DElRJpAL.js → Checkbox-BDrCuC9m.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CHdMYssy.js → Codegen-DWqN0jpL.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BDk4BXjN.js → Col-B7rIr4g3.js} +1 -1
- package/src/assets/web-panel/assets/{Community-ByDrN94M.js → Community-YYEO8SY3.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-D4E0roed.js → Compact-DZHWn-_j.js} +1 -1
- package/src/assets/web-panel/assets/Compliance-CCYzk_rt.js +1 -0
- package/src/assets/web-panel/assets/{Cowork-CMn6mzHv.js → Cowork-D9G6khOx.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-CARdrrMM.js → Cron-IbwddEeZ.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-2pnRIGVn.js → Crosschain-Bct133LN.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BRo55XlY.js → DID-32J0mXoS.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DfNjjw7V.js → Dashboard-TaPAK2WV.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BDTTlG70.js → Dropdown-Df4hUeIm.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CKkeJ169.js → Federation-C0xfKoZr.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-C6DJ0oHT.js → FormItemContext-CoacTa1H.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DDQd8pDl.js → Git-DZZF1lrY.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DZTuAASB.js → Governance-Bo-P_BP3.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CIbj0XmL.js → Inference-agx6qPl9.js} +1 -1
- package/src/assets/web-panel/assets/KnowledgeGraph-Dc8YZGiO.js +1 -0
- package/src/assets/web-panel/assets/{Logs-BrLBwq1m.js → Logs-njAOFc0W.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-q9X5VK92.js → Marketplace-Yu-RUTN2.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DfxuLN57.js → McpTools-BuzdmOwR.js} +1 -1
- package/src/assets/web-panel/assets/{Memory-DND9vjBx.js → Memory-DJyWxXM0.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Ba2jSFl0.js → MobileBridge-CIKfLcfn.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CdclN769.js → MobileProjects-B1OZ0_b1.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BNKpFjlY.js → Mtc-CJHI9qG0.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-BlZJm1Tf.js → MtcAudit-cSrqcG3H.js} +1 -1
- package/src/assets/web-panel/assets/{Multisig-DcX0uBmT.js → Multisig-DTVo9GFR.js} +2 -2
- package/src/assets/web-panel/assets/{NLProgramming-dDIA3V_a.js → NLProgramming-NqfB2jLI.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BDsTuZ5O.js → Notes-MuMFfs67.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DzGuAAKt.js → NotificationSettings-B5ECNQNW.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-DFfncYaU.js → Organization-Dn98sbrZ.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-O5JDtvyx.js → Overflow-Sl5FJV2c.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BTLl5rnf.js → P2P-58-TvQSE.js} +2 -2
- package/src/assets/web-panel/assets/{Permissions-M-jmJa1X.js → Permissions-BFtHCNck.js} +4 -4
- package/src/assets/web-panel/assets/PersonalDataHub-CVH9NAfL.css +1 -0
- package/src/assets/web-panel/assets/PersonalDataHub-Cu--XeWZ.js +1 -0
- package/src/assets/web-panel/assets/{Pipeline-DyXoKp_J.js → Pipeline-DWt_M98L.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Cvv_9eBQ.js → Privacy-BUX3yRZc.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BS2s_sxy.js → ProjectInit-wYWMWfxy.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CGfEpOL1.js → ProjectSettings-CIRbqu0F.js} +1 -1
- package/src/assets/web-panel/assets/{Projects-BkuTxL3o.js → Projects-CDFkiEL3.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-CkhZ5eii.js → Providers-CnPu1q45.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CvGT4zj2.js → QuickAsk-mwOI7Tc-.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-C-gDvXw6.js → Recommend-Ct6SM2HV.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-5zAdCzHT.js → Reputation-D7D6rp3d.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BsuDvMpO.js → Row-CX03nw4D.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-2QQb8p5X.js → RssFeed-BRyNIOp0.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CFT_6Ljj.js → Search-Dh-jwNaq.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BrK_KNJK.js → Security-C53OqK_S.js} +3 -3
- package/src/assets/web-panel/assets/Services-nXK7991F.js +2 -0
- package/src/assets/web-panel/assets/{Skeleton--WjfL2Ay.js → Skeleton-mVGGUSnx.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-1GWFYMGg.js → Skills-AVICQyr7.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-508cBkmT.js → Sla-BO-jiswJ.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DIeNRX6V.js → SpeechSettings-CQ73BtGw.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BQDW6gsX.js → SyncSettings-ozTu_ihm.js} +1 -1
- package/src/assets/web-panel/assets/{Tasks-D39SBKyi.js → Tasks-CwTiFnau.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-tsObCBe6.js → Templates-PJ-SYUEg.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-Ccpw-S6R.js → Tenant-DeckYbHe.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-CIn4gdxj.js +3 -0
- package/src/assets/web-panel/assets/Tokens-Bc40cdFh.js +1 -0
- package/src/assets/web-panel/assets/{Trigger-D4yonKuU.js → Trigger-BERtmWcc.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DHDcLjma.js → Trust-_ktoDZt-.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DBpW0j1p.js → UkeySign-DecT3_Zy.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BPr_46Py.js → VideoEditing-AqPQa7a7.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-4lfplIJV.js → Wallet-CL303fn9.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DI13wkez.js → WebAuthn-Bwy0YO-u.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-CYbHpkQy.js → WorkflowEditor-Bbewn3S4.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BOH4vNJ7.js → chat-CDIxA8Km.js} +1 -1
- package/src/assets/web-panel/assets/{colors-qxXJ45GU.js → colors-rQIxLS12.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Cjb446yk.js → compact-item-1jZiKenx.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CulBut34.js → createContext-B3FjOuaT.js} +1 -1
- package/src/assets/web-panel/assets/{hasIn-DCnwRrNq.js → hasIn-dZ195iTN.js} +1 -1
- package/src/assets/web-panel/assets/{icons-DY9VpXfa.js → icons-BFHq5fEF.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7reeGYU.js → index--NxZmEUk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BAy0ks7N.js → index-19d37fVJ.js} +4 -4
- package/src/assets/web-panel/assets/{index-CRsnuDGC.js → index-AHCOz9NC.js} +1 -1
- package/src/assets/web-panel/assets/{index-CV_vlbaU.js → index-BByVZ5fI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CjJUQvIU.js → index-BC6wcYy3.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bp4_7Kow.js → index-BDZd1181.js} +1 -1
- package/src/assets/web-panel/assets/{index-DG1F9RZd.js → index-BOiuM69x.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpzjQM4w.js → index-Bq8fsYQ6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DC38ymaH.js → index-Br6-EXdw.js} +1 -1
- package/src/assets/web-panel/assets/{index-BA8bUOYK.js → index-BsUXzEb2.js} +1 -1
- package/src/assets/web-panel/assets/{index-CW7a8O5w.js → index-BwIwGE8Y.js} +1 -1
- package/src/assets/web-panel/assets/{index-D80IlXq1.js → index-Bx15E0JQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOFep_rA.js → index-BxnEM3za.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_029Hie.js → index-C0YzTiiB.js} +1 -1
- package/src/assets/web-panel/assets/{index-BKNbteyC.js → index-C3SVypM3.js} +1 -1
- package/src/assets/web-panel/assets/{index-D3bXm2aZ.js → index-C3rYUvdl.js} +1 -1
- package/src/assets/web-panel/assets/{index-PP5MLidC.js → index-C4jmdcCs.js} +1 -1
- package/src/assets/web-panel/assets/index-C5Ifo5EH.js +1 -0
- package/src/assets/web-panel/assets/{index-Bb1KdW4J.js → index-C8IGQbfQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBWR20mC.js → index-CDL_WWYl.js} +1 -1
- package/src/assets/web-panel/assets/{index-DQXojJvN.js → index-CDkCJPtr.js} +1 -1
- package/src/assets/web-panel/assets/{index-hca2ku7U.js → index-D0DtKH7N.js} +1 -1
- package/src/assets/web-panel/assets/{index-DkYY9W4x.js → index-D3QDmYBa.js} +1 -1
- package/src/assets/web-panel/assets/{index-oGqObYfs.js → index-DP5rV4eS.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCr0xH2Q.js → index-DQXt91YA.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cv2hQG7c.js → index-DRIQpe4j.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3ImsNgP.js → index-DWJ5GzxU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BO-vFfxc.js → index-Dvg5ymRK.js} +1 -1
- package/src/assets/web-panel/assets/{index-SHmkRPZ_.js → index-DxwYB7eB.js} +1 -1
- package/src/assets/web-panel/assets/{index-Clxp_Rc0.js → index-U5Y4YNZC.js} +1 -1
- package/src/assets/web-panel/assets/{index-DNooejFX.js → index-XDvSQBl5.js} +1 -1
- package/src/assets/web-panel/assets/{index-cP5FNe0q.js → index-aaHXeryL.js} +1 -1
- package/src/assets/web-panel/assets/index-efjrWv6y.js +1 -0
- package/src/assets/web-panel/assets/{index-DK5iJriy.js → index-hNSGbn-4.js} +1 -1
- package/src/assets/web-panel/assets/{index-6xtj6SRQ.js → index-kg4NgBuP.js} +1 -1
- package/src/assets/web-panel/assets/{index-Civlun-X.js → index-lSnZsO_d.js} +1 -1
- package/src/assets/web-panel/assets/{index-XMsNvoaz.js → index-sygYO1j4.js} +1 -1
- package/src/assets/web-panel/assets/{index-D6-3yvOU.js → index-uL0KmFyf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CFw2RtQ_.js → index-xKOyC0Cx.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Dp93Vlbv.js → initDefaultProps-GbvcoqYL.js} +1 -1
- package/src/assets/web-panel/assets/{motion-yBy7l6Td.js → motion-VM5YQ6Mf.js} +1 -1
- package/src/assets/web-panel/assets/{move-P6GgC8ZU.js → move-CJvGLYlg.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BMF4_2X_.js → omit-3oHJWwWB.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-C1bUV-iL.js → pickAttrs-BWBtl13u.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CpNGMWxW.js → placementArrow-CVESPqrs.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Bt3UzGUn.js → responsiveObserve-BOvUPufq.js} +1 -1
- package/src/assets/web-panel/assets/{slide-B5t0Lgse.js → slide-W_P685Dw.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-nHmUS8yg.js → statusUtils-BnIQmxwT.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DgazP1mu.js → styleChecker-BMXx5Ie5.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BQ4jJS_s.js → useFlexGapSupport-DSJ4Pl17.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-C8aeIQfU.js → useFs-BPbHm7Yn.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DMH0ymoP.js → vnode-HDTJKu2B.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DRmMxFNC.js → zoom-BqKDJys9.js} +1 -1
- package/src/assets/web-panel/index.html +2 -2
- package/src/commands/ui.js +21 -3
- package/src/gateways/ws/message-dispatcher.js +68 -0
- package/src/gateways/ws/personal-data-hub-protocol.js +264 -0
- package/src/lib/personal-data-hub-wiring.js +425 -0
- package/src/runtime/agent-runtime.js +85 -11
- package/src/assets/web-panel/assets/AppLayout-BzzvYjpq.js +0 -3
- package/src/assets/web-panel/assets/Compliance-DCkF4hfd.js +0 -1
- package/src/assets/web-panel/assets/KnowledgeGraph-nTHxy0Fw.js +0 -1
- package/src/assets/web-panel/assets/Services-DAmjLm-1.js +0 -2
- package/src/assets/web-panel/assets/Terminal-CgFg09NA.js +0 -3
- package/src/assets/web-panel/assets/Tokens-BBWOiqLq.js +0 -1
- package/src/assets/web-panel/assets/index-B0YFQoW_.js +0 -1
- package/src/assets/web-panel/assets/index-BX7snsTz.js +0 -1
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Personal Data Hub — CLI / web-shell wiring.
|
|
3
|
+
*
|
|
4
|
+
* Mirror of desktop-app-vue/src/main/personal-data-hub/wiring.js so the
|
|
5
|
+
* SAME vault is reachable from both the Electron app's IPC channels AND
|
|
6
|
+
* the `cc ui` / `cc serve` web-shell's WS topics. Per memory
|
|
7
|
+
* feedback_cross_shell_feature_pattern: any new feature must be reachable
|
|
8
|
+
* via both gateways or the SPA's behavior diverges across shells.
|
|
9
|
+
*
|
|
10
|
+
* Shared vault path: getElectronUserDataDir() + "/.chainlesschain/hub/"
|
|
11
|
+
* — resolves to the same directory that the Electron app uses, so opening
|
|
12
|
+
* either shell sees the same data. Only ONE process should hold the vault
|
|
13
|
+
* at a time (SQLite WAL allows multi-reader / single-writer, but for v0
|
|
14
|
+
* we assume serial access — Phase 4 will add a file-lock).
|
|
15
|
+
*
|
|
16
|
+
* LLM wiring: cli has no llm-manager singleton — it relies on
|
|
17
|
+
* lib/llm-providers.js + per-command HTTP calls. v0 cli-side hub uses a
|
|
18
|
+
* direct OllamaClient (the hub's standalone fallback). To use the same
|
|
19
|
+
* provider the desktop app uses (Volcengine etc.), pass a custom chat
|
|
20
|
+
* function via the env var CC_HUB_LLM_BASE (Ollama URL) or wire it later
|
|
21
|
+
* when cli ↔ desktop LLM sharing is figured out.
|
|
22
|
+
*
|
|
23
|
+
* KG / RAG wiring: same cli modules the desktop uses via dynamic import —
|
|
24
|
+
* but here we're already in cli, so direct import works.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { join } from "node:path";
|
|
28
|
+
import { mkdirSync } from "node:fs";
|
|
29
|
+
// Hub package is CJS; in ESM we default-import then destructure (Node 22
|
|
30
|
+
// won't let us name-import a CJS module unless it ships a separate ESM
|
|
31
|
+
// shim, which we don't).
|
|
32
|
+
import hub from "@chainlesschain/personal-data-hub";
|
|
33
|
+
const {
|
|
34
|
+
LocalVault,
|
|
35
|
+
AdapterRegistry,
|
|
36
|
+
AnalysisEngine,
|
|
37
|
+
MockAdapter,
|
|
38
|
+
OllamaClient,
|
|
39
|
+
CcKgSink,
|
|
40
|
+
CcRagSink,
|
|
41
|
+
FileKeyProvider,
|
|
42
|
+
generateKeyHex,
|
|
43
|
+
EmailAdapter,
|
|
44
|
+
AlipayBillAdapter,
|
|
45
|
+
EntityResolver,
|
|
46
|
+
EntityResolverEmbeddingStage,
|
|
47
|
+
EntityResolverLLMStage,
|
|
48
|
+
} = hub;
|
|
49
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
50
|
+
import { getElectronUserDataDir } from "./paths.js";
|
|
51
|
+
|
|
52
|
+
// ─── Lazy ESM imports of cli KG / BM25 ───────────────────────────────────
|
|
53
|
+
|
|
54
|
+
let _kgMod = null;
|
|
55
|
+
async function loadKg() {
|
|
56
|
+
if (_kgMod) return _kgMod;
|
|
57
|
+
try {
|
|
58
|
+
_kgMod = await import("./knowledge-graph.js");
|
|
59
|
+
} catch (_err) {
|
|
60
|
+
_kgMod = null;
|
|
61
|
+
}
|
|
62
|
+
return _kgMod;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let _bm25Mod = null;
|
|
66
|
+
async function loadBm25() {
|
|
67
|
+
if (_bm25Mod) return _bm25Mod;
|
|
68
|
+
try {
|
|
69
|
+
_bm25Mod = await import("./bm25-search.js");
|
|
70
|
+
} catch (_err) {
|
|
71
|
+
_bm25Mod = null;
|
|
72
|
+
}
|
|
73
|
+
return _bm25Mod;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ─── Hub singleton (CLI process scope) ───────────────────────────────────
|
|
77
|
+
|
|
78
|
+
let _hub = null;
|
|
79
|
+
let _initPromise = null;
|
|
80
|
+
let _bm25 = null;
|
|
81
|
+
|
|
82
|
+
export function resolveHubDir() {
|
|
83
|
+
return join(getElectronUserDataDir(), ".chainlesschain", "hub");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function initHub() {
|
|
87
|
+
const hubDir = resolveHubDir();
|
|
88
|
+
mkdirSync(hubDir, { recursive: true });
|
|
89
|
+
mkdirSync(join(hubDir, "keys"), { recursive: true });
|
|
90
|
+
|
|
91
|
+
const keyProvider = new FileKeyProvider(join(hubDir, "keys"));
|
|
92
|
+
const KEY_NAME = "vault:default";
|
|
93
|
+
let key = await keyProvider.get(KEY_NAME);
|
|
94
|
+
if (!key) {
|
|
95
|
+
key = generateKeyHex();
|
|
96
|
+
await keyProvider.set(KEY_NAME, key);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const vault = new LocalVault({ path: join(hubDir, "vault.db"), key });
|
|
100
|
+
vault.open();
|
|
101
|
+
|
|
102
|
+
// LLM: standalone OllamaClient — connects to localhost:11434.
|
|
103
|
+
// Override via env CC_HUB_OLLAMA_URL / CC_HUB_OLLAMA_MODEL.
|
|
104
|
+
const llm = new OllamaClient({
|
|
105
|
+
baseUrl: process.env.CC_HUB_OLLAMA_URL || "http://localhost:11434",
|
|
106
|
+
model: process.env.CC_HUB_OLLAMA_MODEL || "qwen2.5:7b-instruct",
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// KG sink — direct ESM import works here.
|
|
110
|
+
let kgSink = null;
|
|
111
|
+
const kgMod = await loadKg();
|
|
112
|
+
if (
|
|
113
|
+
kgMod &&
|
|
114
|
+
typeof kgMod.addEntity === "function" &&
|
|
115
|
+
typeof kgMod.addRelation === "function"
|
|
116
|
+
) {
|
|
117
|
+
kgSink = new CcKgSink({
|
|
118
|
+
addEntity: kgMod.addEntity,
|
|
119
|
+
addRelation: kgMod.addRelation,
|
|
120
|
+
db: null,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// RAG sink — instantiate a BM25 per hub.
|
|
125
|
+
let ragSink = null;
|
|
126
|
+
const bm25Mod = await loadBm25();
|
|
127
|
+
if (bm25Mod && typeof bm25Mod.BM25Search === "function") {
|
|
128
|
+
_bm25 = new bm25Mod.BM25Search({ language: "auto" });
|
|
129
|
+
ragSink = new CcRagSink({ bm25: _bm25 });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Phase 8 — EntityResolver pipeline
|
|
133
|
+
const entityResolver = new EntityResolver({ vault });
|
|
134
|
+
try {
|
|
135
|
+
if (llm) {
|
|
136
|
+
const llmStage = new EntityResolverLLMStage({
|
|
137
|
+
llm,
|
|
138
|
+
acceptNonLocal: false,
|
|
139
|
+
});
|
|
140
|
+
entityResolver._llmStage = llmStage.asStageFn();
|
|
141
|
+
}
|
|
142
|
+
const embeddingStage = new EntityResolverEmbeddingStage({
|
|
143
|
+
ollamaUrl: process.env.CC_HUB_OLLAMA_URL || "http://localhost:11434",
|
|
144
|
+
model: process.env.CC_HUB_OLLAMA_EMBED_MODEL || "nomic-embed-text",
|
|
145
|
+
vault,
|
|
146
|
+
});
|
|
147
|
+
entityResolver._embeddingStage = embeddingStage.asStageFn();
|
|
148
|
+
} catch (_err) {
|
|
149
|
+
// Fall back to rule-only — registry still works
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const registry = new AdapterRegistry({
|
|
153
|
+
vault,
|
|
154
|
+
kgSink: kgSink ? kgSink.write.bind(kgSink) : null,
|
|
155
|
+
ragSink: ragSink ? ragSink.write.bind(ragSink) : null,
|
|
156
|
+
entityResolver,
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const engine = new AnalysisEngine({
|
|
160
|
+
vault,
|
|
161
|
+
llm,
|
|
162
|
+
ragRetriever: _bm25
|
|
163
|
+
? async (question) => {
|
|
164
|
+
try {
|
|
165
|
+
const hits = _bm25.search(question, { topK: 10 });
|
|
166
|
+
return Array.isArray(hits)
|
|
167
|
+
? hits
|
|
168
|
+
.map((h) => ({
|
|
169
|
+
id: h.id || (h.doc && h.doc.id),
|
|
170
|
+
text: "",
|
|
171
|
+
metadata: {},
|
|
172
|
+
}))
|
|
173
|
+
.filter((d) => d.id)
|
|
174
|
+
: [];
|
|
175
|
+
} catch (_e) {
|
|
176
|
+
return [];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
: null,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Phase 5.6: auto-register persisted email accounts.
|
|
183
|
+
const emailAccountsPath = join(hubDir, "email-accounts.json");
|
|
184
|
+
const emailAccounts = loadEmailAccounts(emailAccountsPath);
|
|
185
|
+
for (const cfg of emailAccounts) {
|
|
186
|
+
try {
|
|
187
|
+
const adapter = new EmailAdapter({
|
|
188
|
+
account: cfg.account,
|
|
189
|
+
...(cfg.opts || {}),
|
|
190
|
+
});
|
|
191
|
+
registry.register(adapter);
|
|
192
|
+
} catch (_err) {
|
|
193
|
+
// Continue boot even if one config is corrupt
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Phase 6: auto-register persisted Alipay accounts.
|
|
198
|
+
const alipayAccountsPath = join(hubDir, "alipay-accounts.json");
|
|
199
|
+
const alipayAccounts = loadAlipayAccounts(alipayAccountsPath);
|
|
200
|
+
for (const cfg of alipayAccounts) {
|
|
201
|
+
try {
|
|
202
|
+
const adapter = new AlipayBillAdapter({
|
|
203
|
+
account: cfg.account,
|
|
204
|
+
...(cfg.opts || {}),
|
|
205
|
+
});
|
|
206
|
+
if (!registry.has(adapter.name)) registry.register(adapter);
|
|
207
|
+
} catch (_err) {
|
|
208
|
+
// Continue boot even if one config is corrupt
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
vault,
|
|
214
|
+
registry,
|
|
215
|
+
engine,
|
|
216
|
+
llm,
|
|
217
|
+
kgSink,
|
|
218
|
+
ragSink,
|
|
219
|
+
hubDir,
|
|
220
|
+
keyProvider,
|
|
221
|
+
emailAccountsPath,
|
|
222
|
+
alipayAccountsPath,
|
|
223
|
+
entityResolver,
|
|
224
|
+
bm25: _bm25,
|
|
225
|
+
registerMockAdapter(opts = {}) {
|
|
226
|
+
if (registry.has(opts.name || "mock"))
|
|
227
|
+
return registry.get(opts.name || "mock");
|
|
228
|
+
const adapter = new MockAdapter(opts);
|
|
229
|
+
registry.register(adapter);
|
|
230
|
+
return adapter;
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
/** Phase 5.6 — see desktop wiring for full doc */
|
|
234
|
+
async testEmailAuth({ account }) {
|
|
235
|
+
if (!account || typeof account !== "object")
|
|
236
|
+
throw new Error("account required");
|
|
237
|
+
const adapter = new EmailAdapter({ account });
|
|
238
|
+
return await adapter.authenticate();
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
async registerEmailAdapter({ account, opts = {} } = {}) {
|
|
242
|
+
if (!account || typeof account !== "object")
|
|
243
|
+
throw new Error("account required");
|
|
244
|
+
const adapter = new EmailAdapter({ account, ...opts });
|
|
245
|
+
if (registry.has(adapter.name)) {
|
|
246
|
+
throw new Error(`adapter name "${adapter.name}" already registered`);
|
|
247
|
+
}
|
|
248
|
+
registry.register(adapter);
|
|
249
|
+
const accounts = loadEmailAccounts(emailAccountsPath);
|
|
250
|
+
const next = accounts.filter((c) => c.account.email !== account.email);
|
|
251
|
+
next.push({ account, opts, registeredAt: Date.now() });
|
|
252
|
+
saveEmailAccounts(emailAccountsPath, next);
|
|
253
|
+
return {
|
|
254
|
+
name: adapter.name,
|
|
255
|
+
version: adapter.version,
|
|
256
|
+
capabilities: adapter.capabilities,
|
|
257
|
+
sensitivity: adapter.dataDisclosure.sensitivity,
|
|
258
|
+
};
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
async unregisterEmailAdapter(emailAddress) {
|
|
262
|
+
const accounts = loadEmailAccounts(emailAccountsPath);
|
|
263
|
+
const target = accounts.find((c) => c.account.email === emailAddress);
|
|
264
|
+
const next = accounts.filter((c) => c.account.email !== emailAddress);
|
|
265
|
+
saveEmailAccounts(emailAccountsPath, next);
|
|
266
|
+
if (target) registry.unregister("email-imap");
|
|
267
|
+
return { ok: true, removed: !!target };
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
listEmailAccounts() {
|
|
271
|
+
return loadEmailAccounts(emailAccountsPath).map((c) => ({
|
|
272
|
+
email: c.account.email,
|
|
273
|
+
provider: c.account.provider,
|
|
274
|
+
folders: c.account.folders || null,
|
|
275
|
+
registeredAt: c.registeredAt || null,
|
|
276
|
+
pdfPasswordHints:
|
|
277
|
+
c.opts && c.opts.pdfPasswordHints
|
|
278
|
+
? Object.keys(c.opts.pdfPasswordHints)
|
|
279
|
+
: [],
|
|
280
|
+
}));
|
|
281
|
+
},
|
|
282
|
+
|
|
283
|
+
eventDetail(eventId) {
|
|
284
|
+
const ev = vault.getEvent ? vault.getEvent(eventId) : null;
|
|
285
|
+
if (!ev) return null;
|
|
286
|
+
return {
|
|
287
|
+
event: ev,
|
|
288
|
+
classification:
|
|
289
|
+
ev.extra && ev.extra.classification ? ev.extra.classification : null,
|
|
290
|
+
extraction:
|
|
291
|
+
ev.extra && ev.extra.fields
|
|
292
|
+
? {
|
|
293
|
+
template: ev.extra.extractionTemplate,
|
|
294
|
+
confidence: ev.extra.extractionConfidence,
|
|
295
|
+
fields: ev.extra.fields,
|
|
296
|
+
warnings: ev.extra.extractionWarnings || [],
|
|
297
|
+
pdfExtraction: ev.extra.pdfExtraction || null,
|
|
298
|
+
}
|
|
299
|
+
: null,
|
|
300
|
+
};
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
// ─── Phase 6 — Alipay bill import ──────────────────────────────────
|
|
304
|
+
|
|
305
|
+
async registerAlipayAdapter({ account, opts = {} } = {}) {
|
|
306
|
+
if (!account || typeof account !== "object")
|
|
307
|
+
throw new Error("account required");
|
|
308
|
+
const adapter = new AlipayBillAdapter({ account, ...opts });
|
|
309
|
+
if (registry.has(adapter.name)) registry.unregister(adapter.name);
|
|
310
|
+
registry.register(adapter);
|
|
311
|
+
const accounts = loadAlipayAccounts(alipayAccountsPath);
|
|
312
|
+
const next = accounts.filter((c) => c.account.email !== account.email);
|
|
313
|
+
next.push({ account, opts, registeredAt: Date.now() });
|
|
314
|
+
saveAlipayAccounts(alipayAccountsPath, next);
|
|
315
|
+
return {
|
|
316
|
+
name: adapter.name,
|
|
317
|
+
version: adapter.version,
|
|
318
|
+
capabilities: adapter.capabilities,
|
|
319
|
+
sensitivity: adapter.dataDisclosure.sensitivity,
|
|
320
|
+
};
|
|
321
|
+
},
|
|
322
|
+
|
|
323
|
+
async unregisterAlipayAdapter(email) {
|
|
324
|
+
const accounts = loadAlipayAccounts(alipayAccountsPath);
|
|
325
|
+
const target = accounts.find((c) => c.account.email === email);
|
|
326
|
+
const next = accounts.filter((c) => c.account.email !== email);
|
|
327
|
+
saveAlipayAccounts(alipayAccountsPath, next);
|
|
328
|
+
if (target) registry.unregister("alipay-bill");
|
|
329
|
+
return { ok: true, removed: !!target };
|
|
330
|
+
},
|
|
331
|
+
|
|
332
|
+
listAlipayAccounts() {
|
|
333
|
+
return loadAlipayAccounts(alipayAccountsPath).map((c) => ({
|
|
334
|
+
email: c.account.email,
|
|
335
|
+
hasZipPassword: !!(
|
|
336
|
+
c.account.zipPassword ||
|
|
337
|
+
(c.opts && c.opts.zipPassword)
|
|
338
|
+
),
|
|
339
|
+
registeredAt: c.registeredAt || null,
|
|
340
|
+
}));
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
async importAlipayBill({ zipPath, csvPath, zipPassword } = {}) {
|
|
344
|
+
const adapter = registry.get("alipay-bill");
|
|
345
|
+
if (!adapter)
|
|
346
|
+
throw new Error(
|
|
347
|
+
"No Alipay adapter registered — call registerAlipayAdapter first",
|
|
348
|
+
);
|
|
349
|
+
return await registry.syncAdapter("alipay-bill", {
|
|
350
|
+
zipPath,
|
|
351
|
+
csvPath,
|
|
352
|
+
zipPassword,
|
|
353
|
+
});
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// ─── Email account persistence (Phase 5.6) ───────────────────────────────
|
|
359
|
+
|
|
360
|
+
function loadEmailAccounts(filePath) {
|
|
361
|
+
try {
|
|
362
|
+
if (!existsSync(filePath)) return [];
|
|
363
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
364
|
+
const parsed = JSON.parse(raw);
|
|
365
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
366
|
+
} catch (_err) {
|
|
367
|
+
return [];
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function saveEmailAccounts(filePath, accounts) {
|
|
372
|
+
writeFileSync(filePath, JSON.stringify(accounts, null, 2), {
|
|
373
|
+
encoding: "utf-8",
|
|
374
|
+
mode: 0o600,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// ─── Alipay account persistence (Phase 6) ───────────────────────────────
|
|
379
|
+
|
|
380
|
+
function loadAlipayAccounts(filePath) {
|
|
381
|
+
try {
|
|
382
|
+
if (!existsSync(filePath)) return [];
|
|
383
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
384
|
+
const parsed = JSON.parse(raw);
|
|
385
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
386
|
+
} catch (_err) {
|
|
387
|
+
return [];
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function saveAlipayAccounts(filePath, accounts) {
|
|
392
|
+
writeFileSync(filePath, JSON.stringify(accounts, null, 2), {
|
|
393
|
+
encoding: "utf-8",
|
|
394
|
+
mode: 0o600,
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export async function getHub() {
|
|
399
|
+
if (_hub) return _hub;
|
|
400
|
+
if (!_initPromise) {
|
|
401
|
+
_initPromise = initHub()
|
|
402
|
+
.then((h) => {
|
|
403
|
+
_hub = h;
|
|
404
|
+
return h;
|
|
405
|
+
})
|
|
406
|
+
.catch((err) => {
|
|
407
|
+
_initPromise = null;
|
|
408
|
+
throw err;
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
return _initPromise;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export function close() {
|
|
415
|
+
if (_hub && _hub.vault) {
|
|
416
|
+
try {
|
|
417
|
+
_hub.vault.close();
|
|
418
|
+
} catch (_e) {}
|
|
419
|
+
}
|
|
420
|
+
_hub = null;
|
|
421
|
+
_initPromise = null;
|
|
422
|
+
_bm25 = null;
|
|
423
|
+
_kgMod = null;
|
|
424
|
+
_bm25Mod = null;
|
|
425
|
+
}
|
|
@@ -626,6 +626,41 @@ export class AgentRuntime {
|
|
|
626
626
|
runtimeLogger.log(
|
|
627
627
|
` Auth: ${this.policy.token ? chalk.green("enabled") : chalk.yellow("disabled")}`,
|
|
628
628
|
);
|
|
629
|
+
// When bound to 0.0.0.0 the user needs a reachable URL — enumerate the
|
|
630
|
+
// non-loopback IPv4 addresses (typically wlan0 on Android, eth0 on a
|
|
631
|
+
// server) so they can copy/paste the full URL onto another device. Also
|
|
632
|
+
// print the auth token here when present so the user doesn't have to dig
|
|
633
|
+
// it out of env vars. NB: this is local-network display only; we never
|
|
634
|
+
// leak the token over the wire beyond ws/http to clients holding it.
|
|
635
|
+
if (host === "0.0.0.0") {
|
|
636
|
+
try {
|
|
637
|
+
const os = await import("os");
|
|
638
|
+
const ifaces = os.networkInterfaces();
|
|
639
|
+
const lanUrls = [];
|
|
640
|
+
for (const [, addrs] of Object.entries(ifaces)) {
|
|
641
|
+
for (const a of addrs || []) {
|
|
642
|
+
if (a.family === "IPv4" && !a.internal) {
|
|
643
|
+
lanUrls.push(`http://${a.address}:${actualHttpPort}`);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
if (lanUrls.length > 0) {
|
|
648
|
+
runtimeLogger.log("");
|
|
649
|
+
runtimeLogger.log(chalk.bold(" LAN access:"));
|
|
650
|
+
for (const u of lanUrls) {
|
|
651
|
+
runtimeLogger.log(` ${chalk.cyan(u)}`);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
} catch (_err) {
|
|
655
|
+
// Best-effort — keep banner working even if os import fails.
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if (this.policy.token) {
|
|
659
|
+
runtimeLogger.log("");
|
|
660
|
+
runtimeLogger.log(
|
|
661
|
+
` Token: ${chalk.yellow(this.policy.token)} ${chalk.dim("(append as ?token=<TOKEN> or paste into login screen)")}`,
|
|
662
|
+
);
|
|
663
|
+
}
|
|
629
664
|
runtimeLogger.log("");
|
|
630
665
|
runtimeLogger.log(chalk.dim(" Press Ctrl+C to stop"));
|
|
631
666
|
runtimeLogger.log("");
|
|
@@ -634,20 +669,59 @@ export class AgentRuntime {
|
|
|
634
669
|
this.deps.openBrowser(uiUrl);
|
|
635
670
|
}
|
|
636
671
|
|
|
672
|
+
// Force-exit after this deadline if graceful shutdown stalls (typically
|
|
673
|
+
// httpServer.close hanging on persistent keep-alive / WS connections,
|
|
674
|
+
// which is exactly what makes Ctrl+C feel dead on Android local terminal
|
|
675
|
+
// — the pty never sees the prompt return because node never exits).
|
|
676
|
+
const SHUTDOWN_TIMEOUT_MS = 2000;
|
|
677
|
+
let shuttingDown = false;
|
|
637
678
|
const shutdown = async () => {
|
|
679
|
+
if (shuttingDown) {
|
|
680
|
+
// Second Ctrl+C while still draining — escalate immediately.
|
|
681
|
+
runtimeLogger.log(chalk.red("\nForce-exiting..."));
|
|
682
|
+
process.exit(130);
|
|
683
|
+
}
|
|
684
|
+
shuttingDown = true;
|
|
638
685
|
runtimeLogger.log("\n" + chalk.yellow("Shutting down UI server..."));
|
|
639
|
-
|
|
640
|
-
|
|
686
|
+
// NB: do NOT unref() this timer. With unref(), if every other handle
|
|
687
|
+
// clears before the timer fires, the event loop exits and force-exit
|
|
688
|
+
// never runs — exactly the bug we hit on Xiaomi 24115RA8EC 2026-05-19:
|
|
689
|
+
// SIGINT → handler logged "Shutting down" → never exited. We WANT this
|
|
690
|
+
// timer to keep the loop alive through the SHUTDOWN_TIMEOUT_MS window.
|
|
691
|
+
// clearTimeout in the success branches handles graceful exits.
|
|
692
|
+
const forceExit = setTimeout(() => {
|
|
693
|
+
runtimeLogger.log(
|
|
694
|
+
chalk.red(
|
|
695
|
+
`Graceful shutdown stalled after ${SHUTDOWN_TIMEOUT_MS}ms, force-exiting`,
|
|
696
|
+
),
|
|
697
|
+
);
|
|
698
|
+
process.exit(130);
|
|
699
|
+
}, SHUTDOWN_TIMEOUT_MS);
|
|
700
|
+
try {
|
|
701
|
+
if (mcpClient && typeof mcpClient.disconnectAll === "function") {
|
|
702
|
+
await mcpClient.disconnectAll().catch(() => undefined);
|
|
703
|
+
}
|
|
704
|
+
// Kill all PTY sessions before WS so the SPA gets clean terminal.exit
|
|
705
|
+
// frames; without this, node-pty children would outlive cc ui until
|
|
706
|
+
// their OS parent (the cc ui process) actually exits.
|
|
707
|
+
this._terminalCleanup?.();
|
|
708
|
+
// Force-close any persistent HTTP keep-alive / WS upgrades; without
|
|
709
|
+
// this, httpServer.close waits for every browser tab to close its
|
|
710
|
+
// socket before resolving — which never happens until the user
|
|
711
|
+
// manually closes the tab.
|
|
712
|
+
if (typeof httpServer.closeAllConnections === "function") {
|
|
713
|
+
httpServer.closeAllConnections();
|
|
714
|
+
}
|
|
715
|
+
await Promise.all([
|
|
716
|
+
new Promise((resolve) => httpServer.close(resolve)),
|
|
717
|
+
wsServer.stop(),
|
|
718
|
+
]);
|
|
719
|
+
clearTimeout(forceExit);
|
|
720
|
+
process.exit(0);
|
|
721
|
+
} catch (_err) {
|
|
722
|
+
clearTimeout(forceExit);
|
|
723
|
+
process.exit(1);
|
|
641
724
|
}
|
|
642
|
-
// Kill all PTY sessions before WS so the SPA gets clean terminal.exit
|
|
643
|
-
// frames; without this, node-pty children would outlive cc ui until
|
|
644
|
-
// their OS parent (the cc ui process) actually exits.
|
|
645
|
-
this._terminalCleanup?.();
|
|
646
|
-
await Promise.all([
|
|
647
|
-
new Promise((resolve) => httpServer.close(resolve)),
|
|
648
|
-
wsServer.stop(),
|
|
649
|
-
]);
|
|
650
|
-
process.exit(0);
|
|
651
725
|
};
|
|
652
726
|
|
|
653
727
|
process.on("SIGINT", shutdown);
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{f as O,r as K,o as _e,x as pt,K as d,L as c,M as g,c as e,N as t,u as a,R as l,O as i,P as s,Q as C,F as V,Y as ot,Z as J,S as P,I as nt,e as yt,_ as mt,w as ft,H as _t,$ as kt}from"./vendor-M5lGV-wr.js";import{u as ke,_ as ge,E as gt,a as vt,b as ht,T as bt,c as wt,d as G}from"./index-BAy0ks7N.js";import{u as q}from"./useShellMode-CgR0wCYM.js";import{B as fe,R as $t,M as ue,F as Y,G as ee,D as te,h as he,i as ae,j as be,k as oe,A as we,N as $e,l as Le,m as Oe,n as Se,o as Ce,S as Ee,p as Re,q as Ae,r as ne,s as Ne,t as je,u as Te,v as Be,w as Me,x as Pe,y as Ie,P as Ue,z as se,K as ie,H as D,J as De,O as le,Q as Ke,U as ze,W as Fe,V as me,X as re,Y as Ve,Z as qe,_ as ce,$ as We,a0 as He,a1 as Je,a2 as Ge,a3 as Ye,a4 as Ze,a5 as Qe,a6 as Xe,a7 as xe,a8 as et,a9 as Lt,aa as tt,e as Ot}from"./icons-DY9VpXfa.js";import St from"./index-DpzjQM4w.js";import"./KeyCode-D63Tfrq7.js";import"./omit-BMF4_2X_.js";import"./pickAttrs-C1bUV-iL.js";import"./initDefaultProps-Dp93Vlbv.js";import"./motion-yBy7l6Td.js";import"./raf-Deuc0E8-.js";import"./index-cP5FNe0q.js";import"./index-CW7a8O5w.js";import"./isVisible-C7tPsqfj.js";import"./useState-CSzR8F8O.js";import"./devWarning-CNIS3FrJ.js";import"./warning-Pq00owYb.js";import"./compact-item-Cjb446yk.js";import"./createContext-CulBut34.js";import"./Compact-D4E0roed.js";import"./_getTag-BVc6NQ_K.js";import"./styleChecker-DgazP1mu.js";import"./zoom-DRmMxFNC.js";import"./ActionButton-COVVHNnK.js";import"./vnode-DMH0ymoP.js";const Ct=""+new URL("logo-DBCYUiWP.png",import.meta.url).href,L={notifications:K([]),unreadCount:K(0)};function Z(h){if(h&&h.ok===!1)throw new Error(h.error||"notification handler failed");return h?.result??h}function Et(){const h=ke();async function T({limit:r=50,offset:u=0,isRead:_}={}){if(!q().isEmbedded)return L.notifications.value=[],L.unreadCount.value=0,L.notifications.value;const y=await h.sendRaw({type:"notification.list",limit:r,offset:u,isRead:_},15e3),w=Z(y);if(w?.success===!1)throw new Error(w.error||"notification.list failed");return L.notifications.value=Array.isArray(w?.notifications)?w.notifications:[],await E(),L.notifications.value}async function E(){if(!q().isEmbedded)return L.unreadCount.value=0,0;const r=await h.sendRaw({type:"notification.unread-count"},1e4),u=Z(r);return L.unreadCount.value=Number(u?.count)||0,L.unreadCount.value}async function k(r){if(r==null||r==="")throw new Error("id is required");if(!q().isEmbedded)return;const u=await h.sendRaw({type:"notification.mark-read",id:r},1e4),_=Z(u);if(_?.success===!1)throw new Error(_.error||"notification.mark-read failed");const y=L.notifications.value.find(w=>w.id===r);y&&(y.is_read=1),await E()}async function S(){if(!q().isEmbedded)return;const r=await h.sendRaw({type:"notification.mark-all-read"},1e4),u=Z(r);if(u?.success===!1)throw new Error(u.error||"notification.mark-all-read failed");for(const _ of L.notifications.value)_.is_read=1;L.unreadCount.value=0}async function b(r,u=""){if(!q().isEmbedded)throw new Error("桌面通知仅在嵌入式 web-shell 中可用");const _=await h.sendRaw({type:"notification.send-desktop",title:r,body:u},1e4),y=Z(_);if(y?.success===!1)throw new Error(y.error||"notification.send-desktop failed")}return{notifications:O(()=>L.notifications.value),unreadCount:O(()=>L.unreadCount.value),refresh:T,refreshUnreadCount:E,markRead:k,markAllRead:S,sendDesktop:b}}const Rt={class:"notif-toolbar"},At={class:"notif-body"},Nt={key:2,class:"notif-list"},jt=["onClick"],Tt={class:"notif-row"},Bt={class:"notif-title"},Mt={class:"notif-time"},Pt={key:0,class:"notif-message"},It={__name:"NotificationBell",setup(h){const T=K(!1),E=K("all"),k=K(!1),{notifications:S,unreadCount:b,refresh:r,markRead:u,markAllRead:_}=Et();function y(){N()}_e(()=>{window.addEventListener("cc:open-notification-drawer",y)}),pt(()=>{window.removeEventListener("cc:open-notification-drawer",y)});const w=O(()=>E.value==="unread"?S.value.filter(m=>!m.is_read):S.value);async function R(){if(q().isEmbedded){k.value=!0;try{await r({limit:100})}catch{}finally{k.value=!1}}}async function N(){T.value=!0,await R()}async function j(m){if(!m.is_read)try{await u(m.id)}catch{}}async function $(){try{await _()}catch(m){console.warn("[NotificationBell] markAllRead failed:",m?.message||m)}}function A(m){if(!m)return"";const f=typeof m=="string"?Date.parse(m):Number(m);if(!Number.isFinite(f))return String(m);const B=Date.now()-f,z=6e4,I=60*z,W=24*I;return B<z?"刚刚":B<I?`${Math.floor(B/z)} 分钟前`:B<W?`${Math.floor(B/I)} 小时前`:new Date(f).toLocaleDateString()}return(m,f)=>{const B=d("a-badge"),z=d("a-tooltip"),I=d("a-radio-button"),W=d("a-radio-group"),H=d("a-space"),Q=d("a-button"),de=d("a-empty"),pe=d("a-spin"),ye=d("a-drawer");return c(),g(V,null,[e(z,{title:"通知"},{default:t(()=>[e(B,{count:a(b),"overflow-count":99,offset:[-4,4]},{default:t(()=>[l("button",{type:"button",class:"notif-bell-btn","aria-label":"通知",onClick:N},[e(a(fe))])]),_:1},8,["count"])]),_:1}),e(ye,{open:T.value,"onUpdate:open":f[1]||(f[1]=v=>T.value=v),title:"通知中心",placement:"right",width:400,"body-style":{padding:0}},{default:t(()=>[l("div",Rt,[e(H,null,{default:t(()=>[e(W,{value:E.value,"onUpdate:value":f[0]||(f[0]=v=>E.value=v),size:"small","button-style":"solid"},{default:t(()=>[e(I,{value:"all"},{default:t(()=>[i("全部 ("+s(a(S).length)+")",1)]),_:1}),e(I,{value:"unread"},{default:t(()=>[i("未读 ("+s(a(b))+")",1)]),_:1})]),_:1},8,["value"])]),_:1}),e(H,null,{default:t(()=>[e(Q,{size:"small",loading:k.value,onClick:R},{icon:t(()=>[e(a($t))]),_:1},8,["loading"]),e(Q,{size:"small",disabled:a(b)===0,onClick:$},{default:t(()=>[...f[2]||(f[2]=[i(" 全部已读 ",-1)])]),_:1},8,["disabled"])]),_:1})]),l("div",At,[!k.value&&w.value.length===0?(c(),C(de,{key:0,description:"暂无通知",image:a(gt).PRESENTED_IMAGE_SIMPLE,style:{padding:"60px 0"}},null,8,["image"])):k.value?(c(),C(pe,{key:1,style:{display:"block",padding:"60px"}})):(c(),g("ul",Nt,[(c(!0),g(V,null,ot(w.value,v=>(c(),g("li",{key:v.id,class:J(["notif-item",{unread:!v.is_read}]),onClick:n=>j(v)},[l("div",Tt,[l("div",Bt,s(v.title||v.message||"(无标题)"),1),l("span",Mt,s(A(v.created_at)),1)]),v.message&&v.title?(c(),g("div",Pt,s(v.message),1)):P("",!0)],10,jt))),128))]))])]),_:1},8,["open"])],64)}}},Ut=ge(It,[["__scopeId","data-v-af539070"]]),Dt={key:0,class:"mbh-count"},Kt={__name:"MobileBridgeHeaderStatus",setup(h){function T(R){if(!R)return[];try{return JSON.parse(R)}catch{}const N=String(R).split(`
|
|
2
|
-
`),j=N.findIndex($=>{const A=$.trim();if(!A)return!1;const m=A[0];if(m!=="["&&m!=="{")return!1;if(A.length===1)return!0;const f=A[1];return!(f>="A"&&f<="Z"||f>="a"&&f<="z")});if(j<0)return[];for(let $=N.length-1;$>=j;$--){const A=N[$].trim();if(/^[\]\}]/.test(A)&&!/^[\]\}][A-Za-z]/.test(A))try{return JSON.parse(N.slice(j,$+1).join(`
|
|
3
|
-
`))}catch{return[]}}return[]}const E=nt(),k=ke(),S=K([]);let b=null;const r=O(()=>S.value.length),u=O(()=>r.value===0?"var(--text-muted, #999)":"#52c41a"),_=O(()=>r.value===0?"尚未配对任何手机 — 点击进入配对":`已配对 ${r.value} 台手机 — 点击进入管理`);async function y(){if(k.status==="connected")try{const{output:R}=await k.execute("p2p devices --type mobile --json",1e4);S.value=T(R)||[]}catch{}}function w(){E.push("/mobile-bridge")}return _e(()=>{y(),b=setInterval(y,5e3)}),yt(()=>{b&&(clearInterval(b),b=null)}),(R,N)=>{const j=d("a-badge"),$=d("a-tooltip");return c(),C($,{title:_.value},{default:t(()=>[e(j,{count:r.value,"show-zero":!1,"overflow-count":9,offset:[-2,4]},{default:t(()=>[l("button",{type:"button",class:J(["mbh-btn",{"mbh-btn--active":r.value>0}]),onClick:w},[e(a(ue),{style:mt({color:u.value,fontSize:"14px"})},null,8,["style"]),r.value>0?(c(),g("span",Dt,s(r.value),1)):P("",!0)],2)]),_:1},8,["count"])]),_:1},8,["title"])}}},zt=ge(Kt,[["__scopeId","data-v-05eb475d"]]),Ft=["src"],Vt={key:0,class:"logo-text"},qt={key:0,class:"mode-banner project"},Wt={class:"banner-info"},Ht={class:"banner-name"},Jt={class:"banner-sub"},Gt={key:1,class:"mode-banner global"},Yt={class:"banner-name"},Zt=["title"],Qt={class:"group-label"},Xt={class:"group-label"},xt={class:"group-label"},ea={class:"group-label"},ta={class:"group-label"},aa={class:"group-label"},oa={class:"group-label"},na={class:"group-label"},sa={class:"group-label"},ia={key:0,class:"footer-text"},la={class:"header-left"},ra={class:"header-right"},ca={class:"theme-switcher"},ua=["data-theme-key","onClick"],da=["data-locale"],pa={class:"lang-switch-label"},ya={class:"version-tag"},at="cc.web-panel.sidebar.openKeys",ma={__name:"AppLayout",setup(h){const T=nt(),E=_t(),k=ke(),S=vt(),{t:b}=ht(),r=q(),u=K(!1),_=window.__CC_CONFIG__||{},y=O(()=>_.mode==="project"),w="v5.0.3.65",R=O(()=>S.current),N=O(()=>S.config.vars["--menu-mode"]),j=O(()=>{const n=E.name?.toLowerCase()||"dashboard";return[{mcptools:"mcp",quickask:"quick-ask",ukeysign:"ukey-sign"}[n]||n]}),$=["g-overview","g-config","g-data","g-advanced","g-enterprise","g-social","g-media","g-extension"];function A(){try{const n=localStorage.getItem(at);if(n){const p=JSON.parse(n);if(Array.isArray(p))return p.filter(o=>$.includes(o))}}catch{}return[...$]}const m=K(A());ft(m,n=>{try{localStorage.setItem(at,JSON.stringify(n))}catch{}},{deep:!0});const f=O(()=>k.status),B=O(()=>({connected:"success",connecting:"processing",error:"error",disconnected:"default"})[k.status]||"default"),z=O(()=>{const n=`appLayout.footerStatus.${k.status}`,p=b(n);return p===n?b("appLayout.footerStatus.unknown"):p});function I(n){S.setTheme(n)}const{current:W,supported:H,setLocale:Q}=wt();function de(){const n=H[(H.indexOf(W.value)+1)%H.length];Q(n)}async function pe(n){try{const p=await k.sendRaw({type:"window.open",role:n},1e4);if(p?.ok===!1){G.error(`打开失败:${p.error||"未知"}`);return}const o=p?.result??p;o?.reason==="role_reserved"?G.warning("该窗口角色被保留"):o?.reason}catch(p){G.error(`打开桌面窗口失败:${p.message||p}`)}}async function ye(){St.confirm({title:"切换到桌面壳?",content:"回到 V5/V6 桌面壳。完整 electronAPI 表面(UKey 硬件 / 原生对话框 / 系统设置等)会重新可用,但失去 web-panel 的 SPA 体验。保存后需要重启应用才生效。",okText:"切换并重启",cancelText:"取消",centered:!0,async onOk(){try{const n=await k.sendRaw({type:"shell.switch",target:"desktop"},5e3);if(n?.ok===!1)throw new Error(n.error||"shell.switch returned failure");G.loading({content:"正在重启…",duration:0})}catch(n){const p=n instanceof Error?n.message:String(n);G.error("切换失败:"+p)}}})}function v({key:n}){if(typeof n=="string"&&n.startsWith("desktop:")){pe(n);return}T.push({mcp:"/mcp"}[n]||`/${n}`)}return _e(()=>k.connect()),(n,p)=>{const o=d("a-menu-item"),M=d("a-sub-menu"),F=d("a-menu-divider"),st=d("a-menu"),it=d("a-badge"),lt=d("a-layout-sider"),X=d("a-tooltip"),rt=d("a-tag"),ct=d("a-layout-header"),ut=d("router-view"),dt=d("a-layout-content"),ve=d("a-layout");return c(),C(ve,{class:"app-root"},{default:t(()=>[e(lt,{collapsed:u.value,"onUpdate:collapsed":p[2]||(p[2]=U=>u.value=U),collapsible:"","collapsed-width":56,width:216,class:"sidebar"},{default:t(()=>[l("div",{class:J(["logo",{collapsed:u.value}])},[l("img",{src:a(Ct),alt:"ChainlessChain",class:"logo-icon"},null,8,Ft),u.value?P("",!0):(c(),g("span",Vt,"ChainlessChain"))],2),u.value?(c(),g("div",{key:1,class:"mode-icon-sm",title:y.value?a(_).projectName:n.$t("appLayout.scope.global")},[y.value?(c(),C(a(Y),{key:0,style:{color:"#1677ff"}})):(c(),C(a(ee),{key:1,style:{color:"#722ed1"}}))],8,Zt)):(c(),g(V,{key:0},[y.value?(c(),g("div",qt,[e(a(Y),{class:"banner-icon"}),l("div",Wt,[l("div",Ht,s(a(_).projectName||n.$t("appLayout.scope.fallbackProject")),1),l("div",Jt,s(n.$t("appLayout.scope.projectPanel")),1)])])):(c(),g("div",Gt,[e(a(ee),{class:"banner-icon"}),l("span",Yt,s(n.$t("appLayout.scope.global")),1)]))],64)),e(st,{selectedKeys:j.value,"onUpdate:selectedKeys":p[0]||(p[0]=U=>j.value=U),openKeys:m.value,"onUpdate:openKeys":p[1]||(p[1]=U=>m.value=U),theme:N.value,mode:"inline","inline-collapsed":u.value,class:"side-menu",onClick:v},{default:t(()=>[u.value?(c(),g(V,{key:1},[e(o,{key:"dashboard"},{icon:t(()=>[e(a(te))]),_:1}),e(o,{key:"chat"},{icon:t(()=>[e(a(he))]),_:1}),e(o,{key:"quick-ask"},{icon:t(()=>[e(a(ae))]),_:1}),e(o,{key:"cowork"},{icon:t(()=>[e(a(be))]),_:1}),e(o,{key:"services"},{icon:t(()=>[e(a(oe))]),_:1}),e(o,{key:"aiops"},{icon:t(()=>[e(a(we))]),_:1}),e(o,{key:"tokens"},{icon:t(()=>[e(a($e))]),_:1}),e(o,{key:"logs"},{icon:t(()=>[e(a(Le))]),_:1}),e(F,{class:"divider-sm"}),e(o,{key:"skills"},{icon:t(()=>[e(a(Oe))]),_:1}),e(o,{key:"providers"},{icon:t(()=>[e(a(Se))]),_:1}),e(o,{key:"mcp"},{icon:t(()=>[e(a(Ce))]),_:1}),e(o,{key:"project-settings"},{icon:t(()=>[e(a(Y))]),_:1}),e(o,{key:"speech-settings"},{icon:t(()=>[e(a(Ee))]),_:1}),e(o,{key:"notification-settings"},{icon:t(()=>[e(a(fe))]),_:1}),e(o,{key:"sync-settings"},{icon:t(()=>[e(a(Re))]),_:1}),e(o,{key:"nlprog"},{icon:t(()=>[e(a(Ae))]),_:1}),e(o,{key:"codegen"},{icon:t(()=>[e(a(ne))]),_:1}),e(F,{class:"divider-sm"}),e(o,{key:"notes"},{icon:t(()=>[e(a(Ne))]),_:1}),e(o,{key:"search"},{icon:t(()=>[e(a(je))]),_:1}),e(o,{key:"memory"},{icon:t(()=>[e(a(Te))]),_:1}),e(o,{key:"knowledge"},{icon:t(()=>[e(a(Be))]),_:1}),e(o,{key:"marketplace"},{icon:t(()=>[e(a(Me))]),_:1}),e(o,{key:"cron"},{icon:t(()=>[e(a(Pe))]),_:1}),e(o,{key:"workflow"},{icon:t(()=>[e(a(Ie))]),_:1}),e(o,{key:"pipeline"},{icon:t(()=>[e(a(Ue))]),_:1}),e(o,{key:"tasks"},{icon:t(()=>[e(a(ae))]),_:1}),e(F,{class:"divider-sm"}),e(o,{key:"security"},{icon:t(()=>[e(a(se))]),_:1}),e(o,{key:"ukey-sign"},{icon:t(()=>[e(a(ie))]),_:1}),e(o,{key:"trust"},{icon:t(()=>[e(a(D))]),_:1}),e(o,{key:"audit"},{icon:t(()=>[e(a(De))]),_:1}),e(o,{key:"mtc"},{icon:t(()=>[e(a(D))]),_:1}),e(o,{key:"mtc-audit"},{icon:t(()=>[e(a(D))]),_:1}),e(o,{key:"multisig"},{icon:t(()=>[e(a(le))]),_:1}),e(o,{key:"did"},{icon:t(()=>[e(a(Ke))]),_:1}),e(o,{key:"permissions"},{icon:t(()=>[e(a(ze))]),_:1}),e(o,{key:"p2p"},{icon:t(()=>[e(a(Fe))]),_:1}),e(o,{key:"mobile-bridge"},{icon:t(()=>[e(a(ue))]),_:1}),e(o,{key:"terminal"},{icon:t(()=>[e(a(me))]),_:1}),e(o,{key:"backup"},{icon:t(()=>[e(a(re))]),_:1}),e(o,{key:"git"},{icon:t(()=>[e(a(ne))]),_:1}),e(o,{key:"projects"},{icon:t(()=>[e(a(Ve))]),_:1}),e(o,{key:"crosschain"},{icon:t(()=>[e(a(qe))]),_:1}),e(o,{key:"compliance"},{icon:t(()=>[e(a(D))]),_:1}),e(o,{key:"privacy"},{icon:t(()=>[e(a(ce))]),_:1}),e(o,{key:"inference"},{icon:t(()=>[e(a(We))]),_:1}),e(o,{key:"federation"},{icon:t(()=>[e(a(He))]),_:1}),e(F,{class:"divider-sm"}),e(o,{key:"wallet"},{icon:t(()=>[e(a(Je))]),_:1}),e(o,{key:"organization"},{icon:t(()=>[e(a(le))]),_:1}),e(o,{key:"tenant"},{icon:t(()=>[e(a(Ge))]),_:1}),e(o,{key:"sla"},{icon:t(()=>[e(a(te))]),_:1}),e(o,{key:"analytics"},{icon:t(()=>[e(a(Ye))]),_:1}),e(o,{key:"templates"},{icon:t(()=>[e(a(Ze))]),_:1}),e(F,{class:"divider-sm"}),e(o,{key:"community"},{icon:t(()=>[e(a(Qe))]),_:1}),e(o,{key:"governance"},{icon:t(()=>[e(a(Xe))]),_:1}),e(o,{key:"reputation"},{icon:t(()=>[e(a(xe))]),_:1}),e(o,{key:"recommend"},{icon:t(()=>[e(a(et))]),_:1}),e(F,{class:"divider-sm"}),e(o,{key:"rssfeed"},{icon:t(()=>[e(a(tt))]),_:1}),e(o,{key:"webauthn"},{icon:t(()=>[e(a(ie))]),_:1}),a(r).isEmbedded?(c(),g(V,{key:0},[e(F,{class:"divider-sm"}),e(o,{key:"desktop:hardware-wallet"},{icon:t(()=>[e(a(se))]),_:1}),e(o,{key:"desktop:backup-dashboard"},{icon:t(()=>[e(a(re))]),_:1}),e(o,{key:"desktop:llm-test-chat"},{icon:t(()=>[e(a(ce))]),_:1}),e(o,{key:"desktop:settings"},{icon:t(()=>[e(a(oe))]),_:1})],64)):P("",!0)],64)):(c(),g(V,{key:0},[e(M,{key:"g-overview"},{title:t(()=>[l("span",Qt,s(n.$t("appLayout.groups.overview")),1)]),default:t(()=>[e(o,{key:"dashboard"},{icon:t(()=>[e(a(te))]),default:t(()=>[i(s(n.$t("appLayout.items.dashboard")),1)]),_:1}),e(o,{key:"chat"},{icon:t(()=>[e(a(he))]),default:t(()=>[i(s(n.$t("appLayout.items.chat")),1)]),_:1}),e(o,{key:"quick-ask"},{icon:t(()=>[e(a(ae))]),default:t(()=>[i(s(n.$t("appLayout.items.quickAsk")),1)]),_:1}),e(o,{key:"cowork"},{icon:t(()=>[e(a(be))]),default:t(()=>[i(s(n.$t("appLayout.items.cowork")),1)]),_:1}),e(o,{key:"services"},{icon:t(()=>[e(a(oe))]),default:t(()=>[i(s(n.$t("appLayout.items.services")),1)]),_:1}),e(o,{key:"aiops"},{icon:t(()=>[e(a(we))]),default:t(()=>[i(s(n.$t("appLayout.items.aiops")),1)]),_:1}),e(o,{key:"tokens"},{icon:t(()=>[e(a($e))]),default:t(()=>[i(s(n.$t("appLayout.items.tokens")),1)]),_:1}),e(o,{key:"logs"},{icon:t(()=>[e(a(Le))]),default:t(()=>[i(s(n.$t("appLayout.items.logs")),1)]),_:1})]),_:1}),e(M,{key:"g-config"},{title:t(()=>[l("span",Xt,s(n.$t("appLayout.groups.config")),1)]),default:t(()=>[e(o,{key:"skills"},{icon:t(()=>[e(a(Oe))]),default:t(()=>[i(s(n.$t("appLayout.items.skills")),1)]),_:1}),e(o,{key:"providers"},{icon:t(()=>[e(a(Se))]),default:t(()=>[i(s(n.$t("appLayout.items.providers")),1)]),_:1}),e(o,{key:"mcp"},{icon:t(()=>[e(a(Ce))]),default:t(()=>[i(s(n.$t("appLayout.items.mcp")),1)]),_:1}),e(o,{key:"project-settings"},{icon:t(()=>[e(a(Y))]),default:t(()=>[i(s(n.$t("appLayout.items.projectSettings")),1)]),_:1}),e(o,{key:"speech-settings"},{icon:t(()=>[e(a(Ee))]),default:t(()=>[i(s(n.$t("appLayout.items.speechSettings")),1)]),_:1}),e(o,{key:"notification-settings"},{icon:t(()=>[e(a(fe))]),default:t(()=>[i(s(n.$t("appLayout.items.notificationSettings")),1)]),_:1}),e(o,{key:"sync-settings"},{icon:t(()=>[e(a(Re))]),default:t(()=>[i(s(n.$t("appLayout.items.syncSettings")),1)]),_:1}),e(o,{key:"nlprog"},{icon:t(()=>[e(a(Ae))]),default:t(()=>[i(s(n.$t("appLayout.items.nlprog")),1)]),_:1}),e(o,{key:"codegen"},{icon:t(()=>[e(a(ne))]),default:t(()=>[i(s(n.$t("appLayout.items.codegen")),1)]),_:1})]),_:1}),e(M,{key:"g-data"},{title:t(()=>[l("span",xt,s(n.$t("appLayout.groups.data")),1)]),default:t(()=>[e(o,{key:"notes"},{icon:t(()=>[e(a(Ne))]),default:t(()=>[i(s(n.$t("appLayout.items.notes")),1)]),_:1}),e(o,{key:"search"},{icon:t(()=>[e(a(je))]),default:t(()=>[i(s(n.$t("appLayout.items.search")),1)]),_:1}),e(o,{key:"memory"},{icon:t(()=>[e(a(Te))]),default:t(()=>[i(s(n.$t("appLayout.items.memory")),1)]),_:1}),e(o,{key:"knowledge"},{icon:t(()=>[e(a(Be))]),default:t(()=>[i(s(n.$t("appLayout.items.knowledge")),1)]),_:1}),e(o,{key:"marketplace"},{icon:t(()=>[e(a(Me))]),default:t(()=>[i(s(n.$t("appLayout.items.marketplace")),1)]),_:1}),e(o,{key:"cron"},{icon:t(()=>[e(a(Pe))]),default:t(()=>[i(s(n.$t("appLayout.items.cron")),1)]),_:1}),e(o,{key:"workflow"},{icon:t(()=>[e(a(Ie))]),default:t(()=>[i(s(n.$t("appLayout.items.workflow")),1)]),_:1}),e(o,{key:"pipeline"},{icon:t(()=>[e(a(Ue))]),default:t(()=>[i(s(n.$t("appLayout.items.pipeline")),1)]),_:1}),e(o,{key:"tasks"},{icon:t(()=>[e(a(ae))]),default:t(()=>[i(s(n.$t("appLayout.items.tasks")),1)]),_:1})]),_:1}),e(M,{key:"g-advanced"},{title:t(()=>[l("span",ea,s(n.$t("appLayout.groups.advanced")),1)]),default:t(()=>[e(o,{key:"security"},{icon:t(()=>[e(a(se))]),default:t(()=>[i(s(n.$t("appLayout.items.security")),1)]),_:1}),e(o,{key:"ukey-sign"},{icon:t(()=>[e(a(ie))]),default:t(()=>[i(s(n.$t("appLayout.items.ukeySign")),1)]),_:1}),e(o,{key:"trust"},{icon:t(()=>[e(a(D))]),default:t(()=>[i(s(n.$t("appLayout.items.trust")),1)]),_:1}),e(o,{key:"audit"},{icon:t(()=>[e(a(De))]),default:t(()=>[i(s(n.$t("appLayout.items.audit")),1)]),_:1}),e(o,{key:"mtc"},{icon:t(()=>[e(a(D))]),default:t(()=>[i(s(n.$t("appLayout.items.mtc")),1)]),_:1}),e(o,{key:"mtc-audit"},{icon:t(()=>[e(a(D))]),default:t(()=>[i(s(n.$t("appLayout.items.mtcAudit","MTC 审计")),1)]),_:1}),e(o,{key:"multisig"},{icon:t(()=>[e(a(le))]),default:t(()=>[i(s(n.$t("appLayout.items.multisig","M-of-N 多签")),1)]),_:1}),e(o,{key:"did"},{icon:t(()=>[e(a(Ke))]),default:t(()=>[i(s(n.$t("appLayout.items.did")),1)]),_:1}),e(o,{key:"permissions"},{icon:t(()=>[e(a(ze))]),default:t(()=>[i(s(n.$t("appLayout.items.permissions")),1)]),_:1}),e(o,{key:"p2p"},{icon:t(()=>[e(a(Fe))]),default:t(()=>[i(s(n.$t("appLayout.items.p2p")),1)]),_:1}),e(o,{key:"mobile-bridge"},{icon:t(()=>[e(a(ue))]),default:t(()=>[i(s(n.$t("appLayout.items.mobileBridge","移动桥")),1)]),_:1}),e(o,{key:"mobile-projects"},{icon:t(()=>[e(a(ue))]),default:t(()=>[i(s(n.$t("appLayout.items.mobileProjects","手机项目 (v0.2)")),1)]),_:1}),e(o,{key:"terminal"},{icon:t(()=>[e(a(me))]),default:t(()=>[i(s(n.$t("appLayout.items.terminal","远程终端")),1)]),_:1}),e(o,{key:"backup"},{icon:t(()=>[e(a(re))]),default:t(()=>[i(s(n.$t("appLayout.items.backup")),1)]),_:1}),e(o,{key:"git"},{icon:t(()=>[e(a(ne))]),default:t(()=>[i(s(n.$t("appLayout.items.git")),1)]),_:1}),e(o,{key:"projects"},{icon:t(()=>[e(a(Ve))]),default:t(()=>[i(s(n.$t("appLayout.items.projects")),1)]),_:1}),e(o,{key:"crosschain"},{icon:t(()=>[e(a(qe))]),default:t(()=>[i(s(n.$t("appLayout.items.crosschain")),1)]),_:1}),e(o,{key:"compliance"},{icon:t(()=>[e(a(D))]),default:t(()=>[i(s(n.$t("appLayout.items.compliance")),1)]),_:1}),e(o,{key:"privacy"},{icon:t(()=>[e(a(ce))]),default:t(()=>[i(s(n.$t("appLayout.items.privacy")),1)]),_:1}),e(o,{key:"inference"},{icon:t(()=>[e(a(We))]),default:t(()=>[i(s(n.$t("appLayout.items.inference")),1)]),_:1}),e(o,{key:"federation"},{icon:t(()=>[e(a(He))]),default:t(()=>[i(s(n.$t("appLayout.items.federation")),1)]),_:1})]),_:1}),e(M,{key:"g-enterprise"},{title:t(()=>[l("span",ta,s(n.$t("appLayout.groups.enterprise")),1)]),default:t(()=>[e(o,{key:"wallet"},{icon:t(()=>[e(a(Je))]),default:t(()=>[i(s(n.$t("appLayout.items.wallet")),1)]),_:1}),e(o,{key:"organization"},{icon:t(()=>[e(a(le))]),default:t(()=>[i(s(n.$t("appLayout.items.organization")),1)]),_:1}),e(o,{key:"tenant"},{icon:t(()=>[e(a(Ge))]),default:t(()=>[i(s(n.$t("appLayout.items.tenant")),1)]),_:1}),e(o,{key:"sla"},{icon:t(()=>[e(a(te))]),default:t(()=>[i(s(n.$t("appLayout.items.sla")),1)]),_:1}),e(o,{key:"analytics"},{icon:t(()=>[e(a(Ye))]),default:t(()=>[i(s(n.$t("appLayout.items.analytics")),1)]),_:1}),e(o,{key:"templates"},{icon:t(()=>[e(a(Ze))]),default:t(()=>[i(s(n.$t("appLayout.items.templates")),1)]),_:1})]),_:1}),e(M,{key:"g-social"},{title:t(()=>[l("span",aa,s(n.$t("appLayout.groups.social")),1)]),default:t(()=>[e(o,{key:"community"},{icon:t(()=>[e(a(Qe))]),default:t(()=>[i(s(n.$t("appLayout.items.community")),1)]),_:1}),e(o,{key:"governance"},{icon:t(()=>[e(a(Xe))]),default:t(()=>[i(s(n.$t("appLayout.items.governance")),1)]),_:1}),e(o,{key:"reputation"},{icon:t(()=>[e(a(xe))]),default:t(()=>[i(s(n.$t("appLayout.items.reputation")),1)]),_:1}),e(o,{key:"recommend"},{icon:t(()=>[e(a(et))]),default:t(()=>[i(s(n.$t("appLayout.items.recommend")),1)]),_:1})]),_:1}),e(M,{key:"g-media"},{title:t(()=>[l("span",oa,s(n.$t("appLayout.groups.media")),1)]),default:t(()=>[e(o,{key:"video"},{icon:t(()=>[e(a(Lt))]),default:t(()=>[i(s(n.$t("appLayout.items.video")),1)]),_:1})]),_:1}),e(M,{key:"g-extension"},{title:t(()=>[l("span",na,s(n.$t("appLayout.groups.extension")),1)]),default:t(()=>[e(o,{key:"rssfeed"},{icon:t(()=>[e(a(tt))]),default:t(()=>[i(s(n.$t("appLayout.items.rssfeed")),1)]),_:1}),e(o,{key:"webauthn"},{icon:t(()=>[e(a(ie))]),default:t(()=>[i(s(n.$t("appLayout.items.webauthn")),1)]),_:1})]),_:1}),a(r).isEmbedded?(c(),C(M,{key:"g-desktop"},{title:t(()=>[l("span",sa,s(n.$t("appLayout.groups.desktop")),1)]),default:t(()=>[e(o,{key:"desktop:hardware-wallet"},{icon:t(()=>[e(a(se))]),default:t(()=>[i(s(n.$t("appLayout.items.desktopHardware")),1)]),_:1}),e(o,{key:"desktop:backup-dashboard"},{icon:t(()=>[e(a(re))]),default:t(()=>[i(s(n.$t("appLayout.items.desktopBackup")),1)]),_:1}),e(o,{key:"desktop:llm-test-chat"},{icon:t(()=>[e(a(ce))]),default:t(()=>[i(s(n.$t("appLayout.items.desktopLlmTest")),1)]),_:1}),e(o,{key:"desktop:settings"},{icon:t(()=>[e(a(oe))]),default:t(()=>[i(s(n.$t("appLayout.items.desktopSettings")),1)]),_:1})]),_:1})):P("",!0)],64))]),_:1},8,["selectedKeys","openKeys","theme","inline-collapsed"]),l("div",{class:J(["sidebar-footer",{collapsed:u.value}])},[e(it,{status:B.value},null,8,["status"]),u.value?P("",!0):(c(),g("span",ia,s(z.value),1))],2)]),_:1},8,["collapsed"]),e(ve,{class:"main-area"},{default:t(()=>[e(ct,{class:"app-header"},{default:t(()=>[l("div",la,[l("div",{class:J(["scope-tag",y.value?"project":"global"])},[(c(),C(kt(y.value?a(Y):a(ee)))),l("span",null,s(y.value?a(_).projectName||n.$t("appLayout.scope.fallbackProject"):n.$t("appLayout.scope.global")),1),y.value&&a(_).projectRoot?(c(),C(X,{key:0,title:a(_).projectRoot},{default:t(()=>[e(a(Ot),{class:"info-icon"})]),_:1},8,["title"])):P("",!0)],2)]),l("div",ra,[l("div",ca,[(c(!0),g(V,null,ot(a(bt),(U,x)=>(c(),C(X,{key:x,title:U.label},{default:t(()=>[l("button",{class:J(["theme-btn",{active:R.value===x}]),"data-theme-key":x,onClick:fa=>I(x)},s(U.icon),11,ua)]),_:2},1032,["title"]))),128))]),e(X,{title:n.$t("language.label")},{default:t(()=>[l("button",{class:"lang-switch-btn","data-locale":a(W),onClick:de},[e(a(ee),{class:"lang-switch-icon"}),l("span",pa,s(n.$t("language.switch")),1)],8,da)]),_:1},8,["title"]),e(zt),a(r).isEmbedded?(c(),C(Ut,{key:0})):P("",!0),l("span",ya,s(a(w)),1),a(r).isEmbedded?(c(),C(X,{key:1,title:n.$t("appLayout.shellSwitch")},{default:t(()=>[l("button",{type:"button",class:"shell-switch-btn",onClick:ye},[e(a(me))])]),_:1},8,["title"])):P("",!0),e(rt,{color:f.value==="connected"?"green":f.value==="connecting"?"orange":"red",class:"ws-tag"},{default:t(()=>[i(s(f.value==="connected"?n.$t("appLayout.wsStatus.connected"):f.value==="connecting"?n.$t("appLayout.wsStatus.connecting"):n.$t("appLayout.wsStatus.disconnected")),1)]),_:1},8,["color"])])]),_:1}),e(dt,{class:"page-content"},{default:t(()=>[e(ut)]),_:1})]),_:1})]),_:1})}}},za=ge(ma,[["__scopeId","data-v-488ac0f2"]]);export{za as default};
|