chainlesschain 0.166.106 → 0.166.107

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 (204) hide show
  1. package/README.md +179 -4
  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-CKwEku2e.js → AIOps-DCx6L_HW.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-BSUOuTpW.js → ActionButton-DYm1CN3Z.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-CGxvL_FI.js → Analytics-D5ItUS_y.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-bCPwz-5w.js → AppLayout-Cb7XeRdH.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-2_BOWo6e.js → Artifacts-DDDeqCDQ.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-CBOruzgW.js → Audit-BRt3x13w.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-lg0IU5HN.js → BackgroundAgents-C_oNALMd.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-OspCi452.js → Backup-PSU2p6CR.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-BMkliqlz.js → BaseInput-G3oL4hcX.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-BfoiUZwp.js → Chat-C2cLI10b.js} +6 -6
  15. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BjnfMwep.js → ChatBubbleRenderer-KX1OITf8.js} +1 -1
  16. package/src/assets/web-panel/assets/{Checkbox-jTMlkNQZ.js → Checkbox-CHLnEgFD.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-CycyJcnU.js → Codegen-DZm9g_Bc.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-BVWlReQj.js → Col-D5Z4zSay.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-CKRHl4xK.js → Community-DHw69NSk.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-BtpfMdhT.js → Compact-B-vjYNWz.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-DtHB1Ct1.js → Compliance-DaIYVZQY.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-D_8X7-RK.js → Cowork-CoA9U-gF.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-DMCOyvEa.js → Cron-DXqmxlRC.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-CeHdsu7m.js → Crosschain-Cdkc3ue1.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-CL6mR6zX.js → DID-oKfYyNSR.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-oz9n6DC7.js → Dashboard-n_ycvgWu.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-CbWm8mWu.js → Dropdown-D38rZ8WY.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-DXlmbC45.js → EmailListRenderer-BjreeBQ1.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-DPwqgRYm.js → EvolutionSettings-CTxA_SIq.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DkV4YMFj.js → FamilyGuardDashboard-DmECNwV5.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-CpUKHIOH.js → Federation-B2IaaDmQ.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-C6KXRgjR.js → FormItemContext-DgcgqUIk.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-C5Y4L5E3.js → GenericCardRenderer-B1-du6Qm.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-CBwKdF8s.js → Git-XceM21Il.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-Dt-OR7Aa.js → Governance-CV97iz3z.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-Czkl-Lhl.js → Inference-CI7fj305.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-C7NE4949.js → KnowledgeGraph-B5mekWRy.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-CoAuZiMG.js → Logs-BlxFA0xY.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-DTkjTwGI.js → MarkdownRenderer-rDE-XyMY.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-IzrV-7zH.js → Marketplace-DL1BVCiX.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-DYEea7aS.js → McpTools-BPtwrO3c.js} +2 -2
  42. package/src/assets/web-panel/assets/{Memory-Uqe7ZrV6.js → Memory-DuSNw4E-.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-D092EGyM.js → MobileBridge-DTgY9ywI.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-CwA1VoVJ.js → MobileProjects-CTpVHJMa.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-gg4jzfB-.js → Mtc-h4fCLjXw.js} +5 -5
  46. package/src/assets/web-panel/assets/{MtcAudit-BibGfs71.js → MtcAudit-fqMDY3-w.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-BmB5yRXP.js → Multisig-Do3FehBL.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-BBSlPDyY.js → NLProgramming-CQVY0kQF.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-Bui3-KiC.js → Notes-4c3oNvWh.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-ovXtbHe5.js → NotificationSettings-BKr2JD4k.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-Bq-qD7eG.js → OrderTableRenderer-Bq4jgzRt.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-DacIY9oJ.js → Organization-Dy3XidyA.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-CX8osheZ.js → Overflow-DFF0qN5K.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-1lnikqVp.js → P2P-DAgYYykd.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-DCrU-V6A.js → PdhVaultBrowser-DgNHa8b1.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-Dfcb6kM2.js → Permissions-Cev6uSBc.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-dvgai4hf.js → PersonalDataHub-DJzbN06K.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-nymAEtnK.js → Pipeline-CoJWvbQ5.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-D0Vd91oM.js → Privacy-DZxV6etm.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-BpUBcu7o.js → ProjectInit-BFW87JnM.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-DIzwTT-M.js → ProjectSettings-LBrRT27p.js} +2 -2
  62. package/src/assets/web-panel/assets/Projects-O3uz76R1.js +1 -0
  63. package/src/assets/web-panel/assets/{Providers-Cq8p-M0d.js → Providers-CnRbjOYk.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-DSmqOfYk.js → QrScannerModal-BVFnIS3r.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-BDHCeSnA.js → QuickAsk-DrcHx5f1.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-B_9M8oF4.js → Recommend-CbRgrSJm.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-5ot4leHy.js → RemoteSession-B2Uz_ElB.js} +3 -3
  68. package/src/assets/web-panel/assets/{Reputation-B3F013PY.js → Reputation-DS0ljTxL.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-BMyBJnZw.js → Row-ClLobFht.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-WmV0l52g.js → RssFeed-DxxcTD0x.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-Wl80yXnR.js → Search-BbHN0Fik.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-gbDMKb5m.js → Security-BAVU_EcY.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-Bx2Bjhah.js → Services-CtqRSVq_.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-BvJNybjV.js → Skeleton-IJ8ZKdSZ.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-Tz4rQcDp.js → Skills-DXxcznnO.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-BM9gyZwc.js → Sla-fRkhnA3i.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-Bu9FL9Tz.js → SpeechSettings-Bi8sYJ-I.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-D8ICJsMt.js → SyncSettings-CjeplUtS.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-B6MowBDo.js → Tasks-D4KB2Hbx.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-BJzpTD0W.js → Templates-BwVugi8n.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-BN8eX4R2.js → Tenant-CsPuu5xK.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-CjtP9bpq.js → Terminal-DuaeOPjY.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-CpNRa4XW.js → TimelineRenderer-D-PMrFxO.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-2lNNvNAH.js → Tokens-BXZuiQPZ.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-DxtxXyPg.js → Trigger-DgpTaHL3.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-CakzGeF9.js → Trust-Bn7lEGRY.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-CvJeRXwV.js → UkeySign-zz-8JAAQ.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-D80pMzcO.js → VideoEditing-DCzfQGTc.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-BF-VOBmZ.js → Wallet-BiRHM_zB.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-DXyoAzE_.js → WebAuthn-QmPo2JwU.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor-X6CDxzrF.js → WorkflowEditor-gL7SsPnY.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-BcUhqjeA.js → chat-BysvK4hk.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-Dw4bKaCm.js → colors-CQq20vqN.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-BWhu5Eri.js → compact-item-CAHlOf1X.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-BLJ9JKoN.js → createContext-BeF3ESj_.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-D-Iugqxv.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-DIkCiJbt.js → hasIn-CiqnRf-U.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CgsVg5Up.js → index-4a0Lmz_y.js} +1 -1
  99. package/src/assets/web-panel/assets/index-B0Oz2_rQ.js +1 -0
  100. package/src/assets/web-panel/assets/{index-CFGOV-YT.js → index-B2AOvjgR.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BipG-tDs.js → index-B2xbtl_c.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-0mHbawfQ.js → index-B5941vyo.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BaStonJm.js → index-BHpHGGmB.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Cmc7qH2C.js → index-BOiyW31p.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BotMuGS2.js → index-BcVmt6u_.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BcTch6Fp.js → index-BfJabF_8.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CXJ8t1hK.js → index-Br5tGVbC.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-u0tqS0iq.js → index-BsnLkZjz.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-D1r2R4a-.js → index-BtWchYfW.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DOjQi7oU.js → index-Bvkbj3x-.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BAwcMKaD.js → index-CCX0daFQ.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-D-Erv8A9.js → index-CImCEo8S.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CTPoBbIR.js → index-CTp89vmg.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CqGqoID5.js → index-CcccefJc.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DQbWGvE4.js → index-CeIL3-nY.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-uMtx6e3D.js → index-CgkUkmEJ.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-5vzPcr1g.js → index-CowbNBJs.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CDfB6hWf.js → index-Cp3IRTDK.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-B1fufz1A.js → index-D7q5VH2n.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DV4FSjmI.js → index-DBmGQHEz.js} +3 -3
  121. package/src/assets/web-panel/assets/{index-04SKBH8l.js → index-DHGtFwwR.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BxLDNxEQ.js → index-DKYbru3i.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DKzG3kBM.js → index-DTPUVm71.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DHLW27Je.js → index-DXT7MKkD.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BGFqk1-E.js → index-DXsXhR7p.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BUC4TZWg.js → index-Dqkls2_6.js} +1 -1
  127. package/src/assets/web-panel/assets/index-DwoycEQa.js +1 -0
  128. package/src/assets/web-panel/assets/{index-BxfimJOH.js → index-QALafVsT.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Cr05twNa.js → index-TdVEaJfk.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-LOsZYbic.js → index-ZBuJ6O6g.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-C5qms36i.js → index-i9aJV9qk.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D3wp_jgy.js → index-jJhemX1R.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DjEP26Te.js → index-qjaCk1Mj.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-PRYboDFm.js → index-xwtRrgVY.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-D5vFJmmX.js → index-yFQWSRoW.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-BGMzh2oj.js → index-zNkw0IY7.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-Bx6Hj_FG.js → initDefaultProps-BQR2HnKb.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-BSWivB70.js → motion-gAz6l-nZ.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-Dv1Pg9R7.js → move-Cy5TN856.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-Bqtl8fsk.js → mtc-parser-BeT7VrGi.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-DpOBjOSQ.js → omit-BLN3mlgK.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-D-M-dz48.js → pickAttrs-DtwZ8u2d.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-DsTLAifk.js → placementArrow-ViMwQSa-.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-BVTetMpc.js → responsiveObserve-dEL3u4E7.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-abEcz-Cv.js → slide-l05us-Gz.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-CBhrdU2G.js → statusUtils-Bk-Qn2Og.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-CFq8ZCKa.js → styleChecker-Bn186qeY.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-o4eE7fDV.js → useFlexGapSupport-WP-ugR3H.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-Hs9W8ihi.js → useFs-1SvoeSCL.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-Bnet5Jho.js → usePersonalDataHub-CfNU8N3z.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-DJfN4kWs.js → vnode-Bd2Ya101.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-BzV-2e7X.js → zoom-Def_MeZv.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +2 -2
  155. package/src/commands/agent.js +20 -20
  156. package/src/commands/goal.js +299 -1
  157. package/src/commands/plugin.js +129 -68
  158. package/src/constants.js +2 -2
  159. package/src/data/changelog.json +13 -0
  160. package/src/lib/cli-goal-catalog.js +129 -0
  161. package/src/lib/cli-goal-source.js +119 -0
  162. package/src/lib/config-schema.js +1 -1
  163. package/src/lib/eval/stream-terminal.js +27 -2
  164. package/src/lib/evolution/evolution-artifact-ports.js +22 -11
  165. package/src/lib/evolution/evolution-file-witness.js +86 -63
  166. package/src/lib/evolution/evolution-ledger-file-backend.js +22 -0
  167. package/src/lib/evolution/evolution-ledger-file-manifest-catalog.js +34 -35
  168. package/src/lib/evolution/evolution-ledger-file-manifest-head-store.js +32 -39
  169. package/src/lib/evolution/evolution-ledger.js +367 -169
  170. package/src/lib/evolution/evolution-manifest-state-reader.js +58 -0
  171. package/src/lib/evolution/evolution-physical-state-reader.js +308 -0
  172. package/src/lib/evolution/evolution-witness-segments.js +12 -13
  173. package/src/lib/evolution/governed-wiki-pruning-ledger-adapter.js +82 -56
  174. package/src/lib/evolution/rrsi-observed-text-index.js +17 -1
  175. package/src/lib/evolution/rrsi-tenant-index-anchor-history.js +5 -0
  176. package/src/lib/execution-location-failure-site.js +20 -3
  177. package/src/lib/goal-store.js +8 -1
  178. package/src/lib/image-input.js +43 -14
  179. package/src/lib/llm-providers.js +1 -0
  180. package/src/lib/plugin-runtime/capabilities.js +10 -0
  181. package/src/lib/plugin-runtime/cli-goal-draft-request.js +138 -0
  182. package/src/lib/plugin-runtime/cli-goal-drafts.js +413 -0
  183. package/src/lib/plugin-runtime/cli-goal-extension-host.js +234 -0
  184. package/src/lib/plugin-runtime/examples/goal-description-drafter/plugin.json +17 -0
  185. package/src/lib/plugin-runtime/examples/goal-evidence-viewer/plugin.json +25 -0
  186. package/src/lib/plugin-runtime/examples/goal-progress-viewer/plugin.json +21 -0
  187. package/src/lib/plugin-runtime/examples/project-delivery-assistant/plugin.json +38 -0
  188. package/src/lib/plugin-runtime/goal-extension-contract.js +190 -0
  189. package/src/lib/plugin-runtime/goal-extensions.js +277 -0
  190. package/src/lib/plugin-runtime/install.js +40 -40
  191. package/src/lib/plugin-runtime/manifest.js +12 -0
  192. package/src/lib/plugin-runtime/policy.js +1 -0
  193. package/src/lib/project-goal-connection.js +225 -0
  194. package/src/lib/project-goal-draft-connection.js +217 -0
  195. package/src/lib/task-model-selector.js +1 -1
  196. package/src/repl/agent-repl.js +14 -7
  197. package/src/repl/config-summary.js +1 -1
  198. package/src/runtime/agent-core.js +1 -1
  199. package/src/runtime/headless-stream.js +4 -6
  200. package/src/runtime/policies/agent-policy.js +1 -0
  201. package/src/assets/web-panel/assets/Projects-Den4RUw6.js +0 -1
  202. package/src/assets/web-panel/assets/devWarning-D_MJgDGJ.js +0 -1
  203. package/src/assets/web-panel/assets/index-BP8log78.js +0 -1
  204. package/src/assets/web-panel/assets/index-PexF9zYf.js +0 -1
@@ -27,6 +27,7 @@
27
27
  import fs from "fs";
28
28
  import path from "path";
29
29
  import semver from "semver";
30
+ import { normalizeGoalExtension } from "./goal-extension-contract.js";
30
31
  import {
31
32
  normalizeCapabilities,
32
33
  normalizeOptionsSchema,
@@ -89,6 +90,8 @@ export function parsePluginManifest(root) {
89
90
  // actual audit) from a legacy one that declared nothing (unrestricted).
90
91
  capabilities: normalizeCapabilities(null),
91
92
  capabilitiesDeclared: false,
93
+ goalExtensionDeclared: false,
94
+ goalExtension: null,
92
95
  optionsSchema: {},
93
96
  errors,
94
97
  warnings,
@@ -219,6 +222,15 @@ export function parsePluginManifest(root) {
219
222
  result.capabilities = normalizeCapabilities(manifest.permissions);
220
223
  result.capabilitiesDeclared = Boolean(hasPermissions);
221
224
  result.optionsSchema = normalizeOptionsSchema(manifest.optionsSchema);
225
+ result.goalExtensionDeclared = Object.hasOwn(manifest, "goalExtension");
226
+ try {
227
+ result.goalExtension = normalizeGoalExtension(
228
+ manifest.goalExtension,
229
+ manifest.permissions,
230
+ );
231
+ } catch (err) {
232
+ errors.push(err.message);
233
+ }
222
234
  // Declared-vs-actual audit runs ONLY when a permissions block is present — a
223
235
  // legacy plugin that declares nothing is unrestricted by design, so it never
224
236
  // gets these warnings (keeps existing manifests warning-free).
@@ -45,6 +45,7 @@ export function loadManagedPluginPolicy(opts = {}) {
45
45
  const key = String(
46
46
  opts.managedSettingsFile || env.CC_MANAGED_SETTINGS || "<default>",
47
47
  );
48
+ if (opts.fresh === true) _cache.delete(key);
48
49
  if (_cache.has(key)) {
49
50
  const cached = _cache.get(key);
50
51
  // A cached failure sentinel must re-throw on EVERY call — otherwise the
@@ -0,0 +1,225 @@
1
+ /** Explicit short-lived desktop connection. No DB path or client-supplied actor. */
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import http from "node:http";
5
+ import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
6
+ import { inspectPrivatePath } from "@chainlesschain/session-core/private-storage";
7
+ import { goalExtensionRef } from "@chainlesschain/session-core/goal-extension-proposal-contract";
8
+ import { validateGoalEvidenceProjection } from "@chainlesschain/session-core/goal-evidence-contract";
9
+ import { validateGoalDraftDescriptor } from "@chainlesschain/session-core/goal-draft-connection-contract";
10
+ import { createProjectGoalDraftClient } from "./project-goal-draft-connection.js";
11
+ function fail() {
12
+ throw new Error("CLI_GOAL_CONNECTION_UNAVAILABLE");
13
+ }
14
+ const sameFile = (a, b) =>
15
+ a.dev === b.dev &&
16
+ a.ino === b.ino &&
17
+ a.size === b.size &&
18
+ a.mtimeMs === b.mtimeMs &&
19
+ a.ctimeMs === b.ctimeMs;
20
+ export function createProjectGoalConnection(file) {
21
+ let fd;
22
+ try {
23
+ if (
24
+ typeof file !== "string" ||
25
+ !file ||
26
+ file.length > 4096 ||
27
+ /[\u0000-\u001f]/u.test(file)
28
+ )
29
+ fail();
30
+ const target = path.resolve(file);
31
+ const before = fs.lstatSync(target);
32
+ if (
33
+ !before.isFile() ||
34
+ before.isSymbolicLink() ||
35
+ before.nlink !== 1 ||
36
+ before.size > 4096 ||
37
+ !inspectPrivatePath(target).ok
38
+ )
39
+ fail();
40
+ fd = fs.openSync(
41
+ target,
42
+ fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW || 0),
43
+ );
44
+ const opened = fs.fstatSync(fd);
45
+ if (!sameFile(before, opened)) fail();
46
+ const raw = Buffer.alloc(4097);
47
+ const count = fs.readSync(fd, raw, 0, raw.length, 0);
48
+ if (count > 4096 || !sameFile(opened, fs.fstatSync(fd))) fail();
49
+ const descriptor = JSON.parse(raw.subarray(0, count).toString("utf8"));
50
+ if (descriptor.schema === "chainlesschain.project-goal-connection/v3") {
51
+ const verified = validateGoalDraftDescriptor(descriptor);
52
+ return createProjectGoalDraftClient(verified, () => {
53
+ if (
54
+ Date.now() >= verified.expiresAt ||
55
+ !sameFile(opened, fs.lstatSync(target))
56
+ )
57
+ fail();
58
+ });
59
+ }
60
+ const evidence =
61
+ descriptor.schema === "chainlesschain.project-goal-connection/v2";
62
+ const endpointPath = evidence ? "/goal-evidence" : "/goal-summary";
63
+ if (
64
+ Object.keys(descriptor).sort().join() !==
65
+ (evidence
66
+ ? "capability,endpoint,expiresAt,goalRef,key,schema"
67
+ : "endpoint,expiresAt,goalRef,key,schema") ||
68
+ (evidence
69
+ ? descriptor.capability !== "goal.evidence"
70
+ : descriptor.schema !== "chainlesschain.project-goal-connection/v1") ||
71
+ typeof descriptor.endpoint !== "string" ||
72
+ !/^http:\/\/127\.0\.0\.1:[1-9][0-9]{0,4}\/goal-(?:summary|evidence)$/.test(
73
+ descriptor.endpoint,
74
+ ) ||
75
+ new URL(descriptor.endpoint).pathname !== endpointPath ||
76
+ Number(new URL(descriptor.endpoint).port) > 65535 ||
77
+ typeof descriptor.key !== "string" ||
78
+ !/^[a-f0-9]{64}$/.test(descriptor.key) ||
79
+ !Number.isSafeInteger(descriptor.expiresAt) ||
80
+ descriptor.expiresAt <= Date.now() ||
81
+ descriptor.expiresAt > Date.now() + 15 * 60 * 1000 + 5000
82
+ )
83
+ fail();
84
+ const ref = goalExtensionRef(descriptor.goalRef);
85
+ function validate() {
86
+ if (
87
+ Date.now() >= descriptor.expiresAt ||
88
+ !sameFile(opened, fs.lstatSync(target))
89
+ )
90
+ fail();
91
+ }
92
+ const mac = (value) =>
93
+ createHmac("sha256", Buffer.from(descriptor.key, "hex"))
94
+ .update(value)
95
+ .digest("hex");
96
+ async function read(id = ref.id) {
97
+ validate();
98
+ if (id !== ref.id) fail();
99
+ const nonce = randomBytes(32).toString("hex");
100
+ try {
101
+ const result = await new Promise((resolve, reject) => {
102
+ const request = http.get(
103
+ descriptor.endpoint,
104
+ {
105
+ agent: false,
106
+ maxHeaderSize: 4096,
107
+ headers: {
108
+ "X-CC-Nonce": nonce,
109
+ "X-CC-Signature": mac(
110
+ `request\nGET\n${endpointPath}\n${nonce}`,
111
+ ),
112
+ },
113
+ },
114
+ (response) => {
115
+ const chunks = [];
116
+ let bytes = 0;
117
+ response.on("error", reject);
118
+ response.on("data", (chunk) => {
119
+ bytes += chunk.length;
120
+ if (bytes > 16 * 1024) response.destroy(new Error("limit"));
121
+ else chunks.push(chunk);
122
+ });
123
+ response.on("end", () => {
124
+ const body = Buffer.concat(chunks).toString("utf8"),
125
+ signature = response.headers["x-cc-signature"];
126
+ if (
127
+ response.statusCode !== 200 ||
128
+ typeof signature !== "string" ||
129
+ !/^[a-f0-9]{64}$/.test(signature) ||
130
+ !timingSafeEqual(
131
+ Buffer.from(signature),
132
+ Buffer.from(mac(`response\n${nonce}\n${body}`)),
133
+ )
134
+ ) {
135
+ reject(new Error("signature"));
136
+ return;
137
+ }
138
+ try {
139
+ resolve(JSON.parse(body));
140
+ } catch {
141
+ reject(new Error("json"));
142
+ }
143
+ });
144
+ },
145
+ );
146
+ request.setTimeout(5000, () => request.destroy(new Error("timeout")));
147
+ const deadline = setTimeout(
148
+ () => request.destroy(new Error("timeout")),
149
+ 5000,
150
+ );
151
+ request.once("close", () => clearTimeout(deadline));
152
+ request.on("error", reject);
153
+ });
154
+ validate();
155
+ if (
156
+ Object.keys(result).sort().join() !==
157
+ (evidence
158
+ ? "goalRef,objective,receipts,risk,schema,status"
159
+ : "goalRef,objective,schema,status") ||
160
+ result.schema !==
161
+ (evidence
162
+ ? "chainlesschain.project-goal-evidence/v1"
163
+ : "chainlesschain.project-goal-summary/v1") ||
164
+ JSON.stringify(goalExtensionRef(result.goalRef)) !==
165
+ JSON.stringify(ref) ||
166
+ typeof result.objective !== "string" ||
167
+ result.objective.length > 4096 ||
168
+ result.status !== "active"
169
+ )
170
+ fail();
171
+ if (evidence)
172
+ validateGoalEvidenceProjection({
173
+ risk: result.risk,
174
+ receipts: result.receipts,
175
+ });
176
+ return { ...result, goalRef: ref };
177
+ } catch {
178
+ fail();
179
+ }
180
+ }
181
+ validate();
182
+ return Object.freeze({ goalRef: ref, evidence, read });
183
+ } catch {
184
+ fail();
185
+ } finally {
186
+ if (fd !== undefined) fs.closeSync(fd);
187
+ }
188
+ }
189
+
190
+ export async function readProjectGoalCatalog(options = {}) {
191
+ if (
192
+ options.after !== undefined ||
193
+ !Number.isSafeInteger(options.limit ?? 20) ||
194
+ (options.limit ?? 20) < 1 ||
195
+ (options.limit ?? 20) > 20
196
+ )
197
+ fail();
198
+ const source = createProjectGoalConnection(options.connection);
199
+ const goal = await source.read();
200
+ return {
201
+ schema: "chainlesschain.goal-catalog.v1",
202
+ source: "desktop-project",
203
+ snapshot: true,
204
+ storeId: source.goalRef.storeId,
205
+ observedAt: new Date().toISOString(),
206
+ entries: [
207
+ {
208
+ id: source.goalRef.id,
209
+ title: goal.objective
210
+ .replace(
211
+ /[\u0000-\u001f\u007f-\u009f\u200e\u200f\u202a-\u202e\u2066-\u2069]/gu,
212
+ " ",
213
+ )
214
+ .slice(0, 160),
215
+ status: goal.status,
216
+ revision: source.goalRef.revision,
217
+ controlGeneration: source.goalRef.controlGeneration,
218
+ },
219
+ ],
220
+ scannedCount: 1,
221
+ skippedCount: 0,
222
+ invalidNameCount: 0,
223
+ nextCursor: null,
224
+ };
225
+ }
@@ -0,0 +1,217 @@
1
+ import http from "node:http";
2
+ import {
3
+ createHash,
4
+ createHmac,
5
+ randomBytes,
6
+ timingSafeEqual,
7
+ } from "node:crypto";
8
+ import { digestBusinessObjectContent as digest } from "@chainlesschain/session-core/business-object-contract";
9
+ import {
10
+ validateGoalDraftSources,
11
+ validateGoalDraftReceipt,
12
+ validateGoalDraftProposal,
13
+ } from "@chainlesschain/session-core/goal-draft-connection-contract";
14
+ function unavailable() {
15
+ return new Error("CLI_GOAL_CONNECTION_UNAVAILABLE");
16
+ }
17
+ function exact(raw, keys) {
18
+ if (
19
+ !raw ||
20
+ typeof raw !== "object" ||
21
+ Array.isArray(raw) ||
22
+ Object.keys(raw).length !== keys.length ||
23
+ keys.some((key) => !Object.hasOwn(raw, key))
24
+ )
25
+ throw unavailable();
26
+ }
27
+ /** Constructed only after the shared private-file reader verifies the descriptor. */
28
+ export function createProjectGoalDraftClient(descriptor, validate) {
29
+ const ref = Object.freeze({ ...descriptor.goalRef }),
30
+ grant = Object.freeze({
31
+ id: descriptor.grantRef.id,
32
+ epoch: descriptor.grantRef.epoch,
33
+ plugin: Object.freeze({ ...descriptor.plugin }),
34
+ declarationDigest: descriptor.declarationDigest,
35
+ });
36
+ const mac = (text) =>
37
+ createHmac("sha256", Buffer.from(descriptor.key, "hex"))
38
+ .update(text)
39
+ .digest("hex");
40
+ async function exchange(method, payload, writing = false) {
41
+ validate();
42
+ const bytes =
43
+ payload === undefined
44
+ ? Buffer.alloc(0)
45
+ : Buffer.from(JSON.stringify(payload));
46
+ if (bytes.length > 16384) throw unavailable();
47
+ const nonce = randomBytes(32).toString("hex"),
48
+ bodyHash = createHash("sha256").update(bytes).digest("hex");
49
+ let sent = false;
50
+ try {
51
+ const result = await new Promise((resolve, reject) => {
52
+ const request = http.request(
53
+ descriptor.endpoint,
54
+ {
55
+ method,
56
+ agent: false,
57
+ maxHeaderSize: 4096,
58
+ headers: {
59
+ "X-CC-Nonce": nonce,
60
+ "X-CC-Signature": mac(
61
+ `request-v3\n${method}\n/goal-drafts\n${nonce}\n${bodyHash}`,
62
+ ),
63
+ ...(method === "POST"
64
+ ? {
65
+ "Content-Type": "application/json",
66
+ "Content-Length": bytes.length,
67
+ }
68
+ : {}),
69
+ },
70
+ },
71
+ (response) => {
72
+ const chunks = [];
73
+ let size = 0;
74
+ response.on("error", reject);
75
+ response.on("data", (chunk) => {
76
+ size += chunk.length;
77
+ if (size > 16384) response.destroy(unavailable());
78
+ else chunks.push(chunk);
79
+ });
80
+ response.on("end", () => {
81
+ try {
82
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(
83
+ Buffer.concat(chunks),
84
+ ),
85
+ signature = response.headers["x-cc-signature"];
86
+ if (
87
+ typeof signature !== "string" ||
88
+ !/^[a-f0-9]{64}$/u.test(signature) ||
89
+ !timingSafeEqual(
90
+ Buffer.from(signature),
91
+ Buffer.from(
92
+ mac(
93
+ `response-v3\n${nonce}\n${response.statusCode}\n${text}`,
94
+ ),
95
+ ),
96
+ )
97
+ )
98
+ throw unavailable();
99
+ if (response.statusCode !== 200) throw unavailable();
100
+ resolve(JSON.parse(text));
101
+ } catch (error) {
102
+ reject(error);
103
+ }
104
+ });
105
+ },
106
+ );
107
+ const timer = setTimeout(() => request.destroy(unavailable()), 5000);
108
+ request.once("close", () => clearTimeout(timer));
109
+ request.on("error", reject);
110
+ request.setTimeout(5000, () => request.destroy(unavailable()));
111
+ sent = writing;
112
+ request.end(bytes);
113
+ });
114
+ validate();
115
+ if (digest(result.goalRef) !== digest(ref)) throw unavailable();
116
+ return result;
117
+ } catch {
118
+ const error = unavailable();
119
+ if (sent) {
120
+ error.code = "CLI_GOAL_DRAFT_OUTCOME_UNKNOWN";
121
+ error.outcomeUnknown = true;
122
+ }
123
+ throw error;
124
+ }
125
+ }
126
+ async function read(id = ref.id) {
127
+ if (id !== ref.id) throw unavailable();
128
+ const result = await exchange("GET");
129
+ exact(result, [
130
+ "schema",
131
+ "goalRef",
132
+ "objective",
133
+ "status",
134
+ "grant",
135
+ "sources",
136
+ ]);
137
+ if (
138
+ result.schema !== "chainlesschain.project-goal-drafts/v1" ||
139
+ typeof result.objective !== "string" ||
140
+ result.objective.length > 4096 ||
141
+ result.status !== "active" ||
142
+ digest(result.grant) !== digest(grant)
143
+ )
144
+ throw unavailable();
145
+ validateGoalDraftSources(result.sources);
146
+ return { ...result, goalRef: ref };
147
+ }
148
+ async function sources(afterId) {
149
+ const result = await exchange("POST", {
150
+ operation: "sources",
151
+ ...(afterId !== undefined ? { afterId } : {}),
152
+ });
153
+ exact(result, ["schema", "goalRef", "sources"]);
154
+ if (result.schema !== "chainlesschain.goal-draft-sources/v1")
155
+ throw unavailable();
156
+ return validateGoalDraftSources(result.sources);
157
+ }
158
+ async function receipt({ requestId, inputDigest }) {
159
+ const result = await exchange("POST", {
160
+ operation: "receipt",
161
+ requestId,
162
+ inputDigest,
163
+ });
164
+ exact(result, ["schema", "goalRef", "receipt"]);
165
+ if (result.schema !== "chainlesschain.goal-draft-receipt/v1")
166
+ throw unavailable();
167
+ const value = validateGoalDraftReceipt(result.receipt);
168
+ if (value.requestId !== requestId || value.inputDigest !== inputDigest)
169
+ throw unavailable();
170
+ return value;
171
+ }
172
+ async function enqueue(raw) {
173
+ const proposal = validateGoalDraftProposal(raw),
174
+ inputDigest = digest(proposal);
175
+ let received = false;
176
+ try {
177
+ const result = await exchange(
178
+ "POST",
179
+ { operation: "enqueue", proposal },
180
+ true,
181
+ );
182
+ received = true;
183
+ exact(result, ["schema", "goalRef", "receipt"]);
184
+ if (result.schema !== "chainlesschain.goal-draft-submit/v1")
185
+ throw unavailable();
186
+ const value = validateGoalDraftReceipt(result.receipt);
187
+ if (
188
+ value.state !== "saved" ||
189
+ value.requestId !== proposal.requestId ||
190
+ value.inputDigest !== inputDigest
191
+ )
192
+ throw unavailable();
193
+ return value;
194
+ } catch (error) {
195
+ // Once HTTP may have dispatched, an invalid/absent response is not proof
196
+ // that no native draft was saved. Preserve this exact request identity.
197
+ if (received || error.outcomeUnknown) {
198
+ error.code = "CLI_GOAL_DRAFT_OUTCOME_UNKNOWN";
199
+ error.outcomeUnknown = true;
200
+ }
201
+ throw error;
202
+ }
203
+ }
204
+ validate();
205
+ return Object.freeze({
206
+ goalRef: ref,
207
+ evidence: false,
208
+ drafts: true,
209
+ plugin: grant.plugin,
210
+ declarationDigest: grant.declarationDigest,
211
+ grantRef: Object.freeze({ ...descriptor.grantRef }),
212
+ read,
213
+ sources,
214
+ enqueue,
215
+ receipt,
216
+ });
217
+ }
@@ -24,7 +24,7 @@ export const TaskType = {
24
24
  */
25
25
  const TASK_MODEL_MAP = {
26
26
  [TaskType.CHAT]: {
27
- volcengine: "deepseek-v4-flash-ga-260731",
27
+ volcengine: "deepseek-v4-1-flash-260910",
28
28
  openai: "gpt-4o-mini",
29
29
  anthropic: "claude-sonnet-4-6",
30
30
  deepseek: "deepseek-chat",
@@ -9504,12 +9504,18 @@ async function startAgentReplInWorkspaceOwned(
9504
9504
  let _userMessageContent = userContent;
9505
9505
  if (process.env.CC_AUTO_IMAGE !== "0") {
9506
9506
  try {
9507
- const turn = prepareVisionTurn(userContent, {
9508
- provider,
9509
- baseUrl,
9510
- apiKey,
9511
- visionModel: _visionModel,
9512
- });
9507
+ const turn = prepareVisionTurn(
9508
+ userContent,
9509
+ {
9510
+ provider,
9511
+ model,
9512
+ baseUrl,
9513
+ apiKey,
9514
+ visionModel: _visionModel,
9515
+ },
9516
+ {},
9517
+ { visionModel: options.visionModel },
9518
+ );
9513
9519
  if (turn.visionLlm) {
9514
9520
  _userMessageContent = turn.content;
9515
9521
  _visionLlm = turn.visionLlm;
@@ -9549,9 +9555,10 @@ async function startAgentReplInWorkspaceOwned(
9549
9555
  if (!_visionLlm) {
9550
9556
  _visionLlm = resolveVisionLlm({
9551
9557
  hasImage: true,
9552
- flags: {},
9558
+ flags: { visionModel: options.visionModel },
9553
9559
  llm: {
9554
9560
  provider,
9561
+ model,
9555
9562
  baseUrl,
9556
9563
  apiKey,
9557
9564
  visionModel: _visionModel,
@@ -34,7 +34,7 @@ export function parseConfigCommand(argStr) {
34
34
  export const COMMON_CONFIG_KEYS = Object.freeze([
35
35
  ["llm.provider", "LLM provider id"],
36
36
  ["llm.model", "default text model id"],
37
- ["llm.visionModel", "model used for image turns"],
37
+ ["llm.visionModel", "image fallback for a main model without vision"],
38
38
  ["llm.baseUrl", "provider API base URL"],
39
39
  ["llm.apiKey", "provider API key (use cc config set-secret)"],
40
40
  ["webSearch.provider", "web-search backend"],
@@ -12412,7 +12412,7 @@ export async function chatWithTools(rawMessages, options) {
12412
12412
  dashscope: "qwen-turbo",
12413
12413
  mistral: "mistral-large-latest",
12414
12414
  gemini: "gemini-2.0-flash",
12415
- volcengine: "deepseek-v4-flash-ga-260731",
12415
+ volcengine: "deepseek-v4-1-flash-260910",
12416
12416
  };
12417
12417
  const effectiveModel = model || defaultModels[provider] || "gpt-4o-mini";
12418
12418
  const modelProfile = resolveModelCapabilityProfile({
@@ -2079,10 +2079,8 @@ async function runAgentHeadlessStreamInWorkspace(
2079
2079
  return { exitCode: 1, turns: 0 };
2080
2080
  }
2081
2081
  }
2082
- // Vision model (config.llm.visionModel) — image turns switch to it for that
2083
- // turn only (resolveVisionLlm falls back to the default when unset), so a
2084
- // pasted/typed image is read by a vision-capable model even though the
2085
- // session's default model is text-only.
2082
+ // Vision fallback for a text-only main model. Multimodal main models keep
2083
+ // handling both image turns and follow-ups themselves.
2086
2084
  let visionModel = options.visionModel;
2087
2085
  if (!visionModel) {
2088
2086
  try {
@@ -5313,8 +5311,8 @@ async function runAgentHeadlessStreamInWorkspace(
5313
5311
  if (conversationHasImages) {
5314
5312
  turnVisionLlm = resolveVisionLlm({
5315
5313
  hasImage: true,
5316
- flags: {},
5317
- llm: { provider, baseUrl, apiKey, visionModel },
5314
+ flags: { visionModel: options.visionModel },
5315
+ llm: { provider, model, baseUrl, apiKey, visionModel },
5318
5316
  });
5319
5317
  if (parsed.images && parsed.images.length) {
5320
5318
  writeErr(
@@ -10,6 +10,7 @@ export function resolveAgentPolicy({
10
10
 
11
11
  return {
12
12
  model: overrides.model || llm.model || defaults.model || "qwen2:7b",
13
+ visionModel: overrides.visionModel,
13
14
  provider:
14
15
  overrides.provider || llm.provider || defaults.provider || "ollama",
15
16
  baseUrl:
@@ -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-DV4FSjmI.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 Z=await e.sendRaw({...f,type:o},ae);if(!Z?.ok){const $=Z?.error;throw new Error(typeof $=="string"?$:$?.message||`${o} failed`)}return Z.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),L=u(!1),E=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"}],M=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 H(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 Q(o){return{onClick:()=>V(o)}}async function V(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 X(){F.value={name:"",description:"",type:"document",rootPath:""},L.value=!0}async function T(){if(!F.value.name.trim()){d.warning("请输入项目名称");return}E.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}'`),L.value=!1,await C()):d.error("创建失败")}catch(o){d.error(o.message||String(o))}finally{E.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(""),Y=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){Y.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{Y.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:L,creating:E,newProject:F,columns:z,countByStatus:M,filteredProjects:J,statusColor:g,syncColor:K,formatTime:H,loadAll:C,onRowClick:Q,openDetail:V,onDelete:G,onShowCreate:X,onCreate:T,createFileOpen:b,creatingFile:D,newFile:j,createFolderOpen:A,creatingFolder:m,newFolder:R,editFileOpen:n,editingFile:c,editFileContent:q,savingFile:Y,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"],Le={key:0,style:{color:"#888","font-size":"12px"}};function Ee(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"),L=i("a-radio-group"),E=i("a-input-search"),F=i("a-alert"),z=i("a-tag"),M=i("a-popconfirm"),J=i("a-table"),g=i("a-descriptions-item"),K=i("a-descriptions"),H=i("a-divider"),C=i("a-empty"),Q=i("a-list-item"),V=i("a-list"),G=i("a-spin"),X=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(L,{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(E,{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(M,{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(X,{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(H,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(V,{key:1,size:"small","data-source":e.files},{renderItem:a(({item:n})=>[t(Q,null,{extra:a(()=>[t(O,null,{default:a(()=>[n.file_size?(p(),I("span",Le,s(n.file_size)+" B",1)):_("v-if",!0),t(M,{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",Ee],["__scopeId","data-v-019ac5aa"],["__file","/tmp/cc-web-panel-HKM6TL/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-DV4FSjmI.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-BMyBJnZw.js";import{a0 as t}from"./index-DV4FSjmI.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-BVTetMpc.js";import"./useFlexGapSupport-o4eE7fDV.js";import"./styleChecker-CFq8ZCKa.js";import"./index-BAwcMKaD.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-BVWlReQj.js";import{a0 as t}from"./index-DV4FSjmI.js";import"./vendor-Bn1JzzAn.js";import"./index-BAwcMKaD.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};