chainlesschain 0.162.13 → 0.162.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +2 -2
- package/src/assets/web-panel/assets/{AIOps-Bq_zxhCr.js → AIOps-D34d_Nh1.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CaevDm9t.js → ActionButton-Br7HxCnl.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-B0gOmwPw.js → Analytics-bVKq79Xd.js} +1 -1
- package/src/assets/web-panel/assets/{AppLayout-DWhZiV0Q.js → AppLayout-CWSLIbAz.js} +2 -2
- package/src/assets/web-panel/assets/{Audit-ZuZJBCxo.js → Audit-Cmnu1qqa.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CX7jhH5l.js → Backup-Rok20-TL.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CVLx7HVq.js → BaseInput-BJzs_ZtT.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-C6yL5tRD.js → Chat-CSYapbcq.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-BePhbqVq.js → Checkbox-BEa7Sr7e.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B5E4x1Lm.js → Codegen-C9M4e7ne.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CWhNU6A7.js → Col-DU9NoUIi.js} +1 -1
- package/src/assets/web-panel/assets/{Community-mSEAuJhp.js → Community-DA9uz_jP.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DSudHzX3.js → Compact-3_bEraVw.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CxJLYjyn.js → Compliance-BtF8jWUQ.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-C-trppQj.js → Cowork-BqvA7oaM.js} +1 -1
- package/src/assets/web-panel/assets/{Cron-_Ij4v5fY.js → Cron-CxZy7Mzg.js} +1 -1
- package/src/assets/web-panel/assets/{Crosschain-eLHXzp5T.js → Crosschain-1DB-XRGu.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BP04AUUB.js → DID-B6Ezp1pt.js} +1 -1
- package/src/assets/web-panel/assets/{Dashboard-CzEeQv62.js → Dashboard-QDJ6VVsn.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-C_SGOB22.js → Dropdown-CovsWjxG.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BgaP4BOv.js → Federation-DbRxS4Y4.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BxGLLt9r.js → FormItemContext-9E9dNGtx.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Bt_uM_Gw.js → Git-CqEpyxRZ.js} +1 -1
- package/src/assets/web-panel/assets/{Governance-N2-0RG_o.js → Governance-On47KtGq.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-eS3g-CzP.js → Inference-RZcjcyaq.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-CUuvNVah.js → KnowledgeGraph-C-1rRAM9.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-wPbwEt2r.js → Logs-BuunmG_r.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-DH91kTwo.js → Marketplace-CromymyA.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-D-GyyBrI.js → McpTools-5XlFExh7.js} +1 -1
- package/src/assets/web-panel/assets/{Memory-BOtUy-tw.js → Memory-DjnUT7YM.js} +1 -1
- package/src/assets/web-panel/assets/{MobileBridge-DIP__XQd.js → MobileBridge-BrYIgLg6.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-1nqr1UsU.js → MobileProjects-CL5V3fTm.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CCE0x7h2.js → Mtc-CHYJq6zK.js} +1 -1
- package/src/assets/web-panel/assets/{MtcAudit-BBkz0XUO.js → MtcAudit-BZxUO0qt.js} +1 -1
- package/src/assets/web-panel/assets/{Multisig-CIKSJvTY.js → Multisig-FZTmJgW1.js} +1 -1
- package/src/assets/web-panel/assets/{NLProgramming-BDkgeFcq.js → NLProgramming-C9Mhefph.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-ONiUxfN1.js → Notes-W7usj-Ar.js} +1 -1
- package/src/assets/web-panel/assets/{NotificationSettings-CGcyKEIe.js → NotificationSettings-PBuYv_Bh.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BZtMYBJt.js → Organization-CuYCE-rF.js} +1 -1
- package/src/assets/web-panel/assets/{Overflow-C4LfFZAI.js → Overflow-Dojx-kzE.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-D71Cpk-m.js → P2P-BgIaSrLX.js} +1 -1
- package/src/assets/web-panel/assets/{Permissions-DRGYF29v.js → Permissions-Byj2dkF_.js} +1 -1
- package/src/assets/web-panel/assets/{PersonalDataHub-CfRYoIua.js → PersonalDataHub-CMOOI13-.js} +1 -1
- package/src/assets/web-panel/assets/{Pipeline-BOyp0_Qo.js → Pipeline-CWwEOF09.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-a_AcphvF.js → Privacy-VT7gldcN.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CFu1grYt.js → ProjectInit-7UH3c3p7.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectSettings-p54Eivhh.js → ProjectSettings-DqLp-72a.js} +1 -1
- package/src/assets/web-panel/assets/{Projects-DkB88XAu.js → Projects-B_54eDhH.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-EK7f8DEd.js → Providers-BIrNfNpc.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CpO0w3iP.js → QuickAsk-BbYPwCso.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BUJVQdv9.js → Recommend-BF4qBssF.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-kU2fOuZt.js → Reputation-DPEzlC2V.js} +1 -1
- package/src/assets/web-panel/assets/{Row-oGWRbk6g.js → Row-DjHxhH1L.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-saC_46Yo.js → RssFeed-D0_j678P.js} +1 -1
- package/src/assets/web-panel/assets/{Search-CjtRqFUu.js → Search-DctfGehu.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BX0NBVfQ.js → Security-BFHggeYM.js} +1 -1
- package/src/assets/web-panel/assets/{Services-Bgxsnei_.js → Services-CmrFMukV.js} +1 -1
- package/src/assets/web-panel/assets/{Skeleton-CwBb3k2a.js → Skeleton-DR4vn_nS.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CZCMYH6Z.js → Skills-DlXG2yyV.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Djy1uHnZ.js → Sla-4PPGL3SE.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CGUI_Uyh.js → SpeechSettings-D9EhJOqm.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DK2CKHRD.js → SyncSettings-Dasmbi0p.js} +1 -1
- package/src/assets/web-panel/assets/{Tasks-BKiOzeIO.js → Tasks-vilEiuPA.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CnQpleXj.js → Templates-Ca9Rvktn.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DwKz0cjm.js → Tenant-CEZb9gfK.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-A7t_wsR8.js → Terminal-DanCBdbD.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BqYY9l44.js → Tokens-SPkClW2d.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BI4bXFmi.js → Trigger-B645yL7g.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-yMynKTRG.js → Trust-D9sM_Ig0.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-Br4IScM6.js → UkeySign-B_Nr2K-u.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CWcThGsP.js → VideoEditing-U01Lea8j.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CZcAtjxj.js → Wallet-6xBySVV8.js} +1 -1
- package/src/assets/web-panel/assets/{WebAuthn-BnTZFMA0.js → WebAuthn-DbgMoBu6.js} +1 -1
- package/src/assets/web-panel/assets/{WorkflowEditor-N7gGz3_n.js → WorkflowEditor-Bz-Y6IR2.js} +1 -1
- package/src/assets/web-panel/assets/{chat-D175ZIO0.js → chat-BC_O9hag.js} +1 -1
- package/src/assets/web-panel/assets/{colors-LKhZyttv.js → colors-ChlOGOvr.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CsJSebxT.js → compact-item-BSbAYGGF.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BJ_CPYFC.js → createContext-CFcZly5M.js} +1 -1
- package/src/assets/web-panel/assets/{hasIn-CzD3IqH8.js → hasIn-BomYwwYE.js} +1 -1
- package/src/assets/web-panel/assets/{index-BSNibAqz.js → index-5Ewm6KZA.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8kltMTW.js → index-B6LJHQoE.js} +1 -1
- package/src/assets/web-panel/assets/{index-BvF2tC6C.js → index-BEJ6YiLI.js} +1 -1
- package/src/assets/web-panel/assets/{index-BjOrt4vw.js → index-BGUbtM3R.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dm-3kvtD.js → index-BHGsFwYW.js} +1 -1
- package/src/assets/web-panel/assets/{index-D401L3yx.js → index-BHi69MHF.js} +1 -1
- package/src/assets/web-panel/assets/{index-R1cFADfk.js → index-BI1jAWcc.js} +1 -1
- package/src/assets/web-panel/assets/index-BIRYt1of.js +1 -0
- package/src/assets/web-panel/assets/{index-Dd7dICwB.js → index-BYDvb1pi.js} +1 -1
- package/src/assets/web-panel/assets/{index-Kn-Of5ew.js → index-BZGdjNLA.js} +1 -1
- package/src/assets/web-panel/assets/{index-uTEVWPYA.js → index-BwFykZ5U.js} +1 -1
- package/src/assets/web-panel/assets/{index-JTX9A7w0.js → index-ByZQNO0A.js} +1 -1
- package/src/assets/web-panel/assets/{index-BmJdof_c.js → index-C0rr1X9W.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsirlkJ0.js → index-CBhoZhCO.js} +1 -1
- package/src/assets/web-panel/assets/{index-6qPbrYF7.js → index-CCRSz2cR.js} +1 -1
- package/src/assets/web-panel/assets/index-CZfySmWX.js +1 -0
- package/src/assets/web-panel/assets/{index-DJVkBmSc.js → index-Cj47XwJQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DOO73rHE.js → index-Cmzh8gKL.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNVLVzN5.js → index-CnxlKTDK.js} +1 -1
- package/src/assets/web-panel/assets/{index-CTIkCKav.js → index-CoF95pYK.js} +1 -1
- package/src/assets/web-panel/assets/{index-RIO4JKMP.js → index-Ctx97mH-.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEDFHKO3.js → index-D0vX9jQA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRGNuUIM.js → index-DNkth8dM.js} +1 -1
- package/src/assets/web-panel/assets/{index-DnPt5OdD.js → index-DRp5_Xns.js} +1 -1
- package/src/assets/web-panel/assets/{index-E7t1hAnk.js → index-DW-Ji07y.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhiZDGg7.js → index-DXgE2VW6.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7UYymse.js → index-D_0B3CiU.js} +1 -1
- package/src/assets/web-panel/assets/{index-CyHdYUeZ.js → index-Dbf5YmDX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKjBAdm0.js → index-DsNQ2hqI.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2HBKw07.js → index-EY733h9z.js} +1 -1
- package/src/assets/web-panel/assets/{index-DM3uBEWD.js → index-QD_n54XT.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXp1jVsK.js → index-T5Y_9IPv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDSZDDb2.js → index-b8GbH2Yi.js} +3 -3
- package/src/assets/web-panel/assets/{index-BZluCuTH.js → index-gUACAWbM.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7ZcBI5s.js → index-onW325hZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5IZCkZG.js → index-ozVPr1gj.js} +1 -1
- package/src/assets/web-panel/assets/{index-BMvdoiFr.js → index-slYX2rCE.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXH9ujMW.js → index-t9u2bHpH.js} +1 -1
- package/src/assets/web-panel/assets/{index-BV-__mlC.js → index-za1GUJBG.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CBW0okek.js → initDefaultProps-DnadEaxu.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DGAffQ0Z.js → motion-CC_Na0Tl.js} +1 -1
- package/src/assets/web-panel/assets/{move-DFJ0-5IW.js → move-C2d9Mkk9.js} +1 -1
- package/src/assets/web-panel/assets/{omit-AvrDghg1.js → omit-QvpKbF8p.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-D7csw9i1.js → pickAttrs-Dm8r3X1_.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-hZ6Lg6kG.js → placementArrow-DaqaVfoX.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DLLx5VvS.js → responsiveObserve-Iida9fIn.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BaRIT3ev.js → slide-YqHexXQD.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Cdjyuhrz.js → statusUtils-BGKLoeEt.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CbrNybTt.js → styleChecker-aI-gsQO8.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-B8gAhiRC.js → useFlexGapSupport-BiOsz4rc.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BZPy4ICP.js → useFs-CZy7Zo2X.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-6Y0NDMVv.js → vnode-B6WqjmE4.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DTbMGsSH.js → zoom-DTeTrJ2z.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/__tests__/android.test.js +260 -0
- package/src/commands/android.js +284 -0
- package/src/commands/hub.js +57 -17
- package/src/gateways/ws/personal-data-hub-protocol.js +28 -8
- package/src/index.js +2 -0
- package/src/lib/cc-android-bridge.js +162 -0
- package/src/lib/personal-data-hub-wiring.js +74 -18
- package/src/lib/web-ui-server.js +2 -1
- package/src/assets/web-panel/assets/index-CY1mQA2I.js +0 -1
- package/src/assets/web-panel/assets/index-D9nXHfUB.js +0 -1
|
@@ -24,6 +24,9 @@ import {
|
|
|
24
24
|
import { getAIChatWizard } from "../../lib/personal-data-hub-aichat-wizard.js";
|
|
25
25
|
import { existsSync, unlinkSync, readdirSync } from "node:fs";
|
|
26
26
|
import { join } from "node:path";
|
|
27
|
+
import pdhPkg from "@chainlesschain/personal-data-hub";
|
|
28
|
+
|
|
29
|
+
const { ingestSystemDataAndroidSnapshot } = pdhPkg;
|
|
27
30
|
|
|
28
31
|
async function withHub(fn) {
|
|
29
32
|
try {
|
|
@@ -42,6 +45,22 @@ export const PERSONAL_DATA_HUB_HANDLERS = {
|
|
|
42
45
|
return await hub.engine.ask(msg.question, msg.options || {});
|
|
43
46
|
}),
|
|
44
47
|
|
|
48
|
+
// Path Y: prompt context only, no LLM call. Lets web-shell / mobile host
|
|
49
|
+
// its own inference (Volcengine Doubao, OpenRouter, etc.) while keeping
|
|
50
|
+
// vault retrieval centralized.
|
|
51
|
+
"personal-data-hub.retrieve-context": async (msg) =>
|
|
52
|
+
withHub(async (hub) => {
|
|
53
|
+
if (!hub.engine) throw new Error("Analysis engine unavailable");
|
|
54
|
+
return await hub.engine.retrieveContext(msg.question, msg.options || {});
|
|
55
|
+
}),
|
|
56
|
+
|
|
57
|
+
// Path C: phone-collected ContentResolver + PackageManager snapshot →
|
|
58
|
+
// staging file → syncAdapter(system-data-android). Returns SyncReport.
|
|
59
|
+
"personal-data-hub.ingest-system-data-android": async (msg) =>
|
|
60
|
+
withHub(
|
|
61
|
+
async (hub) => await ingestSystemDataAndroidSnapshot(hub, msg.snapshot),
|
|
62
|
+
),
|
|
63
|
+
|
|
45
64
|
"personal-data-hub.stats": async () =>
|
|
46
65
|
withHub((hub) => ({
|
|
47
66
|
vault: hub.vault.stats(),
|
|
@@ -219,14 +238,15 @@ export const PERSONAL_DATA_HUB_HANDLERS = {
|
|
|
219
238
|
withHub(async (hub) => await hub.probeWechatEnv()),
|
|
220
239
|
|
|
221
240
|
"personal-data-hub.register-wechat": async (msg) =>
|
|
222
|
-
withHub(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
241
|
+
withHub(
|
|
242
|
+
async (hub) =>
|
|
243
|
+
await hub.registerWechatAdapter({
|
|
244
|
+
account: msg.account,
|
|
245
|
+
dbPath: msg.dbPath,
|
|
246
|
+
wechatDataPath: msg.wechatDataPath,
|
|
247
|
+
fridaOpts: msg.fridaOpts,
|
|
248
|
+
keyProviderOverride: msg.keyProviderOverride,
|
|
249
|
+
}),
|
|
230
250
|
),
|
|
231
251
|
|
|
232
252
|
"personal-data-hub.unregister-wechat": async (msg) =>
|
package/src/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { registerChatCommand } from "./commands/chat.js";
|
|
|
16
16
|
import { registerAskCommand } from "./commands/ask.js";
|
|
17
17
|
import { registerLlmCommand } from "./commands/llm.js";
|
|
18
18
|
import { registerHubCommand } from "./commands/hub.js";
|
|
19
|
+
import { registerAndroidCommand } from "./commands/android.js";
|
|
19
20
|
import {
|
|
20
21
|
registerAgentCommand,
|
|
21
22
|
registerSubAgentV2Command,
|
|
@@ -407,6 +408,7 @@ export function createProgram(opts = {}) {
|
|
|
407
408
|
registerAskCommand(program);
|
|
408
409
|
registerLlmCommand(program);
|
|
409
410
|
registerHubCommand(program);
|
|
411
|
+
registerAndroidCommand(program);
|
|
410
412
|
registerAgentCommand(program);
|
|
411
413
|
registerSubAgentV2Command(program);
|
|
412
414
|
registerExecBackendV2Command(program);
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cc-android-bridge — Node-side facade for the Android JNI bridge.
|
|
3
|
+
*
|
|
4
|
+
* Plan A Sub-Phase A6/A7 scaffold (see `docs/design/Personal_Data_Hub_Android_Standalone_Cc.md`
|
|
5
|
+
* §4.2 + §6.1). The eventual native binding (`cc-android-bridge.node`,
|
|
6
|
+
* loaded from `android-app/app/src/main/cpp/`) exposes Java/Kotlin APIs to
|
|
7
|
+
* the in-APK Node runtime: ContentResolver query, PackageManager listings,
|
|
8
|
+
* Runtime.exec / Shizuku / Magisk su, Accessibility node tree, SAF DocumentFile
|
|
9
|
+
* read.
|
|
10
|
+
*
|
|
11
|
+
* **v0.1 status**: the native .node binding is NOT yet shipped. This file is
|
|
12
|
+
* a pure stub — every `invoke()` call rejects with ANDROID_BRIDGE_NOT_AVAILABLE.
|
|
13
|
+
* It exists so the `cc android …` commands and `system-data-android` adapter
|
|
14
|
+
* (A7 / A8) can land + be unit-tested ahead of the JNI work. When A6 ships
|
|
15
|
+
* the .node binding, this file's `loadNativeBinding()` will resolve the real
|
|
16
|
+
* module; method dispatch is already wired.
|
|
17
|
+
*
|
|
18
|
+
* Detection precedence (highest first):
|
|
19
|
+
* 1. process.env.CC_ANDROID_BRIDGE_OVERRIDE === "1" — test override; bridge
|
|
20
|
+
* reports "available" and routes through `_deps.testInvoke` (which tests
|
|
21
|
+
* replace with a mock). Lets us exercise the command code paths without
|
|
22
|
+
* a real device.
|
|
23
|
+
* 2. process.platform === "android"
|
|
24
|
+
* 3. process.env.PREFIX startsWith "/data/data/com.chainlesschain.android/"
|
|
25
|
+
* (Termux $PREFIX pattern in the bundled cc).
|
|
26
|
+
*
|
|
27
|
+
* Method names are kebab-case to match the `cc android <verb>` CLI surface,
|
|
28
|
+
* not the underlying JNI signatures (those use Java camelCase). Mapping
|
|
29
|
+
* happens in the future native binding.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { createRequire } from "node:module";
|
|
33
|
+
|
|
34
|
+
const ANDROID_PREFIX = "/data/data/com.chainlesschain.android/";
|
|
35
|
+
const nodeRequire = createRequire(import.meta.url);
|
|
36
|
+
|
|
37
|
+
export function detectAndroid() {
|
|
38
|
+
if (process.env.CC_ANDROID_BRIDGE_OVERRIDE === "1") return true;
|
|
39
|
+
if (process.platform === "android") return true;
|
|
40
|
+
if (
|
|
41
|
+
typeof process.env.PREFIX === "string" &&
|
|
42
|
+
process.env.PREFIX.startsWith(ANDROID_PREFIX)
|
|
43
|
+
) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Lazy-load the native .node binding when we're actually on Android. Stays
|
|
51
|
+
* null elsewhere. The binding is expected at:
|
|
52
|
+
* $APK/lib/<abi>/cc-android-bridge.node
|
|
53
|
+
* resolved via require.resolve("cc-android-bridge").
|
|
54
|
+
*
|
|
55
|
+
* Wrapped in try so a missing binding (current state pre-A6) doesn't crash
|
|
56
|
+
* the CLI on import — `invoke()` reports it as a runtime error instead.
|
|
57
|
+
*/
|
|
58
|
+
export function loadNativeBinding() {
|
|
59
|
+
if (!detectAndroid()) return null;
|
|
60
|
+
if (process.env.CC_ANDROID_BRIDGE_OVERRIDE === "1") return null;
|
|
61
|
+
try {
|
|
62
|
+
return nodeRequire("cc-android-bridge");
|
|
63
|
+
} catch (_e) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export class AndroidBridgeUnavailableError extends Error {
|
|
69
|
+
constructor(reason) {
|
|
70
|
+
super(`ANDROID_BRIDGE_NOT_AVAILABLE: ${reason}`);
|
|
71
|
+
this.code = "ANDROID_BRIDGE_NOT_AVAILABLE";
|
|
72
|
+
this.reason = reason;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Invoke a bridge method.
|
|
78
|
+
*
|
|
79
|
+
* @param {string} method — kebab-case method name (e.g. "contacts.query",
|
|
80
|
+
* "fs.read", "a11y.query", "app.list").
|
|
81
|
+
* @param {object} [params]
|
|
82
|
+
* @returns {Promise<any>}
|
|
83
|
+
*
|
|
84
|
+
* Rejects with AndroidBridgeUnavailableError when:
|
|
85
|
+
* - Not running on Android (and CC_ANDROID_BRIDGE_OVERRIDE != 1)
|
|
86
|
+
* - Running on Android but native binding failed to load
|
|
87
|
+
* - Method is not registered in the native binding
|
|
88
|
+
*/
|
|
89
|
+
export async function invoke(method, params = {}) {
|
|
90
|
+
if (typeof method !== "string" || method.length === 0) {
|
|
91
|
+
throw new TypeError(
|
|
92
|
+
"cc-android-bridge.invoke: method must be non-empty string",
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Test path — _deps.testInvoke replaced by harness.
|
|
97
|
+
if (
|
|
98
|
+
process.env.CC_ANDROID_BRIDGE_OVERRIDE === "1" &&
|
|
99
|
+
typeof _deps.testInvoke === "function"
|
|
100
|
+
) {
|
|
101
|
+
return await _deps.testInvoke(method, params);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!_deps.detectAndroid()) {
|
|
105
|
+
throw new AndroidBridgeUnavailableError(
|
|
106
|
+
`not running on Android (platform=${process.platform})`,
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const native = _deps.loadNativeBinding();
|
|
111
|
+
if (!native) {
|
|
112
|
+
throw new AndroidBridgeUnavailableError(
|
|
113
|
+
"native binding cc-android-bridge.node missing — A6 JNI module not yet bundled",
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
if (typeof native.invoke !== "function") {
|
|
117
|
+
throw new AndroidBridgeUnavailableError(
|
|
118
|
+
"native binding loaded but does not export invoke()",
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
return await native.invoke(method, params);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Check whether the bridge is usable right now without throwing.
|
|
126
|
+
* Returns `{ available: boolean, reason?: string }`.
|
|
127
|
+
*/
|
|
128
|
+
export function caps() {
|
|
129
|
+
if (process.env.CC_ANDROID_BRIDGE_OVERRIDE === "1") {
|
|
130
|
+
return { available: true, reason: "test-override" };
|
|
131
|
+
}
|
|
132
|
+
if (!_deps.detectAndroid()) {
|
|
133
|
+
return {
|
|
134
|
+
available: false,
|
|
135
|
+
reason: `not-on-android (platform=${process.platform})`,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const native = _deps.loadNativeBinding();
|
|
139
|
+
if (!native) {
|
|
140
|
+
return {
|
|
141
|
+
available: false,
|
|
142
|
+
reason: "native-binding-missing (A6 pending)",
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return { available: true };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// _deps injection seam (per [[feedback-vi-mock-cjs-interop]]). Tests reach in
|
|
149
|
+
// and replace these to exercise both success + error paths without needing
|
|
150
|
+
// a real Android device or the unloaded native binding.
|
|
151
|
+
export const _deps = {
|
|
152
|
+
detectAndroid,
|
|
153
|
+
loadNativeBinding,
|
|
154
|
+
testInvoke: null,
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export default {
|
|
158
|
+
invoke,
|
|
159
|
+
caps,
|
|
160
|
+
AndroidBridgeUnavailableError,
|
|
161
|
+
_deps,
|
|
162
|
+
};
|
|
@@ -44,6 +44,7 @@ const {
|
|
|
44
44
|
generateKeyHex,
|
|
45
45
|
EmailAdapter,
|
|
46
46
|
AlipayBillAdapter,
|
|
47
|
+
SystemDataAndroidAdapter,
|
|
47
48
|
EntityResolver,
|
|
48
49
|
EntityResolverEmbeddingStage,
|
|
49
50
|
EntityResolverLLMStage,
|
|
@@ -95,6 +96,28 @@ let _hub = null;
|
|
|
95
96
|
let _initPromise = null;
|
|
96
97
|
let _bm25 = null;
|
|
97
98
|
|
|
99
|
+
// LLM override — see file header. Default cli-side hub uses a direct
|
|
100
|
+
// OllamaClient; when the desktop main process embeds this wiring via
|
|
101
|
+
// ws-cli-loader it can inject a CcLLMAdapter (wrapping LLMManager) so the
|
|
102
|
+
// SAME wiring honors the user's active provider (volcengine / anthropic /
|
|
103
|
+
// etc.) instead of hard-binding Ollama. Must be set BEFORE the first
|
|
104
|
+
// getHub() call — initHub() reads it synchronously at the LLM-wiring step.
|
|
105
|
+
let _llmOverride = null;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Override the default cli-side OllamaClient with a caller-supplied LLM
|
|
109
|
+
* client conforming to the hub's LLMClient contract ({ chat, name, isLocal }).
|
|
110
|
+
*
|
|
111
|
+
* Used by desktop-app-vue web-shell's ws-cli-loader bootstrap: see
|
|
112
|
+
* desktop-app-vue/src/main/web-shell/ws-cli-loader.js. Calling this on
|
|
113
|
+
* an already-initialized hub does NOT swap the live LLM — the override only
|
|
114
|
+
* applies on the next fresh initHub(). Restart the process if you need to
|
|
115
|
+
* change provider mid-session.
|
|
116
|
+
*/
|
|
117
|
+
export function setHubLLMOverride(llm) {
|
|
118
|
+
_llmOverride = llm || null;
|
|
119
|
+
}
|
|
120
|
+
|
|
98
121
|
export function resolveHubDir() {
|
|
99
122
|
return join(getElectronUserDataDir(), ".chainlesschain", "hub");
|
|
100
123
|
}
|
|
@@ -115,12 +138,16 @@ async function initHub() {
|
|
|
115
138
|
const vault = new LocalVault({ path: join(hubDir, "vault.db"), key });
|
|
116
139
|
vault.open();
|
|
117
140
|
|
|
118
|
-
// LLM:
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
141
|
+
// LLM: prefer caller-injected override (desktop web-shell wires CcLLMAdapter
|
|
142
|
+
// wrapping LLMManager so PDH honors the user's saved active provider).
|
|
143
|
+
// Fallback to standalone OllamaClient — connects to localhost:11434.
|
|
144
|
+
// Override the fallback via env CC_HUB_OLLAMA_URL / CC_HUB_OLLAMA_MODEL.
|
|
145
|
+
const llm =
|
|
146
|
+
_llmOverride ||
|
|
147
|
+
new OllamaClient({
|
|
148
|
+
baseUrl: process.env.CC_HUB_OLLAMA_URL || "http://localhost:11434",
|
|
149
|
+
model: process.env.CC_HUB_OLLAMA_MODEL || "qwen2.5:7b-instruct",
|
|
150
|
+
});
|
|
124
151
|
|
|
125
152
|
// KG sink — direct ESM import works here.
|
|
126
153
|
let kgSink = null;
|
|
@@ -147,20 +174,33 @@ async function initHub() {
|
|
|
147
174
|
|
|
148
175
|
// Phase 8 — EntityResolver pipeline
|
|
149
176
|
const entityResolver = new EntityResolver({ vault });
|
|
177
|
+
// Plan A v0.1 — in-APK Android cc has no Ollama on localhost:11434.
|
|
178
|
+
// Every embedding call would TCP-timeout (measured: ~60s extra per sync
|
|
179
|
+
// on Xiaomi 24115RA8EC 2026-05-21). Detect Termux $PREFIX for our APK
|
|
180
|
+
// and skip embedding+LLM stages entirely. Rule-stage still runs; the
|
|
181
|
+
// resolve_queue picks up enqueued pairs later if a host with Ollama is
|
|
182
|
+
// ever attached (e.g. desktop-side replay).
|
|
183
|
+
const isInAppAndroidCc =
|
|
184
|
+
typeof process.env.PREFIX === "string" &&
|
|
185
|
+
process.env.PREFIX.startsWith("/data/data/com.chainlesschain.android");
|
|
186
|
+
const skipEmbeddings =
|
|
187
|
+
isInAppAndroidCc || process.env.CC_HUB_DISABLE_EMBEDDINGS === "1";
|
|
150
188
|
try {
|
|
151
|
-
if (llm) {
|
|
189
|
+
if (llm && !skipEmbeddings) {
|
|
152
190
|
const llmStage = new EntityResolverLLMStage({
|
|
153
191
|
llm,
|
|
154
192
|
acceptNonLocal: false,
|
|
155
193
|
});
|
|
156
194
|
entityResolver._llmStage = llmStage.asStageFn();
|
|
157
195
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
196
|
+
if (!skipEmbeddings) {
|
|
197
|
+
const embeddingStage = new EntityResolverEmbeddingStage({
|
|
198
|
+
ollamaUrl: process.env.CC_HUB_OLLAMA_URL || "http://localhost:11434",
|
|
199
|
+
model: process.env.CC_HUB_OLLAMA_EMBED_MODEL || "nomic-embed-text",
|
|
200
|
+
vault,
|
|
201
|
+
});
|
|
202
|
+
entityResolver._embeddingStage = embeddingStage.asStageFn();
|
|
203
|
+
}
|
|
164
204
|
} catch (_err) {
|
|
165
205
|
// Fall back to rule-only — registry still works
|
|
166
206
|
}
|
|
@@ -210,6 +250,19 @@ async function initHub() {
|
|
|
210
250
|
}
|
|
211
251
|
}
|
|
212
252
|
|
|
253
|
+
// Plan A v0.1 — Android on-device system-data adapter. Stateless: the UI
|
|
254
|
+
// produces a snapshot JSON via ContentResolver/PackageManager and passes
|
|
255
|
+
// its path through opts.inputPath at sync-time, so registration is a
|
|
256
|
+
// one-shot wire here. Safe to register on every host (no-op until a sync
|
|
257
|
+
// call provides inputPath); future hosts may filter by platform if useful.
|
|
258
|
+
try {
|
|
259
|
+
const sda = new SystemDataAndroidAdapter();
|
|
260
|
+
if (!registry.has(sda.name)) registry.register(sda);
|
|
261
|
+
} catch (_err) {
|
|
262
|
+
// Boot must continue even if the adapter fails to register; cc hub will
|
|
263
|
+
// surface the absence via list-adapters.
|
|
264
|
+
}
|
|
265
|
+
|
|
213
266
|
// Phase 6: auto-register persisted Alipay accounts.
|
|
214
267
|
const alipayAccountsPath = join(hubDir, "alipay-accounts.json");
|
|
215
268
|
const alipayAccounts = loadAlipayAccounts(alipayAccountsPath);
|
|
@@ -442,7 +495,11 @@ async function initHub() {
|
|
|
442
495
|
|
|
443
496
|
async registerWechatAdapter(opts = {}) {
|
|
444
497
|
if (!opts || !opts.account || !opts.account.uin) {
|
|
445
|
-
return {
|
|
498
|
+
return {
|
|
499
|
+
ok: false,
|
|
500
|
+
reason: "UIN_REQUIRED",
|
|
501
|
+
message: "opts.account.uin required",
|
|
502
|
+
};
|
|
446
503
|
}
|
|
447
504
|
let r;
|
|
448
505
|
try {
|
|
@@ -476,7 +533,8 @@ async function initHub() {
|
|
|
476
533
|
account: { uin: opts.account.uin },
|
|
477
534
|
dbPath: opts.dbPath || null,
|
|
478
535
|
wechatDataPath: opts.wechatDataPath || null,
|
|
479
|
-
chosenKeyProvider:
|
|
536
|
+
chosenKeyProvider:
|
|
537
|
+
r.keyProvider && r.keyProvider.name ? r.keyProvider.name : null,
|
|
480
538
|
registeredAt: Date.now(),
|
|
481
539
|
lastSyncAt: null,
|
|
482
540
|
});
|
|
@@ -500,9 +558,7 @@ async function initHub() {
|
|
|
500
558
|
}
|
|
501
559
|
const wechatAccountsPath = join(hubDir, "wechat-accounts.json");
|
|
502
560
|
const accounts = loadWechatAccounts(wechatAccountsPath);
|
|
503
|
-
const target = accounts.find(
|
|
504
|
-
(c) => c.account && c.account.uin === uin,
|
|
505
|
-
);
|
|
561
|
+
const target = accounts.find((c) => c.account && c.account.uin === uin);
|
|
506
562
|
const next = accounts.filter(
|
|
507
563
|
(c) => !(c.account && c.account.uin === uin),
|
|
508
564
|
);
|
package/src/lib/web-ui-server.js
CHANGED
|
@@ -1211,7 +1211,8 @@ function findWebPanelDist(staticDir) {
|
|
|
1211
1211
|
return fs.existsSync(path.join(staticDir, "index.html")) ? staticDir : null;
|
|
1212
1212
|
}
|
|
1213
1213
|
// 1. Source tree: packages/web-panel/dist/
|
|
1214
|
-
|
|
1214
|
+
// __dirname = packages/cli/src/lib/ so we need three "../" to reach packages/.
|
|
1215
|
+
const sourceDist = path.resolve(__dirname, "../../../web-panel/dist");
|
|
1215
1216
|
if (fs.existsSync(path.join(sourceDist, "index.html"))) {
|
|
1216
1217
|
return sourceDist;
|
|
1217
1218
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-oGWRbk6g.js";import{S as t}from"./index-BDSZDDb2.js";import"./responsiveObserve-DLLx5VvS.js";import"./vendor-DhFY8mDK.js";import"./useFlexGapSupport-B8gAhiRC.js";import"./styleChecker-CbrNybTt.js";import"./index-BZluCuTH.js";import"./icons-BOPtEWK4.js";const l=t(o);export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-CWhNU6A7.js";import{S as t}from"./index-BDSZDDb2.js";import"./index-BZluCuTH.js";import"./vendor-DhFY8mDK.js";import"./icons-BOPtEWK4.js";const s=t(o);export{s as default};
|