chainlesschain 0.166.16 → 0.166.17

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 (174) hide show
  1. package/README.md +3 -3
  2. package/completions/_cc +1 -1
  3. package/completions/cc.bash +1 -1
  4. package/completions/cc.fish +1 -1
  5. package/completions/cc.ps1 +1 -1
  6. package/package.json +2 -2
  7. package/src/assets/web-panel/assets/{AIOps-CTxa2Wbq.js → AIOps-CVW2n2rh.js} +1 -1
  8. package/src/assets/web-panel/assets/{ActionButton-DHrQyYhy.js → ActionButton-DtuM163O.js} +1 -1
  9. package/src/assets/web-panel/assets/{Analytics-DQiUqcNl.js → Analytics-BXvl_qHu.js} +3 -3
  10. package/src/assets/web-panel/assets/{AppLayout-_Iz4r6wt.js → AppLayout-VDBTFKOp.js} +5 -5
  11. package/src/assets/web-panel/assets/{Artifacts-BNs63YHo.js → Artifacts-BNz2xCiG.js} +1 -1
  12. package/src/assets/web-panel/assets/{Audit-BgHIqRLn.js → Audit-DTu9Hn9P.js} +1 -1
  13. package/src/assets/web-panel/assets/{BackgroundAgents-DUQ5axBB.js → BackgroundAgents-D2OCPzLe.js} +1 -1
  14. package/src/assets/web-panel/assets/{Backup-CJ51E9Vw.js → Backup-C9M-vG7G.js} +1 -1
  15. package/src/assets/web-panel/assets/{BaseInput-o-5toA_R.js → BaseInput-BUkCNiUQ.js} +1 -1
  16. package/src/assets/web-panel/assets/{Chat-Cu7a-x1L.js → Chat-OJ2ajF7l.js} +6 -6
  17. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BUyYkAXr.js → ChatBubbleRenderer-BdZt76Ab.js} +1 -1
  18. package/src/assets/web-panel/assets/{Checkbox-DwdmZ71L.js → Checkbox-C1gXKDsc.js} +1 -1
  19. package/src/assets/web-panel/assets/{Codegen-BrH2eYiP.js → Codegen-BXbznLg7.js} +1 -1
  20. package/src/assets/web-panel/assets/{Col-BVJQEP2j.js → Col-CbCq5N0i.js} +1 -1
  21. package/src/assets/web-panel/assets/{Community-FGO3vZPq.js → Community-V8Ks6Yun.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compact-DYGAFVnT.js → Compact-DkeHQTpQ.js} +1 -1
  23. package/src/assets/web-panel/assets/{Compliance-CRvc8Bdt.js → Compliance-JeLKwn4Q.js} +1 -1
  24. package/src/assets/web-panel/assets/{Cowork-D6Ah2m7A.js → Cowork-azfetcBz.js} +2 -2
  25. package/src/assets/web-panel/assets/{Cron-AXbU2ifR.js → Cron-Q691i_Gp.js} +2 -2
  26. package/src/assets/web-panel/assets/{Crosschain-C5DXgEFd.js → Crosschain-BLjDRbr_.js} +1 -1
  27. package/src/assets/web-panel/assets/{DID-Bxh9QV9v.js → DID-D8ptXplK.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dashboard-B-ZHEta-.js → Dashboard-Ctj2VVZL.js} +2 -2
  29. package/src/assets/web-panel/assets/{Dropdown-66Ik1jqa.js → Dropdown-D8VgkMJ8.js} +1 -1
  30. package/src/assets/web-panel/assets/{EmailListRenderer-CCWk1BIM.js → EmailListRenderer-CQPe5S6q.js} +1 -1
  31. package/src/assets/web-panel/assets/{FamilyGuardDashboard--9faIULK.js → FamilyGuardDashboard-ySA-7SiN.js} +1 -1
  32. package/src/assets/web-panel/assets/{Federation-CejW9CgX.js → Federation-1PMD-fBf.js} +1 -1
  33. package/src/assets/web-panel/assets/{FormItemContext-acHgcXki.js → FormItemContext-C_jr6U4Q.js} +1 -1
  34. package/src/assets/web-panel/assets/{GenericCardRenderer-D2ghd_K4.js → GenericCardRenderer-Bu3bKf2B.js} +1 -1
  35. package/src/assets/web-panel/assets/{Git-BOe1YJrV.js → Git-Dv4Fa_T5.js} +2 -2
  36. package/src/assets/web-panel/assets/{Governance-BjgzJsof.js → Governance-DOEy1n1k.js} +1 -1
  37. package/src/assets/web-panel/assets/{Inference-CXCD5rnP.js → Inference-DkvqzWcJ.js} +1 -1
  38. package/src/assets/web-panel/assets/{KnowledgeGraph-CHA8QgJT.js → KnowledgeGraph-DdUJK949.js} +1 -1
  39. package/src/assets/web-panel/assets/{Logs-DORPMcL6.js → Logs-CRelcdUZ.js} +2 -2
  40. package/src/assets/web-panel/assets/{MarkdownRenderer-CPPHz01z.js → MarkdownRenderer-0AHbbTA4.js} +1 -1
  41. package/src/assets/web-panel/assets/{Marketplace-BCFlo1Yx.js → Marketplace-BuuBKsev.js} +1 -1
  42. package/src/assets/web-panel/assets/{McpTools-Dl_uZAKh.js → McpTools-DlgpEmA1.js} +3 -3
  43. package/src/assets/web-panel/assets/{Memory-DupHamwz.js → Memory-DTfdqUGy.js} +2 -2
  44. package/src/assets/web-panel/assets/{MobileBridge-BRSMPJxW.js → MobileBridge-CXLE5ZFO.js} +1 -1
  45. package/src/assets/web-panel/assets/{MobileProjects-BHpuzsDl.js → MobileProjects-Dz25OB0n.js} +1 -1
  46. package/src/assets/web-panel/assets/{Mtc-Ch0jOQfZ.js → Mtc-kEL0fhgD.js} +2 -2
  47. package/src/assets/web-panel/assets/{MtcAudit-qzwQrDi7.js → MtcAudit-BE4UvFJU.js} +2 -2
  48. package/src/assets/web-panel/assets/{Multisig-B5wHzUcm.js → Multisig-CSApSn8c.js} +3 -3
  49. package/src/assets/web-panel/assets/{NLProgramming-Hy9uAiA0.js → NLProgramming-D11FpKWx.js} +1 -1
  50. package/src/assets/web-panel/assets/{Notes-DkuchMC7.js → Notes-CDL-D2CS.js} +3 -3
  51. package/src/assets/web-panel/assets/{NotificationSettings-CYZhD7Pi.js → NotificationSettings-C0Q6lO-c.js} +1 -1
  52. package/src/assets/web-panel/assets/OrderTableRenderer-ZRE0OKbj.js +1 -0
  53. package/src/assets/web-panel/assets/{Organization-D9AXn6j8.js → Organization-Dc-maVAq.js} +4 -4
  54. package/src/assets/web-panel/assets/{Overflow-Bg15J6hX.js → Overflow-B5mUpSvi.js} +1 -1
  55. package/src/assets/web-panel/assets/{P2P--B54HoQn.js → P2P-TjXV53wq.js} +2 -2
  56. package/src/assets/web-panel/assets/PdhVaultBrowser-DvV2btIr.js +7 -0
  57. package/src/assets/web-panel/assets/{Permissions-DHx38eS1.js → Permissions-DKRzQ2O6.js} +4 -4
  58. package/src/assets/web-panel/assets/{PersonalDataHub-Dw8i2hAs.js → PersonalDataHub-Dx2eqft8.js} +4 -4
  59. package/src/assets/web-panel/assets/{Pipeline-B2o6Ur2G.js → Pipeline-CnYZMB5p.js} +1 -1
  60. package/src/assets/web-panel/assets/{Privacy-8g-h2fnu.js → Privacy-BonKpPnp.js} +1 -1
  61. package/src/assets/web-panel/assets/{ProjectInit-DuVTcINx.js → ProjectInit-DWO0Du3J.js} +2 -2
  62. package/src/assets/web-panel/assets/{ProjectSettings-C8njvdZX.js → ProjectSettings-C9jqyYRv.js} +2 -2
  63. package/src/assets/web-panel/assets/Projects-CYpKwXbz.js +1 -0
  64. package/src/assets/web-panel/assets/{Providers-wFqgod_W.js → Providers-CW-fkwJq.js} +1 -1
  65. package/src/assets/web-panel/assets/{QrScannerModal-9NCXrpmA.js → QrScannerModal-Cw0J3Zud.js} +1 -1
  66. package/src/assets/web-panel/assets/{QuickAsk-WUTNvFkY.js → QuickAsk-BH4A4IpR.js} +1 -1
  67. package/src/assets/web-panel/assets/{Recommend-xT4nYmju.js → Recommend-CDwMwJus.js} +1 -1
  68. package/src/assets/web-panel/assets/{RemoteSession-fak1PBGC.js → RemoteSession-DKIPwzTf.js} +2 -2
  69. package/src/assets/web-panel/assets/{Reputation-D1AkQvD-.js → Reputation-CklDj7qS.js} +1 -1
  70. package/src/assets/web-panel/assets/{Row-DVfm6xGt.js → Row-DJWZKsH0.js} +1 -1
  71. package/src/assets/web-panel/assets/{RssFeed-BDunoLSE.js → RssFeed-BfSLCewo.js} +2 -2
  72. package/src/assets/web-panel/assets/{Search-OPycRoU3.js → Search-B0IST--x.js} +1 -1
  73. package/src/assets/web-panel/assets/{Security-C8-Fm3Dt.js → Security-h1sYNWtt.js} +3 -3
  74. package/src/assets/web-panel/assets/{Services-qM_sMpMl.js → Services-Gh0-oxI_.js} +2 -2
  75. package/src/assets/web-panel/assets/{Skeleton-D3HBJjVF.js → Skeleton-CNDV_jOs.js} +1 -1
  76. package/src/assets/web-panel/assets/{Skills-jr67X-tP.js → Skills-ByCLTh1n.js} +1 -1
  77. package/src/assets/web-panel/assets/{Sla-CS3ggyCg.js → Sla-BfyrJTJz.js} +1 -1
  78. package/src/assets/web-panel/assets/{SpeechSettings-CTOCYxOi.js → SpeechSettings-BQzo9kNX.js} +1 -1
  79. package/src/assets/web-panel/assets/{SyncSettings-D3s3cLT5.js → SyncSettings-B6fS6z_1.js} +2 -2
  80. package/src/assets/web-panel/assets/{Tasks-CdfoJ25m.js → Tasks-C-uKCP-l.js} +1 -1
  81. package/src/assets/web-panel/assets/{Templates-Drb4AI8X.js → Templates-D6oDy7wL.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tenant-DzwR3Qkz.js → Tenant-D3LT2wNQ.js} +1 -1
  83. package/src/assets/web-panel/assets/{Terminal-D-ESq7xp.js → Terminal-BteLcv_O.js} +2 -2
  84. package/src/assets/web-panel/assets/{TimelineRenderer-BK-AUuws.js → TimelineRenderer-DHHuxfqH.js} +1 -1
  85. package/src/assets/web-panel/assets/{Tokens-xGTouuNp.js → Tokens-BRQeykXw.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trigger-BvZj-v2H.js → Trigger-p2XaFWEu.js} +1 -1
  87. package/src/assets/web-panel/assets/{Trust-BLC9CGmc.js → Trust-BxadBMft.js} +1 -1
  88. package/src/assets/web-panel/assets/{UkeySign-BSuCXpmE.js → UkeySign-DRBP7LDk.js} +1 -1
  89. package/src/assets/web-panel/assets/{VideoEditing-DT3A-_Ql.js → VideoEditing-CZ3NZkh7.js} +1 -1
  90. package/src/assets/web-panel/assets/{Wallet-c1OXao85.js → Wallet-C3NTBN7G.js} +4 -4
  91. package/src/assets/web-panel/assets/{WebAuthn-CuA-F7KJ.js → WebAuthn-C7LVgMlb.js} +2 -2
  92. package/src/assets/web-panel/assets/{WorkflowEditor-MANZrf82.js → WorkflowEditor-0_Iveog7.js} +1 -1
  93. package/src/assets/web-panel/assets/{chat-D4Y4Ey0O.js → chat-DzzluYo3.js} +1 -1
  94. package/src/assets/web-panel/assets/{colors-DDH06hKO.js → colors-DSMYXpaj.js} +1 -1
  95. package/src/assets/web-panel/assets/{compact-item-Cym756Xj.js → compact-item-W76u1VSV.js} +1 -1
  96. package/src/assets/web-panel/assets/{createContext-By4Nb1k-.js → createContext-otsESjb5.js} +1 -1
  97. package/src/assets/web-panel/assets/devWarning-BztaXF84.js +1 -0
  98. package/src/assets/web-panel/assets/{hasIn-Ch7OY258.js → hasIn-3sNLrvug.js} +1 -1
  99. package/src/assets/web-panel/assets/index-4jP_hG_4.js +1 -0
  100. package/src/assets/web-panel/assets/{index-DtGValNi.js → index-B1I1AYJs.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-B51otVoZ.js → index-B5LOYdYm.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BBBUn5v7.js → index-B9X_jqXe.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-6CpOV3Pn.js → index-BA8mZxd-.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CUSUzaB8.js → index-BDlDO2px.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-oBsfUbyH.js → index-BJsQio5O.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-q-s04OKn.js → index-BRsD1PT2.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-XGeQMvWK.js → index-BXLx9HfA.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CjNUTBwe.js → index-BcGJtmHM.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-D9le0-dc.js → index-BdtmEKat.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-mL3nOcH6.js → index-BpcQYzP7.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BZB9q-Lp.js → index-C2aht9-M.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CF3Lhyns.js → index-CE7tSow-.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CZn6dmZe.js → index-CENWwjef.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Bo20BfdS.js → index-CKoFyHYQ.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-tZ5BUdad.js → index-Cg86EzNp.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CT-3FYwd.js → index-ClOFeZ-t.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-6-2eYBXr.js → index-CtFOt5x1.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DvnywwUj.js → index-D7A5U2IH.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CGsvEbbq.js → index-DH4cl52p.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CJPks33Y.js → index-DLDh1OW3.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CV8qXTvb.js → index-DMmdIpLA.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CykROEJA.js → index-DS9WYDMf.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-jx7kr6mB.js → index-DTA8Iavv.js} +3 -3
  124. package/src/assets/web-panel/assets/{index-CpudmDhf.js → index-DZKAzEge.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DAkk1M7x.js → index-DdU7IkKX.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DNlxihs8.js → index-Ddd4mird.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BIrRX-ra.js → index-DmpaC2yk.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CV1UC4zo.js → index-GlIOE4ja.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-ArMrnx0v.js → index-MhQQ3h8q.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DjwgJ5Jd.js → index-NaO9AE-F.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DNEJzc0r.js → index-UUHCwfNq.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BFydNU6a.js → index-pVm_iUre.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-ZY2Qs_Sn.js → index-q7ftLqNt.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-D5sADPGY.js → index-uSCkbpZH.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DiewptTL.js → index-vBKPcmAP.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-OU8DZ9BL.js → index-vUmYkqmu.js} +1 -1
  137. package/src/assets/web-panel/assets/index-zxwuAXL5.js +1 -0
  138. package/src/assets/web-panel/assets/{initDefaultProps-DGcX9iPP.js → initDefaultProps-DF6llUXV.js} +1 -1
  139. package/src/assets/web-panel/assets/{motion-2SeL1D8A.js → motion-vtDV8_5K.js} +1 -1
  140. package/src/assets/web-panel/assets/{move-3cYbQCpS.js → move-B6c0bdy2.js} +1 -1
  141. package/src/assets/web-panel/assets/{mtc-parser-IDdxfw0z.js → mtc-parser-DlLYWuBK.js} +1 -1
  142. package/src/assets/web-panel/assets/{omit-BNswdKO6.js → omit-BH0zOxLN.js} +1 -1
  143. package/src/assets/web-panel/assets/{pickAttrs-BwCnem2I.js → pickAttrs-D9di8_In.js} +1 -1
  144. package/src/assets/web-panel/assets/{placementArrow-B9PtZ5rq.js → placementArrow-BDSngufM.js} +1 -1
  145. package/src/assets/web-panel/assets/{responsiveObserve-CPB6iSzV.js → responsiveObserve-C_EawMvP.js} +1 -1
  146. package/src/assets/web-panel/assets/{slide-DZgyblZa.js → slide-B_4wShxA.js} +1 -1
  147. package/src/assets/web-panel/assets/{statusUtils-D82IBdsx.js → statusUtils-CbQu6qJ-.js} +1 -1
  148. package/src/assets/web-panel/assets/{styleChecker-qSHtosM-.js → styleChecker-CvXJWYXb.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFlexGapSupport-CmWO7h0I.js → useFlexGapSupport-jjY1XknO.js} +1 -1
  150. package/src/assets/web-panel/assets/{useFs-yLrs_ub4.js → useFs-CMXBdsK_.js} +1 -1
  151. package/src/assets/web-panel/assets/{usePersonalDataHub-CJ1VW6rh.js → usePersonalDataHub-YbAhhPXx.js} +1 -1
  152. package/src/assets/web-panel/assets/{vnode-CzY_moQ4.js → vnode-BFCTKc0H.js} +1 -1
  153. package/src/assets/web-panel/assets/{zoom-DAa7rEY5.js → zoom-CY9aBl5O.js} +1 -1
  154. package/src/assets/web-panel/index.html +1 -1
  155. package/src/command-help-index.json +2 -2
  156. package/src/command-manifest.json +2 -2
  157. package/src/commands/evolution.js +30 -17
  158. package/src/commands/learning.js +24 -8
  159. package/src/data/changelog.json +13 -0
  160. package/src/lib/evolution/bounded-skill-improvement-pilot.js +498 -0
  161. package/src/lib/evolution/evolution-run-runtime-adapter.js +5 -0
  162. package/src/lib/evolution/skill-evaluated-promotion-durability.js +899 -0
  163. package/src/lib/evolution/skill-evaluated-promotion.js +481 -0
  164. package/src/lib/evolution/skill-promotion-controller.js +114 -2
  165. package/src/lib/evolution/wiki-informed-skill-proposer.js +343 -0
  166. package/src/lib/graph-kernel/evolution-run-runtime-adapter.js +5 -0
  167. package/src/lib/hooks-v2-runtime.js +20 -0
  168. package/src/runtime/agent-core.js +68 -0
  169. package/src/assets/web-panel/assets/OrderTableRenderer-DKOoqajt.js +0 -1
  170. package/src/assets/web-panel/assets/PdhVaultBrowser-Cz9Kk2Nb.js +0 -7
  171. package/src/assets/web-panel/assets/Projects-Ca9BAfu7.js +0 -1
  172. package/src/assets/web-panel/assets/devWarning-KO3pAGeO.js +0 -1
  173. package/src/assets/web-panel/assets/index-Bh4Rgkg2.js +0 -1
  174. package/src/assets/web-panel/assets/index-Dox_coTY.js +0 -1
