chainlesschain 0.162.178 → 0.162.180
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 -2
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-DRftcSue.js → AIOps-D_TIL54O.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BFvUaMKR.js → ActionButton-eQwy9r-f.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-C0-Rru4P.js → Analytics-D2eNuDgT.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-bx-BCljj.js → AppLayout-CFhwOFsf.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-DAJ8B3Un.js → Artifacts-CJUMw6PB.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-hOk4L1lr.js → Audit-CDB9V58o.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-3pbDpM9z.js → BackgroundAgents-TBppYFjN.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BtziGDn9.js → Backup-CYEOUpzJ.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-kmshphJ3.js → BaseInput-C88fFT2u.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-d7tGSosA.js → Chat-mkr1vC3N.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-p-_PBpX_.js → ChatBubbleRenderer-C7bofJuA.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-C4Eh4Tz5.js → Checkbox-CVU4xqti.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-r7gmhZyA.js → Codegen-rrNcByz3.js} +1 -1
- package/src/assets/web-panel/assets/{Col-U7mDaGlL.js → Col-Cqu-zCvh.js} +1 -1
- package/src/assets/web-panel/assets/{Community-Bpu8aH1T.js → Community-RGRlSgXV.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CHb2XBJe.js → Compact-DBm6epOK.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-Cn_r4dey.js → Compliance-BgKw5iaW.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CdMWfDcz.js → Cowork-BqQcNO3Z.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-BtnREHWy.js → Cron-DO5gTFNb.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BKI9TSzr.js → Crosschain-B8hbJNuN.js} +1 -1
- package/src/assets/web-panel/assets/{DID-pkNubzzJ.js → DID-B08bFJ2C.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-1rrz1snN.js → Dashboard-xNdy_ifo.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DLyFVxDc.js → Dropdown-D-KIZgWL.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CtUWfYVq.js → EmailListRenderer-DKCvsaGo.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-B8eX2Qe4.js → FamilyGuardDashboard-D_cfqama.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-D8lsDGus.js → Federation-B-UqQD68.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CRYt_aIw.js → FormItemContext-BWWvWuJW.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-ClKzY8_N.js → GenericCardRenderer-CPchx6N7.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BXj5Dney.js → Git-Vx4co9Ff.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-Cm-I8RMz.js → Governance-D4x0pp_m.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CPvbhvgt.js → Inference-T3KvwPYR.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-sYNDZaoi.js → KnowledgeGraph-Ddv3KUv3.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BZY_3CRZ.js → Logs-DfH-Dkae.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-up0BW6pv.js → MarkdownRenderer-DHW3PbCq.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-C5MEJ2Qe.js → Marketplace-tjgb0R3D.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-ihdrn43I.js → McpTools-DHAk5nYX.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-Br8bPMlh.js → Memory-A2Yx7thM.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BNntgrYW.js → MobileBridge-BEmTVfN5.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BdV915mw.js → MobileProjects-DuFHUgE4.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-A3wDmlqL.js → Mtc-BDSll0OZ.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-CF-mBLWM.js → MtcAudit-CuBvluaS.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-Iy2k_MSo.js → Multisig-BmXAA-Sb.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-kk0W7HUb.js → NLProgramming-ci2stZAe.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-B5u5t_4S.js → Notes-D-1RpqnS.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-BN0POf6_.js → NotificationSettings-C0GyitIT.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-U2bN-hj5.js +1 -0
- package/src/assets/web-panel/assets/{Organization-DwWQESuN.js → Organization-BNZgpPci.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-DG6klrcC.js → Overflow-CDidKmUN.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BwJcKkgZ.js → P2P-BnreBaXq.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-DwJUxO9j.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-CGMXe4TX.js → Permissions-BQGgJPH0.js} +4 -4
- package/src/assets/web-panel/assets/PersonalDataHub-k_fSkCwL.js +9 -0
- package/src/assets/web-panel/assets/{Pipeline-BzJfeoGt.js → Pipeline-WGqKMqau.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DLh3Bblx.js → Privacy-DtHj9Ymq.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-USVWW36c.js → ProjectInit-B3wH2SFC.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CiiOn62h.js → ProjectSettings-Cd0cgcA1.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BbgmyQnS.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CBPWWzpu.js → Providers-DTpxEXur.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-QVwoRUq3.js → QrScannerModal-B2v6gR-C.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CXnR-2Vn.js → QuickAsk-D3Nr9xXR.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-ClaNzjmF.js → Recommend-C9inoMky.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C3rGw8vJ.js → RemoteSession-Bqk3EYSu.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-Ci-OWAoP.js → Reputation-41KFG646.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DRhAwXOS.js → Row-DqAaqqCv.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BQLJQ2_y.js → RssFeed-CMDpCDKc.js} +3 -3
- package/src/assets/web-panel/assets/{Search-QQUpkfFd.js → Search-B6mtegNL.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DdXKzuKT.js → Security-BaePFVZ8.js} +4 -4
- package/src/assets/web-panel/assets/{Services-x2Zh62Qd.js → Services-DeG3Qscl.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-GdY4KwRz.js → Skeleton-D_QP7F90.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-Bv4tY1Fd.js → Skills-DLGyUgIA.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-C3QnM-11.js → Sla-BN2pxW1Q.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Bl3ytvmI.js → SpeechSettings-BWsZPd8B.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Wp9IwTsP.js → SyncSettings-VOZRPODW.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-3bDAUz8K.js +1 -0
- package/src/assets/web-panel/assets/{Templates-CGfvVVM9.js → Templates-eJSob-q0.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CVXmwQ3U.js → Tenant-Bdwk8Rwy.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-bvwrt03E.js → Terminal-CsMLKIoV.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-D0g74KhH.js → TimelineRenderer-D5qkbPKT.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BH4IwzlT.js → Tokens-DKgwn8hI.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DJOpM533.js → Trigger-HlEHniGM.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-B43EPRLr.js → Trust-CdPcsBpN.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BmBFG-em.js → UkeySign-vAdXd-vG.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-n9oJwB8k.js → VideoEditing-9hHBYFnH.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-D5QeivHp.js → Wallet-Dxh5d1yR.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DcNy7igO.js → WebAuthn-BsFmLHkp.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-BVjc7-5-.js → WorkflowEditor-Cn0OIwLn.js} +1 -1
- package/src/assets/web-panel/assets/{chat-Dy5Tfj3m.js → chat-CJ19O6Dh.js} +1 -1
- package/src/assets/web-panel/assets/{colors-C4c2CNZU.js → colors-Du9jzLN0.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DPa3O5vN.js → compact-item-DhEscfzw.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-TLcfNA6_.js → createContext-CwzEfF3i.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BBMFnsja.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-D41LVFkp.js → hasIn-DT_GSE6J.js} +1 -1
- package/src/assets/web-panel/assets/{index-MKZDje0H.js → index-1LoutPJd.js} +1 -1
- package/src/assets/web-panel/assets/{index-DljFsVGI.js → index-53z1YUxX.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsQ7Ev6i.js → index-B6QDWRLk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQiIxHBy.js → index-B8s5FxJY.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQrEHoOG.js → index-BF-ZCVGE.js} +1 -1
- package/src/assets/web-panel/assets/{index-0oevYjfT.js → index-BFD0cEna.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cip7LWml.js → index-BIYTjbv_.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPTGAjee.js → index-BQWENaZf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CzZ49YZL.js → index-BgSR2WMG.js} +1 -1
- package/src/assets/web-panel/assets/{index-388pLGJ1.js → index-BnHhFnwt.js} +1 -1
- package/src/assets/web-panel/assets/{index-Di4X8cfI.js → index-BrkJ7JPm.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYPr9fkz.js → index-C4SN3by5.js} +1 -1
- package/src/assets/web-panel/assets/{index-BSM1cHVK.js → index-CAVW0cWM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CX0VsoP4.js → index-CGvgnfl9.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBUgRs4D.js → index-CQWxDOvM.js} +1 -1
- package/src/assets/web-panel/assets/{index-OHAfRu_3.js → index-Cc9aPkv-.js} +1 -1
- package/src/assets/web-panel/assets/{index-tQ3igERQ.js → index-Cnok8mhZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVjgm992.js → index-CyEhUJcu.js} +1 -1
- package/src/assets/web-panel/assets/{index-Yjr6cqSK.js → index-D-QkW1fp.js} +1 -1
- package/src/assets/web-panel/assets/{index-iQ6gtFih.js → index-D3llLkYM.js} +1 -1
- package/src/assets/web-panel/assets/{index-DNsBj2Ob.js → index-D4kZoXNr.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPtrOBmW.js → index-D5IytTND.js} +1 -1
- package/src/assets/web-panel/assets/{index-CSxex23J.js → index-D8gt0j7r.js} +1 -1
- package/src/assets/web-panel/assets/{index-WinCp6du.js → index-DN60VBn5.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXl0YPNG.js → index-DWL3SYN3.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7xhTVyP.js → index-DfRDyY1q.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cq_hlWNt.js → index-DhXay17G.js} +1 -1
- package/src/assets/web-panel/assets/{index-B8nLBZbv.js → index-DnVVYKCE.js} +3 -3
- package/src/assets/web-panel/assets/{index-CNk_ZooP.js → index-Dny_ZnAO.js} +1 -1
- package/src/assets/web-panel/assets/index-Do8JMV4N.js +1 -0
- package/src/assets/web-panel/assets/{index-BvmziZSG.js → index-DtRwLhee.js} +1 -1
- package/src/assets/web-panel/assets/{index-BvopLC_T.js → index-DzjzrOli.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWK4zOPe.js → index-Mobw3PHs.js} +1 -1
- package/src/assets/web-panel/assets/{index-Btk9qLL2.js → index-NA2oBLSB.js} +1 -1
- package/src/assets/web-panel/assets/index-UYAJ6iNM.js +1 -0
- package/src/assets/web-panel/assets/{index-WEJr8PL5.js → index-VeHs6qH0.js} +1 -1
- package/src/assets/web-panel/assets/{index-Korc3QIe.js → index-gFjYdstW.js} +1 -1
- package/src/assets/web-panel/assets/{index-D2Nkivlm.js → index-tND8-TDU.js} +1 -1
- package/src/assets/web-panel/assets/{index-pt3s7yvV.js → index-v5HLYCVa.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-BFZu87WZ.js → initDefaultProps-Cvt59c10.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DJIo7qvt.js → motion-D15pPEzl.js} +1 -1
- package/src/assets/web-panel/assets/{move-Cfr5qknL.js → move-N55KeXJ7.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-Bgc-OadH.js → mtc-parser-CyFO1bYP.js} +1 -1
- package/src/assets/web-panel/assets/{omit-X3WI-TNp.js → omit-B5IXfxU2.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-pJhU9IxK.js → pickAttrs-CpVqsulV.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BNg_Vj3T.js → placementArrow-ME36sMF3.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-TeSEGQ5-.js → responsiveObserve-BXAIR1r-.js} +1 -1
- package/src/assets/web-panel/assets/{slide-D_t_P0bv.js → slide-BkOX3-Dp.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DrrIMwAT.js → statusUtils-Cy4Aklpt.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BjZCuFRm.js → styleChecker-gUd2T206.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-rTFdlqdQ.js → useFlexGapSupport-CaVD4o99.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-BidCpfLX.js → useFs--pFGl0KD.js} +1 -1
- package/src/assets/web-panel/assets/usePersonalDataHub-D45iP86i.js +1 -0
- package/src/assets/web-panel/assets/{vnode-BrbcRiHZ.js → vnode-BayoChH_.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-PISX7AkR.js → zoom-CpP38poi.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/hub.js +350 -39
- package/src/data/changelog.json +27 -1
- package/src/gateways/ws/personal-data-hub-protocol.js +86 -23
- package/src/lib/host-adb-bridge.js +92 -14
- package/src/lib/personal-data-hub-wiring.js +173 -13
- package/src/assets/web-panel/assets/OrderTableRenderer-CHkSUrXB.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-BwOHG0in.js +0 -7
- package/src/assets/web-panel/assets/PersonalDataHub-ziYqg7-A.js +0 -8
- package/src/assets/web-panel/assets/Projects-6V-PNmcA.js +0 -1
- package/src/assets/web-panel/assets/Tasks-CF3rIrDe.js +0 -1
- package/src/assets/web-panel/assets/devWarning-BAwdDA_5.js +0 -1
- package/src/assets/web-panel/assets/index-DEjVkdzq.js +0 -1
- package/src/assets/web-panel/assets/index-LMOc5xrS.js +0 -1
- package/src/assets/web-panel/assets/usePersonalDataHub-C5mHttA9.js +0 -1
package/src/commands/hub.js
CHANGED
|
@@ -60,6 +60,8 @@ function parsePositiveInt(raw) {
|
|
|
60
60
|
|
|
61
61
|
const SYNC_ENTITY_KEYS = ["events", "persons", "places", "items", "topics"];
|
|
62
62
|
const MAX_SYNC_COOKIE_BYTES = 64 * 1024;
|
|
63
|
+
const MAX_SYNC_ACCESS_TOKEN_BYTES = 16 * 1024;
|
|
64
|
+
const MAX_SYNC_APP_KEY_BYTES = 16 * 1024;
|
|
63
65
|
|
|
64
66
|
function resolveSyncCookie(options = {}, env = process.env) {
|
|
65
67
|
if (options.cookie && options.cookieFile) {
|
|
@@ -80,6 +82,113 @@ function resolveSyncCookie(options = {}, env = process.env) {
|
|
|
80
82
|
return normalized || null;
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
function resolveSyncAccessToken(options = {}, env = process.env) {
|
|
86
|
+
if (options.accessToken && options.accessTokenFile) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
"Use either --access-token or --access-token-file, not both",
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
let raw = options.accessToken || env.CC_PDH_ACCESS_TOKEN || null;
|
|
92
|
+
if (options.accessTokenFile) {
|
|
93
|
+
raw = readFileSync(String(options.accessTokenFile), "utf8");
|
|
94
|
+
if (Buffer.byteLength(raw, "utf8") > MAX_SYNC_ACCESS_TOKEN_BYTES) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Access token file exceeds ${MAX_SYNC_ACCESS_TOKEN_BYTES} bytes`,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (raw == null) return null;
|
|
101
|
+
const normalized = String(raw).trim();
|
|
102
|
+
if (Buffer.byteLength(normalized, "utf8") > MAX_SYNC_ACCESS_TOKEN_BYTES) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Access token exceeds ${MAX_SYNC_ACCESS_TOKEN_BYTES} bytes`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
return normalized || null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function resolveSyncAppKey(options = {}, env = process.env) {
|
|
111
|
+
if (options.appKey && options.appKeyFile) {
|
|
112
|
+
throw new Error("Use either --app-key or --app-key-file, not both");
|
|
113
|
+
}
|
|
114
|
+
let raw = options.appKey || env.CC_PDH_APP_KEY || null;
|
|
115
|
+
if (options.appKeyFile) {
|
|
116
|
+
raw = readFileSync(String(options.appKeyFile), "utf8");
|
|
117
|
+
if (Buffer.byteLength(raw, "utf8") > MAX_SYNC_APP_KEY_BYTES) {
|
|
118
|
+
throw new Error(`App key file exceeds ${MAX_SYNC_APP_KEY_BYTES} bytes`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (raw == null) return null;
|
|
122
|
+
const normalized = String(raw).trim();
|
|
123
|
+
if (Buffer.byteLength(normalized, "utf8") > MAX_SYNC_APP_KEY_BYTES) {
|
|
124
|
+
throw new Error(`App key exceeds ${MAX_SYNC_APP_KEY_BYTES} bytes`);
|
|
125
|
+
}
|
|
126
|
+
return normalized || null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function collectSyncRoot(value, previous = []) {
|
|
130
|
+
const roots = Array.isArray(previous) ? previous : [];
|
|
131
|
+
return [...roots, String(value)];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Resolve local-files scan roots without interpreting path characters.
|
|
136
|
+
*
|
|
137
|
+
* `--root` is repeatable and preserves each argument byte-for-byte after the
|
|
138
|
+
* shell/Commander handoff. The deprecated `--roots` spelling remains safe for
|
|
139
|
+
* one exact path, but comma-containing values are inherently ambiguous (a
|
|
140
|
+
* legal filename versus the former comma-separated syntax), so they fail
|
|
141
|
+
* closed instead of scanning unintended directories.
|
|
142
|
+
*/
|
|
143
|
+
function resolveSyncRoots(options = {}) {
|
|
144
|
+
const roots = Array.isArray(options.root)
|
|
145
|
+
? options.root.map((value) => String(value))
|
|
146
|
+
: options.root == null
|
|
147
|
+
? []
|
|
148
|
+
: [String(options.root)];
|
|
149
|
+
|
|
150
|
+
if (options.roots != null) {
|
|
151
|
+
const legacyRoot = String(options.roots);
|
|
152
|
+
if (legacyRoot.includes(",")) {
|
|
153
|
+
throw new Error(
|
|
154
|
+
"--roots no longer accepts ambiguous comma-separated values; repeat --root <path> for each exact directory",
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
roots.push(legacyRoot);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (roots.some((root) => root.length === 0)) {
|
|
161
|
+
throw new Error("--root requires a non-empty exact directory path");
|
|
162
|
+
}
|
|
163
|
+
return roots;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function applySyncSinceOverride(registry, name, options = {}) {
|
|
167
|
+
if (!Object.prototype.hasOwnProperty.call(options, "since")) return options;
|
|
168
|
+
const adapter =
|
|
169
|
+
registry && typeof registry.get === "function" ? registry.get(name) : null;
|
|
170
|
+
if (adapter?.watermarkStrategy !== "partitioned") {
|
|
171
|
+
options.sinceWatermark = options.since;
|
|
172
|
+
return options;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const targetKeys =
|
|
176
|
+
typeof adapter.targetWatermarkKeys === "function"
|
|
177
|
+
? adapter.targetWatermarkKeys(options)
|
|
178
|
+
: adapter.watermarkStreams;
|
|
179
|
+
const keys = Array.isArray(targetKeys)
|
|
180
|
+
? targetKeys.filter(
|
|
181
|
+
(key) => typeof key === "string" && key.trim().length > 0,
|
|
182
|
+
)
|
|
183
|
+
: [];
|
|
184
|
+
if (keys.length > 0) {
|
|
185
|
+
options.sinceWatermarks = Object.fromEntries(
|
|
186
|
+
keys.map((key) => [key, options.since]),
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
return options;
|
|
190
|
+
}
|
|
191
|
+
|
|
83
192
|
function syncCount(value) {
|
|
84
193
|
return Number.isFinite(value) && value > 0 ? value : 0;
|
|
85
194
|
}
|
|
@@ -756,7 +865,10 @@ async function cmdSyncAdapter(name, options) {
|
|
|
756
865
|
try {
|
|
757
866
|
const hub = await (options._getHub || getHub)();
|
|
758
867
|
const opts = {};
|
|
759
|
-
if (options.since)
|
|
868
|
+
if (options.since) {
|
|
869
|
+
const sinceWatermark = Number(options.since);
|
|
870
|
+
opts.since = sinceWatermark;
|
|
871
|
+
}
|
|
760
872
|
if (options.until) opts.until = Number(options.until);
|
|
761
873
|
if (options.limit) opts.limit = Number(options.limit);
|
|
762
874
|
// Plan A v0.1 — system-data-android needs a snapshot file path. Generic
|
|
@@ -779,23 +891,77 @@ async function cmdSyncAdapter(name, options) {
|
|
|
779
891
|
// history and process listings. The value remains transient.
|
|
780
892
|
const runtimeCookie = resolveSyncCookie(options);
|
|
781
893
|
if (runtimeCookie) opts.cookie = runtimeCookie;
|
|
782
|
-
//
|
|
783
|
-
//
|
|
894
|
+
// Official OAuth collectors receive their token only for this invocation.
|
|
895
|
+
// File/env input is preferred so the secret stays out of shell history.
|
|
896
|
+
const runtimeAccessToken = resolveSyncAccessToken(options);
|
|
897
|
+
if (runtimeAccessToken) opts.accessToken = runtimeAccessToken;
|
|
898
|
+
const runtimeAppKey = resolveSyncAppKey(options);
|
|
899
|
+
if (runtimeAppKey) opts.appKey = runtimeAppKey;
|
|
900
|
+
const runtimeAppId = options.appId || process.env.CC_PDH_APP_ID;
|
|
901
|
+
if (runtimeAppId) opts.appId = String(runtimeAppId);
|
|
902
|
+
// Constructor-optional credential collectors use a transient account
|
|
903
|
+
// identity to isolate watermarks without persisting credentials or ids.
|
|
784
904
|
const runtimeAccountId = options.accountId || process.env.CC_PDH_ACCOUNT_ID;
|
|
785
905
|
if (runtimeAccountId) opts.accountId = String(runtimeAccountId);
|
|
906
|
+
const runtimeSourceUrl = options.sourceUrl || process.env.CC_PDH_SOURCE_URL;
|
|
907
|
+
if (runtimeSourceUrl) opts.sourceUrl = String(runtimeSourceUrl);
|
|
908
|
+
const runtimeDriveId = options.driveId || process.env.CC_PDH_DRIVE_ID;
|
|
909
|
+
if (runtimeDriveId) opts.driveId = String(runtimeDriveId);
|
|
910
|
+
if (options.parentId) opts.parentId = String(options.parentId);
|
|
911
|
+
if (options.shallow) opts.recursive = false;
|
|
912
|
+
if (options.dir) opts.dir = String(options.dir);
|
|
913
|
+
if (options.exportDir) opts.exportDir = String(options.exportDir);
|
|
914
|
+
if (options.profilePath) opts.profilePath = String(options.profilePath);
|
|
915
|
+
if (options.cursorHome) opts.cursorHome = String(options.cursorHome);
|
|
916
|
+
if (options.claudeHome) opts.claudeHome = String(options.claudeHome);
|
|
917
|
+
if (options.hbuilderxHome) {
|
|
918
|
+
opts.hbuilderxHome = String(options.hbuilderxHome);
|
|
919
|
+
}
|
|
920
|
+
if (options.sourceTimezone) {
|
|
921
|
+
opts.sourceTimezone = String(options.sourceTimezone);
|
|
922
|
+
}
|
|
923
|
+
if (options.sourceTimezoneOffsetMinutes != null) {
|
|
924
|
+
opts.sourceTimezoneOffsetMinutes = Number(
|
|
925
|
+
options.sourceTimezoneOffsetMinutes,
|
|
926
|
+
);
|
|
927
|
+
}
|
|
928
|
+
const include = {};
|
|
929
|
+
if (options.history === false) include.history = false;
|
|
930
|
+
if (options.bookmarks === false) include.bookmarks = false;
|
|
931
|
+
if (options.downloads === false) include.downloads = false;
|
|
932
|
+
if (options.localHistory === false) include.localHistory = false;
|
|
933
|
+
if (options.agentTranscripts === false) include.agentTranscripts = false;
|
|
934
|
+
if (options.aiTracking === false) include.aiTracking = false;
|
|
935
|
+
if (options.claudeSubagents === false) {
|
|
936
|
+
include.subagentTranscripts = false;
|
|
937
|
+
}
|
|
938
|
+
if (options.claudeStats === false) include.stats = false;
|
|
939
|
+
if (options.participants === false) include.participants = false;
|
|
940
|
+
if (options.artifacts === false) include.artifacts = false;
|
|
941
|
+
if (options.contacts === false) include.contacts = false;
|
|
942
|
+
if (options.apps === false) include.apps = false;
|
|
943
|
+
if (options.sms === false) include.sms = false;
|
|
944
|
+
if (options.calls === false) include.calls = false;
|
|
945
|
+
if (options.media === false) include.media = false;
|
|
946
|
+
if (Object.keys(include).length > 0) opts.include = include;
|
|
947
|
+
// Keep the legacy field while every shell converges on dataDisclosure's
|
|
948
|
+
// standard include map.
|
|
949
|
+
if (options.participants === false) opts.includeParticipants = false;
|
|
950
|
+
if (options.maxParticipants) {
|
|
951
|
+
opts.maxParticipants = Number(options.maxParticipants);
|
|
952
|
+
}
|
|
953
|
+
if (options.pageSize) opts.pageSize = Number(options.pageSize);
|
|
954
|
+
if (options.maxPages) opts.maxPages = Number(options.maxPages);
|
|
955
|
+
if (options.maxFiles) opts.maxFiles = Number(options.maxFiles);
|
|
786
956
|
// Alipay bill ZIP exports may be password protected. Environment fallback
|
|
787
957
|
// keeps the password out of shell history for automated collection.
|
|
788
958
|
const zipPassword = options.zipPassword || process.env.CC_PDH_ZIP_PASSWORD;
|
|
789
959
|
if (zipPassword) opts.zipPassword = String(zipPassword);
|
|
790
|
-
// L1 local files (module 101):
|
|
791
|
-
//
|
|
792
|
-
|
|
793
|
-
if (
|
|
794
|
-
|
|
795
|
-
.split(",")
|
|
796
|
-
.map((s) => s.trim())
|
|
797
|
-
.filter(Boolean);
|
|
798
|
-
}
|
|
960
|
+
// L1 local files (module 101): repeated --root values are exact paths.
|
|
961
|
+
// The deprecated --roots alias accepts one unambiguous exact path only.
|
|
962
|
+
const roots = resolveSyncRoots(options);
|
|
963
|
+
if (roots.length > 0) opts.roots = roots;
|
|
964
|
+
applySyncSinceOverride(hub.registry, name, opts);
|
|
799
965
|
const report = await hub.registry.syncAdapter(name, opts);
|
|
800
966
|
const analysis = analyzeSyncReport(report);
|
|
801
967
|
// 2026-05-24 in-APK Android exit + flush-race fix. Real-device repro on
|
|
@@ -1460,6 +1626,25 @@ async function cmdSalvage(dumpfile, options) {
|
|
|
1460
1626
|
// the messages, and ingests them. The Android CollectQqNativeTool su-reads the
|
|
1461
1627
|
// DB + uid candidates, then invokes this. Same logic also runs on PC (USB).
|
|
1462
1628
|
// Plaintext is written to a temp file only for parsing, then deleted.
|
|
1629
|
+
function ingestQqParsedBatch(vault, parsed, conflictResolver) {
|
|
1630
|
+
if (!vault || typeof vault.putBatchResolved !== "function") {
|
|
1631
|
+
throw new Error(
|
|
1632
|
+
"collect-qq requires a vault with transactional putBatchResolved support",
|
|
1633
|
+
);
|
|
1634
|
+
}
|
|
1635
|
+
if (typeof conflictResolver !== "function") {
|
|
1636
|
+
throw new Error("collect-qq requires the QQ quality conflict resolver");
|
|
1637
|
+
}
|
|
1638
|
+
const batch = {
|
|
1639
|
+
events: Array.isArray(parsed) ? parsed : parsed?.events || [],
|
|
1640
|
+
persons: Array.isArray(parsed) ? [] : parsed?.persons || [],
|
|
1641
|
+
places: [],
|
|
1642
|
+
items: [],
|
|
1643
|
+
topics: Array.isArray(parsed) ? [] : parsed?.topics || [],
|
|
1644
|
+
};
|
|
1645
|
+
return vault.putBatchResolved(batch, { conflictResolver });
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1463
1648
|
async function cmdCollectQq(options) {
|
|
1464
1649
|
const spinner = options.json
|
|
1465
1650
|
? null
|
|
@@ -1540,30 +1725,14 @@ async function cmdCollectQq(options) {
|
|
|
1540
1725
|
const events = Array.isArray(parsed) ? parsed : parsed.events || [];
|
|
1541
1726
|
const persons = Array.isArray(parsed) ? [] : parsed.persons || [];
|
|
1542
1727
|
const topics = Array.isArray(parsed) ? [] : parsed.topics || [];
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
for (const t of topics) {
|
|
1552
|
-
try {
|
|
1553
|
-
if (typeof vault.putTopic === "function") vault.putTopic(t);
|
|
1554
|
-
} catch {
|
|
1555
|
-
/* dup / optional */
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
let ingested = 0;
|
|
1559
|
-
for (const ev of events) {
|
|
1560
|
-
try {
|
|
1561
|
-
vault.putEvent(ev);
|
|
1562
|
-
ingested++;
|
|
1563
|
-
} catch {
|
|
1564
|
-
/* skip dup/invalid */
|
|
1565
|
-
}
|
|
1566
|
-
}
|
|
1728
|
+
const qualityModule =
|
|
1729
|
+
options._qqQuality ||
|
|
1730
|
+
(await importPdh("@chainlesschain/personal-data-hub"));
|
|
1731
|
+
const conflictResolver =
|
|
1732
|
+
qualityModule.mergeQqEntityConflict ||
|
|
1733
|
+
qualityModule.default?.mergeQqEntityConflict;
|
|
1734
|
+
const ingestResult = ingestQqParsedBatch(vault, parsed, conflictResolver);
|
|
1735
|
+
const ingested = ingestResult.counts.events;
|
|
1567
1736
|
const report = {
|
|
1568
1737
|
ok: true,
|
|
1569
1738
|
matchedUid: result.uid,
|
|
@@ -1572,6 +1741,8 @@ async function cmdCollectQq(options) {
|
|
|
1572
1741
|
persons: persons.length,
|
|
1573
1742
|
topics: topics.length,
|
|
1574
1743
|
ingested,
|
|
1744
|
+
entityCounts: ingestResult.counts,
|
|
1745
|
+
resolvedConflicts: ingestResult.conflicts.length,
|
|
1575
1746
|
};
|
|
1576
1747
|
if (spinner) spinner.succeed(`collect-qq: ${ingested} QQ messages → vault`);
|
|
1577
1748
|
if (options.json) {
|
|
@@ -3399,8 +3570,13 @@ export function registerHubCommand(program) {
|
|
|
3399
3570
|
"Path to a snapshot file or local DB (system-data-android snapshot, douyin <uid>_im.db, wechat-pc MSG*.db, etc.)",
|
|
3400
3571
|
)
|
|
3401
3572
|
.option(
|
|
3402
|
-
"--
|
|
3403
|
-
"
|
|
3573
|
+
"--root <path>",
|
|
3574
|
+
"Exact directory to scan with local-files; repeat for multiple roots (commas and surrounding spaces are preserved)",
|
|
3575
|
+
collectSyncRoot,
|
|
3576
|
+
)
|
|
3577
|
+
.option(
|
|
3578
|
+
"--roots <path>",
|
|
3579
|
+
"Deprecated single exact directory alias; comma-containing values are rejected (use repeated --root)",
|
|
3404
3580
|
)
|
|
3405
3581
|
.option(
|
|
3406
3582
|
"--db-path <path>",
|
|
@@ -3434,9 +3610,138 @@ export function registerHubCommand(program) {
|
|
|
3434
3610
|
"--cookie-file <path>",
|
|
3435
3611
|
"Read the login cookie from a local file (preferred over putting it in shell history)",
|
|
3436
3612
|
)
|
|
3613
|
+
.option(
|
|
3614
|
+
"--access-token <token>",
|
|
3615
|
+
"OAuth access token for supported official API collectors",
|
|
3616
|
+
)
|
|
3617
|
+
.option(
|
|
3618
|
+
"--access-token-file <path>",
|
|
3619
|
+
"Read an OAuth access token from a local file (preferred; or set CC_PDH_ACCESS_TOKEN)",
|
|
3620
|
+
)
|
|
3621
|
+
.option(
|
|
3622
|
+
"--app-id <id>",
|
|
3623
|
+
"OAuth application ID for collectors that require request signing (or set CC_PDH_APP_ID)",
|
|
3624
|
+
)
|
|
3625
|
+
.option("--app-key <key>", "OAuth application key for request signing")
|
|
3626
|
+
.option(
|
|
3627
|
+
"--app-key-file <path>",
|
|
3628
|
+
"Read an OAuth application key from a local file (preferred; or set CC_PDH_APP_KEY)",
|
|
3629
|
+
)
|
|
3437
3630
|
.option(
|
|
3438
3631
|
"--account-id <id>",
|
|
3439
|
-
"
|
|
3632
|
+
"Stable local platform account identity; stored only as a hashed scope",
|
|
3633
|
+
)
|
|
3634
|
+
.option(
|
|
3635
|
+
"--source-url <https-url>",
|
|
3636
|
+
"One-shot HTTPS source endpoint for collectors that require an explicitly captured API URL (or set CC_PDH_SOURCE_URL)",
|
|
3637
|
+
)
|
|
3638
|
+
.option(
|
|
3639
|
+
"--dir <path>",
|
|
3640
|
+
"Baidu Netdisk application directory (required; /apps/{appname} or a subdirectory)",
|
|
3641
|
+
)
|
|
3642
|
+
.option(
|
|
3643
|
+
"--export-dir <path>",
|
|
3644
|
+
"Local directory containing files exported from Tencent Docs",
|
|
3645
|
+
)
|
|
3646
|
+
.option(
|
|
3647
|
+
"--profile-path <path>",
|
|
3648
|
+
"Local browser/app profile or scan directory (also accepts Tencent Meeting and local-files roots)",
|
|
3649
|
+
)
|
|
3650
|
+
.option(
|
|
3651
|
+
"--cursor-home <path>",
|
|
3652
|
+
"Cursor local data home containing projects/agent-transcripts and ai-tracking",
|
|
3653
|
+
)
|
|
3654
|
+
.option(
|
|
3655
|
+
"--claude-home <path>",
|
|
3656
|
+
"Claude Code local data home containing projects and stats-cache.json",
|
|
3657
|
+
)
|
|
3658
|
+
.option(
|
|
3659
|
+
"--hbuilderx-home <path>",
|
|
3660
|
+
"HBuilderX local data directory containing file-activity INI metadata",
|
|
3661
|
+
)
|
|
3662
|
+
.option(
|
|
3663
|
+
"--source-timezone <iana-or-offset>",
|
|
3664
|
+
"Timezone for local timestamps without an embedded offset (for example Asia/Shanghai or UTC+08:00)",
|
|
3665
|
+
)
|
|
3666
|
+
.option(
|
|
3667
|
+
"--source-timezone-offset-minutes <minutes>",
|
|
3668
|
+
"Fixed source timezone offset in minutes (-840 to 840)",
|
|
3669
|
+
)
|
|
3670
|
+
.option("--no-history", "Exclude browser visit history")
|
|
3671
|
+
.option("--no-bookmarks", "Exclude browser bookmarks")
|
|
3672
|
+
.option("--no-downloads", "Exclude browser download history")
|
|
3673
|
+
.option("--no-local-history", "Exclude VS Code Local History save metadata")
|
|
3674
|
+
.option(
|
|
3675
|
+
"--no-agent-transcripts",
|
|
3676
|
+
"Exclude Cursor local Agent prompt/response transcripts",
|
|
3677
|
+
)
|
|
3678
|
+
.option(
|
|
3679
|
+
"--no-ai-tracking",
|
|
3680
|
+
"Exclude Cursor AI conversation summaries and code-activity metadata",
|
|
3681
|
+
)
|
|
3682
|
+
.option(
|
|
3683
|
+
"--no-claude-subagents",
|
|
3684
|
+
"Exclude Claude Code local subagent transcripts",
|
|
3685
|
+
)
|
|
3686
|
+
.option(
|
|
3687
|
+
"--no-claude-stats",
|
|
3688
|
+
"Exclude Claude Code aggregate activity and model-token statistics",
|
|
3689
|
+
)
|
|
3690
|
+
.option(
|
|
3691
|
+
"--no-participants",
|
|
3692
|
+
"Exclude participant names from Tencent Meeting history collection",
|
|
3693
|
+
)
|
|
3694
|
+
.option(
|
|
3695
|
+
"--no-artifacts",
|
|
3696
|
+
"Exclude document, recording, AI-summary, and chat metadata from Tencent Meeting history collection",
|
|
3697
|
+
)
|
|
3698
|
+
.option(
|
|
3699
|
+
"--no-contacts",
|
|
3700
|
+
"Exclude Android contacts from system-data-android collection",
|
|
3701
|
+
)
|
|
3702
|
+
.option(
|
|
3703
|
+
"--no-apps",
|
|
3704
|
+
"Exclude installed Android apps from system-data-android collection",
|
|
3705
|
+
)
|
|
3706
|
+
.option(
|
|
3707
|
+
"--no-sms",
|
|
3708
|
+
"Exclude Android SMS messages from system-data-android collection",
|
|
3709
|
+
)
|
|
3710
|
+
.option(
|
|
3711
|
+
"--no-calls",
|
|
3712
|
+
"Exclude Android call history from system-data-android collection",
|
|
3713
|
+
)
|
|
3714
|
+
.option(
|
|
3715
|
+
"--no-media",
|
|
3716
|
+
"Exclude Android media file metadata from system-data-android collection",
|
|
3717
|
+
)
|
|
3718
|
+
.option(
|
|
3719
|
+
"--max-participants <n>",
|
|
3720
|
+
"Maximum participant records retained per Tencent Meeting (default 1000, max 10000)",
|
|
3721
|
+
)
|
|
3722
|
+
.option(
|
|
3723
|
+
"--drive-id <id>",
|
|
3724
|
+
"Cloud drive ID for collectors that require it (WPS OpenAPI)",
|
|
3725
|
+
)
|
|
3726
|
+
.option(
|
|
3727
|
+
"--parent-id <id>",
|
|
3728
|
+
"Parent folder ID for collectors that support it (WPS defaults to 0)",
|
|
3729
|
+
)
|
|
3730
|
+
.option(
|
|
3731
|
+
"--shallow",
|
|
3732
|
+
"Collect only direct children instead of recursively traversing folders (WPS, Baidu Netdisk, or Tencent Docs exports)",
|
|
3733
|
+
)
|
|
3734
|
+
.option(
|
|
3735
|
+
"--page-size <n>",
|
|
3736
|
+
"Source page size when supported (Baidu Netdisk: 1-1000; WPS: 1-500)",
|
|
3737
|
+
)
|
|
3738
|
+
.option(
|
|
3739
|
+
"--max-pages <n>",
|
|
3740
|
+
"Maximum source pages for this run; an incomplete scan keeps the old watermark",
|
|
3741
|
+
)
|
|
3742
|
+
.option(
|
|
3743
|
+
"--max-files <n>",
|
|
3744
|
+
"Maximum local export files to inspect; an incomplete scan keeps the old watermark",
|
|
3440
3745
|
)
|
|
3441
3746
|
.option(
|
|
3442
3747
|
"--zip-password <password>",
|
|
@@ -4005,6 +4310,11 @@ export const _internal = {
|
|
|
4005
4310
|
summarizeSyncReports,
|
|
4006
4311
|
formatSyncReportLine,
|
|
4007
4312
|
resolveSyncCookie,
|
|
4313
|
+
resolveSyncAccessToken,
|
|
4314
|
+
resolveSyncAppKey,
|
|
4315
|
+
collectSyncRoot,
|
|
4316
|
+
resolveSyncRoots,
|
|
4317
|
+
applySyncSinceOverride,
|
|
4008
4318
|
cmdSyncAdapter,
|
|
4009
4319
|
cmdSyncAll,
|
|
4010
4320
|
cmdAIChatList,
|
|
@@ -4033,4 +4343,5 @@ export const _internal = {
|
|
|
4033
4343
|
importEventsInto,
|
|
4034
4344
|
cmdExportEvents,
|
|
4035
4345
|
cmdImportEvents,
|
|
4346
|
+
ingestQqParsedBatch,
|
|
4036
4347
|
};
|
package/src/data/changelog.json
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"source": "CHANGELOG.md",
|
|
3
3
|
"releases": [
|
|
4
|
+
{
|
|
5
|
+
"productVersion": null,
|
|
6
|
+
"cliVersion": "0.162.180",
|
|
7
|
+
"cliVersions": ["0.162.180"],
|
|
8
|
+
"date": "2026-07-26",
|
|
9
|
+
"title": "",
|
|
10
|
+
"sections": [
|
|
11
|
+
{
|
|
12
|
+
"heading": "Added — cc CLI 0.162.180 + PDH 0.4.56: transactional multi-source ingest",
|
|
13
|
+
"body": "> `chainlesschain` **0.162.180** bundles\n> `@chainlesschain/personal-data-hub` **0.4.56** (2026-07-26).\n\n- **Transactional identity resolution**: adapters can persist source aliases,\n raw observations, and field-level conflict decisions in one transaction;\n entity resolution, KG, and RAG sinks now consume the exact persisted IDs and\n rewritten references.\n- **QQ NT evidence convergence**: direct database reads and Python sidecar\n decoding share canonical message identities while retaining both raw\n observations. Rich decoded text and mutable read state merge without losing\n older evidence, and pre-upgrade rows are rekeyed instead of duplicated.\n- **Reliable bounded sync**: harden cancellation, checkpoint, lookback, and\n resume boundaries for long-running sidecars plus Android and Windows\n incremental collectors.\n- **Release validation**: 253 PDH test files / 4215 tests, the focused\n multi-source ingest suite, and 110 Python bridge tests passed before release."
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"productVersion": null,
|
|
19
|
+
"cliVersion": "0.162.179",
|
|
20
|
+
"cliVersions": ["0.162.179"],
|
|
21
|
+
"date": "2026-07-25",
|
|
22
|
+
"title": "",
|
|
23
|
+
"sections": [
|
|
24
|
+
{
|
|
25
|
+
"heading": "Added — cc CLI 0.162.179 + PDH 0.4.55:跨端实时采集与输入安全收口",
|
|
26
|
+
"body": "> `chainlesschain` **0.162.179** 搭载\n> `@chainlesschain/personal-data-hub` **0.4.55**(2026-07-25)。\n\n- **跨端实时采集**:CLI、桌面端与 Web Panel 统一暴露实时采集控制和流式结果,\n 支持有界 cookie 运行时采集、临时 OAuth 输入及 Android ADB 数据桥接。\n- **可达性与失败闭合**:readiness 只报告当前可达的输入路径;缺失或无效的\n cookie 来源页、采集输入和 WhatsApp 备份不再被误报为成功。\n- **采集可靠性**:支持带密钥的 WhatsApp ADB 同步,WeRead 源错误时保留游标,\n 并恢复 Bilibili Android 采集客户端。\n- **发布链安全**:npm 发布工作流启用 Trusted Publishing/OIDC 与 provenance,\n 同时保留 `NPM_TOKEN` 作为当前发布的备用通道。"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
},
|
|
4
30
|
{
|
|
5
31
|
"productVersion": null,
|
|
6
32
|
"cliVersion": "0.162.178",
|
|
@@ -10,7 +36,7 @@
|
|
|
10
36
|
"sections": [
|
|
11
37
|
{
|
|
12
38
|
"heading": "Fixed — cc CLI 0.162.178 + IDE provider 403 diagnosis hotfix",
|
|
13
|
-
"body": "- Preserve structured provider error codes/messages for failed LLM requests and\n `cc llm test`, with credential-shaped text redacted before display.\n- Do not classify every HTTP 403 as an invalid API key: overdue accounts,\n billing failures, and model-access denials now retain their real corrective\n action in CLI, VS Code, and JetBrains.\n- Release VS Code 0.37.33 and JetBrains 0.4.
|
|
39
|
+
"body": "- Preserve structured provider error codes/messages for failed LLM requests and\n `cc llm test`, with credential-shaped text redacted before display.\n- Do not classify every HTTP 403 as an invalid API key: overdue accounts,\n billing failures, and model-access denials now retain their real corrective\n action in CLI, VS Code, and JetBrains.\n- Release VS Code 0.37.33 and JetBrains 0.4.71 with corrected setup guidance;\n JetBrains 0.4.70 was deleted during Marketplace review and superseded after\n clearing the IntelliJ 2026.2 internal-API warning.\n- Prepare JetBrains 0.4.72 so `/status` and the other live-session slash\n commands use the same routing, output, aliases, arguments, and help text as\n the VS Code panel, including `/expand` reasoning-block toggling."
|
|
14
40
|
}
|
|
15
41
|
]
|
|
16
42
|
},
|
|
@@ -49,6 +49,55 @@ async function ingestSystemDataAndroidSnapshot(hub, snapshot) {
|
|
|
49
49
|
return _ingestSnapshotFn(hub, snapshot);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Adapters that must never consume an Android staging snapshot implicitly.
|
|
54
|
+
* They either have a richer live bridge or read desktop-local state directly.
|
|
55
|
+
* Exported as an immutable array so the transport contract can be guarded
|
|
56
|
+
* without exercising ADB in unit tests.
|
|
57
|
+
*/
|
|
58
|
+
export const ADB_AUTO_PULL_BYPASS_ADAPTERS = Object.freeze([
|
|
59
|
+
"system-data-android",
|
|
60
|
+
"browser-history-chrome",
|
|
61
|
+
"browser-history-edge",
|
|
62
|
+
"browser-history-brave",
|
|
63
|
+
"browser-history-opera",
|
|
64
|
+
"browser-history-vivaldi",
|
|
65
|
+
"browser-history-safari",
|
|
66
|
+
"browser-history-firefox",
|
|
67
|
+
"vscode",
|
|
68
|
+
"vscodium",
|
|
69
|
+
"cursor",
|
|
70
|
+
"claude-code",
|
|
71
|
+
"jetbrains-ide",
|
|
72
|
+
"hbuilderx",
|
|
73
|
+
"win-recent",
|
|
74
|
+
"git-activity",
|
|
75
|
+
"shell-history",
|
|
76
|
+
"local-files",
|
|
77
|
+
"meeting-tencent",
|
|
78
|
+
]);
|
|
79
|
+
|
|
80
|
+
const ADB_AUTO_PULL_BYPASS_SET = new Set(ADB_AUTO_PULL_BYPASS_ADAPTERS);
|
|
81
|
+
const EXPLICIT_LIVE_SOURCE_OPTION_KEYS = Object.freeze([
|
|
82
|
+
"cookie",
|
|
83
|
+
"cookies",
|
|
84
|
+
"accessToken",
|
|
85
|
+
"appKey",
|
|
86
|
+
"apiKey",
|
|
87
|
+
"token",
|
|
88
|
+
"sourceUrl",
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
export function hasExplicitLiveSourceOptions(options) {
|
|
92
|
+
if (!options || typeof options !== "object") return false;
|
|
93
|
+
return EXPLICIT_LIVE_SOURCE_OPTION_KEYS.some((key) => {
|
|
94
|
+
const value = options[key];
|
|
95
|
+
if (typeof value === "string") return value.trim().length > 0;
|
|
96
|
+
if (Array.isArray(value)) return value.length > 0;
|
|
97
|
+
return value != null && typeof value === "object";
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
52
101
|
/**
|
|
53
102
|
* If the caller didn't pass `inputPath`, try to pull a snapshot for
|
|
54
103
|
* this adapter off the attached Android phone via `adb shell run-as
|
|
@@ -70,7 +119,7 @@ async function ingestSystemDataAndroidSnapshot(hub, snapshot) {
|
|
|
70
119
|
* return the original options unchanged so the adapter's normal error
|
|
71
120
|
* path fires and the UI banner shows a meaningful message.
|
|
72
121
|
*/
|
|
73
|
-
async function _tryAdbAutoPullInputPath(hub, name, options) {
|
|
122
|
+
export async function _tryAdbAutoPullInputPath(hub, name, options) {
|
|
74
123
|
if (
|
|
75
124
|
options &&
|
|
76
125
|
typeof options.inputPath === "string" &&
|
|
@@ -78,6 +127,13 @@ async function _tryAdbAutoPullInputPath(hub, name, options) {
|
|
|
78
127
|
) {
|
|
79
128
|
return options; // caller already supplied a path
|
|
80
129
|
}
|
|
130
|
+
// An explicit live credential or endpoint is a stronger user intent than
|
|
131
|
+
// an implicit, potentially stale Android staging snapshot. Every dual-mode
|
|
132
|
+
// adapter checks inputPath first, so adding an auto-pulled path here would
|
|
133
|
+
// silently turn a requested live sync into a snapshot import.
|
|
134
|
+
if (hasExplicitLiveSourceOptions(options)) {
|
|
135
|
+
return options;
|
|
136
|
+
}
|
|
81
137
|
// Skip auto-pull for adapters that have a live bridge mode — pulling
|
|
82
138
|
// a stale snapshot file would short-circuit the bridge path which
|
|
83
139
|
// yields fresher / richer data (e.g. system-data-android's bridge
|
|
@@ -85,20 +141,11 @@ async function _tryAdbAutoPullInputPath(hub, name, options) {
|
|
|
85
141
|
// an Android-collected snapshot only contains contacts + apps).
|
|
86
142
|
// Keep this list in sync with adapters whose _syncViaBridge is
|
|
87
143
|
// strictly richer than their snapshot output.
|
|
88
|
-
// browser-history
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
"browser-history-chrome",
|
|
94
|
-
"browser-history-edge",
|
|
95
|
-
"vscode",
|
|
96
|
-
"win-recent",
|
|
97
|
-
"git-activity",
|
|
98
|
-
"shell-history",
|
|
99
|
-
"local-files",
|
|
100
|
-
]);
|
|
101
|
-
if (BRIDGE_PREFERRED.has(name)) {
|
|
144
|
+
// browser-history-*, vscode/vscodium/cursor, claude-code, and
|
|
145
|
+
// jetbrains-ide read desktop-local files (browser profiles, editor/Agent
|
|
146
|
+
// state, Claude Code transcripts, or JetBrains recentProjects.xml);
|
|
147
|
+
// an ADB snapshot is meaningless for them.
|
|
148
|
+
if (ADB_AUTO_PULL_BYPASS_SET.has(name)) {
|
|
102
149
|
return options || {};
|
|
103
150
|
}
|
|
104
151
|
try {
|
|
@@ -326,7 +373,9 @@ export const PERSONAL_DATA_HUB_HANDLERS = {
|
|
|
326
373
|
unlinkSync(p);
|
|
327
374
|
removed.push(p);
|
|
328
375
|
}
|
|
329
|
-
} catch
|
|
376
|
+
} catch {
|
|
377
|
+
// Account files are removed on a best-effort basis.
|
|
378
|
+
}
|
|
330
379
|
}
|
|
331
380
|
}
|
|
332
381
|
if (alsoWipeMasterKey) {
|
|
@@ -337,14 +386,20 @@ export const PERSONAL_DATA_HUB_HANDLERS = {
|
|
|
337
386
|
try {
|
|
338
387
|
unlinkSync(join(keyDir, f));
|
|
339
388
|
removed.push(join(keyDir, f));
|
|
340
|
-
} catch
|
|
389
|
+
} catch {
|
|
390
|
+
// Key fragments are removed on a best-effort basis.
|
|
391
|
+
}
|
|
341
392
|
}
|
|
342
393
|
}
|
|
343
|
-
} catch
|
|
394
|
+
} catch {
|
|
395
|
+
// Key-directory cleanup is best-effort.
|
|
396
|
+
}
|
|
344
397
|
}
|
|
345
398
|
try {
|
|
346
399
|
closeHub();
|
|
347
|
-
} catch
|
|
400
|
+
} catch {
|
|
401
|
+
// The hub may already be closed after a partial wipe.
|
|
402
|
+
}
|
|
348
403
|
return { result: { ok: true, removed } };
|
|
349
404
|
} catch (err) {
|
|
350
405
|
return { error: err && err.message ? err.message : String(err) };
|
|
@@ -640,11 +695,15 @@ export const PERSONAL_DATA_HUB_STREAMING_HANDLERS = {
|
|
|
640
695
|
type: "personal-data-hub.sync-adapter-stream.event",
|
|
641
696
|
event: evt,
|
|
642
697
|
});
|
|
643
|
-
} catch
|
|
698
|
+
} catch {
|
|
699
|
+
// Streaming clients may disconnect while collection continues.
|
|
700
|
+
}
|
|
644
701
|
if (typeof original === "function") {
|
|
645
702
|
try {
|
|
646
703
|
original(evt);
|
|
647
|
-
} catch
|
|
704
|
+
} catch {
|
|
705
|
+
// A prior observer must not break collection telemetry.
|
|
706
|
+
}
|
|
648
707
|
}
|
|
649
708
|
};
|
|
650
709
|
const options = await _tryAdbAutoPullInputPath(hub, msg.name, msg.options);
|
|
@@ -669,11 +728,15 @@ export const PERSONAL_DATA_HUB_STREAMING_HANDLERS = {
|
|
|
669
728
|
hub.registry.onSyncEvent = (evt) => {
|
|
670
729
|
try {
|
|
671
730
|
sender({ type: "personal-data-hub.sync-all-stream.event", event: evt });
|
|
672
|
-
} catch
|
|
731
|
+
} catch {
|
|
732
|
+
// Streaming clients may disconnect while collection continues.
|
|
733
|
+
}
|
|
673
734
|
if (typeof original === "function") {
|
|
674
735
|
try {
|
|
675
736
|
original(evt);
|
|
676
|
-
} catch
|
|
737
|
+
} catch {
|
|
738
|
+
// A prior observer must not break collection telemetry.
|
|
739
|
+
}
|
|
677
740
|
}
|
|
678
741
|
};
|
|
679
742
|
try {
|