chainlesschain 0.162.9 → 0.162.12

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.
Files changed (144) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-BgQaSGlp.js → AIOps-C3TDNq29.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-BhTVuWPn.js → ActionButton-C9fE18pE.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-BO1jPw9V.js → Analytics-wnZF602C.js} +1 -1
  5. package/src/assets/web-panel/assets/{AppLayout-VX_9bmhs.js → AppLayout-BjgTMK7O.js} +2 -2
  6. package/src/assets/web-panel/assets/{Audit-Qvf0oq_Y.js → Audit-BBL0BW5_.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-TjzfYOeC.js → Backup-BKLqYCWU.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-BLuumXTZ.js → BaseInput-BGSzMCZs.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-CXrCvi7a.js → Chat-CQWzZWEY.js} +1 -1
  10. package/src/assets/web-panel/assets/{Checkbox--DOdo_Nz.js → Checkbox-BkTri12Q.js} +1 -1
  11. package/src/assets/web-panel/assets/{Codegen-DAJaraZ7.js → Codegen-BH1m09EO.js} +1 -1
  12. package/src/assets/web-panel/assets/{Col-CezPMM8r.js → Col-BXnBuqIa.js} +1 -1
  13. package/src/assets/web-panel/assets/{Community-95cmfh28.js → Community-C_Nr4XCx.js} +1 -1
  14. package/src/assets/web-panel/assets/{Compact-GlEOCt_z.js → Compact-Du6GwLrj.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compliance-Np9rHlBD.js → Compliance-66M0oi1Q.js} +1 -1
  16. package/src/assets/web-panel/assets/{Cowork-DhobloKt.js → Cowork-DQrkZRNd.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cron-DsvEYSze.js → Cron-CwdIFH_v.js} +1 -1
  18. package/src/assets/web-panel/assets/{Crosschain-D5h0edtx.js → Crosschain-DqlcrQ9L.js} +1 -1
  19. package/src/assets/web-panel/assets/{DID-BgEIvDQh.js → DID-OmPLKf7L.js} +1 -1
  20. package/src/assets/web-panel/assets/{Dashboard-BQ9z2Vs6.js → Dashboard-D_dampTL.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dropdown-zDSAIpGs.js → Dropdown-CA1W7jAn.js} +1 -1
  22. package/src/assets/web-panel/assets/{Federation-Bhn4LZO4.js → Federation-Chlk9a7s.js} +1 -1
  23. package/src/assets/web-panel/assets/{FormItemContext-D_NMXINy.js → FormItemContext-t0UqYFLq.js} +1 -1
  24. package/src/assets/web-panel/assets/{Git-D6iEbQtW.js → Git-CEq0raYm.js} +1 -1
  25. package/src/assets/web-panel/assets/{Governance-DXZrVh5v.js → Governance-C06CX7Ge.js} +1 -1
  26. package/src/assets/web-panel/assets/{Inference-DxgJQVdT.js → Inference-6VIFHxIP.js} +1 -1
  27. package/src/assets/web-panel/assets/{KnowledgeGraph-B6iB6jMD.js → KnowledgeGraph-BCJPjMBQ.js} +1 -1
  28. package/src/assets/web-panel/assets/{Logs-Bam2v_rb.js → Logs-BBpOYFct.js} +1 -1
  29. package/src/assets/web-panel/assets/{Marketplace-hmoE5rhf.js → Marketplace-BFH6jMWt.js} +1 -1
  30. package/src/assets/web-panel/assets/{McpTools-XLZTBQ9E.js → McpTools-uCFvRqGs.js} +1 -1
  31. package/src/assets/web-panel/assets/{Memory-C-NXlOEE.js → Memory-B0Kux_KT.js} +1 -1
  32. package/src/assets/web-panel/assets/{MobileBridge-Xi_Xzm7u.js → MobileBridge-DHow2jiK.js} +1 -1
  33. package/src/assets/web-panel/assets/{MobileProjects-BVxyrtNp.js → MobileProjects-BFo9YQZp.js} +1 -1
  34. package/src/assets/web-panel/assets/{Mtc-DY8puwdE.js → Mtc-riOh1G_F.js} +1 -1
  35. package/src/assets/web-panel/assets/{MtcAudit-DJShrgkU.js → MtcAudit-Bm-hE2SP.js} +1 -1
  36. package/src/assets/web-panel/assets/{Multisig-CsNe5Aor.js → Multisig-DfUQxh5a.js} +1 -1
  37. package/src/assets/web-panel/assets/{NLProgramming-Me0yNI2U.js → NLProgramming-DuNvLBEq.js} +1 -1
  38. package/src/assets/web-panel/assets/{Notes-D_g-p2Tg.js → Notes-DB20wd3c.js} +1 -1
  39. package/src/assets/web-panel/assets/{NotificationSettings-DT7K69Vl.js → NotificationSettings-CB-GkOWR.js} +1 -1
  40. package/src/assets/web-panel/assets/{Organization-D4hlrApo.js → Organization-3bU7PZuG.js} +1 -1
  41. package/src/assets/web-panel/assets/{Overflow-BAvaHETK.js → Overflow-BGCPP_0Y.js} +1 -1
  42. package/src/assets/web-panel/assets/{P2P-D570BCdt.js → P2P-BHgAe1oC.js} +1 -1
  43. package/src/assets/web-panel/assets/{Permissions-5lYj-mLS.js → Permissions-BuOD4xwc.js} +1 -1
  44. package/src/assets/web-panel/assets/{PersonalDataHub-DwFzyawJ.js → PersonalDataHub--WA-aZAJ.js} +1 -1
  45. package/src/assets/web-panel/assets/{Pipeline-Ce72g3py.js → Pipeline-DBS5U4LB.js} +1 -1
  46. package/src/assets/web-panel/assets/{Privacy-BsLyD5gE.js → Privacy-UNjIc5El.js} +1 -1
  47. package/src/assets/web-panel/assets/{ProjectInit-CE0ATemT.js → ProjectInit-CicqCJGy.js} +1 -1
  48. package/src/assets/web-panel/assets/{ProjectSettings-Cnevuf69.js → ProjectSettings-CIxAbt4Y.js} +1 -1
  49. package/src/assets/web-panel/assets/{Projects-Bwe8FTDK.js → Projects-BJycZScO.js} +1 -1
  50. package/src/assets/web-panel/assets/{Providers-BlN2_n0e.js → Providers-DxXvprme.js} +1 -1
  51. package/src/assets/web-panel/assets/{QuickAsk-D90_0612.js → QuickAsk-rrqjU8_Y.js} +1 -1
  52. package/src/assets/web-panel/assets/{Recommend-CAdqobLh.js → Recommend-BEwHMhI7.js} +1 -1
  53. package/src/assets/web-panel/assets/{Reputation-gAeuZfsd.js → Reputation-DoVKCCMn.js} +1 -1
  54. package/src/assets/web-panel/assets/{Row-Dsz4KRaU.js → Row-F5XcDhHr.js} +1 -1
  55. package/src/assets/web-panel/assets/{RssFeed-BuTu0HKl.js → RssFeed-cZrRG7k8.js} +1 -1
  56. package/src/assets/web-panel/assets/{Search-B6jcG3iF.js → Search-B9ctZjqx.js} +1 -1
  57. package/src/assets/web-panel/assets/{Security-CcEX8TPI.js → Security-Z62hl1mc.js} +1 -1
  58. package/src/assets/web-panel/assets/{Services-BBbLFK_e.js → Services-CQf5XqgZ.js} +1 -1
  59. package/src/assets/web-panel/assets/{Skeleton-CARhezYN.js → Skeleton-DuCKw2Eh.js} +1 -1
  60. package/src/assets/web-panel/assets/{Skills-B9dCFkON.js → Skills-qVkhva0s.js} +1 -1
  61. package/src/assets/web-panel/assets/{Sla-Ds2N-wGY.js → Sla-BQbatr7s.js} +1 -1
  62. package/src/assets/web-panel/assets/{SpeechSettings-flimA105.js → SpeechSettings-DLFBzAgD.js} +1 -1
  63. package/src/assets/web-panel/assets/{SyncSettings-B1tJs8pr.js → SyncSettings-CrzETZMW.js} +1 -1
  64. package/src/assets/web-panel/assets/{Tasks-Cs7_NAOr.js → Tasks-D_EQ1nJ7.js} +1 -1
  65. package/src/assets/web-panel/assets/{Templates-D3iXQ2gE.js → Templates-D4y-dGRc.js} +1 -1
  66. package/src/assets/web-panel/assets/{Tenant-Z6mUmAVT.js → Tenant-2XI0jkPn.js} +1 -1
  67. package/src/assets/web-panel/assets/{Terminal-PIR1l-39.js → Terminal-fUi5V2Z9.js} +1 -1
  68. package/src/assets/web-panel/assets/{Tokens-BLjbrTa1.js → Tokens-BuUNB2mg.js} +1 -1
  69. package/src/assets/web-panel/assets/{Trigger-CIJzC6pS.js → Trigger-7DqLLuej.js} +1 -1
  70. package/src/assets/web-panel/assets/{Trust-D_-71Gjt.js → Trust-CeACvTYx.js} +1 -1
  71. package/src/assets/web-panel/assets/{UkeySign-CwjoYze6.js → UkeySign-mDP9EXHq.js} +1 -1
  72. package/src/assets/web-panel/assets/{VideoEditing-BUvHAwqx.js → VideoEditing-veWlKclv.js} +1 -1
  73. package/src/assets/web-panel/assets/{Wallet-Ds-Mgv8V.js → Wallet-Cd2Hheb8.js} +1 -1
  74. package/src/assets/web-panel/assets/{WebAuthn-B1HCLfzA.js → WebAuthn-DyL7ZiHX.js} +1 -1
  75. package/src/assets/web-panel/assets/{WorkflowEditor-BiJ0uOBt.js → WorkflowEditor-C7-7LJH9.js} +1 -1
  76. package/src/assets/web-panel/assets/{chat-CRWoVJL9.js → chat-DXomZMuo.js} +1 -1
  77. package/src/assets/web-panel/assets/{colors-D90H7N7U.js → colors-DlU92QNs.js} +1 -1
  78. package/src/assets/web-panel/assets/{compact-item-C6U27ikN.js → compact-item-sBiTL8mX.js} +1 -1
  79. package/src/assets/web-panel/assets/{createContext-dR8PtJ-p.js → createContext-DZXEnzum.js} +1 -1
  80. package/src/assets/web-panel/assets/{hasIn-CFe-8hdI.js → hasIn-CpCHBZ2M.js} +1 -1
  81. package/src/assets/web-panel/assets/{index-B5fuCdMf.js → index-B0Qbxr57.js} +1 -1
  82. package/src/assets/web-panel/assets/{index-DlIs_MhZ.js → index-B23tuoo9.js} +1 -1
  83. package/src/assets/web-panel/assets/{index-DEEu_VP1.js → index-B3k9UPHc.js} +1 -1
  84. package/src/assets/web-panel/assets/{index-gLrDgd8C.js → index-BK2AFy44.js} +1 -1
  85. package/src/assets/web-panel/assets/{index-_UAOyaYh.js → index-B_-RETt0.js} +1 -1
  86. package/src/assets/web-panel/assets/{index-ml1s2nd5.js → index-BqnhEJls.js} +1 -1
  87. package/src/assets/web-panel/assets/{index-WmmdmN6b.js → index-C52udT0_.js} +3 -3
  88. package/src/assets/web-panel/assets/{index-DrPvpDNw.js → index-C59FgSkU.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-CSIH2KxQ.js → index-C6SDf50u.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-DOW32kkX.js → index-CD3iljXs.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-rhwSri9e.js → index-CDyzZ8_O.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-w5t-vMNO.js → index-CJ7XYa5K.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-zDn5JJTC.js → index-CUe5t5Aa.js} +1 -1
  94. package/src/assets/web-panel/assets/index-CcRX6BlT.js +1 -0
  95. package/src/assets/web-panel/assets/{index-BOOxNqWQ.js → index-ChahjdYE.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-66g2WGdx.js → index-CivbS-57.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CvJ3UZ52.js → index-CjXSvceY.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-5JpRRs-N.js → index-ClN_JuFa.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BWUElbLB.js → index-CwbWZubA.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DN4iOH17.js → index-DKe9jmKG.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-l3oIS_5E.js → index-DUlPMzoM.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CE1ONO_z.js → index-D_IgY63-.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BL7VlSvq.js → index-D_MzScPM.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Cbm7lyTa.js → index-DeGnHcp5.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-D43N1wTf.js → index-Di1_EQ-X.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Du2kakr1.js → index-Dj9Nvz6S.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-pOwjlfcg.js → index-Dn8m1d1f.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DibOj-Y8.js → index-Dq5Rn5VS.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-nrBwYuLT.js → index-Dyg6ikIL.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BCKkZgvL.js → index-DygNvCeR.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BKAuW9ip.js → index-F9cBucYf.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-D5x3uBml.js → index-ThrAiEF9.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BCKut9LD.js → index-TwQZkVGh.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-cERDyhbA.js → index-X48zYgZ6.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BbQx_BA_.js → index-XI6772AD.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-cMms0yaN.js → index-_zyXBoS7.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CFbyZ4VS.js → index-ibFHnqHz.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BZopu374.js → index-s8tvk-fF.js} +1 -1
  119. package/src/assets/web-panel/assets/index-z6h6tqP3.js +1 -0
  120. package/src/assets/web-panel/assets/{initDefaultProps-BYQdbBmy.js → initDefaultProps-DEi92ZnZ.js} +1 -1
  121. package/src/assets/web-panel/assets/{motion-BtpQTgfW.js → motion-BtYKzpOc.js} +1 -1
  122. package/src/assets/web-panel/assets/{move-BXl4Tr-C.js → move-Cb3A1-v-.js} +1 -1
  123. package/src/assets/web-panel/assets/{omit-D83siT_K.js → omit-B6qPDdOf.js} +1 -1
  124. package/src/assets/web-panel/assets/{pickAttrs-DAo4jR1m.js → pickAttrs-DDyeQMUc.js} +1 -1
  125. package/src/assets/web-panel/assets/{placementArrow-BroqhS4u.js → placementArrow-BPV6VO47.js} +1 -1
  126. package/src/assets/web-panel/assets/{responsiveObserve-CQ1ZgLXP.js → responsiveObserve-DJ1ra4dT.js} +1 -1
  127. package/src/assets/web-panel/assets/{slide-tkfTw6kp.js → slide-D6v8tHvB.js} +1 -1
  128. package/src/assets/web-panel/assets/{statusUtils-CGzZbaVH.js → statusUtils-DulKcQLZ.js} +1 -1
  129. package/src/assets/web-panel/assets/{styleChecker-CDEoUvcb.js → styleChecker-Bne7zwMt.js} +1 -1
  130. package/src/assets/web-panel/assets/{useFlexGapSupport-Ba76kVFx.js → useFlexGapSupport-C1miTomM.js} +1 -1
  131. package/src/assets/web-panel/assets/{useFs-B4iO8Fmn.js → useFs-CR-iLa4Z.js} +1 -1
  132. package/src/assets/web-panel/assets/{vnode-vHVV16AJ.js → vnode-yL9axxBy.js} +1 -1
  133. package/src/assets/web-panel/assets/{zoom-DifdtHK7.js → zoom-B-VCMXSD.js} +1 -1
  134. package/src/assets/web-panel/index.html +1 -1
  135. package/src/commands/hub.js +464 -0
  136. package/src/commands/init.js +10 -0
  137. package/src/commands/notification.js +260 -0
  138. package/src/commands/pack.js +319 -0
  139. package/src/commands/persona.js +160 -1
  140. package/src/index.js +4 -0
  141. package/src/lib/packer/pkg-config-generator.js +111 -5
  142. package/src/runtime/agent-core.js +26 -2
  143. package/src/assets/web-panel/assets/index-EFyvtYMT.js +0 -1
  144. package/src/assets/web-panel/assets/index-ohea9DVW.js +0 -1