@@ -0,0 +1,343 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ export const WIKI_SKILL_PROPOSAL_SCHEMA =
4
+ "chainlesschain.wiki-informed-skill-proposal/v1";
5
+ export const WIKI_PROPOSAL_STATUS = Object.freeze({
6
+ PROPOSAL: "proposal",
7
+ NO_PROPOSAL: "no-proposal",
8
+ NEEDS_EVIDENCE: "needs-evidence",
9
+ });
10
+
11
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
12
+ const SKILL_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
13
+ const INITIAL_SOURCES = Object.freeze([
14
+ "wiki-index",
15
+ "skill-impact",
16
+ "active-skill",
17
+ "training-summary",
18
+ ]);
19
+ const SELECTIVE_SOURCES = new Set(["pattern", "raw"]);
20
+ const SAFE_DIFF_ROOTS = new Set([
21
+ "SKILL.md",
22
+ "PURPOSE.md",
23
+ "assets",
24
+ "references",
25
+ "scripts",
26
+ ]);
27
+
28
+ function canonical(value) {
29
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
30
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
31
+ return `{${Object.keys(value)
32
+ .sort()
33
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
34
+ .join(",")}}`;
35
+ }
36
+
37
+ function hash(value) {
38
+ return `sha256:${createHash("sha256").update(canonical(value)).digest("hex")}`;
39
+ }
40
+
41
+ function deepFreeze(value) {
42
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
43
+ Object.freeze(value);
44
+ for (const child of Object.values(value)) deepFreeze(child);
45
+ }
46
+ return value;
47
+ }
48
+
49
+ function requiredString(value, name) {
50
+ if (typeof value !== "string" || value.trim() === "") {
51
+ throw new TypeError(`${name} is required`);
52
+ }
53
+ return value;
54
+ }
55
+
56
+ function stringList(value, name, { allowEmpty = false, max = 64 } = {}) {
57
+ if (
58
+ !Array.isArray(value) ||
59
+ (!allowEmpty && value.length === 0) ||
60
+ value.length > max ||
61
+ value.some((item) => typeof item !== "string" || item.trim() === "") ||
62
+ new Set(value).size !== value.length
63
+ ) {
64
+ throw new TypeError(`${name} must be a bounded unique string list`);
65
+ }
66
+ return [...value];
67
+ }
68
+
69
+ function verifyEnvelope(value, expectedKind) {
70
+ if (
71
+ !value ||
72
+ typeof value !== "object" ||
73
+ value.kind !== expectedKind ||
74
+ value.trusted !== true ||
75
+ typeof value.ref !== "string" ||
76
+ !DIGEST.test(value.digest ?? "") ||
77
+ value.digest !== hash(value.data)
78
+ ) {
79
+ const error = new Error(`${expectedKind} evidence is not digest-bound and trusted`);
80
+ error.code = "WIKI_PROPOSAL_UNTRUSTED_EVIDENCE";
81
+ throw error;
82
+ }
83
+ return deepFreeze({
84
+ kind: value.kind,
85
+ ref: value.ref,
86
+ digest: value.digest,
87
+ data: structuredClone(value.data),
88
+ });
89
+ }
90
+
91
+ function normalizeDescriptor(input) {
92
+ const descriptor = {
93
+ tenantId: requiredString(input?.tenantId, "tenantId"),
94
+ evolutionRunId: requiredString(input?.evolutionRunId, "evolutionRunId"),
95
+ targetSkillName: requiredString(input?.targetSkillName, "targetSkillName"),
96
+ wikiRevision: requiredString(input?.wikiRevision, "wikiRevision"),
97
+ proposerModel: requiredString(input?.proposerModel, "proposerModel"),
98
+ minEvidenceSamples: Math.max(1, Number(input?.minEvidenceSamples) || 1),
99
+ maxSelectiveEvidence: Math.min(
100
+ 16,
101
+ Math.max(0, Number(input?.maxSelectiveEvidence) || 4),
102
+ ),
103
+ };
104
+ if (!SKILL_NAME.test(descriptor.targetSkillName)) {
105
+ throw new TypeError("targetSkillName must be canonical kebab-case");
106
+ }
107
+ return deepFreeze(descriptor);
108
+ }
109
+
110
+ function validateDiff(diff) {
111
+ if (!Array.isArray(diff) || diff.length === 0 || diff.length > 128) {
112
+ throw new TypeError("machineDiff must contain 1..128 operations");
113
+ }
114
+ return diff.map((entry) => {
115
+ if (!entry || !["add", "replace", "remove"].includes(entry.op)) {
116
+ throw new TypeError("machineDiff operation is invalid");
117
+ }
118
+ const path = requiredString(entry.path, "machineDiff.path").replaceAll("\\", "/");
119
+ const parts = path.split("/");
120
+ if (
121
+ path.startsWith("/") ||
122
+ parts.includes("..") ||
123
+ !SAFE_DIFF_ROOTS.has(parts[0]) ||
124
+ /(^|\/)(active|\.chainlesschain)(\/|$)/u.test(path)
125
+ ) {
126
+ const error = new Error("machineDiff escaped the single candidate Skill");
127
+ error.code = "WIKI_PROPOSAL_UNSAFE_DIFF";
128
+ throw error;
129
+ }
130
+ return {
131
+ op: entry.op,
132
+ path,
133
+ beforeDigest: entry.beforeDigest ?? null,
134
+ afterDigest: entry.afterDigest ?? null,
135
+ };
136
+ });
137
+ }
138
+
139
+ function validateProposal(output, descriptor, evidence) {
140
+ if (output?.status !== WIKI_PROPOSAL_STATUS.PROPOSAL) {
141
+ throw new TypeError("proposal output status is invalid");
142
+ }
143
+ if (output.skillName !== descriptor.targetSkillName) {
144
+ const error = new Error("proposer attempted to change more than the fixed Skill");
145
+ error.code = "WIKI_PROPOSAL_MULTI_SKILL";
146
+ throw error;
147
+ }
148
+ const knownRefs = new Set(evidence.map((item) => item.ref));
149
+ const purpose = {
150
+ summary: requiredString(output.purpose?.summary, "purpose.summary"),
151
+ patternRefs: stringList(output.purpose?.patternRefs, "purpose.patternRefs"),
152
+ sourceEvidenceRefs: stringList(
153
+ output.purpose?.sourceEvidenceRefs,
154
+ "purpose.sourceEvidenceRefs",
155
+ ),
156
+ };
157
+ for (const ref of [...purpose.patternRefs, ...purpose.sourceEvidenceRefs]) {
158
+ if (!knownRefs.has(ref)) {
159
+ const error = new Error("PURPOSE references evidence outside the resolved set");
160
+ error.code = "WIKI_PROPOSAL_UNKNOWN_LINEAGE";
161
+ throw error;
162
+ }
163
+ }
164
+ const contextCost = {
165
+ maxTokens: Number(output.contextCost?.maxTokens),
166
+ maxBytes: Number(output.contextCost?.maxBytes),
167
+ };
168
+ if (
169
+ !Number.isInteger(contextCost.maxTokens) ||
170
+ contextCost.maxTokens <= 0 ||
171
+ !Number.isInteger(contextCost.maxBytes) ||
172
+ contextCost.maxBytes <= 0
173
+ ) {
174
+ throw new TypeError("contextCost must provide positive maxTokens/maxBytes");
175
+ }
176
+ return deepFreeze({
177
+ schema: WIKI_SKILL_PROPOSAL_SCHEMA,
178
+ status: WIKI_PROPOSAL_STATUS.PROPOSAL,
179
+ tenantId: descriptor.tenantId,
180
+ evolutionRunId: descriptor.evolutionRunId,
181
+ skillName: descriptor.targetSkillName,
182
+ purpose,
183
+ applicableWhen: stringList(output.applicableWhen, "applicableWhen"),
184
+ notApplicableWhen: stringList(output.notApplicableWhen, "notApplicableWhen"),
185
+ failureCounterexamples: stringList(
186
+ output.failureCounterexamples,
187
+ "failureCounterexamples",
188
+ ),
189
+ rollbackSteps: stringList(output.rollbackSteps, "rollbackSteps"),
190
+ validationMethods: stringList(output.validationMethods, "validationMethods"),
191
+ requestedCapabilities: stringList(
192
+ output.requestedCapabilities,
193
+ "requestedCapabilities",
194
+ { allowEmpty: true },
195
+ ),
196
+ targetRuntimes: stringList(output.targetRuntimes, "targetRuntimes"),
197
+ contextCost,
198
+ machineDiff: validateDiff(output.machineDiff),
199
+ sourceEvidenceRefs: evidence.map(({ ref, digest }) => ({ ref, digest })),
200
+ wikiRevision: descriptor.wikiRevision,
201
+ proposerModel: descriptor.proposerModel,
202
+ });
203
+ }
204
+
205
+ function abstention(status, reason, evidence = []) {
206
+ return deepFreeze({
207
+ schema: WIKI_SKILL_PROPOSAL_SCHEMA,
208
+ status,
209
+ reason,
210
+ sourceEvidenceRefs: evidence.map(({ ref, digest }) => ({ ref, digest })),
211
+ });
212
+ }
213
+
214
+ export class WikiInformedSkillProposer {
215
+ constructor({ descriptor, policy, ports } = {}) {
216
+ this.descriptor = normalizeDescriptor(descriptor);
217
+ if (policy?.proposerWikiRead !== true || policy?.executionAgentWikiRead === true) {
218
+ throw new Error("capability policy must isolate Wiki reads to the proposer");
219
+ }
220
+ if (typeof ports?.readInitial !== "function")
221
+ throw new TypeError("readInitial port is required");
222
+ if (typeof ports?.readSelective !== "function")
223
+ throw new TypeError("readSelective port is required");
224
+ if (typeof ports?.generate !== "function")
225
+ throw new TypeError("generate port is required");
226
+ if (typeof ports?.createCandidate !== "function")
227
+ throw new TypeError("createCandidate port is required");
228
+ this._ports = ports;
229
+ Object.freeze(this);
230
+ }
231
+
232
+ async propose() {
233
+ const initial = [];
234
+ for (const kind of INITIAL_SOURCES) {
235
+ initial.push(verifyEnvelope(await this._ports.readInitial(kind), kind));
236
+ }
237
+ const wiki = initial.find((item) => item.kind === "wiki-index");
238
+ const training = initial.find((item) => item.kind === "training-summary");
239
+ if ((wiki.data?.contradictionRefs?.length ?? 0) > 0) {
240
+ return abstention(
241
+ WIKI_PROPOSAL_STATUS.NEEDS_EVIDENCE,
242
+ "wiki evidence is contradictory",
243
+ initial,
244
+ );
245
+ }
246
+ if (Number(training.data?.sampleCount) < this.descriptor.minEvidenceSamples) {
247
+ return abstention(
248
+ WIKI_PROPOSAL_STATUS.NEEDS_EVIDENCE,
249
+ "training evidence sample is insufficient",
250
+ initial,
251
+ );
252
+ }
253
+
254
+ let evidence = [...initial];
255
+ let output = await this._ports.generate({
256
+ descriptor: this.descriptor,
257
+ evidence: deepFreeze([...evidence]),
258
+ });
259
+ if (output?.status === WIKI_PROPOSAL_STATUS.NO_PROPOSAL) {
260
+ return abstention(output.status, requiredString(output.reason, "reason"), evidence);
261
+ }
262
+ if (output?.status === WIKI_PROPOSAL_STATUS.NEEDS_EVIDENCE) {
263
+ const requests = output.requests;
264
+ if (
265
+ !Array.isArray(requests) ||
266
+ requests.length === 0 ||
267
+ requests.length > this.descriptor.maxSelectiveEvidence
268
+ ) {
269
+ return abstention(output.status, "selective evidence request is invalid", evidence);
270
+ }
271
+ for (const request of requests) {
272
+ if (!SELECTIVE_SOURCES.has(request?.kind)) {
273
+ return abstention(output.status, "requested evidence scope is not allowed", evidence);
274
+ }
275
+ evidence.push(
276
+ verifyEnvelope(
277
+ await this._ports.readSelective(request.kind, request.ref),
278
+ request.kind,
279
+ ),
280
+ );
281
+ }
282
+ output = await this._ports.generate({
283
+ descriptor: this.descriptor,
284
+ evidence: deepFreeze([...evidence]),
285
+ });
286
+ if (output?.status !== WIKI_PROPOSAL_STATUS.PROPOSAL) {
287
+ return abstention(
288
+ output?.status === WIKI_PROPOSAL_STATUS.NO_PROPOSAL
289
+ ? output.status
290
+ : WIKI_PROPOSAL_STATUS.NEEDS_EVIDENCE,
291
+ requiredString(output?.reason, "reason"),
292
+ evidence,
293
+ );
294
+ }
295
+ }
296
+
297
+ const proposal = validateProposal(output, this.descriptor, evidence);
298
+ const proposalDigest = hash(proposal);
299
+ const candidateInput = deepFreeze({
300
+ tenantId: proposal.tenantId,
301
+ skillName: proposal.skillName,
302
+ derivationMode: "wiki",
303
+ wikiRevision: proposal.wikiRevision,
304
+ proposerModel: proposal.proposerModel,
305
+ requestedCapabilities: proposal.requestedCapabilities,
306
+ sourceEvidenceRefs: proposal.sourceEvidenceRefs,
307
+ content: canonical(proposal),
308
+ });
309
+ const created = await this._ports.createCandidate(candidateInput);
310
+ const candidate = created?.candidate;
311
+ if (
312
+ typeof candidate?.candidateId !== "string" ||
313
+ typeof candidate?.contentDigest !== "string" ||
314
+ candidate.skillName !== proposal.skillName ||
315
+ candidate.content !== candidateInput.content ||
316
+ candidate.derivationMode !== "wiki" ||
317
+ candidate.wikiRevision !== proposal.wikiRevision ||
318
+ candidate.proposerModel !== proposal.proposerModel ||
319
+ canonical(candidate.requestedCapabilities) !==
320
+ canonical(proposal.requestedCapabilities) ||
321
+ canonical(candidate.targetRuntimes) !== canonical(proposal.targetRuntimes) ||
322
+ canonical(candidate.sourceEvidenceRefs) !==
323
+ canonical(proposal.sourceEvidenceRefs)
324
+ ) {
325
+ const error = new Error(
326
+ "candidate sink did not return an exact immutable proposal binding",
327
+ );
328
+ error.code = "WIKI_PROPOSAL_CANDIDATE_UNCONFIRMED";
329
+ throw error;
330
+ }
331
+ return deepFreeze({
332
+ status: WIKI_PROPOSAL_STATUS.PROPOSAL,
333
+ proposal,
334
+ proposalDigest,
335
+ candidateId: candidate.candidateId,
336
+ contentDigest: candidate.contentDigest,
337
+ });
338
+ }
339
+ }
340
+
341
+ export function createWikiInformedSkillProposer(options) {
342
+ return new WikiInformedSkillProposer(options);
343
+ }
@@ -0,0 +1,5 @@
1
+ import evolutionRun from "@chainlesschain/session-core/evolution-run";
2
+
3
+ export function projectGraphEvolutionRun(events, options) {
4
+ return evolutionRun.projectEvolutionRun(events, options);
5
+ }
@@ -872,6 +872,26 @@ class HooksV2Runtime extends EventEmitter {
872
872
  }
