chainlesschain 0.162.12 → 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 +29 -24
- package/package.json +5 -2
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-C3TDNq29.js → AIOps-D34d_Nh1.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-C9fE18pE.js → ActionButton-Br7HxCnl.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-wnZF602C.js → Analytics-bVKq79Xd.js} +1 -1
- package/src/assets/web-panel/assets/{AppLayout-BjgTMK7O.js → AppLayout-CWSLIbAz.js} +2 -2
- package/src/assets/web-panel/assets/{Audit-BBL0BW5_.js → Audit-Cmnu1qqa.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BKLqYCWU.js → Backup-Rok20-TL.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BGSzMCZs.js → BaseInput-BJzs_ZtT.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CQWzZWEY.js → Chat-CSYapbcq.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-BkTri12Q.js → Checkbox-BEa7Sr7e.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BH1m09EO.js → Codegen-C9M4e7ne.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BXnBuqIa.js → Col-DU9NoUIi.js} +1 -1
- package/src/assets/web-panel/assets/{Community-C_Nr4XCx.js → Community-DA9uz_jP.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-Du6GwLrj.js → Compact-3_bEraVw.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-66M0oi1Q.js → Compliance-BtF8jWUQ.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DQrkZRNd.js → Cowork-BqvA7oaM.js} +1 -1
- package/src/assets/web-panel/assets/{Cron-CwdIFH_v.js → Cron-CxZy7Mzg.js} +1 -1
- package/src/assets/web-panel/assets/{Crosschain-DqlcrQ9L.js → Crosschain-1DB-XRGu.js} +1 -1
- package/src/assets/web-panel/assets/{DID-OmPLKf7L.js → DID-B6Ezp1pt.js} +1 -1
- package/src/assets/web-panel/assets/{Dashboard-D_dampTL.js → Dashboard-QDJ6VVsn.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CA1W7jAn.js → Dropdown-CovsWjxG.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Chlk9a7s.js → Federation-DbRxS4Y4.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-t0UqYFLq.js → FormItemContext-9E9dNGtx.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CEq0raYm.js → Git-CqEpyxRZ.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-C06CX7Ge.js → Governance-On47KtGq.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-6VIFHxIP.js → Inference-RZcjcyaq.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BCJPjMBQ.js → KnowledgeGraph-C-1rRAM9.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BBpOYFct.js → Logs-BuunmG_r.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-BFH6jMWt.js → Marketplace-CromymyA.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-uCFvRqGs.js → McpTools-5XlFExh7.js} +1 -1
- package/src/assets/web-panel/assets/{Memory-B0Kux_KT.js → Memory-DjnUT7YM.js} +1 -1
- package/src/assets/web-panel/assets/{MobileBridge-DHow2jiK.js → MobileBridge-BrYIgLg6.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BFo9YQZp.js → MobileProjects-CL5V3fTm.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-riOh1G_F.js → Mtc-CHYJq6zK.js} +1 -1
- package/src/assets/web-panel/assets/{MtcAudit-Bm-hE2SP.js → MtcAudit-BZxUO0qt.js} +1 -1
- package/src/assets/web-panel/assets/{Multisig-DfUQxh5a.js → Multisig-FZTmJgW1.js} +2 -2
- package/src/assets/web-panel/assets/{NLProgramming-DuNvLBEq.js → NLProgramming-C9Mhefph.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DB20wd3c.js → Notes-W7usj-Ar.js} +1 -1
- package/src/assets/web-panel/assets/{NotificationSettings-CB-GkOWR.js → NotificationSettings-PBuYv_Bh.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-3bU7PZuG.js → Organization-CuYCE-rF.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BGCPP_0Y.js → Overflow-Dojx-kzE.js} +1 -1
- package/src/assets/web-panel/assets/{OverrideContext-x9ZzjLwk.js → OverrideContext-C_4H9tGA.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BHgAe1oC.js → P2P-BgIaSrLX.js} +1 -1
- package/src/assets/web-panel/assets/{Permissions-BuOD4xwc.js → Permissions-Byj2dkF_.js} +1 -1
- package/src/assets/web-panel/assets/PersonalDataHub-CMOOI13-.js +1 -0
- package/src/assets/web-panel/assets/PersonalDataHub-Dvaa8niQ.css +1 -0
- package/src/assets/web-panel/assets/{Pipeline-DBS5U4LB.js → Pipeline-CWwEOF09.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-UNjIc5El.js → Privacy-VT7gldcN.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CicqCJGy.js → ProjectInit-7UH3c3p7.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectSettings-CIxAbt4Y.js → ProjectSettings-DqLp-72a.js} +1 -1
- package/src/assets/web-panel/assets/{Projects-BJycZScO.js → Projects-B_54eDhH.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DxXvprme.js → Providers-BIrNfNpc.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-rrqjU8_Y.js → QuickAsk-BbYPwCso.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BEwHMhI7.js → Recommend-BF4qBssF.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-DoVKCCMn.js → Reputation-DPEzlC2V.js} +1 -1
- package/src/assets/web-panel/assets/{Row-F5XcDhHr.js → Row-DjHxhH1L.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-cZrRG7k8.js → RssFeed-D0_j678P.js} +1 -1
- package/src/assets/web-panel/assets/{Search-B9ctZjqx.js → Search-DctfGehu.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Z62hl1mc.js → Security-BFHggeYM.js} +1 -1
- package/src/assets/web-panel/assets/{Services-CQf5XqgZ.js → Services-CmrFMukV.js} +1 -1
- package/src/assets/web-panel/assets/{Skeleton-DuCKw2Eh.js → Skeleton-DR4vn_nS.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-qVkhva0s.js → Skills-DlXG2yyV.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-BQbatr7s.js → Sla-4PPGL3SE.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DLFBzAgD.js → SpeechSettings-D9EhJOqm.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CrzETZMW.js → SyncSettings-Dasmbi0p.js} +1 -1
- package/src/assets/web-panel/assets/{Tasks-D_EQ1nJ7.js → Tasks-vilEiuPA.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D4y-dGRc.js → Templates-Ca9Rvktn.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-2XI0jkPn.js → Tenant-CEZb9gfK.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-fUi5V2Z9.js → Terminal-DanCBdbD.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BuUNB2mg.js → Tokens-SPkClW2d.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-7DqLLuej.js → Trigger-B645yL7g.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CeACvTYx.js → Trust-D9sM_Ig0.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-mDP9EXHq.js → UkeySign-B_Nr2K-u.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-veWlKclv.js → VideoEditing-U01Lea8j.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Cd2Hheb8.js → Wallet-6xBySVV8.js} +1 -1
- package/src/assets/web-panel/assets/{WebAuthn-DyL7ZiHX.js → WebAuthn-DbgMoBu6.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-C7-7LJH9.js → WorkflowEditor-Bz-Y6IR2.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DXomZMuo.js → chat-BC_O9hag.js} +1 -1
- package/src/assets/web-panel/assets/{collapseMotion-CjFH_Jop.js → collapseMotion-DfnRZex1.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DlU92QNs.js → colors-ChlOGOvr.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-sBiTL8mX.js → compact-item-BSbAYGGF.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DZXEnzum.js → createContext-CFcZly5M.js} +1 -1
- package/src/assets/web-panel/assets/{echarts-Bq-n0MtJ.js → echarts-Dj_pBaVI.js} +1 -1
- package/src/assets/web-panel/assets/{hasIn-CpCHBZ2M.js → hasIn-BomYwwYE.js} +1 -1
- package/src/assets/web-panel/assets/{icons-CLQTHa5-.js → icons-BOPtEWK4.js} +4 -4
- package/src/assets/web-panel/assets/{index-B0Qbxr57.js → index-5Ewm6KZA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CjXSvceY.js → index-B6LJHQoE.js} +1 -1
- package/src/assets/web-panel/assets/{index-CD3iljXs.js → index-BEJ6YiLI.js} +1 -1
- package/src/assets/web-panel/assets/{index-BK2AFy44.js → index-BGUbtM3R.js} +1 -1
- package/src/assets/web-panel/assets/{index-Di1_EQ-X.js → index-BHGsFwYW.js} +1 -1
- package/src/assets/web-panel/assets/{index-B23tuoo9.js → index-BHi69MHF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUlPMzoM.js → index-BI1jAWcc.js} +1 -1
- package/src/assets/web-panel/assets/index-BIRYt1of.js +1 -0
- package/src/assets/web-panel/assets/{index-B3k9UPHc.js → index-BYDvb1pi.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwbWZubA.js → index-BZGdjNLA.js} +1 -1
- package/src/assets/web-panel/assets/{index-ThrAiEF9.js → index-BwFykZ5U.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUe5t5Aa.js → index-ByZQNO0A.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dn8m1d1f.js → index-C0rr1X9W.js} +2 -2
- package/src/assets/web-panel/assets/{index-C6SDf50u.js → index-CBhoZhCO.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClN_JuFa.js → index-CCRSz2cR.js} +1 -1
- package/src/assets/web-panel/assets/index-CZfySmWX.js +1 -0
- package/src/assets/web-panel/assets/{index-Dq5Rn5VS.js → index-Cj47XwJQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-ChahjdYE.js → index-Cmzh8gKL.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dyg6ikIL.js → index-CnxlKTDK.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dj9Nvz6S.js → index-CoF95pYK.js} +1 -1
- package/src/assets/web-panel/assets/{index-TwQZkVGh.js → index-Ctx97mH-.js} +1 -1
- package/src/assets/web-panel/assets/{index-s8tvk-fF.js → index-D0vX9jQA.js} +1 -1
- package/src/assets/web-panel/assets/{index-X48zYgZ6.js → index-DNkth8dM.js} +1 -1
- package/src/assets/web-panel/assets/{index-DygNvCeR.js → index-DRp5_Xns.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_MzScPM.js → index-DW-Ji07y.js} +1 -1
- package/src/assets/web-panel/assets/{index-BqnhEJls.js → index-DXgE2VW6.js} +1 -1
- package/src/assets/web-panel/assets/{index-CDyzZ8_O.js → index-D_0B3CiU.js} +1 -1
- package/src/assets/web-panel/assets/{index-C59FgSkU.js → index-Dbf5YmDX.js} +1 -1
- package/src/assets/web-panel/assets/{index-_zyXBoS7.js → index-DsNQ2hqI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJ7XYa5K.js → index-EY733h9z.js} +1 -1
- package/src/assets/web-panel/assets/{index-ibFHnqHz.js → index-QD_n54XT.js} +1 -1
- package/src/assets/web-panel/assets/{index-CivbS-57.js → index-T5Y_9IPv.js} +1 -1
- package/src/assets/web-panel/assets/{index-C52udT0_.js → index-b8GbH2Yi.js} +4 -4
- package/src/assets/web-panel/assets/{index-XI6772AD.js → index-gUACAWbM.js} +1 -1
- package/src/assets/web-panel/assets/{index-F9cBucYf.js → index-onW325hZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKe9jmKG.js → index-ozVPr1gj.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_IgY63-.js → index-slYX2rCE.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_-RETt0.js → index-t9u2bHpH.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeGnHcp5.js → index-za1GUJBG.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-DEi92ZnZ.js → initDefaultProps-DnadEaxu.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BtYKzpOc.js → motion-CC_Na0Tl.js} +1 -1
- package/src/assets/web-panel/assets/{move-Cb3A1-v-.js → move-C2d9Mkk9.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B6qPDdOf.js → omit-QvpKbF8p.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DDyeQMUc.js → pickAttrs-Dm8r3X1_.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BPV6VO47.js → placementArrow-DaqaVfoX.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DJ1ra4dT.js → responsiveObserve-Iida9fIn.js} +1 -1
- package/src/assets/web-panel/assets/{slide-D6v8tHvB.js → slide-YqHexXQD.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DulKcQLZ.js → statusUtils-BGKLoeEt.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Bne7zwMt.js → styleChecker-aI-gsQO8.js} +1 -1
- package/src/assets/web-panel/assets/useFlexGapSupport-BiOsz4rc.js +1 -0
- package/src/assets/web-panel/assets/{useFs-CR-iLa4Z.js → useFs-CZy7Zo2X.js} +1 -1
- package/src/assets/web-panel/assets/{useMergedState-O7QXt4P5.js → useMergedState-WwedrFR0.js} +1 -1
- package/src/assets/web-panel/assets/{useRefs-0J6m8UWN.js → useRefs-Cdq8EWeF.js} +1 -1
- package/src/assets/web-panel/assets/{useState-CSzR8F8O.js → useState-DGS1NOyn.js} +1 -1
- package/src/assets/web-panel/assets/{vendor-M5lGV-wr.js → vendor-DhFY8mDK.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-yL9axxBy.js → vnode-B6WqjmE4.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-B-VCMXSD.js → zoom-DTeTrJ2z.js} +1 -1
- package/src/assets/web-panel/index.html +3 -3
- package/src/commands/__tests__/android.test.js +260 -0
- package/src/commands/__tests__/hub-aichat.test.js +277 -0
- package/src/commands/__tests__/hub-wechat.test.js +243 -0
- package/src/commands/android.js +284 -0
- package/src/commands/hub.js +457 -0
- package/src/commands/sync-providers.js +436 -0
- package/src/gateways/ws/personal-data-hub-protocol.js +88 -0
- package/src/index.js +6 -0
- package/src/lib/__tests__/personal-data-hub-aichat-wizard.test.js +209 -0
- package/src/lib/__tests__/sync-credentials.test.js +265 -0
- package/src/lib/__tests__/sync-engine-cli.test.js +293 -0
- package/src/lib/cc-android-bridge.js +162 -0
- package/src/lib/personal-data-hub-aichat-wizard.js +242 -0
- package/src/lib/personal-data-hub-wiring.js +258 -13
- package/src/lib/sync-cli-db.js +194 -0
- package/src/lib/sync-credentials.js +225 -0
- package/src/lib/sync-engine-cli.js +406 -0
- package/src/lib/sync-oss-client.js +273 -0
- package/src/lib/sync-webdav-client.js +194 -0
- package/src/lib/web-ui-server.js +2 -1
- package/src/assets/web-panel/assets/PersonalDataHub--WA-aZAJ.js +0 -1
- package/src/assets/web-panel/assets/PersonalDataHub-BK7I0Rsb.css +0 -1
- package/src/assets/web-panel/assets/index-CcRX6BlT.js +0 -1
- package/src/assets/web-panel/assets/index-z6h6tqP3.js +0 -1
- package/src/assets/web-panel/assets/useFlexGapSupport-C1miTomM.js +0 -1
package/src/commands/hub.js
CHANGED
|
@@ -19,6 +19,7 @@ import chalk from "chalk";
|
|
|
19
19
|
import ora from "ora";
|
|
20
20
|
import { logger } from "../lib/logger.js";
|
|
21
21
|
import { getHub } from "../lib/personal-data-hub-wiring.js";
|
|
22
|
+
import { getAIChatWizard } from "../lib/personal-data-hub-aichat-wizard.js";
|
|
22
23
|
|
|
23
24
|
function printJson(obj) {
|
|
24
25
|
console.log(JSON.stringify(obj, null, 2));
|
|
@@ -190,6 +191,9 @@ async function cmdSyncAdapter(name, options) {
|
|
|
190
191
|
if (options.since) opts.since = Number(options.since);
|
|
191
192
|
if (options.until) opts.until = Number(options.until);
|
|
192
193
|
if (options.limit) opts.limit = Number(options.limit);
|
|
194
|
+
// Plan A v0.1 — system-data-android needs a snapshot file path. Generic
|
|
195
|
+
// pass-through so other input-driven adapters reuse the same flag.
|
|
196
|
+
if (options.input) opts.inputPath = String(options.input);
|
|
193
197
|
const report = await hub.registry.syncAdapter(name, opts);
|
|
194
198
|
if (spinner) spinner.succeed(`synced ${name}`);
|
|
195
199
|
if (options.json) {
|
|
@@ -356,6 +360,339 @@ async function cmdRunSkill(name, options) {
|
|
|
356
360
|
}
|
|
357
361
|
}
|
|
358
362
|
|
|
363
|
+
// ─── Phase 10.3 — cc hub aichat <verb> wizard subcommand surface ─────
|
|
364
|
+
//
|
|
365
|
+
// Mirrors the WS topics (personal-data-hub.aichat-*) so scripts and the
|
|
366
|
+
// Android in-app terminal can drive the AIChat WebView wizard without a
|
|
367
|
+
// UI. cc ui defaults to fallbackMode:"paste" — these subcommands inherit
|
|
368
|
+
// that, so the user-facing path is always: login (print loginUrl) →
|
|
369
|
+
// fetch cookies in external browser → register --cookies <string>.
|
|
370
|
+
|
|
371
|
+
async function cmdAIChatList(options) {
|
|
372
|
+
try {
|
|
373
|
+
const wiz =
|
|
374
|
+
options._wizard ||
|
|
375
|
+
getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
|
|
376
|
+
// Probe each known vendor for current health
|
|
377
|
+
const items = [];
|
|
378
|
+
for (const vendor of options._knownVendors || _defaultKnownVendors()) {
|
|
379
|
+
const opened = await wiz.openVendorLogin({ vendor });
|
|
380
|
+
items.push({
|
|
381
|
+
vendor,
|
|
382
|
+
displayName: opened.notes ? opened.notes.split(";")[0] : vendor,
|
|
383
|
+
loginUrl: opened.loginUrl,
|
|
384
|
+
fallbackMode: opened.fallbackMode,
|
|
385
|
+
requiredCookies: opened.requiredCookies || [],
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
if (options.json) {
|
|
389
|
+
printJson({ vendors: items });
|
|
390
|
+
} else {
|
|
391
|
+
logger.log(chalk.bold("可注册 vendor 列表:"));
|
|
392
|
+
for (const v of items) {
|
|
393
|
+
logger.log(` • ${chalk.cyan(v.vendor)} ${chalk.gray(v.loginUrl)}`);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
} catch (err) {
|
|
397
|
+
fail(null, err, options.json);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
async function cmdAIChatLogin(vendor, options) {
|
|
402
|
+
try {
|
|
403
|
+
const wiz =
|
|
404
|
+
options._wizard ||
|
|
405
|
+
getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
|
|
406
|
+
const r = await wiz.openVendorLogin({ vendor });
|
|
407
|
+
if (options.json) {
|
|
408
|
+
printJson(r);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
if (!r.ok) {
|
|
412
|
+
logger.error(chalk.red(`✗ ${r.reason || "open failed"}`));
|
|
413
|
+
process.exit(1);
|
|
414
|
+
}
|
|
415
|
+
logger.log(chalk.bold(`vendor: ${vendor}`));
|
|
416
|
+
logger.log(` loginUrl: ${chalk.cyan(r.loginUrl)}`);
|
|
417
|
+
if (r.helpText) logger.log(` ${chalk.gray(r.helpText)}`);
|
|
418
|
+
if (r.requiredCookies && r.requiredCookies.length) {
|
|
419
|
+
logger.log(
|
|
420
|
+
chalk.gray(
|
|
421
|
+
` required: ${r.requiredCookies.join(", ")} (至少识别 1 个)`,
|
|
422
|
+
),
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
logger.log(
|
|
426
|
+
chalk.gray(
|
|
427
|
+
"\n登录完成后从浏览器 DevTools 复制 cookie,再跑:\n cc hub aichat register " +
|
|
428
|
+
vendor +
|
|
429
|
+
' --cookies "<paste>"',
|
|
430
|
+
),
|
|
431
|
+
);
|
|
432
|
+
} catch (err) {
|
|
433
|
+
fail(null, err, options.json);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async function cmdAIChatProbe(vendor, options) {
|
|
438
|
+
try {
|
|
439
|
+
const wiz =
|
|
440
|
+
options._wizard ||
|
|
441
|
+
getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
|
|
442
|
+
if (!options.cookies) {
|
|
443
|
+
throw new Error('--cookies <string> required (e.g. "a=1; b=2")');
|
|
444
|
+
}
|
|
445
|
+
const r = await wiz.probeCookies({ vendor, cookieHeader: options.cookies });
|
|
446
|
+
if (options.json) {
|
|
447
|
+
printJson(r);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
if (!r.ok) {
|
|
451
|
+
logger.error(
|
|
452
|
+
chalk.red(
|
|
453
|
+
`✗ ${r.reason || "incomplete"} — missing: ${(r.missingRequired || []).join(", ") || "(none)"}`,
|
|
454
|
+
),
|
|
455
|
+
);
|
|
456
|
+
process.exit(1);
|
|
457
|
+
}
|
|
458
|
+
logger.log(chalk.green(`✓ ${vendor} cookies look valid`));
|
|
459
|
+
logger.log(` found: ${(r.foundRequired || []).join(", ")}`);
|
|
460
|
+
if (r.foundOptional && r.foundOptional.length) {
|
|
461
|
+
logger.log(` +opt: ${r.foundOptional.join(", ")}`);
|
|
462
|
+
}
|
|
463
|
+
} catch (err) {
|
|
464
|
+
fail(null, err, options.json);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
async function cmdAIChatRegister(vendor, options) {
|
|
469
|
+
try {
|
|
470
|
+
if (!options.cookies) {
|
|
471
|
+
throw new Error("--cookies <string> required");
|
|
472
|
+
}
|
|
473
|
+
const wiz =
|
|
474
|
+
options._wizard ||
|
|
475
|
+
getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
|
|
476
|
+
const r = await wiz.registerVendor({ vendor, cookies: options.cookies });
|
|
477
|
+
if (options.json) {
|
|
478
|
+
printJson(r);
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
if (!r.ok) {
|
|
482
|
+
logger.error(chalk.red(`✗ ${r.reason || "register failed"}`));
|
|
483
|
+
if (r.missingRequired && r.missingRequired.length) {
|
|
484
|
+
logger.error(chalk.gray(` missing: ${r.missingRequired.join(", ")}`));
|
|
485
|
+
}
|
|
486
|
+
process.exit(1);
|
|
487
|
+
}
|
|
488
|
+
logger.log(chalk.green(`✓ registered ${vendor} (${r.accountId})`));
|
|
489
|
+
} catch (err) {
|
|
490
|
+
fail(null, err, options.json);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
async function cmdAIChatHealth(options) {
|
|
495
|
+
// One-shot health-checker pass (does NOT start the periodic loop —
|
|
496
|
+
// that's owned by long-running processes like the cc ui server). This
|
|
497
|
+
// is the manual/scripted equivalent.
|
|
498
|
+
try {
|
|
499
|
+
const factoryDeps = options._factoryDeps || {};
|
|
500
|
+
const hubDir =
|
|
501
|
+
factoryDeps.hubDir || (await (options._getHub || getHub)()).hubDir;
|
|
502
|
+
const { createAIChatHealthChecker } =
|
|
503
|
+
await import("@chainlesschain/personal-data-hub/adapters/ai-chat-history/health-checker");
|
|
504
|
+
const { createAccountsStore, createVendorAdapterBridge } =
|
|
505
|
+
await import("../lib/personal-data-hub-aichat-wizard.js");
|
|
506
|
+
const accountsStore =
|
|
507
|
+
factoryDeps.accountsStore || createAccountsStore({ hubDir });
|
|
508
|
+
const vendorAdapter =
|
|
509
|
+
factoryDeps.vendorAdapter || createVendorAdapterBridge();
|
|
510
|
+
const hc = createAIChatHealthChecker({
|
|
511
|
+
accountsStore,
|
|
512
|
+
vendorAdapter,
|
|
513
|
+
_deps: factoryDeps.timerDeps,
|
|
514
|
+
});
|
|
515
|
+
const r = await hc.runOnce();
|
|
516
|
+
if (options.json) {
|
|
517
|
+
printJson(r);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
logger.log(
|
|
521
|
+
`checked=${r.checked} ${chalk.green("ok=" + r.ok)} ${chalk.red("failed=" + r.failed)} ${chalk.yellow("mismatch=" + r.mismatch)}`,
|
|
522
|
+
);
|
|
523
|
+
} catch (err) {
|
|
524
|
+
fail(null, err, options.json);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
async function cmdAIChatUnregister(vendor, options) {
|
|
529
|
+
try {
|
|
530
|
+
const factoryDeps = options._factoryDeps || {};
|
|
531
|
+
const hubDir =
|
|
532
|
+
factoryDeps.hubDir || (await (options._getHub || getHub)()).hubDir;
|
|
533
|
+
const { createAccountsStore } =
|
|
534
|
+
await import("../lib/personal-data-hub-aichat-wizard.js");
|
|
535
|
+
const accountsStore =
|
|
536
|
+
factoryDeps.accountsStore || createAccountsStore({ hubDir });
|
|
537
|
+
const existing = await accountsStore.get(vendor);
|
|
538
|
+
if (!existing) {
|
|
539
|
+
const result = { ok: false, reason: "NOT_REGISTERED", vendor };
|
|
540
|
+
if (options.json) printJson(result);
|
|
541
|
+
else logger.error(chalk.red(`✗ ${vendor} is not registered`));
|
|
542
|
+
process.exit(1);
|
|
543
|
+
}
|
|
544
|
+
await accountsStore.delete(vendor);
|
|
545
|
+
if (options.json) {
|
|
546
|
+
printJson({ ok: true, vendor, removed: true });
|
|
547
|
+
} else {
|
|
548
|
+
logger.log(chalk.green(`✓ removed ${vendor} from aichat-accounts.json`));
|
|
549
|
+
}
|
|
550
|
+
} catch (err) {
|
|
551
|
+
fail(null, err, options.json);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// ─── Phase 12.6.9 — cc hub wechat <verb> subcommand surface ─────────
|
|
556
|
+
//
|
|
557
|
+
// Mirrors the WS topics (personal-data-hub.wechat-env-probe /
|
|
558
|
+
// register-wechat / unregister-wechat / list-wechat-accounts). Useful
|
|
559
|
+
// for headless / scripted setup on a rooted Android attached to a Mac
|
|
560
|
+
// where the user doesn't want to bring up the Vue page just to wire
|
|
561
|
+
// the adapter (cf. cc hub aichat).
|
|
562
|
+
|
|
563
|
+
async function cmdWechatEnvProbe(options) {
|
|
564
|
+
try {
|
|
565
|
+
const hub = await (options._getHub || getHub)();
|
|
566
|
+
const probe = await hub.probeWechatEnv();
|
|
567
|
+
if (options.json) {
|
|
568
|
+
printJson(probe);
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
logger.log(chalk.bold("WeChat env-probe:"));
|
|
572
|
+
logger.log(
|
|
573
|
+
` ${probe.ok ? chalk.green("✓") : chalk.red("✗")} suggested: ${chalk.cyan(probe.suggestedKeyProvider)}`,
|
|
574
|
+
);
|
|
575
|
+
logger.log(
|
|
576
|
+
` device: ${probe.device.reachable ? chalk.green("reachable") : chalk.red("unreachable")}${probe.device.serial ? " (" + probe.device.serial + ")" : ""} abi=${probe.device.abi || "?"}`,
|
|
577
|
+
);
|
|
578
|
+
logger.log(
|
|
579
|
+
` root: ${probe.root.detected ? chalk.green("yes") : chalk.gray("no")} magisk=${probe.root.magiskInstalled ? "yes" : "no"}`,
|
|
580
|
+
);
|
|
581
|
+
logger.log(
|
|
582
|
+
` frida-server: ${probe.frida.serverRunning ? chalk.green("running") : chalk.gray("not running")}${probe.frida.port ? " :" + probe.frida.port : ""}`,
|
|
583
|
+
);
|
|
584
|
+
logger.log(
|
|
585
|
+
` wechat: ${probe.wechat.installed ? chalk.green(probe.wechat.versionName) : chalk.gray("not installed")}`,
|
|
586
|
+
);
|
|
587
|
+
for (const reason of probe.reasons || [])
|
|
588
|
+
logger.log(` · ${chalk.gray(reason)}`);
|
|
589
|
+
for (const w of probe.warnings || [])
|
|
590
|
+
logger.log(` ${chalk.yellow("!")} ${chalk.yellow(w)}`);
|
|
591
|
+
} catch (err) {
|
|
592
|
+
fail(null, err, options.json);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
async function cmdWechatRegister(options) {
|
|
597
|
+
try {
|
|
598
|
+
if (!options.uin) {
|
|
599
|
+
throw new Error("--uin <wxid-or-uin> required");
|
|
600
|
+
}
|
|
601
|
+
const hub = await (options._getHub || getHub)();
|
|
602
|
+
const r = await hub.registerWechatAdapter({
|
|
603
|
+
account: { uin: options.uin },
|
|
604
|
+
dbPath: options.db || null,
|
|
605
|
+
wechatDataPath: options.wechatDataPath || null,
|
|
606
|
+
keyProviderOverride: options.forceProvider || null,
|
|
607
|
+
fridaOpts: options.fridaDeviceId
|
|
608
|
+
? { deviceId: options.fridaDeviceId }
|
|
609
|
+
: null,
|
|
610
|
+
});
|
|
611
|
+
if (options.json) {
|
|
612
|
+
printJson(r);
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
if (!r.ok) {
|
|
616
|
+
logger.error(
|
|
617
|
+
chalk.red(`✗ ${r.reason || "register failed"}: ${r.message || ""}`),
|
|
618
|
+
);
|
|
619
|
+
if (r.probe) {
|
|
620
|
+
for (const reason of r.probe.reasons || [])
|
|
621
|
+
logger.error(chalk.gray(" · " + reason));
|
|
622
|
+
}
|
|
623
|
+
process.exit(1);
|
|
624
|
+
}
|
|
625
|
+
logger.log(chalk.green(`✓ wechat registered (uin=${options.uin})`));
|
|
626
|
+
logger.log(` provider: ${chalk.cyan(r.chosenKeyProvider)}`);
|
|
627
|
+
logger.log(` sensitivity: ${r.sensitivity}`);
|
|
628
|
+
} catch (err) {
|
|
629
|
+
fail(null, err, options.json);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
async function cmdWechatList(options) {
|
|
634
|
+
try {
|
|
635
|
+
const hub = await (options._getHub || getHub)();
|
|
636
|
+
const rows = hub.listWechatAccounts();
|
|
637
|
+
if (options.json) {
|
|
638
|
+
printJson({ accounts: rows });
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
if (rows.length === 0) {
|
|
642
|
+
logger.log(chalk.gray("(no registered WeChat accounts)"));
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
logger.log(chalk.bold("Registered WeChat accounts:"));
|
|
646
|
+
for (const row of rows) {
|
|
647
|
+
logger.log(
|
|
648
|
+
` • uin=${chalk.cyan(row.uin)} provider=${row.chosenKeyProvider || "?"} db=${row.dbPath || "(none)"} regAt=${row.registeredAt ? new Date(row.registeredAt).toISOString() : "?"}`,
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
} catch (err) {
|
|
652
|
+
fail(null, err, options.json);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
async function cmdWechatUnregister(uin, options) {
|
|
657
|
+
try {
|
|
658
|
+
if (!uin) throw new Error("uin argument required");
|
|
659
|
+
const hub = await (options._getHub || getHub)();
|
|
660
|
+
const r = await hub.unregisterWechatAdapter(uin);
|
|
661
|
+
if (options.json) {
|
|
662
|
+
printJson(r);
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
if (!r.ok) {
|
|
666
|
+
logger.error(chalk.red(`✗ ${r.reason || "unregister failed"}`));
|
|
667
|
+
process.exit(1);
|
|
668
|
+
}
|
|
669
|
+
if (r.removed)
|
|
670
|
+
logger.log(chalk.green(`✓ removed wechat account (uin=${uin})`));
|
|
671
|
+
else
|
|
672
|
+
logger.log(
|
|
673
|
+
chalk.gray(`(uin=${uin} was not registered — nothing removed)`),
|
|
674
|
+
);
|
|
675
|
+
} catch (err) {
|
|
676
|
+
fail(null, err, options.json);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
function _defaultKnownVendors() {
|
|
681
|
+
// Match KNOWN_VENDORS in the hub package — kept inline so this file
|
|
682
|
+
// doesn't have to dynamic-import that module on the hot path.
|
|
683
|
+
return [
|
|
684
|
+
"deepseek",
|
|
685
|
+
"kimi",
|
|
686
|
+
"tongyi",
|
|
687
|
+
"zhipu",
|
|
688
|
+
"hunyuan",
|
|
689
|
+
"qianfan",
|
|
690
|
+
"coze",
|
|
691
|
+
"dreamina",
|
|
692
|
+
"doubao",
|
|
693
|
+
];
|
|
694
|
+
}
|
|
695
|
+
|
|
359
696
|
// ─── Commander wire-up ───────────────────────────────────────────────
|
|
360
697
|
|
|
361
698
|
export function registerHubCommand(program) {
|
|
@@ -401,6 +738,10 @@ export function registerHubCommand(program) {
|
|
|
401
738
|
.option("--since <ms>", "Override watermark — sync from this unix-ms")
|
|
402
739
|
.option("--until <ms>", "Stop at this unix-ms")
|
|
403
740
|
.option("--limit <n>", "Cap ingested events")
|
|
741
|
+
.option(
|
|
742
|
+
"--input <path>",
|
|
743
|
+
"Path to a snapshot file produced by a UI layer (system-data-android, etc.)",
|
|
744
|
+
)
|
|
404
745
|
.option("--json", "Output JSON")
|
|
405
746
|
.action(cmdSyncAdapter);
|
|
406
747
|
|
|
@@ -461,4 +802,120 @@ export function registerHubCommand(program) {
|
|
|
461
802
|
.option("--confirm", "Required to proceed")
|
|
462
803
|
.option("--json", "Output JSON")
|
|
463
804
|
.action(cmdDestroy);
|
|
805
|
+
|
|
806
|
+
// Phase 10.3 — AIChat WebView wizard CLI surface (paste-mode on cc ui).
|
|
807
|
+
const aichat = hub
|
|
808
|
+
.command("aichat")
|
|
809
|
+
.description(
|
|
810
|
+
"AIChat WebView 鉴权向导 — list / login / probe / register / health / unregister 9 家国产 AI",
|
|
811
|
+
);
|
|
812
|
+
|
|
813
|
+
aichat
|
|
814
|
+
.command("list")
|
|
815
|
+
.description("List the 9 known AIChat vendors with their login URLs")
|
|
816
|
+
.option("--json", "Output JSON")
|
|
817
|
+
.action(cmdAIChatList);
|
|
818
|
+
|
|
819
|
+
aichat
|
|
820
|
+
.command("login <vendor>")
|
|
821
|
+
.description("Print the vendor's login URL + paste-fallback help text")
|
|
822
|
+
.option("--json", "Output JSON")
|
|
823
|
+
.action(cmdAIChatLogin);
|
|
824
|
+
|
|
825
|
+
aichat
|
|
826
|
+
.command("probe <vendor>")
|
|
827
|
+
.description(
|
|
828
|
+
"Classify a pasted cookie string against the vendor spec (dry-run)",
|
|
829
|
+
)
|
|
830
|
+
.option("--cookies <string>", 'Raw cookie header (e.g. "a=1; b=2")')
|
|
831
|
+
.option("--json", "Output JSON")
|
|
832
|
+
.action(cmdAIChatProbe);
|
|
833
|
+
|
|
834
|
+
aichat
|
|
835
|
+
.command("register <vendor>")
|
|
836
|
+
.description(
|
|
837
|
+
"Register the vendor — runs validateCookie + persists aichat-accounts.json",
|
|
838
|
+
)
|
|
839
|
+
.option("--cookies <string>", "Raw cookie header from the browser")
|
|
840
|
+
.option("--json", "Output JSON")
|
|
841
|
+
.action(cmdAIChatRegister);
|
|
842
|
+
|
|
843
|
+
aichat
|
|
844
|
+
.command("health")
|
|
845
|
+
.description("Run one HealthChecker pass over registered AIChat vendors")
|
|
846
|
+
.option("--json", "Output JSON")
|
|
847
|
+
.action(cmdAIChatHealth);
|
|
848
|
+
|
|
849
|
+
aichat
|
|
850
|
+
.command("unregister <vendor>")
|
|
851
|
+
.description(
|
|
852
|
+
"Remove a registered AIChat vendor entry (does not touch vault data)",
|
|
853
|
+
)
|
|
854
|
+
.option("--json", "Output JSON")
|
|
855
|
+
.action(cmdAIChatUnregister);
|
|
856
|
+
|
|
857
|
+
// Phase 12.6.9 — cc hub wechat <verb> mirror of WS topics.
|
|
858
|
+
const wechat = hub
|
|
859
|
+
.command("wechat")
|
|
860
|
+
.description(
|
|
861
|
+
"WeChat adapter — env-probe / register / list / unregister (rooted Android required for 8.0+)",
|
|
862
|
+
);
|
|
863
|
+
|
|
864
|
+
wechat
|
|
865
|
+
.command("env-probe")
|
|
866
|
+
.description(
|
|
867
|
+
"Probe attached Android device for adb / root / frida-server / WeChat version",
|
|
868
|
+
)
|
|
869
|
+
.option("--json", "Output JSON")
|
|
870
|
+
.action(cmdWechatEnvProbe);
|
|
871
|
+
|
|
872
|
+
wechat
|
|
873
|
+
.command("register")
|
|
874
|
+
.description(
|
|
875
|
+
"Bootstrap a WeChat adapter (chooses md5 or frida path per env-probe) and persist wechat-accounts.json",
|
|
876
|
+
)
|
|
877
|
+
.requiredOption("--uin <id>", "WeChat numeric UIN (≤ 8.0) or wxid (8.0+)")
|
|
878
|
+
.option("--db <path>", "Local path to the already-pulled EnMicroMsg.db")
|
|
879
|
+
.option(
|
|
880
|
+
"--wechat-data-path <dir>",
|
|
881
|
+
"Local pulled /data/data/com.tencent.mm/ tree (required for md5 path)",
|
|
882
|
+
)
|
|
883
|
+
.option("--force-provider <md5|frida>", "Override env-probe suggestion")
|
|
884
|
+
.option(
|
|
885
|
+
"--frida-device-id <id>",
|
|
886
|
+
"Frida device id (defaults to first USB device)",
|
|
887
|
+
)
|
|
888
|
+
.option("--json", "Output JSON")
|
|
889
|
+
.action(cmdWechatRegister);
|
|
890
|
+
|
|
891
|
+
wechat
|
|
892
|
+
.command("list")
|
|
893
|
+
.description("List registered WeChat accounts (scrubbed)")
|
|
894
|
+
.option("--json", "Output JSON")
|
|
895
|
+
.action(cmdWechatList);
|
|
896
|
+
|
|
897
|
+
wechat
|
|
898
|
+
.command("unregister <uin>")
|
|
899
|
+
.description(
|
|
900
|
+
"Remove a registered WeChat account (does not touch vault data)",
|
|
901
|
+
)
|
|
902
|
+
.option("--json", "Output JSON")
|
|
903
|
+
.action(cmdWechatUnregister);
|
|
464
904
|
}
|
|
905
|
+
|
|
906
|
+
// exported for tests — handler functions can be invoked directly with
|
|
907
|
+
// `_wizard` / `_factoryDeps` / `_knownVendors` injected, bypassing the
|
|
908
|
+
// real `getHub()` call. The commander wiring above is the runtime path.
|
|
909
|
+
export const _internal = {
|
|
910
|
+
cmdAIChatList,
|
|
911
|
+
cmdAIChatLogin,
|
|
912
|
+
cmdAIChatProbe,
|
|
913
|
+
cmdAIChatRegister,
|
|
914
|
+
cmdAIChatHealth,
|
|
915
|
+
cmdAIChatUnregister,
|
|
916
|
+
cmdWechatEnvProbe,
|
|
917
|
+
cmdWechatRegister,
|
|
918
|
+
cmdWechatList,
|
|
919
|
+
cmdWechatUnregister,
|
|
920
|
+
_defaultKnownVendors,
|
|
921
|
+
};
|