chainlesschain 0.162.12 → 0.162.13
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 +30 -25
- package/package.json +4 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-C3TDNq29.js → AIOps-Bq_zxhCr.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-C9fE18pE.js → ActionButton-CaevDm9t.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-wnZF602C.js → Analytics-B0gOmwPw.js} +1 -1
- package/src/assets/web-panel/assets/{AppLayout-BjgTMK7O.js → AppLayout-DWhZiV0Q.js} +2 -2
- package/src/assets/web-panel/assets/{Audit-BBL0BW5_.js → Audit-ZuZJBCxo.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BKLqYCWU.js → Backup-CX7jhH5l.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BGSzMCZs.js → BaseInput-CVLx7HVq.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CQWzZWEY.js → Chat-C6yL5tRD.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-BkTri12Q.js → Checkbox-BePhbqVq.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BH1m09EO.js → Codegen-B5E4x1Lm.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BXnBuqIa.js → Col-CWhNU6A7.js} +1 -1
- package/src/assets/web-panel/assets/{Community-C_Nr4XCx.js → Community-mSEAuJhp.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-Du6GwLrj.js → Compact-DSudHzX3.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-66M0oi1Q.js → Compliance-CxJLYjyn.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DQrkZRNd.js → Cowork-C-trppQj.js} +1 -1
- package/src/assets/web-panel/assets/{Cron-CwdIFH_v.js → Cron-_Ij4v5fY.js} +1 -1
- package/src/assets/web-panel/assets/{Crosschain-DqlcrQ9L.js → Crosschain-eLHXzp5T.js} +1 -1
- package/src/assets/web-panel/assets/{DID-OmPLKf7L.js → DID-BP04AUUB.js} +1 -1
- package/src/assets/web-panel/assets/{Dashboard-D_dampTL.js → Dashboard-CzEeQv62.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CA1W7jAn.js → Dropdown-C_SGOB22.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Chlk9a7s.js → Federation-BgaP4BOv.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-t0UqYFLq.js → FormItemContext-BxGLLt9r.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CEq0raYm.js → Git-Bt_uM_Gw.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-C06CX7Ge.js → Governance-N2-0RG_o.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-6VIFHxIP.js → Inference-eS3g-CzP.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-BCJPjMBQ.js → KnowledgeGraph-CUuvNVah.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BBpOYFct.js → Logs-wPbwEt2r.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-BFH6jMWt.js → Marketplace-DH91kTwo.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-uCFvRqGs.js → McpTools-D-GyyBrI.js} +1 -1
- package/src/assets/web-panel/assets/{Memory-B0Kux_KT.js → Memory-BOtUy-tw.js} +1 -1
- package/src/assets/web-panel/assets/{MobileBridge-DHow2jiK.js → MobileBridge-DIP__XQd.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BFo9YQZp.js → MobileProjects-1nqr1UsU.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-riOh1G_F.js → Mtc-CCE0x7h2.js} +1 -1
- package/src/assets/web-panel/assets/{MtcAudit-Bm-hE2SP.js → MtcAudit-BBkz0XUO.js} +1 -1
- package/src/assets/web-panel/assets/{Multisig-DfUQxh5a.js → Multisig-CIKSJvTY.js} +2 -2
- package/src/assets/web-panel/assets/{NLProgramming-DuNvLBEq.js → NLProgramming-BDkgeFcq.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DB20wd3c.js → Notes-ONiUxfN1.js} +1 -1
- package/src/assets/web-panel/assets/{NotificationSettings-CB-GkOWR.js → NotificationSettings-CGcyKEIe.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-3bU7PZuG.js → Organization-BZtMYBJt.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BGCPP_0Y.js → Overflow-C4LfFZAI.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-D71Cpk-m.js} +1 -1
- package/src/assets/web-panel/assets/{Permissions-BuOD4xwc.js → Permissions-DRGYF29v.js} +1 -1
- package/src/assets/web-panel/assets/PersonalDataHub-CfRYoIua.js +1 -0
- package/src/assets/web-panel/assets/PersonalDataHub-Dvaa8niQ.css +1 -0
- package/src/assets/web-panel/assets/{Pipeline-DBS5U4LB.js → Pipeline-BOyp0_Qo.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-UNjIc5El.js → Privacy-a_AcphvF.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CicqCJGy.js → ProjectInit-CFu1grYt.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectSettings-CIxAbt4Y.js → ProjectSettings-p54Eivhh.js} +1 -1
- package/src/assets/web-panel/assets/{Projects-BJycZScO.js → Projects-DkB88XAu.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DxXvprme.js → Providers-EK7f8DEd.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-rrqjU8_Y.js → QuickAsk-CpO0w3iP.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BEwHMhI7.js → Recommend-BUJVQdv9.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-DoVKCCMn.js → Reputation-kU2fOuZt.js} +1 -1
- package/src/assets/web-panel/assets/{Row-F5XcDhHr.js → Row-oGWRbk6g.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-cZrRG7k8.js → RssFeed-saC_46Yo.js} +1 -1
- package/src/assets/web-panel/assets/{Search-B9ctZjqx.js → Search-CjtRqFUu.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Z62hl1mc.js → Security-BX0NBVfQ.js} +1 -1
- package/src/assets/web-panel/assets/{Services-CQf5XqgZ.js → Services-Bgxsnei_.js} +1 -1
- package/src/assets/web-panel/assets/{Skeleton-DuCKw2Eh.js → Skeleton-CwBb3k2a.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-qVkhva0s.js → Skills-CZCMYH6Z.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-BQbatr7s.js → Sla-Djy1uHnZ.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DLFBzAgD.js → SpeechSettings-CGUI_Uyh.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CrzETZMW.js → SyncSettings-DK2CKHRD.js} +1 -1
- package/src/assets/web-panel/assets/{Tasks-D_EQ1nJ7.js → Tasks-BKiOzeIO.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D4y-dGRc.js → Templates-CnQpleXj.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-2XI0jkPn.js → Tenant-DwKz0cjm.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-fUi5V2Z9.js → Terminal-A7t_wsR8.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BuUNB2mg.js → Tokens-BqYY9l44.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-7DqLLuej.js → Trigger-BI4bXFmi.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CeACvTYx.js → Trust-yMynKTRG.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-mDP9EXHq.js → UkeySign-Br4IScM6.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-veWlKclv.js → VideoEditing-CWcThGsP.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Cd2Hheb8.js → Wallet-CZcAtjxj.js} +1 -1
- package/src/assets/web-panel/assets/{WebAuthn-DyL7ZiHX.js → WebAuthn-BnTZFMA0.js} +3 -3
- package/src/assets/web-panel/assets/{WorkflowEditor-C7-7LJH9.js → WorkflowEditor-N7gGz3_n.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DXomZMuo.js → chat-D175ZIO0.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-LKhZyttv.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-sBiTL8mX.js → compact-item-CsJSebxT.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DZXEnzum.js → createContext-BJ_CPYFC.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-CzD3IqH8.js} +1 -1
- package/src/assets/web-panel/assets/{icons-CLQTHa5-.js → icons-BOPtEWK4.js} +4 -4
- package/src/assets/web-panel/assets/{index-ClN_JuFa.js → index-6qPbrYF7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CDyzZ8_O.js → index-B7UYymse.js} +1 -1
- package/src/assets/web-panel/assets/{index-C52udT0_.js → index-BDSZDDb2.js} +4 -4
- package/src/assets/web-panel/assets/{index-s8tvk-fF.js → index-BEDFHKO3.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_IgY63-.js → index-BMvdoiFr.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dyg6ikIL.js → index-BNVLVzN5.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0Qbxr57.js → index-BSNibAqz.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeGnHcp5.js → index-BV-__mlC.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_-RETt0.js → index-BXH9ujMW.js} +1 -1
- package/src/assets/web-panel/assets/{index-XI6772AD.js → index-BZluCuTH.js} +1 -1
- package/src/assets/web-panel/assets/{index-BqnhEJls.js → index-BhiZDGg7.js} +1 -1
- package/src/assets/web-panel/assets/{index-BK2AFy44.js → index-BjOrt4vw.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dn8m1d1f.js → index-BmJdof_c.js} +2 -2
- package/src/assets/web-panel/assets/{index-C6SDf50u.js → index-BsirlkJ0.js} +1 -1
- package/src/assets/web-panel/assets/{index-CD3iljXs.js → index-BvF2tC6C.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJ7XYa5K.js → index-C2HBKw07.js} +1 -1
- package/src/assets/web-panel/assets/{index-_zyXBoS7.js → index-CKjBAdm0.js} +1 -1
- package/src/assets/web-panel/assets/{index-X48zYgZ6.js → index-CRGNuUIM.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dj9Nvz6S.js → index-CTIkCKav.js} +1 -1
- package/src/assets/web-panel/assets/index-CY1mQA2I.js +1 -0
- package/src/assets/web-panel/assets/{index-C59FgSkU.js → index-CyHdYUeZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B23tuoo9.js → index-D401L3yx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKe9jmKG.js → index-D5IZCkZG.js} +1 -1
- package/src/assets/web-panel/assets/{index-F9cBucYf.js → index-D7ZcBI5s.js} +1 -1
- package/src/assets/web-panel/assets/{index-CjXSvceY.js → index-D8kltMTW.js} +1 -1
- package/src/assets/web-panel/assets/index-D9nXHfUB.js +1 -0
- package/src/assets/web-panel/assets/{index-Dq5Rn5VS.js → index-DJVkBmSc.js} +1 -1
- package/src/assets/web-panel/assets/{index-ibFHnqHz.js → index-DM3uBEWD.js} +1 -1
- package/src/assets/web-panel/assets/{index-ChahjdYE.js → index-DOO73rHE.js} +1 -1
- package/src/assets/web-panel/assets/{index-CivbS-57.js → index-DXp1jVsK.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3k9UPHc.js → index-Dd7dICwB.js} +1 -1
- package/src/assets/web-panel/assets/{index-Di1_EQ-X.js → index-Dm-3kvtD.js} +1 -1
- package/src/assets/web-panel/assets/{index-DygNvCeR.js → index-DnPt5OdD.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_MzScPM.js → index-E7t1hAnk.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUe5t5Aa.js → index-JTX9A7w0.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwbWZubA.js → index-Kn-Of5ew.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUlPMzoM.js → index-R1cFADfk.js} +1 -1
- package/src/assets/web-panel/assets/{index-TwQZkVGh.js → index-RIO4JKMP.js} +1 -1
- package/src/assets/web-panel/assets/{index-ThrAiEF9.js → index-uTEVWPYA.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-DEi92ZnZ.js → initDefaultProps-CBW0okek.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BtYKzpOc.js → motion-DGAffQ0Z.js} +1 -1
- package/src/assets/web-panel/assets/{move-Cb3A1-v-.js → move-DFJ0-5IW.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B6qPDdOf.js → omit-AvrDghg1.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DDyeQMUc.js → pickAttrs-D7csw9i1.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BPV6VO47.js → placementArrow-hZ6Lg6kG.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DJ1ra4dT.js → responsiveObserve-DLLx5VvS.js} +1 -1
- package/src/assets/web-panel/assets/{slide-D6v8tHvB.js → slide-BaRIT3ev.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DulKcQLZ.js → statusUtils-Cdjyuhrz.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Bne7zwMt.js → styleChecker-CbrNybTt.js} +1 -1
- package/src/assets/web-panel/assets/useFlexGapSupport-B8gAhiRC.js +1 -0
- package/src/assets/web-panel/assets/{useFs-CR-iLa4Z.js → useFs-BZPy4ICP.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-6Y0NDMVv.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-B-VCMXSD.js → zoom-DTbMGsSH.js} +1 -1
- package/src/assets/web-panel/index.html +3 -3
- package/src/commands/__tests__/hub-aichat.test.js +277 -0
- package/src/commands/__tests__/hub-wechat.test.js +243 -0
- package/src/commands/hub.js +417 -0
- package/src/commands/sync-providers.js +436 -0
- package/src/gateways/ws/personal-data-hub-protocol.js +68 -0
- package/src/index.js +4 -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/personal-data-hub-aichat-wizard.js +242 -0
- package/src/lib/personal-data-hub-wiring.js +189 -0
- 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/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));
|
|
@@ -356,6 +357,316 @@ async function cmdRunSkill(name, options) {
|
|
|
356
357
|
}
|
|
357
358
|
}
|
|
358
359
|
|
|
360
|
+
// ─── Phase 10.3 — cc hub aichat <verb> wizard subcommand surface ─────
|
|
361
|
+
//
|
|
362
|
+
// Mirrors the WS topics (personal-data-hub.aichat-*) so scripts and the
|
|
363
|
+
// Android in-app terminal can drive the AIChat WebView wizard without a
|
|
364
|
+
// UI. cc ui defaults to fallbackMode:"paste" — these subcommands inherit
|
|
365
|
+
// that, so the user-facing path is always: login (print loginUrl) →
|
|
366
|
+
// fetch cookies in external browser → register --cookies <string>.
|
|
367
|
+
|
|
368
|
+
async function cmdAIChatList(options) {
|
|
369
|
+
try {
|
|
370
|
+
const wiz =
|
|
371
|
+
options._wizard ||
|
|
372
|
+
getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
|
|
373
|
+
// Probe each known vendor for current health
|
|
374
|
+
const items = [];
|
|
375
|
+
for (const vendor of options._knownVendors || _defaultKnownVendors()) {
|
|
376
|
+
const opened = await wiz.openVendorLogin({ vendor });
|
|
377
|
+
items.push({
|
|
378
|
+
vendor,
|
|
379
|
+
displayName: opened.notes ? opened.notes.split(";")[0] : vendor,
|
|
380
|
+
loginUrl: opened.loginUrl,
|
|
381
|
+
fallbackMode: opened.fallbackMode,
|
|
382
|
+
requiredCookies: opened.requiredCookies || [],
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
if (options.json) {
|
|
386
|
+
printJson({ vendors: items });
|
|
387
|
+
} else {
|
|
388
|
+
logger.log(chalk.bold("可注册 vendor 列表:"));
|
|
389
|
+
for (const v of items) {
|
|
390
|
+
logger.log(` • ${chalk.cyan(v.vendor)} ${chalk.gray(v.loginUrl)}`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
} catch (err) {
|
|
394
|
+
fail(null, err, options.json);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
async function cmdAIChatLogin(vendor, options) {
|
|
399
|
+
try {
|
|
400
|
+
const wiz =
|
|
401
|
+
options._wizard ||
|
|
402
|
+
getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
|
|
403
|
+
const r = await wiz.openVendorLogin({ vendor });
|
|
404
|
+
if (options.json) {
|
|
405
|
+
printJson(r);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
if (!r.ok) {
|
|
409
|
+
logger.error(chalk.red(`✗ ${r.reason || "open failed"}`));
|
|
410
|
+
process.exit(1);
|
|
411
|
+
}
|
|
412
|
+
logger.log(chalk.bold(`vendor: ${vendor}`));
|
|
413
|
+
logger.log(` loginUrl: ${chalk.cyan(r.loginUrl)}`);
|
|
414
|
+
if (r.helpText) logger.log(` ${chalk.gray(r.helpText)}`);
|
|
415
|
+
if (r.requiredCookies && r.requiredCookies.length) {
|
|
416
|
+
logger.log(
|
|
417
|
+
chalk.gray(
|
|
418
|
+
` required: ${r.requiredCookies.join(", ")} (至少识别 1 个)`,
|
|
419
|
+
),
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
logger.log(
|
|
423
|
+
chalk.gray(
|
|
424
|
+
"\n登录完成后从浏览器 DevTools 复制 cookie,再跑:\n cc hub aichat register " +
|
|
425
|
+
vendor +
|
|
426
|
+
' --cookies "<paste>"',
|
|
427
|
+
),
|
|
428
|
+
);
|
|
429
|
+
} catch (err) {
|
|
430
|
+
fail(null, err, options.json);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
async function cmdAIChatProbe(vendor, options) {
|
|
435
|
+
try {
|
|
436
|
+
const wiz =
|
|
437
|
+
options._wizard ||
|
|
438
|
+
getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
|
|
439
|
+
if (!options.cookies) {
|
|
440
|
+
throw new Error('--cookies <string> required (e.g. "a=1; b=2")');
|
|
441
|
+
}
|
|
442
|
+
const r = await wiz.probeCookies({ vendor, cookieHeader: options.cookies });
|
|
443
|
+
if (options.json) {
|
|
444
|
+
printJson(r);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
if (!r.ok) {
|
|
448
|
+
logger.error(
|
|
449
|
+
chalk.red(
|
|
450
|
+
`✗ ${r.reason || "incomplete"} — missing: ${(r.missingRequired || []).join(", ") || "(none)"}`,
|
|
451
|
+
),
|
|
452
|
+
);
|
|
453
|
+
process.exit(1);
|
|
454
|
+
}
|
|
455
|
+
logger.log(chalk.green(`✓ ${vendor} cookies look valid`));
|
|
456
|
+
logger.log(` found: ${(r.foundRequired || []).join(", ")}`);
|
|
457
|
+
if (r.foundOptional && r.foundOptional.length) {
|
|
458
|
+
logger.log(` +opt: ${r.foundOptional.join(", ")}`);
|
|
459
|
+
}
|
|
460
|
+
} catch (err) {
|
|
461
|
+
fail(null, err, options.json);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
async function cmdAIChatRegister(vendor, options) {
|
|
466
|
+
try {
|
|
467
|
+
if (!options.cookies) {
|
|
468
|
+
throw new Error("--cookies <string> required");
|
|
469
|
+
}
|
|
470
|
+
const wiz =
|
|
471
|
+
options._wizard ||
|
|
472
|
+
getAIChatWizard({ hubDir: (await (options._getHub || getHub)()).hubDir });
|
|
473
|
+
const r = await wiz.registerVendor({ vendor, cookies: options.cookies });
|
|
474
|
+
if (options.json) {
|
|
475
|
+
printJson(r);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
if (!r.ok) {
|
|
479
|
+
logger.error(chalk.red(`✗ ${r.reason || "register failed"}`));
|
|
480
|
+
if (r.missingRequired && r.missingRequired.length) {
|
|
481
|
+
logger.error(chalk.gray(` missing: ${r.missingRequired.join(", ")}`));
|
|
482
|
+
}
|
|
483
|
+
process.exit(1);
|
|
484
|
+
}
|
|
485
|
+
logger.log(chalk.green(`✓ registered ${vendor} (${r.accountId})`));
|
|
486
|
+
} catch (err) {
|
|
487
|
+
fail(null, err, options.json);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
async function cmdAIChatHealth(options) {
|
|
492
|
+
// One-shot health-checker pass (does NOT start the periodic loop —
|
|
493
|
+
// that's owned by long-running processes like the cc ui server). This
|
|
494
|
+
// is the manual/scripted equivalent.
|
|
495
|
+
try {
|
|
496
|
+
const factoryDeps = options._factoryDeps || {};
|
|
497
|
+
const hubDir =
|
|
498
|
+
factoryDeps.hubDir || (await (options._getHub || getHub)()).hubDir;
|
|
499
|
+
const { createAIChatHealthChecker } =
|
|
500
|
+
await import("@chainlesschain/personal-data-hub/adapters/ai-chat-history/health-checker");
|
|
501
|
+
const { createAccountsStore, createVendorAdapterBridge } =
|
|
502
|
+
await import("../lib/personal-data-hub-aichat-wizard.js");
|
|
503
|
+
const accountsStore =
|
|
504
|
+
factoryDeps.accountsStore || createAccountsStore({ hubDir });
|
|
505
|
+
const vendorAdapter =
|
|
506
|
+
factoryDeps.vendorAdapter || createVendorAdapterBridge();
|
|
507
|
+
const hc = createAIChatHealthChecker({
|
|
508
|
+
accountsStore,
|
|
509
|
+
vendorAdapter,
|
|
510
|
+
_deps: factoryDeps.timerDeps,
|
|
511
|
+
});
|
|
512
|
+
const r = await hc.runOnce();
|
|
513
|
+
if (options.json) {
|
|
514
|
+
printJson(r);
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
logger.log(
|
|
518
|
+
`checked=${r.checked} ${chalk.green("ok=" + r.ok)} ${chalk.red("failed=" + r.failed)} ${chalk.yellow("mismatch=" + r.mismatch)}`,
|
|
519
|
+
);
|
|
520
|
+
} catch (err) {
|
|
521
|
+
fail(null, err, options.json);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
async function cmdAIChatUnregister(vendor, options) {
|
|
526
|
+
try {
|
|
527
|
+
const factoryDeps = options._factoryDeps || {};
|
|
528
|
+
const hubDir =
|
|
529
|
+
factoryDeps.hubDir || (await (options._getHub || getHub)()).hubDir;
|
|
530
|
+
const { createAccountsStore } =
|
|
531
|
+
await import("../lib/personal-data-hub-aichat-wizard.js");
|
|
532
|
+
const accountsStore =
|
|
533
|
+
factoryDeps.accountsStore || createAccountsStore({ hubDir });
|
|
534
|
+
const existing = await accountsStore.get(vendor);
|
|
535
|
+
if (!existing) {
|
|
536
|
+
const result = { ok: false, reason: "NOT_REGISTERED", vendor };
|
|
537
|
+
if (options.json) printJson(result);
|
|
538
|
+
else logger.error(chalk.red(`✗ ${vendor} is not registered`));
|
|
539
|
+
process.exit(1);
|
|
540
|
+
}
|
|
541
|
+
await accountsStore.delete(vendor);
|
|
542
|
+
if (options.json) {
|
|
543
|
+
printJson({ ok: true, vendor, removed: true });
|
|
544
|
+
} else {
|
|
545
|
+
logger.log(chalk.green(`✓ removed ${vendor} from aichat-accounts.json`));
|
|
546
|
+
}
|
|
547
|
+
} catch (err) {
|
|
548
|
+
fail(null, err, options.json);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// ─── Phase 12.6.9 — cc hub wechat <verb> subcommand surface ─────────
|
|
553
|
+
//
|
|
554
|
+
// Mirrors the WS topics (personal-data-hub.wechat-env-probe /
|
|
555
|
+
// register-wechat / unregister-wechat / list-wechat-accounts). Useful
|
|
556
|
+
// for headless / scripted setup on a rooted Android attached to a Mac
|
|
557
|
+
// where the user doesn't want to bring up the Vue page just to wire
|
|
558
|
+
// the adapter (cf. cc hub aichat).
|
|
559
|
+
|
|
560
|
+
async function cmdWechatEnvProbe(options) {
|
|
561
|
+
try {
|
|
562
|
+
const hub = await (options._getHub || getHub)();
|
|
563
|
+
const probe = await hub.probeWechatEnv();
|
|
564
|
+
if (options.json) {
|
|
565
|
+
printJson(probe);
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
logger.log(chalk.bold("WeChat env-probe:"));
|
|
569
|
+
logger.log(` ${probe.ok ? chalk.green("✓") : chalk.red("✗")} suggested: ${chalk.cyan(probe.suggestedKeyProvider)}`);
|
|
570
|
+
logger.log(` device: ${probe.device.reachable ? chalk.green("reachable") : chalk.red("unreachable")}${probe.device.serial ? " (" + probe.device.serial + ")" : ""} abi=${probe.device.abi || "?"}`);
|
|
571
|
+
logger.log(` root: ${probe.root.detected ? chalk.green("yes") : chalk.gray("no")} magisk=${probe.root.magiskInstalled ? "yes" : "no"}`);
|
|
572
|
+
logger.log(` frida-server: ${probe.frida.serverRunning ? chalk.green("running") : chalk.gray("not running")}${probe.frida.port ? " :" + probe.frida.port : ""}`);
|
|
573
|
+
logger.log(` wechat: ${probe.wechat.installed ? chalk.green(probe.wechat.versionName) : chalk.gray("not installed")}`);
|
|
574
|
+
for (const reason of probe.reasons || []) logger.log(` · ${chalk.gray(reason)}`);
|
|
575
|
+
for (const w of probe.warnings || []) logger.log(` ${chalk.yellow("!")} ${chalk.yellow(w)}`);
|
|
576
|
+
} catch (err) {
|
|
577
|
+
fail(null, err, options.json);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
async function cmdWechatRegister(options) {
|
|
582
|
+
try {
|
|
583
|
+
if (!options.uin) {
|
|
584
|
+
throw new Error("--uin <wxid-or-uin> required");
|
|
585
|
+
}
|
|
586
|
+
const hub = await (options._getHub || getHub)();
|
|
587
|
+
const r = await hub.registerWechatAdapter({
|
|
588
|
+
account: { uin: options.uin },
|
|
589
|
+
dbPath: options.db || null,
|
|
590
|
+
wechatDataPath: options.wechatDataPath || null,
|
|
591
|
+
keyProviderOverride: options.forceProvider || null,
|
|
592
|
+
fridaOpts: options.fridaDeviceId ? { deviceId: options.fridaDeviceId } : null,
|
|
593
|
+
});
|
|
594
|
+
if (options.json) {
|
|
595
|
+
printJson(r);
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
if (!r.ok) {
|
|
599
|
+
logger.error(chalk.red(`✗ ${r.reason || "register failed"}: ${r.message || ""}`));
|
|
600
|
+
if (r.probe) {
|
|
601
|
+
for (const reason of r.probe.reasons || []) logger.error(chalk.gray(" · " + reason));
|
|
602
|
+
}
|
|
603
|
+
process.exit(1);
|
|
604
|
+
}
|
|
605
|
+
logger.log(chalk.green(`✓ wechat registered (uin=${options.uin})`));
|
|
606
|
+
logger.log(` provider: ${chalk.cyan(r.chosenKeyProvider)}`);
|
|
607
|
+
logger.log(` sensitivity: ${r.sensitivity}`);
|
|
608
|
+
} catch (err) {
|
|
609
|
+
fail(null, err, options.json);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
async function cmdWechatList(options) {
|
|
614
|
+
try {
|
|
615
|
+
const hub = await (options._getHub || getHub)();
|
|
616
|
+
const rows = hub.listWechatAccounts();
|
|
617
|
+
if (options.json) {
|
|
618
|
+
printJson({ accounts: rows });
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
if (rows.length === 0) {
|
|
622
|
+
logger.log(chalk.gray("(no registered WeChat accounts)"));
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
logger.log(chalk.bold("Registered WeChat accounts:"));
|
|
626
|
+
for (const row of rows) {
|
|
627
|
+
logger.log(` • uin=${chalk.cyan(row.uin)} provider=${row.chosenKeyProvider || "?"} db=${row.dbPath || "(none)"} regAt=${row.registeredAt ? new Date(row.registeredAt).toISOString() : "?"}`);
|
|
628
|
+
}
|
|
629
|
+
} catch (err) {
|
|
630
|
+
fail(null, err, options.json);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
async function cmdWechatUnregister(uin, options) {
|
|
635
|
+
try {
|
|
636
|
+
if (!uin) throw new Error("uin argument required");
|
|
637
|
+
const hub = await (options._getHub || getHub)();
|
|
638
|
+
const r = await hub.unregisterWechatAdapter(uin);
|
|
639
|
+
if (options.json) {
|
|
640
|
+
printJson(r);
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
if (!r.ok) {
|
|
644
|
+
logger.error(chalk.red(`✗ ${r.reason || "unregister failed"}`));
|
|
645
|
+
process.exit(1);
|
|
646
|
+
}
|
|
647
|
+
if (r.removed) logger.log(chalk.green(`✓ removed wechat account (uin=${uin})`));
|
|
648
|
+
else logger.log(chalk.gray(`(uin=${uin} was not registered — nothing removed)`));
|
|
649
|
+
} catch (err) {
|
|
650
|
+
fail(null, err, options.json);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
function _defaultKnownVendors() {
|
|
655
|
+
// Match KNOWN_VENDORS in the hub package — kept inline so this file
|
|
656
|
+
// doesn't have to dynamic-import that module on the hot path.
|
|
657
|
+
return [
|
|
658
|
+
"deepseek",
|
|
659
|
+
"kimi",
|
|
660
|
+
"tongyi",
|
|
661
|
+
"zhipu",
|
|
662
|
+
"hunyuan",
|
|
663
|
+
"qianfan",
|
|
664
|
+
"coze",
|
|
665
|
+
"dreamina",
|
|
666
|
+
"doubao",
|
|
667
|
+
];
|
|
668
|
+
}
|
|
669
|
+
|
|
359
670
|
// ─── Commander wire-up ───────────────────────────────────────────────
|
|
360
671
|
|
|
361
672
|
export function registerHubCommand(program) {
|
|
@@ -461,4 +772,110 @@ export function registerHubCommand(program) {
|
|
|
461
772
|
.option("--confirm", "Required to proceed")
|
|
462
773
|
.option("--json", "Output JSON")
|
|
463
774
|
.action(cmdDestroy);
|
|
775
|
+
|
|
776
|
+
// Phase 10.3 — AIChat WebView wizard CLI surface (paste-mode on cc ui).
|
|
777
|
+
const aichat = hub
|
|
778
|
+
.command("aichat")
|
|
779
|
+
.description(
|
|
780
|
+
"AIChat WebView 鉴权向导 — list / login / probe / register / health / unregister 9 家国产 AI",
|
|
781
|
+
);
|
|
782
|
+
|
|
783
|
+
aichat
|
|
784
|
+
.command("list")
|
|
785
|
+
.description("List the 9 known AIChat vendors with their login URLs")
|
|
786
|
+
.option("--json", "Output JSON")
|
|
787
|
+
.action(cmdAIChatList);
|
|
788
|
+
|
|
789
|
+
aichat
|
|
790
|
+
.command("login <vendor>")
|
|
791
|
+
.description("Print the vendor's login URL + paste-fallback help text")
|
|
792
|
+
.option("--json", "Output JSON")
|
|
793
|
+
.action(cmdAIChatLogin);
|
|
794
|
+
|
|
795
|
+
aichat
|
|
796
|
+
.command("probe <vendor>")
|
|
797
|
+
.description(
|
|
798
|
+
"Classify a pasted cookie string against the vendor spec (dry-run)",
|
|
799
|
+
)
|
|
800
|
+
.option("--cookies <string>", 'Raw cookie header (e.g. "a=1; b=2")')
|
|
801
|
+
.option("--json", "Output JSON")
|
|
802
|
+
.action(cmdAIChatProbe);
|
|
803
|
+
|
|
804
|
+
aichat
|
|
805
|
+
.command("register <vendor>")
|
|
806
|
+
.description(
|
|
807
|
+
"Register the vendor — runs validateCookie + persists aichat-accounts.json",
|
|
808
|
+
)
|
|
809
|
+
.option("--cookies <string>", "Raw cookie header from the browser")
|
|
810
|
+
.option("--json", "Output JSON")
|
|
811
|
+
.action(cmdAIChatRegister);
|
|
812
|
+
|
|
813
|
+
aichat
|
|
814
|
+
.command("health")
|
|
815
|
+
.description("Run one HealthChecker pass over registered AIChat vendors")
|
|
816
|
+
.option("--json", "Output JSON")
|
|
817
|
+
.action(cmdAIChatHealth);
|
|
818
|
+
|
|
819
|
+
aichat
|
|
820
|
+
.command("unregister <vendor>")
|
|
821
|
+
.description(
|
|
822
|
+
"Remove a registered AIChat vendor entry (does not touch vault data)",
|
|
823
|
+
)
|
|
824
|
+
.option("--json", "Output JSON")
|
|
825
|
+
.action(cmdAIChatUnregister);
|
|
826
|
+
|
|
827
|
+
// Phase 12.6.9 — cc hub wechat <verb> mirror of WS topics.
|
|
828
|
+
const wechat = hub
|
|
829
|
+
.command("wechat")
|
|
830
|
+
.description(
|
|
831
|
+
"WeChat adapter — env-probe / register / list / unregister (rooted Android required for 8.0+)",
|
|
832
|
+
);
|
|
833
|
+
|
|
834
|
+
wechat
|
|
835
|
+
.command("env-probe")
|
|
836
|
+
.description("Probe attached Android device for adb / root / frida-server / WeChat version")
|
|
837
|
+
.option("--json", "Output JSON")
|
|
838
|
+
.action(cmdWechatEnvProbe);
|
|
839
|
+
|
|
840
|
+
wechat
|
|
841
|
+
.command("register")
|
|
842
|
+
.description(
|
|
843
|
+
"Bootstrap a WeChat adapter (chooses md5 or frida path per env-probe) and persist wechat-accounts.json",
|
|
844
|
+
)
|
|
845
|
+
.requiredOption("--uin <id>", "WeChat numeric UIN (≤ 8.0) or wxid (8.0+)")
|
|
846
|
+
.option("--db <path>", "Local path to the already-pulled EnMicroMsg.db")
|
|
847
|
+
.option("--wechat-data-path <dir>", "Local pulled /data/data/com.tencent.mm/ tree (required for md5 path)")
|
|
848
|
+
.option("--force-provider <md5|frida>", "Override env-probe suggestion")
|
|
849
|
+
.option("--frida-device-id <id>", "Frida device id (defaults to first USB device)")
|
|
850
|
+
.option("--json", "Output JSON")
|
|
851
|
+
.action(cmdWechatRegister);
|
|
852
|
+
|
|
853
|
+
wechat
|
|
854
|
+
.command("list")
|
|
855
|
+
.description("List registered WeChat accounts (scrubbed)")
|
|
856
|
+
.option("--json", "Output JSON")
|
|
857
|
+
.action(cmdWechatList);
|
|
858
|
+
|
|
859
|
+
wechat
|
|
860
|
+
.command("unregister <uin>")
|
|
861
|
+
.description("Remove a registered WeChat account (does not touch vault data)")
|
|
862
|
+
.option("--json", "Output JSON")
|
|
863
|
+
.action(cmdWechatUnregister);
|
|
464
864
|
}
|
|
865
|
+
|
|
866
|
+
// exported for tests — handler functions can be invoked directly with
|
|
867
|
+
// `_wizard` / `_factoryDeps` / `_knownVendors` injected, bypassing the
|
|
868
|
+
// real `getHub()` call. The commander wiring above is the runtime path.
|
|
869
|
+
export const _internal = {
|
|
870
|
+
cmdAIChatList,
|
|
871
|
+
cmdAIChatLogin,
|
|
872
|
+
cmdAIChatProbe,
|
|
873
|
+
cmdAIChatRegister,
|
|
874
|
+
cmdAIChatHealth,
|
|
875
|
+
cmdAIChatUnregister,
|
|
876
|
+
cmdWechatEnvProbe,
|
|
877
|
+
cmdWechatRegister,
|
|
878
|
+
cmdWechatList,
|
|
879
|
+
cmdWechatUnregister,
|
|
880
|
+
_defaultKnownVendors,
|
|
881
|
+
};
|