873
873
  }
874
874
  for (const hook of asyncHooks) {
875
+ if (
876
+ options.skipAsyncWithoutDispatcher === true &&
877
+ typeof options.asyncDispatcher !== "function"
878
+ ) {
879
+ results.push({
880
+ execId: crypto.randomUUID(),
881
+ hookId: hook.id,
882
+ sourceHookId: hook.databaseHookId || hook.id,
883
+ hookName: hook.databaseHookName || hook.description || hook.id,
884
+ event: eventName,
885
+ type: hook.type,
886
+ priority: normalizeHookPriority(hook.priority),
887
+ executionMode: HOOK_EXECUTION_MODE.ASYNC,
888
+ status: "skipped",
889
+ decision: "continue",
890
+ deferred: false,
891
+ skipReason: "async_dispatcher_unavailable",
892
+ });
893
+ continue;
894
+ }
875
895
  const queued = {
876
896
  execId: crypto.randomUUID(),
877
897
  hookId: hook.id,
@@ -19,7 +19,10 @@ import path from "path";
19
19
  import broker from "../lib/process-execution-broker/index.js";
20
20
  import os from "os";
21
21
  import { createHash, randomUUID } from "node:crypto";
22
+ import skillInvocationReceipt from "@chainlesschain/session-core/skill-invocation-receipt";
22
23
  import { isProxy } from "node:util/types";
24
+
25
+ const { startSkillInvocation, settleSkillInvocation } = skillInvocationReceipt;
23
26
  import sharedCodingAgentPolicy from "./coding-agent-policy.cjs";
24
27
  import sharedShellPolicy from "./coding-agent-shell-policy.cjs";
25
28
  import sharedPermissionRules from "../lib/permission-rules.cjs";
@@ -3570,6 +3573,8 @@ export async function executeTool(name, args, context = {}) {
3570
3573
  onProviderReceipt: context.onProviderReceipt || null,
3571
3574
  onToolCallBoundary: context.onToolCallBoundary || null,
3572
3575
  onToolCallSettlement: context.onToolCallSettlement || null,
3576
+ hookTraceId: context.hookTraceId || null,
3577
+ skillLifecycleMode: context.skillLifecycleMode || "active",
3573
3578
  backgroundUsageFailureState: context.backgroundUsageFailureState || null,
3574
3579
  planManager,
3575
3580
  permissionRules: context.permissionRules || null,
@@ -3707,6 +3712,7 @@ export async function executeTool(name, args, context = {}) {
3707
3712
  { cwd, broker },
3708
3713
  )
3709
3714
  : null,
3715
+ skipAsyncWithoutDispatcher: true,
3710
3716
  },
3711
3717
  );
3712
3718
  for (const hookResult of outcome.results || []) {
@@ -5151,6 +5157,7 @@ async function executeToolInner(
5151
5157
  // Hook-envelope tracing: this run's trace id, threaded into child loops
5152
5158
  // (spawn_sub_agent / isolated run_skill) as their parent_id.
5153
5159
  hookTraceId = null,
5160
+ skillLifecycleMode = "active",
5154
5161
  },
5155
5162
  ) {
5156
5163
  const localToolDescriptor =
@@ -7866,6 +7873,63 @@ async function executeToolInner(
7866
7873
  });
7867
7874
  }