@@ -0,0 +1,464 @@
1
+ /**
2
+ * Personal Data Hub — CLI subcommand surface.
3
+ *
4
+ * Exposes the same operations the WS gateway (gateways/ws/personal-data-
5
+ * hub-protocol.js) handles, so `cc hub <verb>` works identically across:
6
+ * - Desktop in-app terminal (Phase 2.5 cc bundle)
7
+ * - `cc ui` web-shell (WS topic personal-data-hub.* — peer to this)
8
+ * - Direct CLI invocation (this file)
9
+ *
10
+ * Plan A v0.1 Sub-Phase A3.1. Real-device verified on Xiaomi 24115RA8EC
11
+ * 2026-05-20 via cc-smoke.js (T1/T2/T3 PASS) — bs3mc + SQLCipher vault
12
+ * proven working in-app. This command surface is what makes those
13
+ * capabilities usable without writing JS.
14
+ *
15
+ * All output supports --json for scripting. Default is human-readable.
16
+ */
17
+
18
+ import chalk from "chalk";
19
+ import ora from "ora";
20
+ import { logger } from "../lib/logger.js";
21
+ import { getHub } from "../lib/personal-data-hub-wiring.js";
22
+
23
+ function printJson(obj) {
24
+ console.log(JSON.stringify(obj, null, 2));
25
+ }
26
+
27
+ function fail(spinner, err, asJson) {
28
+ if (spinner) spinner.stop();
29
+ const msg = err && err.message ? err.message : String(err);
30
+ if (asJson) {
31
+ printJson({ error: msg });
32
+ } else {
33
+ logger.error(chalk.red(`✗ ${msg}`));
34
+ }
35
+ process.exit(1);
36
+ }
37
+
38
+ // ─── ask ──────────────────────────────────────────────────────────────
39
+
40
+ async function cmdAsk(question, options) {
41
+ const spinner = options.json ? null : ora("Asking hub...").start();
42
+ try {
43
+ const hub = await getHub();
44
+ if (!hub.engine) throw new Error("Analysis engine unavailable");
45
+ const result = await hub.engine.ask(question, {
46
+ useRag: options.useRag !== false,
47
+ acceptNonLocal: !!options.acceptNonLocal,
48
+ });
49
+ if (spinner) spinner.stop();
50
+ if (options.json) {
51
+ printJson(result);
52
+ } else {
53
+ if (result.error) {
54
+ logger.error(chalk.red(`✗ ${result.error}`));
55
+ process.exit(1);
56
+ }
57
+ logger.log(result.answer);
58
+ if (result.citations && result.citations.length) {
59
+ logger.log(
60
+ chalk.gray(
61
+ `\n依据: ${result.citations.map((c) => c.eventId).join(", ")}`,
62
+ ),
63
+ );
64
+ }
65
+ if (result.llmName) {
66
+ const localTag = result.isLocal
67
+ ? chalk.green("[local]")
68
+ : chalk.yellow("[remote]");
69
+ logger.log(chalk.gray(`-- ${result.llmName} ${localTag}`));
70
+ }
71
+ }
72
+ } catch (err) {
73
+ fail(spinner, err, options.json);
74
+ }
75
+ }
76
+
77
+ // ─── stats ────────────────────────────────────────────────────────────
78
+
79
+ async function cmdStats(options) {
80
+ try {
81
+ const hub = await getHub();
82
+ const out = {
83
+ vault: hub.vault.stats(),
84
+ adapters: hub.registry.list(),
85
+ hubDir: hub.hubDir,
86
+ llm: hub.llm ? { name: hub.llm.name, isLocal: hub.llm.isLocal } : null,
87
+ };
88
+ if (options.json) {
89
+ printJson(out);
90
+ } else {
91
+ const v = out.vault;
92
+ logger.log(chalk.bold("vault:"));
93
+ logger.log(` events: ${v.events}`);
94
+ logger.log(` persons: ${v.persons}`);
95
+ logger.log(` places: ${v.places}`);
96
+ logger.log(` items: ${v.items}`);
97
+ logger.log(` topics: ${v.topics}`);
98
+ logger.log(chalk.bold(`\nadapters (${out.adapters.length}):`));
99
+ for (const a of out.adapters) {
100
+ logger.log(` ${chalk.cyan(a.name)} v${a.version}`);
101
+ }
102
+ logger.log(chalk.gray(`\nhubDir: ${out.hubDir}`));
103
+ if (out.llm) {
104
+ const tag = out.llm.isLocal
105
+ ? chalk.green("[local]")
106
+ : chalk.yellow("[remote]");
107
+ logger.log(chalk.gray(`llm: ${out.llm.name} ${tag}`));
108
+ } else {
109
+ logger.log(chalk.yellow("llm: (none)"));
110
+ }
111
+ }
112
+ } catch (err) {
113
+ fail(null, err, options.json);
114
+ }
115
+ }
116
+
117
+ // ─── health ───────────────────────────────────────────────────────────
118
+
119
+ async function cmdHealth(options) {
120
+ try {
121
+ const hub = await getHub();
122
+ const out = {
123
+ vault: {
124
+ ok: !!hub.vault.db,
125
+ schemaVersion: hub.vault.schemaVersion(),
126
+ },
127
+ llm: hub.llm
128
+ ? { ok: true, isLocal: hub.llm.isLocal, name: hub.llm.name }
129
+ : { ok: false, reason: "LLM unavailable" },
130
+ kgSink: { ok: !!hub.kgSink },
131
+ ragSink: { ok: !!hub.ragSink },
132
+ };
133
+ if (options.json) {
134
+ printJson(out);
135
+ } else {
136
+ const mark = (ok) => (ok ? chalk.green("✓") : chalk.red("✗"));
137
+ logger.log(
138
+ `${mark(out.vault.ok)} vault schema=${out.vault.schemaVersion}`,
139
+ );
140
+ logger.log(
141
+ `${mark(out.llm.ok)} llm ${out.llm.name || out.llm.reason}${
142
+ out.llm.ok
143
+ ? out.llm.isLocal
144
+ ? chalk.green(" [local]")
145
+ : chalk.yellow(" [remote]")
146
+ : ""
147
+ }`,
148
+ );
149
+ logger.log(`${mark(out.kgSink.ok)} kgSink`);
150
+ logger.log(`${mark(out.ragSink.ok)} ragSink`);
151
+ }
152
+ } catch (err) {
153
+ fail(null, err, options.json);
154
+ }
155
+ }
156
+
157
+ // ─── list-adapters ────────────────────────────────────────────────────
158
+
159
+ async function cmdListAdapters(options) {
160
+ try {
161
+ const hub = await getHub();
162
+ const adapters = hub.registry.list();
163
+ if (options.json) {
164
+ printJson(adapters);
165
+ } else {
166
+ if (!adapters.length) {
167
+ logger.log(chalk.yellow("(no adapters registered)"));
168
+ return;
169
+ }
170
+ for (const a of adapters) {
171
+ logger.log(
172
+ `${chalk.cyan(a.name.padEnd(22))} v${a.version.padEnd(8)} ${
173
+ a.sensitivity ? chalk.gray(`(${a.sensitivity})`) : ""
174
+ }`,
175
+ );
176
+ }
177
+ }
178
+ } catch (err) {
179
+ fail(null, err, options.json);
180
+ }
181
+ }
182
+
183
+ // ─── sync-adapter / sync-all ──────────────────────────────────────────
184
+
185
+ async function cmdSyncAdapter(name, options) {
186
+ const spinner = options.json ? null : ora(`syncing ${name}...`).start();
187
+ try {
188
+ const hub = await getHub();
189
+ const opts = {};
190
+ if (options.since) opts.since = Number(options.since);
191
+ if (options.until) opts.until = Number(options.until);
192
+ if (options.limit) opts.limit = Number(options.limit);
193
+ const report = await hub.registry.syncAdapter(name, opts);
194
+ if (spinner) spinner.succeed(`synced ${name}`);
195
+ if (options.json) {
196
+ printJson(report);
197
+ } else {
198
+ logger.log(
199
+ `ingested=${report.ingested} kgTriples=${report.kgTriples} ragDocs=${report.ragDocs} durationMs=${report.durationMs}`,
200
+ );
201
+ }
202
+ } catch (err) {
203
+ fail(spinner, err, options.json);
204
+ }
205
+ }
206
+
207
+ async function cmdSyncAll(options) {
208
+ const spinner = options.json ? null : ora("syncing all...").start();
209
+ try {
210
+ const hub = await getHub();
211
+ const opts = {};
212
+ if (options.since) opts.since = Number(options.since);
213
+ if (options.until) opts.until = Number(options.until);
214
+ if (options.limit) opts.limit = Number(options.limit);
215
+ const reports = await hub.registry.syncAll(opts);
216
+ if (spinner) spinner.succeed(`synced ${reports.length} adapters`);
217
+ if (options.json) {
218
+ printJson(reports);
219
+ } else {
220
+ for (const r of reports) {
221
+ logger.log(
222
+ `${chalk.cyan(r.adapter)} ingested=${r.ingested} dur=${r.durationMs}ms`,
223
+ );
224
+ }
225
+ }
226
+ } catch (err) {
227
+ fail(spinner, err, options.json);
228
+ }
229
+ }
230
+
231
+ // ─── query-events / recent-audit ─────────────────────────────────────
232
+
233
+ async function cmdQueryEvents(options) {
234
+ try {
235
+ const hub = await getHub();
236
+ const q = {};
237
+ if (options.subtype) q.subtype = options.subtype;
238
+ if (options.since) q.since = Number(options.since);
239
+ if (options.until) q.until = Number(options.until);
240
+ if (options.actor) q.actor = options.actor;
241
+ if (options.adapter) q.adapter = options.adapter;
242
+ if (options.limit) q.limit = Number(options.limit);
243
+ const events = hub.vault.queryEvents(q);
244
+ if (options.json) {
245
+ printJson(events);
246
+ } else {
247
+ logger.log(`${events.length} events:`);
248
+ for (const ev of events) {
249
+ const at = new Date(ev.at).toISOString();
250
+ logger.log(
251
+ ` ${chalk.gray(at)} ${chalk.cyan(ev.subtype)} ${ev.summary || ev.id}`,
252
+ );
253
+ }
254
+ }
255
+ } catch (err) {
256
+ fail(null, err, options.json);
257
+ }
258
+ }
259
+
260
+ async function cmdRecentAudit(options) {
261
+ try {
262
+ const hub = await getHub();
263
+ const q = {};
264
+ if (options.since) q.since = Number(options.since);
265
+ if (options.action) q.action = options.action;
266
+ if (options.limit) q.limit = Number(options.limit);
267
+ const rows = hub.vault.queryAudit(q);
268
+ if (options.json) {
269
+ printJson(rows);
270
+ } else {
271
+ logger.log(`${rows.length} audit rows:`);
272
+ for (const r of rows) {
273
+ const at = new Date(r.at).toISOString();
274
+ logger.log(
275
+ ` ${chalk.gray(at)} ${chalk.cyan(r.action)} ${r.adapter || ""} ${r.eventId || ""}`,
276
+ );
277
+ }
278
+ }
279
+ } catch (err) {
280
+ fail(null, err, options.json);
281
+ }
282
+ }
283
+
284
+ // ─── register-mock ───────────────────────────────────────────────────
285
+
286
+ async function cmdRegisterMock(options) {
287
+ try {
288
+ const hub = await getHub();
289
+ const a = hub.registerMockAdapter({
290
+ name: options.name || "mock",
291
+ count: options.count ? Number(options.count) : 20,
292
+ seed: options.seed ? Number(options.seed) : 1,
293
+ });
294
+ const out = { name: a.name, version: a.version };
295
+ if (options.json) {
296
+ printJson(out);
297
+ } else {
298
+ logger.log(chalk.green(`✓ registered ${out.name} v${out.version}`));
299
+ }
300
+ } catch (err) {
301
+ fail(null, err, options.json);
302
+ }
303
+ }
304
+
305
+ // ─── destroy ─────────────────────────────────────────────────────────
306
+
307
+ async function cmdDestroy(options) {
308
+ if (!options.confirm) {
309
+ const msg =
310
+ "Destructive: pass --confirm to wipe vault. This deletes vault.db + WAL.";
311
+ if (options.json) {
312
+ printJson({ error: msg });
313
+ } else {
314
+ logger.error(chalk.red(`✗ ${msg}`));
315
+ }
316
+ process.exit(1);
317
+ }
318
+ try {
319
+ const hub = await getHub();
320
+ hub.vault.destroy();
321
+ if (options.json) {
322
+ printJson({ ok: true });
323
+ } else {
324
+ logger.log(chalk.green("✓ vault destroyed"));
325
+ }
326
+ } catch (err) {
327
+ fail(null, err, options.json);
328
+ }
329
+ }
330
+
331
+ // ─── runSkill ────────────────────────────────────────────────────────
332
+
333
+ async function cmdRunSkill(name, options) {
334
+ const spinner = options.json
335
+ ? null
336
+ : ora(`running analysis skill ${name}...`).start();
337
+ try {
338
+ const hub = await getHub();
339
+ if (!hub.analysisSkillNames.includes(name)) {
340
+ throw new Error(
341
+ `Unknown skill: ${name}. Available: ${hub.analysisSkillNames.join(", ")}`,
342
+ );
343
+ }
344
+ const skillOpts = {};
345
+ if (options.since) skillOpts.since = Number(options.since);
346
+ if (options.until) skillOpts.until = Number(options.until);
347
+ const result = await hub.runSkill(name, skillOpts);
348
+ if (spinner) spinner.stop();
349
+ if (options.json) {
350
+ printJson(result);
351
+ } else {
352
+ logger.log(JSON.stringify(result, null, 2));
353
+ }
354
+ } catch (err) {
355
+ fail(spinner, err, options.json);
356
+ }
357
+ }
358
+
359
+ // ─── Commander wire-up ───────────────────────────────────────────────
360
+
361
+ export function registerHubCommand(program) {
362
+ const hub = program
363
+ .command("hub")
364
+ .description(
365
+ "Personal Data Hub — local vault + adapters + AnalysisEngine on this machine",
366
+ );
367
+
368
+ hub
369
+ .command("ask <question>")
370
+ .description("Natural-language question over your local vault")
371
+ .option("--use-rag", "Enable RAG retrieval (default true)", true)
372
+ .option("--no-use-rag", "Disable RAG retrieval")
373
+ .option(
374
+ "--accept-non-local",
375
+ "Allow non-local LLM (sends data off device — required when provider is not Ollama/vLLM)",
376
+ )
377
+ .option("--json", "Output JSON")
378
+ .action(cmdAsk);
379
+
380
+ hub
381
+ .command("stats")
382
+ .description("Vault row counts + registered adapter list + hub paths")
383
+ .option("--json", "Output JSON")
384
+ .action(cmdStats);
385
+
386
+ hub
387
+ .command("health")
388
+ .description("Component health: vault / llm / kgSink / ragSink")
389
+ .option("--json", "Output JSON")
390
+ .action(cmdHealth);
391
+
392
+ hub
393
+ .command("list-adapters")
394
+ .description("List registered adapters")
395
+ .option("--json", "Output JSON")
396
+ .action(cmdListAdapters);
397
+
398
+ hub
399
+ .command("sync-adapter <name>")
400
+ .description("Run one adapter's ingest pipeline")
401
+ .option("--since <ms>", "Override watermark — sync from this unix-ms")
402
+ .option("--until <ms>", "Stop at this unix-ms")
403
+ .option("--limit <n>", "Cap ingested events")
404
+ .option("--json", "Output JSON")
405
+ .action(cmdSyncAdapter);
406
+
407
+ hub
408
+ .command("sync-all")
409
+ .description("Run all registered adapters in series")
410
+ .option("--since <ms>", "Override watermark for all")
411
+ .option("--until <ms>", "Stop at this unix-ms")
412
+ .option("--limit <n>", "Cap each adapter")
413
+ .option("--json", "Output JSON")
414
+ .action(cmdSyncAll);
415
+
416
+ hub
417
+ .command("query-events")
418
+ .description("Query vault events with filters")
419
+ .option("--subtype <t>", "Event subtype filter")
420
+ .option("--since <ms>", "Start of time window (unix-ms)")
421
+ .option("--until <ms>", "End of time window (unix-ms)")
422
+ .option("--actor <id>", "Actor person id filter")
423
+ .option("--adapter <name>", "Adapter origin filter")
424
+ .option("--limit <n>", "Max rows", "100")
425
+ .option("--json", "Output JSON")
426
+ .action(cmdQueryEvents);
427
+
428
+ hub
429
+ .command("recent-audit")
430
+ .description("Recent audit log entries")
431
+ .option("--since <ms>", "Start of time window (unix-ms)")
432
+ .option("--action <a>", "Filter by action (ingest / ask / register / ...)")
433
+ .option("--limit <n>", "Max rows", "50")
434
+ .option("--json", "Output JSON")
435
+ .action(cmdRecentAudit);
436
+
437
+ hub
438
+ .command("register-mock")
439
+ .description("Register MockAdapter (dev/smoke only)")
440
+ .option("--name <n>", "Adapter name", "mock")
441
+ .option("--count <n>", "How many fake events per sync", "20")
442
+ .option("--seed <n>", "Deterministic seed", "1")
443
+ .option("--json", "Output JSON")
444
+ .action(cmdRegisterMock);
445
+
446
+ hub
447
+ .command("run-skill <name>")
448
+ .description(
449
+ "Run one of the built-in analysis skills (spending/relations/footprint/interests/timeline)",
450
+ )
451
+ .option("--since <ms>", "Start of time window")
452
+ .option("--until <ms>", "End of time window")
453
+ .option("--json", "Output JSON")
454
+ .action(cmdRunSkill);
455
+
456
+ hub
457
+ .command("destroy")
458
+ .description(
459
+ "DESTRUCTIVE: wipe vault.db + WAL. Requires --confirm. Adapters / accounts files preserved.",
460
+ )
461
+ .option("--confirm", "Required to proceed")
462
+ .option("--json", "Output JSON")
463
+ .action(cmdDestroy);
464
+ }
@@ -2479,7 +2479,17 @@ export function registerInitCommand(program) {
2479
2479
  },
2480
2480
  };
2481
2481
  if (tmpl.persona) {
2482
+ // Backward-compat: legacy single-persona field. `_loadProjectPersona`
2483
+ // still falls back to this when no named persona resolves.
2482
2484
  config.persona = tmpl.persona;
2485
+ // Phase 3d: named-persona registry so `CC_PACK_AUTO_PERSONA` and
2486
+ // `cc persona activate <name>` can resolve by name. Keyed the same
2487
+ // as the auto-activated persona skill (`.chainlesschain/skills/
2488
+ // <template>-persona/SKILL.md`) for cross-reference symmetry.
2489
+ config.personas = {
2490
+ [`${template}-persona`]: tmpl.persona,
2491
+ };
2492
+ config.activePersonaName = `${template}-persona`;
2483
2493
  }
2484
2494
  fs.writeFileSync(
2485
2495
  path.join(ccDir, "config.json"),