chainlesschain 0.166.80 → 0.166.82

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 (175) hide show
  1. package/README.md +8 -8
  2. package/package.json +2 -2
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/assets/{AIOps-C5NtVVBN.js → AIOps-DMzLSUWK.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-CE9-HsoR.js → ActionButton-CgnA23oA.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-DRO6sI0Z.js → Analytics-CtXmm8Qe.js} +2 -2
  8. package/src/assets/web-panel/assets/{AppLayout-CuVJiyC_.js → AppLayout-C5RIh5jA.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-GNahHsyZ.js → Artifacts-DM525zx0.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-DWvTomfm.js → Audit-ChBx6f2l.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-k4TuA3ec.js → BackgroundAgents-BBHDxCda.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-BxqN-65D.js → Backup-B-qzCAoM.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-CYYLvwwD.js → BaseInput-C5yoIWAD.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-CoDmZ9yb.js → Chat-NmTrci9a.js} +5 -5
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-pPuUDG2V.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-CRVlfbkN.js → Checkbox-KdFSU3vd.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-BttMy7rW.js → Codegen-L__BOv_4.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-DsdlE4QC.js → Col-Dfuw4IQV.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-BulheyO-.js → Community-BRlEhSbx.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-BC_7wMxW.js → Compact-D7dRkv8n.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-BA3PDNLK.js → Compliance-CdlFYNR3.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-B6Y3L-GP.js → Cowork-Ey7ksHq4.js} +4 -4
  23. package/src/assets/web-panel/assets/{Cron-DLk_CG77.js → Cron-DBH__wGJ.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-CvsKV-90.js → Crosschain-D3nu9dw7.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-CD8K9G3F.js → DID-DS6vZBNv.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-CXNE434f.js → Dashboard-DwFRk2T0.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-C_P5mttB.js → Dropdown-D7b73q3I.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-MxZvItNA.js → EmailListRenderer-DPNaVH36.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-DRoJQrDb.js → EvolutionSettings-BEsOtdpf.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CBrz9T6T.js → FamilyGuardDashboard-ijSqsSsF.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-DKlGgjNs.js → Federation-C0BOzPDh.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-CteicPS5.js → FormItemContext-DkF5NoAg.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-Bs10mDna.js → GenericCardRenderer-DQsMcyJj.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-CXwzFBIh.js → Git-DQRt88PU.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-CYzcwfwf.js → Governance-DIjPmDN8.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-pYpCF1ws.js → Inference-BWMFtT7i.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-B0YJnOpj.js → KnowledgeGraph-M7TfkUVl.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-D-hJWfq-.js → Logs-BZv9Z6BY.js} +2 -2
  39. package/src/assets/web-panel/assets/MarkdownRenderer-D5NZGdg3.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-D5ZmI-si.js → Marketplace-Crd9MYHg.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-DByD6jY1.js → McpTools-C37yOQV0.js} +2 -2
  42. package/src/assets/web-panel/assets/{Memory--lsjJd7Y.js → Memory-BBsijJCd.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-GQ3vGZO9.js → MobileBridge-CiXIQCju.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-Dh2wq-NU.js → MobileProjects-C0KSvQm5.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-uQFoRe_Z.js → Mtc-C0XaQsOY.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-BUBYbvuz.js → MtcAudit-DPqggKhw.js} +2 -2
  47. package/src/assets/web-panel/assets/{Multisig-D790SLqM.js → Multisig-Bie0ZVHe.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-DcV9gSqn.js → NLProgramming-BbuJlQ5b.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-sVl7Y_vt.js → Notes-CgqrJV8w.js} +4 -4
  50. package/src/assets/web-panel/assets/{NotificationSettings-BHRPqBZ3.js → NotificationSettings-CusdZEQl.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-B029pIMF.js → OrderTableRenderer-B7RrCvCQ.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-BKrF-dtp.js → Organization-BnFpz3bb.js} +2 -2
  53. package/src/assets/web-panel/assets/{Overflow-DOAGxhhi.js → Overflow-C_4_HyyZ.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-7uQ4F7lh.js → P2P-D0KpHxeg.js} +2 -2
  55. package/src/assets/web-panel/assets/PdhVaultBrowser-Cfd_C9nc.js +7 -0
  56. package/src/assets/web-panel/assets/{Permissions-C0qK0tAi.js → Permissions-D2LxL66N.js} +3 -3
  57. package/src/assets/web-panel/assets/{PersonalDataHub-DCnfXKyb.js → PersonalDataHub-CvSNIxt0.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-D8wdVvao.js → Pipeline-rUl-SM7V.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-C-dGmb9y.js → Privacy-BD8cWSNd.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-ChKvrsfc.js → ProjectInit-RM7J4X2F.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-CaWnzNBi.js → ProjectSettings-BIH38RsB.js} +2 -2
  62. package/src/assets/web-panel/assets/Projects-CTgx3Fxc.js +1 -0
  63. package/src/assets/web-panel/assets/{Providers-DTufbN-S.js → Providers-B9Kja2RK.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-CGv6QJMC.js → QrScannerModal-ByDKowTD.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-BfNcUCfG.js → QuickAsk-DqEN1QOE.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-B0s5YT2K.js → Recommend-CLrYwNiv.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-YCs5wa8P.js → RemoteSession-DyDltVPC.js} +3 -3
  68. package/src/assets/web-panel/assets/{Reputation-DBC__Ylq.js → Reputation-BfP8rJ1-.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-D_NT1ROe.js → Row-BpnP6r1H.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-Dd9ktNRw.js → RssFeed-CBNI1lCN.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-BsmlT4PY.js → Search-CLjrM-xj.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-DN-_e3oM.js → Security-dRXtg-Mq.js} +2 -2
  73. package/src/assets/web-panel/assets/{Services-Bm_KqSDz.js → Services-DAHCtOHL.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-BYldeYI0.js → Skeleton-D11Jgtur.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-h7XAXSls.js → Skills-DchvTO4k.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-4ArxAaMJ.js → Sla-BFOc2SbL.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-B639ejZr.js → SpeechSettings-Dud1xDd2.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-DR6RRo1O.js → SyncSettings-CILfsA2S.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-DysrrJVE.js → Tasks-C6Qrah_5.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-DyyB9L9f.js → Templates--puiHyCR.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-XbmWbUl1.js → Tenant-cz5vITz_.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-C5GeciJG.js → Terminal-YRs75Gz8.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-Db-NjeVy.js → TimelineRenderer-C5myb_QZ.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-Btm9pYvJ.js → Tokens-Bk60iMIj.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-BhJ35b0V.js → Trigger-BAb-Fd4z.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-C5T4GJky.js → Trust-BlqwmpEB.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-CqWxh5U0.js → UkeySign-C6jvuF-7.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-DKyI9zg1.js → VideoEditing-7zbsdQUj.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-kgvyQOtT.js → Wallet-BAouk_kp.js} +2 -2
  90. package/src/assets/web-panel/assets/{WebAuthn-1wWucdJt.js → WebAuthn-BQapv504.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor-rHVIbLME.js → WorkflowEditor-ChUXM-Qx.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-DV8ZtfWQ.js → chat-7B6U8zgJ.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-zznFfEpj.js → colors-C8UqaLpe.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-CWk10Qsu.js → compact-item-x47giTCj.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-CtoMW-kY.js → createContext-D6ZwjgaZ.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-BFfV5AtN.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-ieyHKAZZ.js → hasIn-Cv3d9-Bu.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-14ADEHo7.js → index-B7Dorc7r.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-Dz1TqS34.js → index-BGxo1YH0.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DNlvUg0O.js → index-BM-NYjej.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-zY56IXHj.js → index-BMPk5D1m.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-D7yq9nAq.js → index-BTBkdyLk.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CrBful_u.js → index-BTisPSqa.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-G9bqTRu6.js → index-BUzw-kDo.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BGYCtfL-.js → index-C1ElqYDD.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-B9w6Zr_O.js → index-CQ0-ny-o.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BrpyZMUe.js → index-CUUgXcPh.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Bf9069uM.js → index-CUtcWTSe.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-McW2cdbg.js → index-CXG6yiAf.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DPwOEcUt.js → index-CXIUyx4U.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Cn71LASJ.js → index-CaPZ_8kP.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-B2WI4Jse.js → index-Cbf4RqOd.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BG9KlVJl.js → index-Cc2bhSuI.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-0GSB8LOT.js → index-Cc6jr0Yb.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CdSnkhrR.js → index-Ce666S9v.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CjkiJdIX.js → index-CiVEatgH.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CewbVIM8.js → index-CrGQsbpb.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DR1Uw5as.js → index-D4ZHX6wo.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-2TTLREp7.js → index-D9lFBkS4.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DjNjO-VL.js → index-DD-V-N_m.js} +3 -3
  121. package/src/assets/web-panel/assets/{index-9fgmdiB_.js → index-DLHnYXVa.js} +1 -1
  122. package/src/assets/web-panel/assets/index-DUz_bv5i.js +1 -0
  123. package/src/assets/web-panel/assets/{index-Cqpfzkch.js → index-DVBG0Jqz.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CGZGQTF5.js → index-Dc0hePXV.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DSnQWQ4L.js → index-DtBUgc0G.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CLeX8Qp7.js → index-Dv5E07PZ.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DdMho2Wr.js → index-DvoMGeL9.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CxSgg3Xc.js → index-EDWA9JL1.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-D9jmNLfO.js → index-IVelXaiQ.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DmtyRKy8.js → index-N9hNOl1i.js} +1 -1
  131. package/src/assets/web-panel/assets/{index--6zQrvYc.js → index-WhoNHp50.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CBS8OtL2.js → index-dbM4QvQZ.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-fmwnODwg.js → index-jgN2e0Oy.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-esCpkxIZ.js → index-nogjrcQE.js} +1 -1
  135. package/src/assets/web-panel/assets/index-rQ59l7GO.js +1 -0
  136. package/src/assets/web-panel/assets/{index-DRuSuXJh.js → index-yYdCdtY1.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-CVk4LKJK.js → initDefaultProps-DkKS5xtR.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-IAABGXc_.js → motion-CU-zBUIg.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-B9HSYeZc.js → move-zBE0VEd4.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-CJfDtM89.js → mtc-parser-B9WyO1je.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-D5dYnom7.js → omit-6sCoBNTL.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-xbUkaZdY.js → pickAttrs-DDRv_sFc.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-CIUU5NKN.js → placementArrow-Cy_CBDw5.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-BZpgHE8P.js → responsiveObserve-CIczLq9K.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-x_8rsSKk.js → slide-DFfZCvnG.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-BZyDnVJs.js → statusUtils-DW-0HUl-.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-DusfWp6J.js → styleChecker-BPYaBorP.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-022JzYAL.js → useFlexGapSupport-DYPoOaZc.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-DRDxX7-3.js → useFs-ODUEWR17.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-DFrCp7m_.js → usePersonalDataHub-CstUt15X.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-bCuSFOmr.js → vnode-D2GW8xCL.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-sCpZ0sw7.js → zoom-Bz6GoDwq.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/data/changelog.json +26 -0
  155. package/src/gateways/ws/ws-approval-gate.js +7 -0
  156. package/src/lib/auto-mode-config.js +129 -40
  157. package/src/lib/context-memory-kernel/task-worklog-port.js +73 -24
  158. package/src/lib/diagnostic-excerpt.js +91 -10
  159. package/src/lib/diagnostic-workflow.js +2 -0
  160. package/src/lib/git-tool-input.js +7 -0
  161. package/src/lib/plan-mode.js +15 -4
  162. package/src/lib/process-execution-broker/linux-generic-bwrap-runtime.js +2 -2
  163. package/src/lib/process-execution-broker/linux-open-flags.js +26 -0
  164. package/src/lib/process-execution-broker/platform-sandbox.js +5 -9
  165. package/src/lib/remote-read-loop-guard.js +59 -14
  166. package/src/lib/task-progress-tracker.js +112 -12
  167. package/src/repl/agent-repl.js +15 -14
  168. package/src/runtime/agent-core.js +88 -2
  169. package/src/assets/web-panel/assets/ChatBubbleRenderer-ChTIMWch.js +0 -1
  170. package/src/assets/web-panel/assets/MarkdownRenderer-BPQlDtB7.js +0 -1
  171. package/src/assets/web-panel/assets/PdhVaultBrowser-BegpATva.js +0 -7
  172. package/src/assets/web-panel/assets/Projects-2uNBqS05.js +0 -1
  173. package/src/assets/web-panel/assets/devWarning-_Wlo1cZJ.js +0 -1
  174. package/src/assets/web-panel/assets/index-Cj8Mcdok.js +0 -1
  175. package/src/assets/web-panel/assets/index-vira2aS_.js +0 -1
@@ -1,6 +1,9 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { remoteReadTarget } from "./remote-read-loop-guard.js";
3
- import { diagnosticExcerpt } from "./diagnostic-excerpt.js";
3
+ import {
4
+ diagnosticExcerpt,
5
+ hasTestFailureVerdict,
6
+ } from "./diagnostic-excerpt.js";
4
7
  import { DIAGNOSTIC_WORKFLOW_GUIDANCE } from "./diagnostic-workflow.js";
5
8
 
6
9
  // Discovery and bookkeeping are useful, but are not evidence that the task
@@ -63,21 +66,36 @@ function isGitInspection(result, args) {
63
66
  function isRemoteInspectionCommand(command) {
64
67
  if (typeof command !== "string") return false;
65
68
  if (
66
- /(?:^|[\s;&|])gh(?:\.exe)?\s+(?:run\s+(?:view|list|watch)|pr\s+(?:view|list|diff|checks)|workflow\s+(?:view|list)|auth\s+status)\b/i.test(
69
+ /(?:^|[\s;&|])gh(?:\.exe)?\s+(?:run\s+(?:view|list|watch|download)|(?:pr|issue)\s+(?:view|list|diff|checks)|workflow\s+(?:view|list)|release\s+(?:view|list|download)|repo\s+view|search\s+\w+|auth\s+status|(?:\w+\s+)*(?:--help|-h))\b/i.test(
67
70
  command,
68
71
  )
69
72
  )
70
73
  return true;
71
74
  return (
72
75
  /(?:^|[\s;&|])gh(?:\.exe)?\s+api\s/i.test(command) &&
73
- /(?:https:\/\/api\.github\.com\/)?\/?repos\/[\w.-]+\/[\w.-]+\/(?:actions|pulls|compare|releases|commits|check-runs|check-suites)\b/i.test(
74
- command,
75
- ) &&
76
76
  !/(?:^|\s)(?:--method|-X)(?:=|\s*)["']?(?!GET\b)\w+/i.test(command) &&
77
77
  !/(?:^|\s)(?:(?:--field|--raw-field|--input)(?:=|\s)|-[fF])/.test(command)
78
78
  );
79
79
  }
80
80
 
81
+ // Shell equivalents of read_file/search_files/list_dir are discovery too.
82
+ // This is advisory accounting, never an execution parser or permission grant.
83
+ function isLocalInspectionCommand(command) {
84
+ if (typeof command !== "string") return false;
85
+ if (
86
+ /\b(?:npm(?:\.cmd)?\s+(?:test|run|publish)|node(?:\.exe)?\s+--test|(?:go|mvn(?:\.cmd)?)\s+test|pytest|git\s+(?:commit|merge|cherry-pick|push)|gh\s+(?:(?:pr|issue)\s+(?:create|merge|close|edit|comment)|run\s+rerun))\b/i.test(
87
+ command,
88
+ ) ||
89
+ /\b(?:Set-Content|Add-Content|Remove-Item|Move-Item|Copy-Item|New-Item)\b/i.test(
90
+ command,
91
+ )
92
+ )
93
+ return false;
94
+ return /(?:^|[;&|\r\n]|-Command\s+["']?|=\s*)\s*(?:Get-Content|Get-ChildItem|Select-String|Select-Object|Test-Path|cat|head|tail|grep|rg|findstr(?:\.exe)?|dir|type|more|jq)(?=\s|$)/i.test(
95
+ command,
96
+ );
97
+ }
98
+
81
99
  // Advisory classification, never execution parsing or permission approval.
82
100
  // A retry wrapper or JSON filter is still investigation, even when each call
83
101
  // prints a different small result. Unknown computations remain available.
@@ -85,10 +103,8 @@ function isInspectionScript(code) {
85
103
  if (typeof code !== "string") return false;
86
104
  // Keep actual changes and focused verification eligible to advance the task.
87
105
  if (
88
- /\b(?:writeFile(?:Sync)?|appendFile(?:Sync)?|unlink(?:Sync)?|rename(?:Sync)?|mkdir(?:Sync)?|rmSync|rmdirSync|assert|pytest|vitest|unittest)\b/.test(
89
- code,
90
- ) ||
91
- /\b(?:npm\s+(?:test|run|publish)|git\s+(?:commit|merge|cherry-pick|push)|gh\s+(?:pr\s+(?:create|merge|close)|run\s+rerun))\b/i.test(
106
+ /\b(?:assert|pytest|vitest|unittest)\b/.test(code) ||
107
+ /\b(?:npm\s+(?:test|run|publish)|git\s+(?:commit|merge|cherry-pick|push)|gh\s+(?:(?:pr|issue)\s+(?:create|merge|close|edit|comment)|run\s+rerun))\b/i.test(
92
108
  code,
93
109
  )
94
110
  )
@@ -104,6 +120,15 @@ function isInspectionScript(code) {
104
120
  literals.some((value) => isRemoteInspectionCommand(`gh ${value}`))
105
121
  )
106
122
  return true;
123
+ // Saving fetched metadata is still inspection. Other file changes can be
124
+ // implementation work and remain eligible to advance the task.
125
+ if (
126
+ /\b(?:writeFile(?:Sync)?|appendFile(?:Sync)?|unlink(?:Sync)?|rename(?:Sync)?|mkdir(?:Sync)?|rmSync|rmdirSync)\b/.test(
127
+ code,
128
+ )
129
+ )
130
+ return false;
131
+ if (literals.some((value) => isLocalInspectionCommand(value))) return true;
107
132
  // Parsing previously saved logs/metadata is evidence collection too.
108
133
  return (
109
134
  /\b(?:readFileSync|readFile|readdirSync|readdir|read_text|read_bytes|json\.load)\s*\(/.test(
@@ -141,6 +166,7 @@ export class TaskProgressTracker {
141
166
  this.remoteInspections = [];
142
167
  this.localFindings = [];
143
168
  this.diagnostics = [];
169
+ this.failureEvidence = new Map();
144
170
  }
145
171
 
146
172
  retainChildResult(id, result, owner = "root") {
@@ -180,6 +206,51 @@ export class TaskProgressTracker {
180
206
  typeof args.old_string === "string" &&
181
207
  args.old_string === args.new_string);
182
208
 
209
+ // Preserve observed test verdicts separately from the rolling last-four
210
+ // queries. Repeated metadata reads must not evict the original failure.
211
+ // These are source excerpts, never an inferred root cause or fix verdict.
212
+ if (result?.code !== "CC_TOOL_RECOVERY_PAUSED") {
213
+ const evidence = [
214
+ result?.stdout_diagnostics,
215
+ result?.stderr_diagnostics,
216
+ result?.output,
217
+ result?.stdout,
218
+ result?.stderr,
219
+ result?.content,
220
+ result?.matches,
221
+ ]
222
+ .filter(Boolean)
223
+ .map((value) =>
224
+ typeof value === "string" ? value : JSON.stringify(value),
225
+ )
226
+ .join("\n");
227
+ if (hasTestFailureVerdict(evidence)) {
228
+ const excerpt = diagnosticExcerpt(evidence, 1600);
229
+ const digest = createHash("sha256").update(excerpt).digest("hex");
230
+ const entries = this.failureEvidence.get(owner) || [];
231
+ if (!entries.some((entry) => entry.digest === digest)) {
232
+ const entry = {
233
+ digest,
234
+ tool,
235
+ observedAt: this.now(),
236
+ source: boundedText(
237
+ args.path || args.command || args.code || result?.path,
238
+ 400,
239
+ ),
240
+ excerpt,
241
+ excerptTruncated: evidence.length > excerpt.length,
242
+ };
243
+ // Keep the first failure plus the latest distinct observation.
244
+ remember(
245
+ this.failureEvidence,
246
+ owner,
247
+ entries.length ? [entries[0], entry] : [entry],
248
+ MAX_CHECKPOINT_OWNERS,
249
+ );
250
+ }
251
+ }
252
+ }
253
+
183
254
  // Preserve observed reproduction results through compaction, including
184
255
  // failed runs and completed background tasks. They do not establish that
185
256
  // the original CI failure was reproduced or fixed.
@@ -219,7 +290,8 @@ export class TaskProgressTracker {
219
290
  ? "git-inspection"
220
291
  : remoteTarget?.github || isRemoteInspectionCommand(command)
221
292
  ? "remote-inspection"
222
- : tool === "run_code" && isInspectionScript(command)
293
+ : (tool === "run_code" && isInspectionScript(command)) ||
294
+ (tool === "run_shell" && isLocalInspectionCommand(command))
223
295
  ? "script-inspection"
224
296
  : "local-execution"),
225
297
  invocation: boundedText(command || previous?.invocation, 1000),
@@ -334,6 +406,7 @@ export class TaskProgressTracker {
334
406
  exploration =
335
407
  !!remoteReadTarget(tool, args) ||
336
408
  remoteInspection ||
409
+ (tool === "run_shell" && isLocalInspectionCommand(args.command)) ||
337
410
  (tool === "run_code" && isInspectionScript(args.code)) ||
338
411
  output.length >= 8000 ||
339
412
  this.commandOutputs.has(digest);
@@ -413,11 +486,21 @@ export class TaskProgressTracker {
413
486
  !this.lastActions.length &&
414
487
  !this.remoteInspections.length &&
415
488
  !this.diagnostics.length &&
416
- !this.localFindings.length
489
+ !this.localFindings.length &&
490
+ !this.failureEvidence.size
417
491
  )
418
492
  return null;
419
493
  const checkpoint = {
420
494
  bounded: true,
495
+ observedTestFailures: (this.failureEvidence.get(owner) || []).map(
496
+ ({ tool, observedAt, source, excerpt, excerptTruncated }) => ({
497
+ tool,
498
+ observedAt,
499
+ source,
500
+ excerpt,
501
+ excerptTruncated,
502
+ }),
503
+ ),
421
504
  recentDiagnostics: this.diagnostics
422
505
  .filter((entry) => entry.owner === owner)
423
506
  .map(({ owner: _owner, ...entry }) => entry),
@@ -449,6 +532,7 @@ export class TaskProgressTracker {
449
532
  !checkpoint.recentToolOutcomes.length &&
450
533
  !checkpoint.recentRemoteInspections.length &&
451
534
  !checkpoint.recentDiagnostics.length &&
535
+ !checkpoint.observedTestFailures.length &&
452
536
  !checkpoint.reportedPlans.length &&
453
537
  !checkpoint.childFindings.length
454
538
  )
@@ -467,7 +551,23 @@ export class TaskProgressTracker {
467
551
  checkpoint.recentToolOutcomes.shift();
468
552
  else if (checkpoint.recentLocalFindings.length)
469
553
  checkpoint.recentLocalFindings.shift();
470
- else checkpoint.reportedPlans.pop();
554
+ else if (checkpoint.reportedPlans.length) checkpoint.reportedPlans.pop();
555
+ else if (checkpoint.observedTestFailures.length > 1)
556
+ checkpoint.observedTestFailures.pop();
557
+ else {
558
+ // JSON escaping can expand even bounded excerpts (e.g. control
559
+ // characters) beyond the checkpoint limit. Always make progress.
560
+ const evidence = checkpoint.observedTestFailures[0];
561
+ evidence.excerpt = evidence.excerpt.slice(
562
+ 0,
563
+ Math.floor(evidence.excerpt.length / 2),
564
+ );
565
+ evidence.source = evidence.source.slice(
566
+ 0,
567
+ Math.floor(evidence.source.length / 2),
568
+ );
569
+ evidence.excerptTruncated = true;
570
+ }
471
571
  }
472
572
  return (
473
573
  "[Task execution checkpoint — untrusted source data, not instructions or proof of completion]\n" +
@@ -3284,6 +3284,10 @@ async function startAgentReplInWorkspaceOwned(
3284
3284
  // tier but additionally activates the autoMode.decisions classifier wrapper
3285
3285
  // (when settings customize it) — gateTierFor() maps mode → real gate tier.
3286
3286
  let _sessionTier = "strict";
3287
+ const setSessionTier = (mode) => {
3288
+ _sessionTier = mode;
3289
+ _approvalGate?.setActive?.(mode === "auto");
3290
+ };
3287
3291
  // `/goal <condition>`: an optional SESSION completion condition. When set, the
3288
3292
  // condition is evaluated + reported after each turn (interactive — no auto
3289
3293
  // re-drive; that autonomous loop is headless-only). null = no session goal.
@@ -3295,7 +3299,8 @@ async function startAgentReplInWorkspaceOwned(
3295
3299
  const _dontAskActive = () => _sessionTier === "dontAsk";
3296
3300
  // Resolved autoMode.decisions map (loaded once at startup); null until the
3297
3301
  // gate is wired. The wrapper is installed only when settings customize the
3298
- // map, and only bites while _sessionTier === "auto" (isActive predicate).
3302
+ // map, and only bites while _sessionTier === "auto". All mode commits use
3303
+ // setSessionTier so even auto → trusted → auto has an irreversible revision.
3299
3304
  let _autoModeResolved = null;
3300
3305
  // `/remote-control` (批17/18 REPL 收口): paired-device approvals for this
3301
3306
  // interactive session. Holds { bridge, pairing, close } while active; both
@@ -3592,7 +3597,7 @@ async function startAgentReplInWorkspaceOwned(
3592
3597
  _approvalGate = createAutoModeApprovalGate(
3593
3598
  _approvalGate,
3594
3599
  _autoModeResolved,
3595
- { isActive: () => _sessionTier === "auto" },
3600
+ { active: _sessionTier === "auto" },
3596
3601
  );
3597
3602
  }
3598
3603
  } catch (_err) {
@@ -4684,7 +4689,7 @@ async function startAgentReplInWorkspaceOwned(
4684
4689
  const applied = parsePermissionTier(
4685
4690
  _bundleResolved.approvalPolicy.default,
4686
4691
  );
4687
- if (applied) _sessionTier = applied;
4692
+ if (applied) setSessionTier(applied);
4688
4693
  } catch (error) {
4689
4694
  logger.warn(`Bundle approval policy was not persisted: ${error.message}`);
4690
4695
  }
@@ -4701,11 +4706,9 @@ async function startAgentReplInWorkspaceOwned(
4701
4706
  try {
4702
4707
  await _approvalGate.setSessionPolicy(sessionId, parsed.tier);
4703
4708
  await _approvalGate.awaitPersistence?.();
4704
- _sessionTier = parsed.auto
4705
- ? "auto"
4706
- : parsed.dontAsk
4707
- ? "dontAsk"
4708
- : parsed.tier;
4709
+ setSessionTier(
4710
+ parsed.auto ? "auto" : parsed.dontAsk ? "dontAsk" : parsed.tier,
4711
+ );
4709
4712
  } catch (error) {
4710
4713
  logger.warn(`Approval policy was not persisted: ${error.message}`);
4711
4714
  }
@@ -5418,7 +5421,7 @@ async function startAgentReplInWorkspaceOwned(
5418
5421
  try {
5419
5422
  await _approvalGate.setSessionPolicy(sessionId, next);
5420
5423
  await _approvalGate.awaitPersistence?.();
5421
- _sessionTier = next;
5424
+ setSessionTier(next);
5422
5425
  process.stdout.write(
5423
5426
  "\n" +
5424
5427
  chalk.cyan(`⇥ approval: ${next}`) +
@@ -8850,11 +8853,9 @@ async function startAgentReplInWorkspaceOwned(
8850
8853
  try {
8851
8854
  await _approvalGate.setSessionPolicy(sessionId, parsed.tier);
8852
8855
  await _approvalGate.awaitPersistence?.();
8853
- _sessionTier = parsed.auto
8854
- ? "auto"
8855
- : parsed.dontAsk
8856
- ? "dontAsk"
8857
- : parsed.tier;
8856
+ setSessionTier(
8857
+ parsed.auto ? "auto" : parsed.dontAsk ? "dontAsk" : parsed.tier,
8858
+ );
8858
8859
  logger.info(
8859
8860
  `Approval policy → ${chalk.cyan(_sessionTier)} ${chalk.gray(`(${describeTier(_sessionTier)})`)}`,
8860
8861
  );
@@ -2443,12 +2443,16 @@ function selectedHostToolPolicy(hostAuthority, tool) {
2443
2443
  function snapshotPlanToolAuthority(planManager, tool, args) {
2444
2444
  const active = planManager?.isActive?.() === true;
2445
2445
  return {
2446
+ revision:
2447
+ Number.isSafeInteger(planManager?.revision) && planManager.revision >= 0
2448
+ ? planManager.revision
2449
+ : null,
2446
2450
  active,
2447
2451
  executionLockActive: planManager?.executionLock != null,
2448
2452
  toolAllowed:
2449
2453
  !active || (tool === "git" && isReadOnlyGitCommand(args?.command))
2450
2454
  ? true
2451
- : planManager?.isToolAllowed?.(tool) === true,
2455
+ : planManager?.isToolAllowed?.(tool, { recordBlocked: false }) === true,
2452
2456
  };
2453
2457
  }
2454
2458
 
@@ -2546,6 +2550,10 @@ function snapshotApprovalPolicyAuthority(approvalGate, sessionId) {
2546
2550
  */
2547
2551
  export async function executeTool(name, args, context = {}) {
2548
2552
  const liveExecutionContext = context;
2553
+ let admittedApprovalGate = null;
2554
+ let admittedApprovalPolicyDigest = null;
2555
+ let entryPlanManager = null;
2556
+ let entryPlanPolicyDigest = null;
2549
2557
  // run_shell can cross several asynchronous permission/hook boundaries before
2550
2558
  // reaching executeToolInner. Capture its declared tuple and working directory
2551
2559
  // before any of them so an in-process caller cannot swap the approved command
@@ -2599,6 +2607,31 @@ export async function executeTool(name, args, context = {}) {
2599
2607
  };
2600
2608
  }
2601
2609
  }
2610
+ if (name === "run_shell") {
2611
+ try {
2612
+ admittedApprovalGate = context.approvalGate || null;
2613
+ admittedApprovalPolicyDigest = digestPolicyAuthority(
2614
+ snapshotApprovalPolicyAuthority(
2615
+ admittedApprovalGate,
2616
+ context.sessionId || null,
2617
+ ),
2618
+ );
2619
+ entryPlanManager = context.planManager || getPlanModeManager();
2620
+ entryPlanPolicyDigest = digestPolicyAuthority(
2621
+ snapshotPlanToolAuthority(entryPlanManager, name, args),
2622
+ );
2623
+ } catch (error) {
2624
+ return {
2625
+ error:
2626
+ "[Shell Dispatch] The initial shell policy authority could not be bound. No command side effect was started.",
2627
+ policy: {
2628
+ decision: "blocked",
2629
+ via: "shell-policy-authority",
2630
+ code: error?.code || "CC_SHELL_POLICY_AUTHORITY_UNAVAILABLE",
2631
+ },
2632
+ };
2633
+ }
2634
+ }
2602
2635
  if (name === "run_code") {
2603
2636
  try {
2604
2637
  const entryProcessCwd = process.cwd();
@@ -3019,9 +3052,20 @@ export async function executeTool(name, args, context = {}) {
3019
3052
  let admittedPlanPolicyDigest = null;
3020
3053
  if (name === "run_shell") {
3021
3054
  try {
3022
- admittedPlanPolicyDigest = digestPolicyAuthority(
3055
+ const currentPlanPolicyDigest = digestPolicyAuthority(
3023
3056
  snapshotPlanToolAuthority(planManager, name, args),
3024
3057
  );
3058
+ if (
3059
+ planManager !== entryPlanManager ||
3060
+ currentPlanPolicyDigest !== entryPlanPolicyDigest
3061
+ ) {
3062
+ const error = new Error(
3063
+ "Plan authority changed during initial permission resolution",
3064
+ );
3065
+ error.code = "CC_SHELL_POLICY_AUTHORITY_CHANGED";
3066
+ throw error;
3067
+ }
3068
+ admittedPlanPolicyDigest = currentPlanPolicyDigest;
3025
3069
  } catch (error) {
3026
3070
  return {
3027
3071
  error:
@@ -3380,6 +3424,9 @@ export async function executeTool(name, args, context = {}) {
3380
3424
  classifyAllShell: context.classifyAllShell === true,
3381
3425
  };
3382
3426
  if (
3427
+ approvalGate !== admittedApprovalGate ||
3428
+ digestPolicyAuthority(initialProjection.approval) !==
3429
+ admittedApprovalPolicyDigest ||
3383
3430
  digestPolicyAuthority(initialProjection.permission) !==
3384
3431
  admittedPermissionPolicyDigest ||
3385
3432
  digestPolicyAuthority(initialProjection.host) !==
@@ -6673,6 +6720,8 @@ async function executeToolInner(
6673
6720
  let dockerEgressSession = null;
6674
6721
  let proxyFailed = false;
6675
6722
  let authorityMonitor = null;
6723
+ let removePlanAuthorityListener = null;
6724
+ let removeApprovalAuthorityListener = null;
6676
6725
  if (needsEgress) {
6677
6726
  try {
6678
6727
  const { startEgressProxyWorker } =
@@ -6742,6 +6791,41 @@ async function executeToolInner(
6742
6791
  },
6743
6792
  abortProxy: () => proxyHandle.abort(),
6744
6793
  });
6794
+ if (
6795
+ Number.isSafeInteger(planManager?.revision) &&
6796
+ planManager.revision >= 0 &&
6797
+ typeof planManager.on === "function" &&
6798
+ typeof planManager.off === "function"
6799
+ ) {
6800
+ const onPlanMutation = () => {
6801
+ const error = new Error(
6802
+ "Plan authority changed during Docker egress execution",
6803
+ );
6804
+ error.code = "CC_SHELL_POLICY_AUTHORITY_CHANGED";
6805
+ authorityMonitor.revoke(error);
6806
+ };
6807
+ planManager.on("revision-changed", onPlanMutation);
6808
+ removePlanAuthorityListener = () =>
6809
+ planManager.off("revision-changed", onPlanMutation);
6810
+ }
6811
+ if (
6812
+ sessionId &&
6813
+ typeof approvalGate?.subscribePolicyRevision === "function"
6814
+ ) {
6815
+ removeApprovalAuthorityListener =
6816
+ approvalGate.subscribePolicyRevision(sessionId, () => {
6817
+ const error = new Error(
6818
+ "Approval policy changed during Docker egress execution",
6819
+ );
6820
+ error.code = "CC_SHELL_POLICY_AUTHORITY_CHANGED";
6821
+ authorityMonitor.revoke(error);
6822
+ });
6823
+ if (typeof removeApprovalAuthorityListener !== "function") {
6824
+ throw new TypeError(
6825
+ "approval policy revision subscription must return an unsubscribe function",
6826
+ );
6827
+ }
6828
+ }
6745
6829
  authorityMonitor.start();
6746
6830
  await authorityMonitor.checkNow();
6747
6831
  } else {
@@ -6805,6 +6889,8 @@ async function executeToolInner(
6805
6889
  });
6806
6890
  }
6807
6891
  } finally {
6892
+ removeApprovalAuthorityListener?.();
6893
+ removePlanAuthorityListener?.();
6808
6894
  authorityMonitor?.stop();
6809
6895
  await authorityMonitor?.awaitCleanup();
6810
6896
  if (dockerEgressSession) {
@@ -1 +0,0 @@
1
- import{I as h,P as m,J as S,U as n,R as a,S as y,K as C,Q as x,V as w,_ as B,b as s}from"./vendor-Bn1JzzAn.js";import{_ as k}from"./index-DjNjO-VL.js";import"./icons-DG5UD-6K.js";const M={__name:"ChatBubbleRenderer",props:{event:{type:Object,required:!0}},setup(c,{expose:d}){d();const t=c,r=s(()=>{const e=t.event.content||{};return e.text||e.body||e.message||e.title||JSON.stringify(e).slice(0,200)}),i=s(()=>{const e=t.event.content||{};return e.from||e.sender||e.senderName||t.event.actor||"(unknown)"}),l=s(()=>{const e=(t.event.actor||"").toLowerCase();return e.includes("self")||e==="me"||e.endsWith("_self")}),o=s(()=>{const e=t.event.source.adapter||"";return e.startsWith("messaging-qq")?"magenta":e==="wechat"?"green":"blue"}),u=s(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),p=e.getFullYear(),f=String(e.getMonth()+1).padStart(2,"0"),g=String(e.getDate()).padStart(2,"0"),b=String(e.getHours()).padStart(2,"0"),v=String(e.getMinutes()).padStart(2,"0");return`${p}-${f}-${g} ${b}:${v}`}catch{return""}}),_={props:t,messageText:r,actorLabel:i,isMine:l,adapterColor:o,formattedTime:u,computed:s};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}},N={class:"bubble"},T={class:"meta"},V={class:"actor"},R={class:"time"},q={class:"body"};function D(c,d,t,r,i,l){const o=h("a-tag");return m(),S("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",N,[n("div",T,[n("span",V,a(r.actorLabel),1),n("span",R,a(r.formattedTime),1)]),n("div",q,a(r.messageText),1),t.event.source.adapter?(m(),y(o,{key:0,class:"src",color:r.adapterColor},{default:C(()=>[x(a(t.event.source.adapter),1)]),_:1},8,["color"])):w("v-if",!0)])],2)}const A=k(M,[["render",D],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-VvMmZ9/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{A as default};
@@ -1 +0,0 @@
1
- import{P as c,J as p,b as s}from"./vendor-Bn1JzzAn.js";import{r as a}from"./markdown-Yo_c6Krv.js";import{_ as d}from"./index-DjNjO-VL.js";const _={__name:"MarkdownRenderer",props:{content:{type:String,default:""}},setup(t,{expose:o}){o();const e=t,r=s(()=>a(e.content||"")),n={props:e,rendered:r,computed:s,get renderMarkdown(){return a}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}},i=["innerHTML"];function m(t,o,e,r,n,u){return c(),p("div",{class:"markdown-content",innerHTML:r.rendered},null,8,i)}const M=d(_,[["render",m],["__scopeId","data-v-0b0b9f63"],["__file","/tmp/cc-web-panel-VvMmZ9/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{M};
@@ -1,7 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./ChatBubbleRenderer-ChTIMWch.js","./vendor-Bn1JzzAn.js","./index-DjNjO-VL.js","./icons-DG5UD-6K.js","./index-Cq93VfoF.css","./ChatBubbleRenderer-gy5SDGw2.css","./OrderTableRenderer-B029pIMF.js","./OrderTableRenderer-CfrDjSHT.css","./TimelineRenderer-Db-NjeVy.js","./TimelineRenderer-BlTAtkOc.css","./EmailListRenderer-MxZvItNA.js","./EmailListRenderer-DTPZPx_S.css","./GenericCardRenderer-Bs10mDna.js","./GenericCardRenderer-o85VDYQS.css"])))=>i.map(i=>d[i]);
2
- import{E as ue,r as R,b as w,I as g,P as u,J as O,U as v,c,S as C,V as E,_ as N,F as B,Z as se,a0 as ae,R as x,K as m,Q as b,W as L,o as J}from"./vendor-Bn1JzzAn.js";import{u as U}from"./usePersonalDataHub-DFrCp7m_.js";import{_ as D,e as F,d as P}from"./index-DjNjO-VL.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 _e,R as ye}from"./icons-DG5UD-6K.js";import"./useShellMode-CgR0wCYM.js";const I=Object.freeze({q:"",category:null,adapter:null,subtype:null,since:null,until:null}),V=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,_=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 y(){const S=++d;e.value=!0,a.value=null;const p=U();try{const[f,T]=await Promise.all([p.searchEvents(h({limit:V})),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:V}));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},_&&clearTimeout(_),_=setTimeout(()=>{_=null,y()},Y)}function ie(S){return r.value={...I,...S},_&&(clearTimeout(_),_=null),y()}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:y,loadMore:k,setFilter:le,setFilters:ie,reset:ce,PAGE_SIZE:V,SEARCH_DEBOUNCE_MS:Y}}),ge=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 M(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 ge},get categoryLabel(){return M}};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=g("a-badge");return u(),O("div",Se,[t[2]||(t[2]=v("div",{class:"sidebar-title"},"数据类型",-1)),v("div",{class:N(["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(B,null,se(e.CATEGORIES,s=>(u(),O("div",{key:s,class:N(["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-VvMmZ9/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((y,k)=>k[1]-y[1]).map(([y,k])=>({value:y,label:`${y} (${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 _(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[y,k]=h;o("set-filter","since",y?+y: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:_,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=g("a-input-search"),s=g("a-select"),i=g("a-range-picker"),d=g("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]=_=>r.$emit("set-filter","adapter",_||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]=_=>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-VvMmZ9/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-ChTIMWch.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url)),e=L(()=>F(()=>import("./OrderTableRenderer-B029pIMF.js"),__vite__mapDeps([6,1,2,3,4,7]),import.meta.url)),o=L(()=>F(()=>import("./TimelineRenderer-Db-NjeVy.js"),__vite__mapDeps([8,1,2,3,4,9]),import.meta.url)),a=L(()=>F(()=>import("./EmailListRenderer-MxZvItNA.js"),__vite__mapDeps([10,1,2,3,4,11]),import.meta.url)),l=L(()=>F(()=>import("./GenericCardRenderer-Bs10mDna.js"),__vite__mapDeps([12,1,2,3,4,13]),import.meta.url));function s(d){const _=d&&d.source&&d.source.adapter;switch($(_)){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-VvMmZ9/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),_=oe(i,n.category);re(d,_,o[i]),P.success(`已导出 ${n.events.length} 条到 ${_}`)}catch(d){P.error(`导出失败: ${d.message||d}`)}}const s={props:n,hasResults:e,MIME:o,serialize:a,onClick:l,computed:w,get DownloadOutlined(){return _e},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=g("a-button"),s=g("a-menu-item"),i=g("a-menu"),d=g("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 Ve=D(Pe,[["render",qe],["__file","/tmp/cc-web-panel-VvMmZ9/repo/packages/web-panel/src/components/pdh/ExportDropdown.vue"]]),Be={__name:"PdhVaultBrowser",setup(r,{expose:t}){t();const n=X(),e=w(()=>n.filters.q?`没有匹配 "${n.filters.q}" 的事件 — 试试更短的关键词或换个类目`:n.filters.category?`「${M(n.filters.category)}」类目下还没有数据 — 去采集页同步对应 adapter`:"Vault 里还没有数据 — 去「个人数据中台」页面同步任意 adapter");function o(s){n.filters.category=s,n.search()}function a(s,i){n.setFilter(s,i)}J(()=>{!n.hasResults&&!n.isLoading&&n.search()});const l={store:n,emptyHint:e,onCategorySelect:o,onSetFilter:a,onMounted:J,computed:w,get ReloadOutlined(){return ye},get usePdhBrowserStore(){return X},get categoryLabel(){return M},CategorySidebar:ke,SearchFilterBar:Le,RendererDispatcher:Te,ExportDropdown:Ve};return Object.defineProperty(l,"__isScriptSetup",{enumerable:!1,value:!0}),l}},Me={class:"pdh-browser-page"},Ne={class:"page-header"},Je={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=g("a-tag"),s=g("a-button"),i=g("a-space"),d=g("a-col"),_=g("a-spin"),j=g("a-alert"),A=g("a-empty"),h=g("a-row");return u(),O("div",Me,[v("div",Ne,[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]=y=>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",Je,[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]=y=>{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(_,{size:"small"}),t[7]||(t[7]=b(" 载入中… ",-1))])):(u(),O(B,{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(B,null,se(e.store.results,(y,k)=>(u(),C(e.RendererDispatcher,{key:`r-${k}-${y.id}`,event:y},null,8,["event"]))),128))]),e.store.canLoadMore?(u(),O("div",Ke,[c(s,{loading:e.store.isAppending,onClick:t[2]||(t[2]=y=>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(Be,[["render",We],["__scopeId","data-v-0f7c02cd"],["__file","/tmp/cc-web-panel-VvMmZ9/repo/packages/web-panel/src/views/PdhVaultBrowser.vue"]]);export{nt as default};
@@ -1 +0,0 @@
1
- import{I as i,J as I,U,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-DjNjO-VL.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:W}=de();async function w(o,f,ye,ae=8e3){if(W){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}),J=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:""}),A=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:""},A.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}'`),A.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:W,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:J,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:A,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"}},Ae={class:"page-title"},Ie={class:"page-sub"},Ue={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,W,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"),J=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"),A=i("a-modal"),m=i("a-select-option"),R=i("a-select");return p(),I("div",null,[U("div",ze,[U("div",null,[U("h2",Ae,s(e.t("projects.title")),1),U("p",Ie,[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 "),U("div",Ue,[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(J,{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(),I("code",he,s(c.id.slice(0,8))+"…",1)):n.key==="name"?(p(),I(ne,{key:1},[U("strong",null,s(c.name),1),c.description?(p(),I("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(),I(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(()=>[U("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(),I("code",Re,s(e.detail.root_path),1)):(p(),I("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(),I("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(()=>[U("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(A,{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(A,{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(A,{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(A,{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 We=we(Pe,[["render",Le],["__scopeId","data-v-019ac5aa"],["__file","/tmp/cc-web-panel-VvMmZ9/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-DjNjO-VL.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-DsdlE4QC.js";import{a0 as t}from"./index-DjNjO-VL.js";import"./vendor-Bn1JzzAn.js";import"./index-DRuSuXJh.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-D_NT1ROe.js";import{a0 as t}from"./index-DjNjO-VL.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-BZpgHE8P.js";import"./useFlexGapSupport-022JzYAL.js";import"./styleChecker-DusfWp6J.js";import"./index-DRuSuXJh.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};