7868
7875
 
7876
+ const selectedSkillDigest =
7877
+ match.executionIdentity?.contentDigest ||
7878
+ `sha256:${createHash("sha256").update(admittedSkillBody).digest("hex")}`;
7879
+ const toolSetDigest = `sha256:${createHash("sha256")
7880
+ .update(
7881
+ JSON.stringify(
7882
+ [...(effectiveAllowedToolNames || [])].map(String).sort(),
7883
+ ),
7884
+ )
7885
+ .digest("hex")}`;
7886
+ const policyDigest = `sha256:${createHash("sha256")
7887
+ .update(
7888
+ JSON.stringify({
7889
+ hasApprovalGate: Boolean(approvalGate),
7890
+ hasPermissionRules: Boolean(permissionRules),
7891
+ hasSandbox: Boolean(sandbox),
7892
+ hermeticExecution: hermeticExecution === true,
7893
+ }),
7894
+ )
7895
+ .digest("hex")}`;
7896
+ const invocationStartedAt = Date.now();
7897
+ const invocationStart = startSkillInvocation({
7898
+ attributionRequired: ["automatic-candidate", "canary"].includes(
7899
+ skillLifecycleMode,
7900
+ ),
7901
+ evolutionRunId: workflowEffectId || sessionId,
7902
+ traceId: hookTraceId || sessionId,
7903
+ trajectorySegmentId: turnId || toolCallId,
7904
+ selectedSkillDigest,
7905
+ routerCandidates: [
7906
+ {
7907
+ digest: selectedSkillDigest,
7908
+ score: 1,
7909
+ reason: "explicit-run_skill",
7910
+ },
7911
+ ],
7912
+ providerModelVersion:
7913
+ llmOptions?.provider && llmOptions?.model
7914
+ ? `${llmOptions.provider}:${llmOptions.model}`
7915
+ : null,
7916
+ toolSetDigest,
7917
+ osSandboxPermissionPolicyDigest: policyDigest,
7918
+ taskCohort: "cli:run_skill",
7919
+ });
7920
+ const settleInvocation = (executionStatus, result = {}) =>
7921
+ settleSkillInvocation(invocationStart, {
7922
+ executionStatus,
7923
+ graderReceipts: result.graderReceipts || [],
7924
+ userCorrectionRef: result.userCorrectionRef || null,
7925
+ tokensInput:
7926
+ result.usage?.inputTokens || result.usage?.tokensInput || 0,
7927
+ tokensOutput:
7928
+ result.usage?.outputTokens || result.usage?.tokensOutput || 0,
7929
+ costUsd: result.usage?.costUsd || result.costUsd || 0,
7930
+ latencyMs: Date.now() - invocationStartedAt,
7931
+ });
7932
+
7869
7933
  // Check if skill requests isolation (via SKILL.md frontmatter)
7870
7934
  const skillIsolation = match.isolation === true;
7871
7935
  if (skillIsolation) {
@@ -8066,6 +8130,7 @@ async function executeToolInner(
8066
8130
  success: false,
8067
8131
  isolated: true,
8068
8132
  skill: args.skill_name,
8133
+ invocationReceipt: settleInvocation("failed", result),
8069
8134
  code: result?.code || "CC_SKILL_ISOLATED_EXECUTION_FAILED",
8070
8135
  error: `Isolated skill execution failed: ${failureDetail}`,
8071
8136
  ...(result?.summary ? { summary: result.summary } : {}),
@@ -8075,6 +8140,7 @@ async function executeToolInner(
8075
8140
  success: true,
8076
8141
  isolated: true,
8077
8142
  skill: args.skill_name,
8143
+ invocationReceipt: settleInvocation("completed", result),
8078
8144
  summary: result.summary,
8079
8145
  toolsUsed: result.toolsUsed,
8080
8146
  });
@@ -8096,6 +8162,7 @@ async function executeToolInner(
8096
8162
  success: false,
8097
8163
  isolated: true,
8098
8164
  skill: args.skill_name,
8165
+ invocationReceipt: settleInvocation("failed"),
8099
8166
  code: err?.code || "CC_SKILL_ISOLATED_EXECUTION_FAILED",
8100
8167
  error: `Isolated skill execution failed: ${err.message}`,
8101
8168
  });
@@ -8112,6 +8179,7 @@ async function executeToolInner(
8112
8179
  return attachDescriptor({
8113
8180
  error: `Skill "${args.skill_name}" cannot execute handler.js directly. Add isolation: true and use the controlled agent-tool path.`,
8114
8181
  code: "CC_SKILL_DIRECT_HANDLER_BLOCKED",
8182
+ invocationReceipt: settleInvocation("blocked"),
8115
8183
  policy: { decision: "blocked", via: "skill-execution-boundary" },
8116
8184
  });
8117
8185
  }
@@ -1 +0,0 @@
1
- import{I as w,P as l,J as u,U as s,R as n,c as i,K as v,Q as _,V as g,b as a}from"./vendor-Bn1JzzAn.js";import{_ as S}from"./index-jx7kr6mB.js";import"./icons-DG5UD-6K.js";const k={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const o=p,e=a(()=>o.event.content||{}),d=a(()=>o.event.extra||{}),m=a(()=>d.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=a(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),y=a(()=>{const t=e.value.amount??e.value.price??e.value.total;return t==null?"—":`${e.value.currency||"¥"} ${typeof t=="number"?t.toFixed(2):t}`}),T=a(()=>d.value.orderNo||e.value.orderNo||e.value.orderId),f=a(()=>e.value.status||e.value.state),b=a(()=>{const t=(f.value||"").toLowerCase();return t.includes("成功")||t.includes("succe")||t.includes("paid")?"green":t.includes("退")||t.includes("refund")?"orange":t.includes("失败")||t.includes("fail")?"red":"default"}),h=a(()=>{if(!o.event.occurredAt)return"";const t=new Date(o.event.occurredAt);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}),x={props:o,c:e,e:d,merchantText:m,itemText:c,amountText:y,orderNo:T,statusText:f,statusColor:b,formattedTime:h,computed:a};return Object.defineProperty(x,"__isScriptSetup",{enumerable:!1,value:!0}),x}},N={class:"order-card"},C={class:"head"},O={class:"time"},V={class:"row"},R={class:"val"},B={class:"row"},D={class:"val"},I={class:"row amount-row"},j={class:"val amount"},A={key:0,class:"row"},F={class:"val mono"},J={key:1,class:"row"};function M(p,r,o,e,d,m){const c=w("a-tag");return l(),u("div",N,[s("div",C,[s("span",O,n(e.formattedTime),1),i(c,{color:"gold"},{default:v(()=>[_(n(o.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(o.event.subtype),1)]),_:1})]),s("div",V,[r[0]||(r[0]=s("span",{class:"key"},"商户",-1)),s("span",R,n(e.merchantText),1)]),s("div",B,[r[1]||(r[1]=s("span",{class:"key"},"商品/项目",-1)),s("span",D,n(e.itemText),1)]),s("div",I,[r[2]||(r[2]=s("span",{class:"key"},"金额",-1)),s("span",j,n(e.amountText),1)]),e.orderNo?(l(),u("div",A,[r[3]||(r[3]=s("span",{class:"key"},"单号",-1)),s("span",F,n(e.orderNo),1)])):g("v-if",!0),e.statusText?(l(),u("div",J,[r[4]||(r[4]=s("span",{class:"key"},"状态",-1)),i(c,{color:e.statusColor},{default:v(()=>[_(n(e.statusText),1)]),_:1},8,["color"])])):g("v-if",!0)])}const H=S(k,[["render",M],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-UJ86gZ/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{H as default};
@@ -1,7 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./ChatBubbleRenderer-BUyYkAXr.js","./vendor-Bn1JzzAn.js","./index-jx7kr6mB.js","./icons-DG5UD-6K.js","./index-Cq93VfoF.css","./ChatBubbleRenderer-gy5SDGw2.css","./OrderTableRenderer-DKOoqajt.js","./OrderTableRenderer-CfrDjSHT.css","./TimelineRenderer-BK-AUuws.js","./TimelineRenderer-BlTAtkOc.css","./EmailListRenderer-CCWk1BIM.js","./EmailListRenderer-DTPZPx_S.css","./GenericCardRenderer-D2ghd_K4.js","./GenericCardRenderer-o85VDYQS.css"])))=>i.map(i=>d[i]);
2
- import{E as ue,r as R,b as w,I as y,P as u,J as O,U as v,c,S as C,V as E,_ as J,F as V,Z as se,a0 as ae,R as x,K as m,Q as b,W as L,o as M}from"./vendor-Bn1JzzAn.js";import{u as U}from"./usePersonalDataHub-CJ1VW6rh.js";import{_ as D,e as F,d as P}from"./index-jx7kr6mB.js";import{aa as q,ag as Q,M as z,aI as Z,v as G,aH as H,aq as K,ac as W,e as de,d as fe,k as pe,ai as me,aA as ge,R as _e}from"./icons-DG5UD-6K.js";import"./useShellMode-CgR0wCYM.js";const I=Object.freeze({q:"",category:null,adapter:null,subtype:null,since:null,until:null}),B=50,Y=300,X=ue("pdhBrowser",()=>{const r=R({...I}),t=R([]),n=R(null),e=R(!1),o=R(!1),a=R(null),l=R(null),s=R(!1),i=R({byCategory:{},byAdapter:{},bySubtype:{},total:0});let d=0,g=null;const j=w(()=>t.value.length>0),A=w(()=>n.value!=null);function h(S={}){const p={},f=r.value;return f.q&&f.q.trim()&&(p.q=f.q.trim()),f.category&&(p.category=f.category),f.adapter&&(p.adapter=f.adapter),f.subtype&&(p.subtype=f.subtype),Number.isFinite(f.since)&&(p.since=f.since),Number.isFinite(f.until)&&(p.until=f.until),{...p,...S}}async function _(){const S=++d;e.value=!0,a.value=null;const p=U();try{const[f,T]=await Promise.all([p.searchEvents(h({limit:B})),p.facetCounts({...r.value.q&&r.value.q.trim()?{q:r.value.q.trim()}:{},...Number.isFinite(r.value.since)?{since:r.value.since}:{},...Number.isFinite(r.value.until)?{until:r.value.until}:{}})]);if(S!==d)return;t.value=f.rows||[],n.value=f.nextCursor||null,l.value=f.mode||"like",s.value=!!f.shortQuery,i.value={byCategory:T.byCategory||{},byAdapter:T.byAdapter||{},bySubtype:T.bySubtype||{},total:T.total||0}}catch(f){if(S!==d)return;a.value=f&&f.message?f.message:String(f),t.value=[],n.value=null}finally{S===d&&(e.value=!1)}}async function k(){if(!n.value||o.value)return;o.value=!0,a.value=null;const S=U();try{const p=await S.searchEvents(h({cursor:n.value,limit:B}));t.value=t.value.concat(p.rows||[]),n.value=p.nextCursor||null,l.value=p.mode||l.value}catch(p){a.value=p&&p.message?p.message:String(p)}finally{o.value=!1}}function le(S,p){if(!(S in I))throw new Error(`pdhBrowser.setFilter: unknown key "${S}"`);r.value={...r.value,[S]:p},g&&clearTimeout(g),g=setTimeout(()=>{g=null,_()},Y)}function ie(S){return r.value={...I,...S},g&&(clearTimeout(g),g=null),_()}function ce(){r.value={...I},t.value=[],n.value=null,a.value=null,i.value={byCategory:{},byAdapter:{},bySubtype:{},total:0}}return{filters:r,results:t,cursor:n,isLoading:e,isAppending:o,error:a,mode:l,shortQuery:s,facets:i,hasResults:j,canLoadMore:A,search:_,loadMore:k,setFilter:le,setFilters:ie,reset:ce,PAGE_SIZE:B,SEARCH_DEBOUNCE_MS:Y}}),ye=Object.freeze(["chat","social","email","shopping","travel","system","ai-chat","other"]),ve=Object.freeze({chat:"社交聊天",social:"内容平台",email:"邮件",shopping:"支付订单",travel:"出行",system:"系统数据","ai-chat":"AI 对话",other:"其他"});function N(r){return ve[r]||r||"未知"}const be=Object.freeze([["wechat","chat"],["messaging-","chat"],["social-","social"],["email-","email"],["shopping-","shopping"],["alipay-","shopping"],["travel-","travel"],["system-data","system"],["browser-","system"],["meeting-","system"],["vscode","system"],["vscodium","system"],["jetbrains-ide","system"],["win-recent","system"],["git-activity","system"],["shell-history","system"],["hbuilderx","system"],["local-files","system"],["cursor","ai-chat"],["claude-code","ai-chat"],["ai-chat-","ai-chat"]]);function $(r){if(typeof r!="string"||r.length===0)return"other";for(const[t,n]of be)if(t.endsWith("-")||t==="system-data"){if(r.startsWith(t))return n}else if(r===t)return n;return"other"}const he={__name:"CategorySidebar",props:{selected:{type:String,default:null},facets:{type:Object,default:()=>({byCategory:{},total:0})}},emits:["select"],setup(r,{expose:t}){t();const n=r,e=w(()=>n.facets.total||0),o={chat:W,social:K,email:H,shopping:G,travel:Z,system:z,"ai-chat":Q,other:q};function a(i){return o[i]||q}function l(i){return i?{backgroundColor:"#fff",color:"#1677ff"}:{backgroundColor:"#f0f0f0",color:"#666"}}const s={props:n,total:e,ICONS:o,iconFor:a,badgeStyle:l,computed:w,get AppstoreOutlined(){return q},get MessageOutlined(){return W},get PlayCircleOutlined(){return K},get MailOutlined(){return H},get ShoppingOutlined(){return G},get CarOutlined(){return Z},get MobileOutlined(){return z},get RobotOutlined(){return Q},get CATEGORIES(){return ye},get categoryLabel(){return N}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},Se={class:"pdh-sidebar"},Oe=["onClick"],we={class:"label"};function Ce(r,t,n,e,o,a){const l=y("a-badge");return u(),O("div",Se,[t[2]||(t[2]=v("div",{class:"sidebar-title"},"数据类型",-1)),v("div",{class:J(["cat-item",{active:n.selected===null}]),onClick:t[0]||(t[0]=s=>r.$emit("select",null))},[c(e.AppstoreOutlined,{class:"icon"}),t[1]||(t[1]=v("span",{class:"label"},"全部",-1)),e.total>0?(u(),C(l,{key:0,count:e.total,"number-style":e.badgeStyle(n.selected===null),"overflow-count":9999},null,8,["count","number-style"])):E("v-if",!0)],2),(u(!0),O(V,null,se(e.CATEGORIES,s=>(u(),O("div",{key:s,class:J(["cat-item",{active:n.selected===s,dim:!n.facets.byCategory[s]}]),onClick:i=>r.$emit("select",s)},[(u(),C(ae(e.iconFor(s)),{class:"icon"})),v("span",we,x(e.categoryLabel(s)),1),n.facets.byCategory[s]?(u(),C(l,{key:0,count:n.facets.byCategory[s],"number-style":e.badgeStyle(n.selected===s),"overflow-count":9999},null,8,["count","number-style"])):E("v-if",!0)],10,Oe))),128))])}const ke=D(he,[["render",Ce],["__scopeId","data-v-6b62a22e"],["__file","/tmp/cc-web-panel-UJ86gZ/repo/packages/web-panel/src/components/pdh/CategorySidebar.vue"]]),Ee={__name:"SearchFilterBar",props:{filters:{type:Object,required:!0},facets:{type:Object,default:()=>({byAdapter:{}})},isLoading:{type:Boolean,default:!1},mode:{type:String,default:null},shortQuery:{type:Boolean,default:!1}},emits:["set-filter","reset"],setup(r,{expose:t,emit:n}){t();const e=r,o=n,a=w(()=>e.filters.category?`在「${e.filters.category}」类目内搜索…`:"搜索关键词(如:支付宝、罗技、Kotlin)…"),l=w(()=>Object.entries(e.facets.byAdapter||{}).sort((_,k)=>k[1]-_[1]).map(([_,k])=>({value:_,label:`${_} (${k})`}))),s=w(()=>!e.filters.since&&!e.filters.until?null:[e.filters.since?new Date(e.filters.since):null,e.filters.until?new Date(e.filters.until):null]),i=w(()=>!!(e.filters.q||e.filters.adapter||e.filters.subtype||e.filters.since||e.filters.until));function d(h){o("set-filter","q",h||"")}function g(h){o("set-filter","q",h||"")}function j(h){if(!h||h.length===0){o("set-filter","since",null),o("set-filter","until",null);return}const[_,k]=h;o("set-filter","since",_?+_:null),o("set-filter","until",k?+k:null)}const A={props:e,emit:o,placeholderText:a,adapterOptions:l,dateRangeValue:s,hasActiveFilters:i,onQInput:d,onSearch:g,onDateChange:j,computed:w,get SearchOutlined(){return pe},get CloseCircleOutlined(){return fe},get InfoCircleOutlined(){return de}};return Object.defineProperty(A,"__isScriptSetup",{enumerable:!1,value:!0}),A}},Re={class:"pdh-filter-bar"},xe={key:1,class:"hint"},je={key:2,class:"hint"};function Ae(r,t,n,e,o,a){const l=y("a-input-search"),s=y("a-select"),i=y("a-range-picker"),d=y("a-button");return u(),O("div",Re,[c(l,{value:n.filters.q,placeholder:e.placeholderText,"enter-button":"搜索","allow-clear":"",loading:n.isLoading,style:{flex:"1","max-width":"480px"},"onUpdate:value":e.onQInput,onSearch:e.onSearch},{prefix:m(()=>[c(e.SearchOutlined)]),_:1},8,["value","placeholder","loading"]),c(s,{value:n.filters.adapter,placeholder:"所有 adapter","allow-clear":"",options:e.adapterOptions,style:{width:"200px"},"onUpdate:value":t[0]||(t[0]=g=>r.$emit("set-filter","adapter",g||null))},null,8,["value","options"]),c(i,{value:e.dateRangeValue,placeholder:["开始日期","结束日期"],style:{width:"280px"},"onUpdate:value":e.onDateChange},null,8,["value"]),e.hasActiveFilters?(u(),C(d,{key:0,type:"link",danger:"",onClick:t[1]||(t[1]=g=>r.$emit("reset"))},{icon:m(()=>[c(e.CloseCircleOutlined)]),default:m(()=>[t[2]||(t[2]=b(" 清空筛选 ",-1))]),_:1})):E("v-if",!0),n.shortQuery?(u(),O("span",xe,[c(e.InfoCircleOutlined),t[3]||(t[3]=b(" 关键词需至少 3 字 (FTS5 trigram 限制) ",-1))])):n.mode==="like"?(u(),O("span",je,[c(e.InfoCircleOutlined),t[4]||(t[4]=b(" 当前为 LIKE 兜底模式 ",-1))])):E("v-if",!0)])}const Le=D(Ee,[["render",Ae],["__scopeId","data-v-d7cce6e9"],["__file","/tmp/cc-web-panel-UJ86gZ/repo/packages/web-panel/src/components/pdh/SearchFilterBar.vue"]]),Fe={__name:"RendererDispatcher",props:{event:{type:Object,required:!0}},setup(r,{expose:t}){t();const n=L(()=>F(()=>import("./ChatBubbleRenderer-BUyYkAXr.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url)),e=L(()=>F(()=>import("./OrderTableRenderer-DKOoqajt.js"),__vite__mapDeps([6,1,2,3,4,7]),import.meta.url)),o=L(()=>F(()=>import("./TimelineRenderer-BK-AUuws.js"),__vite__mapDeps([8,1,2,3,4,9]),import.meta.url)),a=L(()=>F(()=>import("./EmailListRenderer-CCWk1BIM.js"),__vite__mapDeps([10,1,2,3,4,11]),import.meta.url)),l=L(()=>F(()=>import("./GenericCardRenderer-D2ghd_K4.js"),__vite__mapDeps([12,1,2,3,4,13]),import.meta.url));function s(d){const g=d&&d.source&&d.source.adapter;switch($(g)){case"chat":case"ai-chat":return n;case"shopping":return e;case"travel":return o;case"email":return a;default:return l}}const i={ChatBubbleRenderer:n,OrderTableRenderer:e,TimelineRenderer:o,EmailListRenderer:a,GenericCardRenderer:l,rendererFor:s,defineAsyncComponent:L,get getCategory(){return $}};return Object.defineProperty(i,"__isScriptSetup",{enumerable:!1,value:!0}),i}};function De(r,t,n,e,o,a){return u(),C(ae(e.rendererFor(n.event)),{event:n.event},null,8,["event"])}const Te=D(Fe,[["render",De],["__file","/tmp/cc-web-panel-UJ86gZ/repo/packages/web-panel/src/components/pdh/renderers/RendererDispatcher.vue"]]);function ee(r){return JSON.stringify(r,null,2)}function te(r){return r.map(t=>JSON.stringify(t)).join(`
3
- `)+`
4
- `}function ne(r){const n=["id","subtype","occurredAt","occurredAtIso","actor","place","adapter","summary","contentJson","extraJson"].join(","),e=r.map(o=>{const a=Number.isFinite(o.occurredAt)?o.occurredAt:null,l=a?new Date(a).toISOString():"",s=o.source&&o.source.adapter||"",i=o.content&&(o.content.text||o.content.title||o.content.subject)||"";return[o.id||"",o.subtype||"",a!=null?String(a):"",l,o.actor||"",o.place||"",s,i,o.content?JSON.stringify(o.content):"",o.extra?JSON.stringify(o.extra):""].map(Ie).join(",")});return[n,...e].join(`
5
- `)+`
6
- `}function Ie(r){const t=String(r??"");return t.includes(",")||t.includes('"')||t.includes(`
7
- `)||t.includes("\r")?'"'+t.replace(/"/g,'""')+'"':t}function re(r,t,n="application/octet-stream"){if(typeof window>"u"||typeof document>"u")return t;const e=new Blob([r],{type:n}),o=URL.createObjectURL(e),a=document.createElement("a");return a.href=o,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),setTimeout(()=>URL.revokeObjectURL(o),1e3),t}function oe(r,t=null){const n=new Date,e=n.getFullYear(),o=String(n.getMonth()+1).padStart(2,"0"),a=String(n.getDate()).padStart(2,"0"),l=r==="ndjson"?"ndjson":r,s=t?`-${t}`:"";return`pdh-events-${e}-${o}-${a}${s}.${l}`}const Pe={__name:"ExportDropdown",props:{events:{type:Array,required:!0},category:{type:String,default:null}},setup(r,{expose:t}){t();const n=r,e=w(()=>n.events.length>0),o={json:"application/json;charset=utf-8",ndjson:"application/x-ndjson;charset=utf-8",csv:"text/csv;charset=utf-8"};function a(i){switch(i){case"json":return ee(n.events);case"ndjson":return te(n.events);case"csv":return ne(n.events);default:throw new Error(`unknown format: ${i}`)}}function l({key:i}){try{const d=a(i),g=oe(i,n.category);re(d,g,o[i]),P.success(`已导出 ${n.events.length} 条到 ${g}`)}catch(d){P.error(`导出失败: ${d.message||d}`)}}const s={props:n,hasResults:e,MIME:o,serialize:a,onClick:l,computed:w,get DownloadOutlined(){return ge},get DownOutlined(){return me},get message(){return P},get eventsToJson(){return ee},get eventsToNdjson(){return te},get eventsToCsv(){return ne},get downloadAs(){return re},get suggestFilename(){return oe}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}};function qe(r,t,n,e,o,a){const l=y("a-button"),s=y("a-menu-item"),i=y("a-menu"),d=y("a-dropdown");return u(),C(d,{disabled:!e.hasResults},{overlay:m(()=>[c(i,{onClick:e.onClick},{default:m(()=>[c(s,{key:"json"},{default:m(()=>[...t[0]||(t[0]=[b("JSON (.json)",-1)])]),_:1}),c(s,{key:"ndjson"},{default:m(()=>[...t[1]||(t[1]=[b("NDJSON (.ndjson)",-1)])]),_:1}),c(s,{key:"csv"},{default:m(()=>[...t[2]||(t[2]=[b("CSV (.csv)",-1)])]),_:1})]),_:1})]),default:m(()=>[c(l,{disabled:!e.hasResults},{icon:m(()=>[c(e.DownloadOutlined)]),default:m(()=>[b(" 导出 ("+x(n.events.length)+") ",1),c(e.DownOutlined)]),_:1},8,["disabled"])]),_:1},8,["disabled"])}const Be=D(Pe,[["render",qe],["__file","/tmp/cc-web-panel-UJ86gZ/repo/packages/web-panel/src/components/pdh/ExportDropdown.vue"]]),Ve={__name:"PdhVaultBrowser",setup(r,{expose:t}){t();const n=X(),e=w(()=>n.filters.q?`没有匹配 "${n.filters.q}" 的事件 — 试试更短的关键词或换个类目`:n.filters.category?`「${N(n.filters.category)}」类目下还没有数据 — 去采集页同步对应 adapter`:"Vault 里还没有数据 — 去「个人数据中台」页面同步任意 adapter");function o(s){n.filters.category=s,n.search()}function a(s,i){n.setFilter(s,i)}M(()=>{!n.hasResults&&!n.isLoading&&n.search()});const l={store:n,emptyHint:e,onCategorySelect:o,onSetFilter:a,onMounted:M,computed:w,get ReloadOutlined(){return _e},get usePdhBrowserStore(){return X},get categoryLabel(){return N},CategorySidebar:ke,SearchFilterBar:Le,RendererDispatcher:Te,ExportDropdown:Be};return Object.defineProperty(l,"__isScriptSetup",{enumerable:!1,value:!0}),l}},Ne={class:"pdh-browser-page"},Je={class:"page-header"},Me={class:"main-pane"},Ue={class:"results-summary"},Qe={key:0},ze={key:0},Ze={key:1},Ge={class:"loaded-of"},He={class:"results-list"},Ke={key:2,class:"load-more"};function We(r,t,n,e,o,a){const l=y("a-tag"),s=y("a-button"),i=y("a-space"),d=y("a-col"),g=y("a-spin"),j=y("a-alert"),A=y("a-empty"),h=y("a-row");return u(),O("div",Ne,[v("div",Je,[t[6]||(t[6]=v("div",null,[v("h2",{class:"page-title"},"数据浏览器"),v("p",{class:"page-sub"}," Vault 里所有已采集的数据,按类目浏览 / 全文检索 / 时间窗口筛选。 完全离线,不外传。 ")],-1)),c(i,null,{default:m(()=>[e.store.mode==="fts5"?(u(),C(l,{key:0,color:"green"},{default:m(()=>[...t[3]||(t[3]=[b("FTS5 trigram",-1)])]),_:1})):e.store.mode==="like"?(u(),C(l,{key:1,color:"orange"},{default:m(()=>[...t[4]||(t[4]=[b("LIKE 兜底",-1)])]),_:1})):E("v-if",!0),c(e.ExportDropdown,{events:e.store.results,category:e.store.filters.category},null,8,["events","category"]),c(s,{onClick:t[0]||(t[0]=_=>e.store.search()),loading:e.store.isLoading},{icon:m(()=>[c(e.ReloadOutlined)]),default:m(()=>[t[5]||(t[5]=b(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),c(h,{gutter:16,class:"browser-layout"},{default:m(()=>[c(d,{xs:24,sm:24,md:6,lg:5,xl:4},{default:m(()=>[c(e.CategorySidebar,{selected:e.store.filters.category,facets:e.store.facets,onSelect:e.onCategorySelect},null,8,["selected","facets"])]),_:1}),c(d,{xs:24,sm:24,md:18,lg:19,xl:20},{default:m(()=>[v("div",Me,[c(e.SearchFilterBar,{filters:e.store.filters,facets:e.store.facets,"is-loading":e.store.isLoading,mode:e.store.mode,"short-query":e.store.shortQuery,onSetFilter:e.onSetFilter,onReset:t[1]||(t[1]=_=>{e.store.reset(),e.store.search()})},null,8,["filters","facets","is-loading","mode","short-query"]),v("div",Ue,[e.store.isLoading&&e.store.results.length===0?(u(),O("span",Qe,[c(g,{size:"small"}),t[7]||(t[7]=b(" 载入中… ",-1))])):(u(),O(V,{key:1},[v("strong",null,x(e.store.facets.total),1),t[11]||(t[11]=b(" 条事件 ",-1)),e.store.filters.category?(u(),O("span",ze,[t[8]||(t[8]=b(" / 当前类目 ",-1)),v("strong",null,x(e.categoryLabel(e.store.filters.category)),1),v("strong",null,x(e.store.facets.byCategory[e.store.filters.category]||0),1)])):E("v-if",!0),e.store.filters.q?(u(),O("span",Ze,[t[9]||(t[9]=b(' / 关键词 "',-1)),v("em",null,x(e.store.filters.q),1),t[10]||(t[10]=b('"',-1))])):E("v-if",!0),v("span",Ge," / 已显示 "+x(e.store.results.length),1)],64))]),e.store.error?(u(),C(j,{key:0,type:"error","show-icon":"",message:e.store.error,closable:"",style:{margin:"12px 0"}},null,8,["message"])):E("v-if",!0),!e.store.isLoading&&e.store.results.length===0&&!e.store.error?(u(),C(A,{key:1,description:e.emptyHint,style:{"margin-top":"40px"}},null,8,["description"])):E("v-if",!0),v("div",He,[(u(!0),O(V,null,se(e.store.results,(_,k)=>(u(),C(e.RendererDispatcher,{key:`r-${k}-${_.id}`,event:_},null,8,["event"]))),128))]),e.store.canLoadMore?(u(),O("div",Ke,[c(s,{loading:e.store.isAppending,onClick:t[2]||(t[2]=_=>e.store.loadMore()),block:""},{default:m(()=>[...t[12]||(t[12]=[b(" 加载下一页 (50 条) ",-1)])]),_:1},8,["loading"])])):E("v-if",!0)])]),_:1})]),_:1})])}const nt=D(Ve,[["render",We],["__scopeId","data-v-0f7c02cd"],["__file","/tmp/cc-web-panel-UJ86gZ/repo/packages/web-panel/src/views/PdhVaultBrowser.vue"]]);export{nt as default};
@@ -1 +0,0 @@
1
- import{I as i,J as A,U as I,R as s,Q as r,c as t,K as a,V as _,S as x,o as oe,b as ee,r as u,P as p,F as ne,a2 as ge}from"./vendor-Bn1JzzAn.js";import{_ as we,b as re,u as ie,d}from"./index-jx7kr6mB.js";import{u as de}from"./useShellMode-CgR0wCYM.js";import{aN as ke,aO as Fe,aP as be,f as je,a5 as Ce,a8 as xe,at as Oe,R as Se}from"./icons-DG5UD-6K.js";const Pe={__name:"Projects",setup(se,{expose:l}){l();const{t:te}=re(),e=ie(),{isEmbedded:J}=de();async function w(o,f,ye,ae=8e3){if(J){const Y=await e.sendRaw({...f,type:o},ae);if(!Y?.ok){const $=Y?.error;throw new Error(typeof $=="string"?$:$?.message||`${o} failed`)}return Y.result}return e.executeJson(ye,ae)}const B=u(!1),y=u([]),O=u(""),S=u(""),P=u(!1),v=u(null),h=u([]),k=u(!1),E=u(!1),L=u(!1),F=u({name:"",description:"",type:"document",rootPath:""}),z=[{title:"ID",key:"id",width:110},{title:"名称",key:"name"},{title:"类型",key:"project_type",width:120},{title:"状态",key:"status",width:100},{title:"同步",key:"sync_status",width:100},{title:"更新",key:"updated_at",width:160},{title:"操作",key:"actions",width:180,fixed:"right"}],V=ee(()=>{const o={active:0,draft:0,completed:0,archived:0};for(const f of y.value)o[f.status]!==void 0&&(o[f.status]+=1);return o}),W=ee(()=>y.value.filter(o=>!(O.value&&o.status!==O.value||S.value&&!o.name.toLowerCase().includes(S.value.toLowerCase()))));function g(o){switch(o){case"active":return"green";case"draft":return"default";case"completed":return"cyan";case"archived":return"gold";default:return"default"}}function K(o){switch(o){case"synced":return"green";case"pending":return"orange";case"conflict":return"red";case"error":return"red";default:return"default"}}function Q(o){return!o&&o!==0?"-":new Date(typeof o=="number"?o:parseInt(o,10)).toLocaleString("zh-CN",{hour12:!1})}async function C(){B.value=!0;try{const o=await w("project.list",{limit:500},"project list --limit 500 --json",1e4);y.value=Array.isArray(o?.projects)?o.projects:Array.isArray(o)?o:[]}catch(o){d.error("加载失败: "+(o.message||o)),y.value=[]}finally{B.value=!1}}function Z(o){return{onClick:()=>M(o)}}async function M(o){v.value=o,P.value=!0,k.value=!0,h.value=[];try{const f=await w("project.listFiles",{projectId:o.id,limit:200},`project list-files ${o.id} --json`,8e3);h.value=Array.isArray(f?.files)?f.files:[]}catch{h.value=[]}finally{k.value=!1}}async function G(o){try{(await w("project.delete",{id:o.id},`project delete ${o.id} --json`,8e3))?.ok?(d.success(`已删除项目 '${o.name}'`),P.value=!1,await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}function H(){F.value={name:"",description:"",type:"document",rootPath:""},E.value=!0}async function T(){if(!F.value.name.trim()){d.warning("请输入项目名称");return}L.value=!0;try{const o=await w("project.init",{name:F.value.name.trim(),description:F.value.description||null,projectType:F.value.type,rootPath:F.value.rootPath||null},`project init "${F.value.name.trim()}" --type ${F.value.type} --json`,8e3);o?.id?(d.success(`已创建项目 '${o.name}'`),E.value=!1,await C()):d.error("创建失败")}catch(o){d.error(o.message||String(o))}finally{L.value=!1}}const b=u(!1),D=u(!1),j=u({path:"",content:""}),U=u(!1),m=u(!1),R=u({path:""}),n=u(!1),c=u(null),q=u(""),X=u(!1);function ue(){j.value={path:"",content:""},b.value=!0}function ce(){R.value={path:""},U.value=!0}async function N(){if(v.value){k.value=!0;try{const o=await w("project.listFiles",{projectId:v.value.id,limit:200},`project list-files ${v.value.id} --json`,8e3);h.value=Array.isArray(o?.files)?o.files:[]}catch(o){d.error("刷新文件失败: "+(o.message||o))}finally{k.value=!1}}}async function fe(){if(!j.value.path.trim()){d.warning("请输入文件路径");return}if(v.value){D.value=!0;try{const o=await w("project.createFile",{projectId:v.value.id,filePath:j.value.path.trim(),content:j.value.content||""},`project create-file ${v.value.id} "${j.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件 '${o.file_name}'`),b.value=!1,await N(),await C()):d.error("创建文件失败")}catch(o){d.error(o.message||String(o))}finally{D.value=!1}}}async function pe(){if(!R.value.path.trim()){d.warning("请输入文件夹路径");return}if(v.value){m.value=!0;try{const o=await w("project.createFolder",{projectId:v.value.id,folderPath:R.value.path.trim()},`project create-folder ${v.value.id} "${R.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件夹 '${o.file_name}'`),U.value=!1,await N(),await C()):d.error("创建文件夹失败")}catch(o){d.error(o.message||String(o))}finally{m.value=!1}}}async function ve(o){try{(await w("project.deleteFile",{fileId:o.id},`project delete-file ${o.id} --json`,8e3))?.deleted?(d.success(`已删除 '${o.file_name}'`),await N(),await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}async function me(o){if(o.is_folder){d.info("文件夹无内容可编辑");return}try{const f=await w("project.getFile",{fileId:o.id},`project get-file ${o.id} --json`,8e3);c.value=o,q.value=f?.content||"",n.value=!0}catch(f){d.error("读取文件失败: "+(f.message||f))}}async function _e(){if(c.value){X.value=!0;try{(await w("project.writeFile",{fileId:c.value.id,content:q.value},`project write-file ${c.value.id} --json`,8e3))?.id?(d.success("已保存"),n.value=!1,await N()):d.error("保存失败")}catch(o){d.error(o.message||String(o))}finally{X.value=!1}}}oe(()=>{C()});const le={t:te,ws:e,isEmbedded:J,callProjectTopic:w,loading:B,projects:y,statusFilter:O,nameFilter:S,detailOpen:P,detail:v,files:h,filesLoading:k,createOpen:E,creating:L,newProject:F,columns:z,countByStatus:V,filteredProjects:W,statusColor:g,syncColor:K,formatTime:Q,loadAll:C,onRowClick:Z,openDetail:M,onDelete:G,onShowCreate:H,onCreate:T,createFileOpen:b,creatingFile:D,newFile:j,createFolderOpen:U,creatingFolder:m,newFolder:R,editFileOpen:n,editingFile:c,editFileContent:q,savingFile:X,openCreateFile:ue,openCreateFolder:ce,refreshFiles:N,onCreateFile:fe,onCreateFolder:pe,onDeleteFile:ve,openEditFile:me,onSaveFile:_e,ref:u,computed:ee,onMounted:oe,get ReloadOutlined(){return Se},get PlusOutlined(){return Oe},get FolderOutlined(){return xe},get FileTextOutlined(){return Ce},get CheckCircleOutlined(){return je},get CheckSquareOutlined(){return be},get FileAddOutlined(){return Fe},get FolderAddOutlined(){return ke},get message(){return d},get useI18n(){return re},get useWsStore(){return ie},get useShellMode(){return de}};return Object.defineProperty(le,"__isScriptSetup",{enumerable:!1,value:!0}),le}},ze={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},Ue={class:"page-title"},Ae={class:"page-sub"},Ie={class:"filter-bar",style:{"margin-bottom":"12px",display:"flex",gap:"12px","align-items":"center"}},he={key:0,style:{"font-size":"12px",color:"#888"}},De={key:0,style:{color:"#888","font-size":"12px"}},Re={key:0},Te={key:1,style:{color:"#888"}},Be=["onClick"],Ee={key:0,style:{color:"#888","font-size":"12px"}};function Le(se,l,te,e,J,w){const B=i("router-link"),y=i("a-button"),O=i("a-space"),S=i("a-statistic"),P=i("a-card"),v=i("a-col"),h=i("a-row"),k=i("a-radio-button"),E=i("a-radio-group"),L=i("a-input-search"),F=i("a-alert"),z=i("a-tag"),V=i("a-popconfirm"),W=i("a-table"),g=i("a-descriptions-item"),K=i("a-descriptions"),Q=i("a-divider"),C=i("a-empty"),Z=i("a-list-item"),M=i("a-list"),G=i("a-spin"),H=i("a-drawer"),T=i("a-input"),b=i("a-form-item"),D=i("a-textarea"),j=i("a-form"),U=i("a-modal"),m=i("a-select-option"),R=i("a-select");return p(),A("div",null,[I("div",ze,[I("div",null,[I("h2",Ue,s(e.t("projects.title")),1),I("p",Ae,[l[17]||(l[17]=r("桌面 / CLI / 手机 三端共享同一份项目数据,Phase 3d sync 自动同步 (",-1)),t(B,{to:"/project-init"},{default:a(()=>[...l[16]||(l[16]=[r("项目初始化 / 环境设置",-1)])]),_:1}),l[18]||(l[18]=r(")",-1))])]),t(O,null,{default:a(()=>[t(y,{loading:e.loading,onClick:e.loadAll},{icon:a(()=>[t(e.ReloadOutlined)]),default:a(()=>[l[19]||(l[19]=r(" 刷新 ",-1))]),_:1},8,["loading"]),t(y,{type:"primary",onClick:e.onShowCreate},{icon:a(()=>[t(e.PlusOutlined)]),default:a(()=>[l[20]||(l[20]=r(" 新建项目 ",-1))]),_:1})]),_:1})]),_(" Stats "),t(h,{gutter:[16,16],style:{"margin-bottom":"20px"}},{default:a(()=>[t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"总项目",value:e.projects.length,"value-style":{color:"#1677ff",fontSize:"20px"}},{prefix:a(()=>[t(e.FolderOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"活跃",value:e.countByStatus.active,"value-style":{color:"#52c41a",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckCircleOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"草稿",value:e.countByStatus.draft,"value-style":{color:"#8c8c8c",fontSize:"20px"}},{prefix:a(()=>[t(e.FileTextOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"已完成",value:e.countByStatus.completed,"value-style":{color:"#13c2c2",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckSquareOutlined)]),_:1},8,["value"])]),_:1})]),_:1})]),_:1}),_(" Filter "),I("div",Ie,[t(E,{value:e.statusFilter,"onUpdate:value":l[0]||(l[0]=n=>e.statusFilter=n),size:"small","button-style":"solid"},{default:a(()=>[t(k,{value:""},{default:a(()=>[...l[21]||(l[21]=[r("全部",-1)])]),_:1}),t(k,{value:"active"},{default:a(()=>[...l[22]||(l[22]=[r("活跃",-1)])]),_:1}),t(k,{value:"draft"},{default:a(()=>[...l[23]||(l[23]=[r("草稿",-1)])]),_:1}),t(k,{value:"completed"},{default:a(()=>[...l[24]||(l[24]=[r("已完成",-1)])]),_:1}),t(k,{value:"archived"},{default:a(()=>[...l[25]||(l[25]=[r("已归档",-1)])]),_:1})]),_:1},8,["value"]),t(L,{value:e.nameFilter,"onUpdate:value":l[1]||(l[1]=n=>e.nameFilter=n),placeholder:"按名称过滤",style:{"max-width":"260px"},"allow-clear":""},null,8,["value"])]),!e.projects.length&&!e.loading?(p(),x(F,{key:0,type:"info",message:"还没有项目",description:'运行 `cc project init <name>` 或点击右上角"新建项目"按钮创建。桌面 / CLI / 手机三端共享同一份数据。',"show-icon":"",style:{"margin-bottom":"16px"}})):_("v-if",!0),e.projects.length||e.loading?(p(),x(W,{key:1,columns:e.columns,"data-source":e.filteredProjects,loading:e.loading,pagination:{pageSize:20,showSizeChanger:!0},"row-key":"id","custom-row":e.onRowClick},{bodyCell:a(({column:n,record:c})=>[n.key==="id"?(p(),A("code",he,s(c.id.slice(0,8))+"…",1)):n.key==="name"?(p(),A(ne,{key:1},[I("strong",null,s(c.name),1),c.description?(p(),A("div",De,s(c.description),1)):_("v-if",!0)],64)):n.key==="project_type"?(p(),x(z,{key:2},{default:a(()=>[r(s(c.project_type),1)]),_:2},1024)):n.key==="status"?(p(),x(z,{key:3,color:e.statusColor(c.status)},{default:a(()=>[r(s(c.status),1)]),_:2},1032,["color"])):n.key==="sync_status"?(p(),x(z,{key:4,color:e.syncColor(c.sync_status)},{default:a(()=>[r(s(c.sync_status||"unknown"),1)]),_:2},1032,["color"])):n.key==="updated_at"?(p(),A(ne,{key:5},[r(s(e.formatTime(c.updated_at)),1)],64)):n.key==="actions"?(p(),x(O,{key:6,onClick:l[2]||(l[2]=ge(()=>{},["stop"]))},{default:a(()=>[t(y,{size:"small",onClick:q=>e.openDetail(c)},{default:a(()=>[...l[26]||(l[26]=[r("详情",-1)])]),_:1},8,["onClick"]),t(V,{title:`删除项目 '${c.name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:q=>e.onDelete(c)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[27]||(l[27]=[r("删除",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)):_("v-if",!0)]),_:1},8,["data-source","loading"])):_("v-if",!0),_(" Detail drawer "),t(H,{open:e.detailOpen,"onUpdate:open":l[3]||(l[3]=n=>e.detailOpen=n),title:e.detail?.name||"项目详情",width:"640",placement:"right"},{default:a(()=>[e.detail?(p(),x(K,{key:0,column:1,bordered:"",size:"small"},{default:a(()=>[t(g,{label:"ID"},{default:a(()=>[I("code",null,s(e.detail.id),1)]),_:1}),t(g,{label:"名称"},{default:a(()=>[r(s(e.detail.name),1)]),_:1}),t(g,{label:"描述"},{default:a(()=>[r(s(e.detail.description||"-"),1)]),_:1}),t(g,{label:"类型"},{default:a(()=>[t(z,null,{default:a(()=>[r(s(e.detail.project_type),1)]),_:1})]),_:1}),t(g,{label:"状态"},{default:a(()=>[t(z,{color:e.statusColor(e.detail.status)},{default:a(()=>[r(s(e.detail.status),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"同步状态"},{default:a(()=>[t(z,{color:e.syncColor(e.detail.sync_status)},{default:a(()=>[r(s(e.detail.sync_status||"unknown"),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"用户"},{default:a(()=>[r(s(e.detail.user_id),1)]),_:1}),t(g,{label:"根路径"},{default:a(()=>[e.detail.root_path?(p(),A("code",Re,s(e.detail.root_path),1)):(p(),A("span",Te,"(无)"))]),_:1}),t(g,{label:"文件数"},{default:a(()=>[r(s(e.detail.file_count||0),1)]),_:1}),t(g,{label:"创建"},{default:a(()=>[r(s(e.formatTime(e.detail.created_at)),1)]),_:1}),t(g,{label:"更新"},{default:a(()=>[r(s(e.formatTime(e.detail.updated_at)),1)]),_:1})]),_:1})):_("v-if",!0),t(Q,null,{default:a(()=>[...l[28]||(l[28]=[r("文件",-1)])]),_:1}),_(" Sub-phase 7.3 (2026-05-17): 文件 CRUD toolbar "),t(O,{style:{"margin-bottom":"12px"}},{default:a(()=>[t(y,{size:"small",type:"primary",disabled:!e.detail,onClick:e.openCreateFile},{default:a(()=>[t(e.FileAddOutlined),l[29]||(l[29]=r(" 新建文件 ",-1))]),_:1},8,["disabled"]),t(y,{size:"small",disabled:!e.detail,onClick:e.openCreateFolder},{default:a(()=>[t(e.FolderAddOutlined),l[30]||(l[30]=r(" 新建文件夹 ",-1))]),_:1},8,["disabled"])]),_:1}),t(G,{spinning:e.filesLoading},{default:a(()=>[!e.files.length&&!e.filesLoading?(p(),x(C,{key:0,description:"无文件 (点上方按钮新建)"})):(p(),x(M,{key:1,size:"small","data-source":e.files},{renderItem:a(({item:n})=>[t(Z,null,{extra:a(()=>[t(O,null,{default:a(()=>[n.file_size?(p(),A("span",Ee,s(n.file_size)+" B",1)):_("v-if",!0),t(V,{title:`删除 ${n.is_folder?"文件夹":"文件"} '${n.file_name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:c=>e.onDeleteFile(n)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[31]||(l[31]=[r("×",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)]),default:a(()=>[I("span",{style:{cursor:"pointer"},onClick:c=>e.openEditFile(n)},s(n.is_folder?"📁":"📄")+" "+s(n.file_path),9,Be)]),_:2},1024)]),_:1},8,["data-source"]))]),_:1},8,["spinning"])]),_:1},8,["open","title"]),_(" Sub-phase 7.3: Create file modal "),t(U,{open:e.createFileOpen,"onUpdate:open":l[6]||(l[6]=n=>e.createFileOpen=n),title:"新建文件","confirm-loading":e.creatingFile,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFile},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"文件路径(项目内)",required:""},{default:a(()=>[t(T,{value:e.newFile.path,"onUpdate:value":l[4]||(l[4]=n=>e.newFile.path=n),placeholder:"例如 README.md 或 src/main.kt"},null,8,["value"])]),_:1}),t(b,{label:"初始内容(可选)"},{default:a(()=>[t(D,{value:e.newFile.content,"onUpdate:value":l[5]||(l[5]=n=>e.newFile.content=n),rows:6,placeholder:"留空创建空文件"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Create folder modal "),t(U,{open:e.createFolderOpen,"onUpdate:open":l[8]||(l[8]=n=>e.createFolderOpen=n),title:"新建文件夹","confirm-loading":e.creatingFolder,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFolder},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"文件夹路径(项目内)",required:""},{default:a(()=>[t(T,{value:e.newFolder.path,"onUpdate:value":l[7]||(l[7]=n=>e.newFolder.path=n),placeholder:"例如 src/utils"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Edit file content modal "),t(U,{open:e.editFileOpen,"onUpdate:open":l[10]||(l[10]=n=>e.editFileOpen=n),title:`编辑 ${e.editingFile?.file_name||""}`,"confirm-loading":e.savingFile,"ok-text":"保存","cancel-text":"取消",onOk:e.onSaveFile,width:"720"},{default:a(()=>[t(D,{value:e.editFileContent,"onUpdate:value":l[9]||(l[9]=n=>e.editFileContent=n),rows:18,"auto-size":{minRows:12,maxRows:24},style:{"font-family":"monospace"}},null,8,["value"])]),_:1},8,["open","title","confirm-loading"]),_(" Create modal "),t(U,{open:e.createOpen,"onUpdate:open":l[15]||(l[15]=n=>e.createOpen=n),title:"新建项目","confirm-loading":e.creating,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreate},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"项目名称",required:""},{default:a(()=>[t(T,{value:e.newProject.name,"onUpdate:value":l[11]||(l[11]=n=>e.newProject.name=n),placeholder:"例如:旅行计划-上海"},null,8,["value"])]),_:1}),t(b,{label:"描述"},{default:a(()=>[t(D,{value:e.newProject.description,"onUpdate:value":l[12]||(l[12]=n=>e.newProject.description=n),rows:2},null,8,["value"])]),_:1}),t(b,{label:"类型"},{default:a(()=>[t(R,{value:e.newProject.type,"onUpdate:value":l[13]||(l[13]=n=>e.newProject.type=n)},{default:a(()=>[t(m,{value:"document"},{default:a(()=>[...l[32]||(l[32]=[r("文档 (document)",-1)])]),_:1}),t(m,{value:"data"},{default:a(()=>[...l[33]||(l[33]=[r("数据 (data)",-1)])]),_:1}),t(m,{value:"web"},{default:a(()=>[...l[34]||(l[34]=[r("Web",-1)])]),_:1}),t(m,{value:"app"},{default:a(()=>[...l[35]||(l[35]=[r("应用 (app)",-1)])]),_:1}),t(m,{value:"presentation"},{default:a(()=>[...l[36]||(l[36]=[r("演示文稿",-1)])]),_:1}),t(m,{value:"spreadsheet"},{default:a(()=>[...l[37]||(l[37]=[r("表格",-1)])]),_:1}),t(m,{value:"design"},{default:a(()=>[...l[38]||(l[38]=[r("设计",-1)])]),_:1}),t(m,{value:"code"},{default:a(()=>[...l[39]||(l[39]=[r("代码",-1)])]),_:1}),t(m,{value:"workflow"},{default:a(()=>[...l[40]||(l[40]=[r("工作流",-1)])]),_:1}),t(m,{value:"knowledge"},{default:a(()=>[...l[41]||(l[41]=[r("知识库",-1)])]),_:1})]),_:1},8,["value"])]),_:1}),t(b,{label:"根路径 (可选)"},{default:a(()=>[t(T,{value:e.newProject.rootPath,"onUpdate:value":l[14]||(l[14]=n=>e.newProject.rootPath=n),placeholder:"留空则仅元数据"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"])])}const Je=we(Pe,[["render",Le],["__scopeId","data-v-019ac5aa"],["__file","/tmp/cc-web-panel-UJ86gZ/repo/packages/web-panel/src/views/Projects.vue"]]);export{Je as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-jx7kr6mB.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-DVfm6xGt.js";import{a0 as t}from"./index-jx7kr6mB.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-CPB6iSzV.js";import"./useFlexGapSupport-CmWO7h0I.js";import"./styleChecker-qSHtosM-.js";import"./index-DNlxihs8.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-BVJQEP2j.js";import{a0 as t}from"./index-jx7kr6mB.js";import"./vendor-Bn1JzzAn.js";import"./index-DNlxihs8.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};