chainlesschain 0.162.114 → 0.162.116

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 (152) hide show
  1. package/package.json +2 -2
  2. package/src/assets/web-panel/assets/{AIOps-0-uMzHS0.js → AIOps-DDOyyepP.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-DIZPfP0j.js → ActionButton-Du7WNR7z.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-D0XaT-HY.js → Analytics-BfgWzxK9.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-BTRaqYvd.js → AppLayout-u3psvW1D.js} +3 -3
  6. package/src/assets/web-panel/assets/{Audit-CNf5Kaoi.js → Audit-CHzFroRa.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-BAo4Hi0L.js → Backup-BxGsrw2B.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-Cvl0T59f.js → BaseInput-Dbt9fGx6.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-Cun14ni3.js → Chat-D_Q57G4I.js} +5 -5
  10. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CVSvw44R.js → ChatBubbleRenderer-BJT1bSLa.js} +1 -1
  11. package/src/assets/web-panel/assets/{Checkbox-DJdTjyls.js → Checkbox-D1EETx0O.js} +1 -1
  12. package/src/assets/web-panel/assets/{Codegen-Bz_l_yn_.js → Codegen-CbKlHMn4.js} +1 -1
  13. package/src/assets/web-panel/assets/{Col-Bht2QpqM.js → Col-C1CLqeq2.js} +1 -1
  14. package/src/assets/web-panel/assets/{Community-7KcO0kT1.js → Community-CPRsLFyz.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compact-B7rBvHIs.js → Compact-DpleToCJ.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compliance-BuxUJTnd.js → Compliance-CGqa-Ogf.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cowork-CJdjs2tJ.js → Cowork-DJk_xDYM.js} +4 -4
  18. package/src/assets/web-panel/assets/{Cron-BZFJ7-YN.js → Cron-M_yDyNBF.js} +2 -2
  19. package/src/assets/web-panel/assets/{Crosschain-BKsLLmuh.js → Crosschain-D7AojU-F.js} +1 -1
  20. package/src/assets/web-panel/assets/{DID-BxRlZh9g.js → DID-BETwaPmP.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dashboard-B6RppX5d.js → Dashboard-BQ78uhsa.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dropdown-DKtl6tbR.js → Dropdown-CH1HJZ3n.js} +1 -1
  23. package/src/assets/web-panel/assets/{EmailListRenderer-BRyFvNHM.js → EmailListRenderer-ChXV7GIc.js} +1 -1
  24. package/src/assets/web-panel/assets/{FamilyGuardDashboard-C99TnWli.js → FamilyGuardDashboard-CsKuOtrn.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-lC9Io-Wx.js → Federation-BZLlylg9.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-kTzkIiAH.js → FormItemContext-DeCMnWLf.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-ffjSPeHn.js → GenericCardRenderer-CH7to4tQ.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-Ch-eo0ft.js → Git-C_HcR2op.js} +2 -2
  29. package/src/assets/web-panel/assets/{Governance-CSlXyDt9.js → Governance-PTau8O3i.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-innJ4CHB.js → Inference-DtnYaICi.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-BoKWXlKH.js → KnowledgeGraph-CdVgxVhJ.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-Bvu1ZVlJ.js → Logs-BieJHWlI.js} +2 -2
  33. package/src/assets/web-panel/assets/{Marketplace-Bz5plU9l.js → Marketplace-DCz5yk3o.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-Ce2O172z.js → McpTools-CZ1xedJY.js} +5 -5
  35. package/src/assets/web-panel/assets/{Memory-CVTPzpDT.js → Memory-Bz7CQQml.js} +2 -2
  36. package/src/assets/web-panel/assets/{MobileBridge-DroRONe3.js → MobileBridge-dJ9Br_56.js} +2 -2
  37. package/src/assets/web-panel/assets/MobileProjects-Bpmjz4V6.js +1 -0
  38. package/src/assets/web-panel/assets/{Mtc-BLe-_MDX.js → Mtc-eeWBcjEL.js} +5 -5
  39. package/src/assets/web-panel/assets/{MtcAudit-Cx6CIX_g.js → MtcAudit-C5wyRjHk.js} +6 -6
  40. package/src/assets/web-panel/assets/{Multisig-OEeP6h30.js → Multisig-BJRGIqgZ.js} +3 -3
  41. package/src/assets/web-panel/assets/{NLProgramming-B79aNNrY.js → NLProgramming-S07UoipU.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-BzKbClTh.js → Notes-COxSrwZ3.js} +4 -4
  43. package/src/assets/web-panel/assets/{NotificationSettings-6BcdjMJk.js → NotificationSettings-DfvE_1K3.js} +1 -1
  44. package/src/assets/web-panel/assets/OrderTableRenderer-CeyDa5Ed.js +1 -0
  45. package/src/assets/web-panel/assets/{Organization-B_g6tN2h.js → Organization-CcsPrDEP.js} +4 -4
  46. package/src/assets/web-panel/assets/{Overflow-BPeDct0h.js → Overflow-DcYp9yIj.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-AbEH8Ad6.js → P2P-a4dzjJXx.js} +2 -2
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-DTYIEFuT.js → PdhVaultBrowser-DFxZ5o8Q.js} +4 -4
  49. package/src/assets/web-panel/assets/{Permissions-Mtl6DRWC.js → Permissions-Bz9d8JCZ.js} +4 -4
  50. package/src/assets/web-panel/assets/{PersonalDataHub-CrfCdPgN.js → PersonalDataHub-CsNBmJ7S.js} +3 -3
  51. package/src/assets/web-panel/assets/{Pipeline-Znd89-so.js → Pipeline-D-0xA6R_.js} +1 -1
  52. package/src/assets/web-panel/assets/{Privacy-1QK70XJJ.js → Privacy-X7QLakEK.js} +1 -1
  53. package/src/assets/web-panel/assets/{ProjectInit-Dbh6fHo4.js → ProjectInit-D0AlRjbd.js} +2 -2
  54. package/src/assets/web-panel/assets/{ProjectSettings-CtqWEUUX.js → ProjectSettings-DYMl5xmt.js} +2 -2
  55. package/src/assets/web-panel/assets/Projects-CHQNv-qk.js +1 -0
  56. package/src/assets/web-panel/assets/{Providers-VRTSkt2N.js → Providers-TVCjZ2J6.js} +1 -1
  57. package/src/assets/web-panel/assets/{QuickAsk-CP2dz_95.js → QuickAsk--451B-MZ.js} +1 -1
  58. package/src/assets/web-panel/assets/{Recommend-Bc81SmNo.js → Recommend-BGGOKiGR.js} +1 -1
  59. package/src/assets/web-panel/assets/{Reputation-cRunHZiV.js → Reputation-BH4nds8K.js} +1 -1
  60. package/src/assets/web-panel/assets/{Row-BwL7ApAT.js → Row-D0pT0QQ0.js} +1 -1
  61. package/src/assets/web-panel/assets/{RssFeed-BVbyxvzm.js → RssFeed-DNU6r0C1.js} +3 -3
  62. package/src/assets/web-panel/assets/{Search-D5PgTvOP.js → Search-8pr5NiWu.js} +1 -1
  63. package/src/assets/web-panel/assets/{Security-Ddt1DCcC.js → Security-DL3-Rbou.js} +3 -3
  64. package/src/assets/web-panel/assets/{Services-6UaJxmZU.js → Services-D0-F3yHP.js} +2 -2
  65. package/src/assets/web-panel/assets/{Skeleton-DFRbEQwp.js → Skeleton-BUNukrAi.js} +1 -1
  66. package/src/assets/web-panel/assets/{Skills-5yq43K-X.js → Skills-MeuPy4i2.js} +1 -1
  67. package/src/assets/web-panel/assets/{Sla-yMroQlH9.js → Sla-DRFzpJxS.js} +1 -1
  68. package/src/assets/web-panel/assets/{SpeechSettings-B2S3Iamq.js → SpeechSettings-B74NyhKi.js} +1 -1
  69. package/src/assets/web-panel/assets/{SyncSettings-BkKtXU71.js → SyncSettings-DWZX4Em2.js} +2 -2
  70. package/src/assets/web-panel/assets/{Tasks-CBtNUwgq.js → Tasks-zBrdGeRn.js} +1 -1
  71. package/src/assets/web-panel/assets/{Templates-C2drh0s2.js → Templates-Dp_FFrKZ.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tenant-BLk2CVEv.js → Tenant-C53QENNf.js} +1 -1
  73. package/src/assets/web-panel/assets/{Terminal-mElJ0fhK.js → Terminal-DnD72zQh.js} +2 -2
  74. package/src/assets/web-panel/assets/{TimelineRenderer-D4E9FDsp.js → TimelineRenderer-Cfb2GB_R.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tokens-Cgmf0-_P.js → Tokens-CMLbuZMs.js} +1 -1
  76. package/src/assets/web-panel/assets/{Trigger-BRlJLDbx.js → Trigger-CLYPsW_7.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trust-C6RUSQhG.js → Trust-D3jxWR77.js} +1 -1
  78. package/src/assets/web-panel/assets/{UkeySign-Chi7u_hM.js → UkeySign-fNDw_KhV.js} +1 -1
  79. package/src/assets/web-panel/assets/{VideoEditing-4-bo8EmV.js → VideoEditing-D8csuHqj.js} +1 -1
  80. package/src/assets/web-panel/assets/{Wallet-B2hSD9eY.js → Wallet-Gemx68ru.js} +4 -4
  81. package/src/assets/web-panel/assets/{WebAuthn-D8xa8fun.js → WebAuthn-Wg6nAGh8.js} +4 -4
  82. package/src/assets/web-panel/assets/{WorkflowEditor-Db9dxskT.js → WorkflowEditor-BSr0116-.js} +1 -1
  83. package/src/assets/web-panel/assets/{chat-CXYLRZpi.js → chat-BcwDKrOw.js} +1 -1
  84. package/src/assets/web-panel/assets/{colors-CaKoXOVA.js → colors-CRwuUljZ.js} +1 -1
  85. package/src/assets/web-panel/assets/{compact-item-Br5NvOwQ.js → compact-item-BH9-TA7W.js} +1 -1
  86. package/src/assets/web-panel/assets/{createContext-B-yHAw0V.js → createContext-DHPD7o_2.js} +1 -1
  87. package/src/assets/web-panel/assets/devWarning--UYULS4h.js +1 -0
  88. package/src/assets/web-panel/assets/{hasIn-CqrdCz3g.js → hasIn-BUiPtAz2.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-KRKDnsR0.js → index-2MwQ3X6t.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-CvFe9Qyg.js → index-6sUosvN8.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-BWxntLTd.js → index-B6I9juJW.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-CQDhGgK-.js → index-BUZj4TZu.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-BRlkm8k6.js → index-BVGXk0kl.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-BzpkjYz4.js → index-BX4JG3HI.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DGtE2LX-.js → index-BjpXUPEm.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DHwefCFJ.js → index-C2i-topE.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DirWkR61.js → index-C4HqTPhK.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Byv9CEgj.js → index-CJ7N4Kq9.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DbrcBvEd.js → index-CTjTueAe.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-1jqJ37zO.js → index-CU_cl403.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-Ds4JSZQz.js → index-Che8xizE.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-ZB70zTAh.js → index-CiYqE6r2.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-B1IlWIb6.js → index-CjXX3_MF.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CuaLeS0m.js → index-Ck7VlFKq.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DaQkxUNc.js → index-CnxAcX-8.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CvJruKpV.js → index-CoD_ykaF.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-D6ngQeA0.js → index-CqZvL3PL.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BrruO38Y.js → index-CxSHxzVl.js} +3 -3
  109. package/src/assets/web-panel/assets/index-D-IknxcC.js +1 -0
  110. package/src/assets/web-panel/assets/{index-CIZKEANZ.js → index-D3OP_UGM.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BmV-MOO5.js → index-DBwWELfk.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-8ghdlyXM.js → index-DDfr0pto.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-D39l1vpr.js → index-DDyIWF6G.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DZ9ISv1n.js → index-DJhRnT33.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-nT_CmIwR.js → index-DSofQ6_z.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BeQiNau_.js → index-DY6005b1.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BjAkyQXg.js → index-DZjfQdtu.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-D98MYD3m.js → index-DcjCDs8_.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DE2mB1ae.js → index-DjzesLfN.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BQcTQlrC.js → index-DnSYxJLa.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-hsgVTIGX.js → index-Dt9hI0-B.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CMecOYUY.js → index-SJMQljkQ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BbZxkCWu.js → index-UNqiZIfY.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CVt4C93w.js → index-USRQuY0h.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BeE50mEy.js → index-X925i3Ec.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-W_LrSwhD.js → index-YGHrRaLk.js} +1 -1
  127. package/src/assets/web-panel/assets/index-ZfyW2JSr.js +1 -0
  128. package/src/assets/web-panel/assets/{initDefaultProps-CikG-5bi.js → initDefaultProps-DXCAtRs8.js} +1 -1
  129. package/src/assets/web-panel/assets/{motion--tkkEE3m.js → motion-x5-S0MDV.js} +1 -1
  130. package/src/assets/web-panel/assets/{move-D6xAZefU.js → move-luyXzjjS.js} +1 -1
  131. package/src/assets/web-panel/assets/{omit-CsD8Wwta.js → omit-Dqkw0CTp.js} +1 -1
  132. package/src/assets/web-panel/assets/{pickAttrs-D4qa94u9.js → pickAttrs-BIkNmysd.js} +1 -1
  133. package/src/assets/web-panel/assets/{placementArrow-9fx4sI6E.js → placementArrow-DuE-e6si.js} +1 -1
  134. package/src/assets/web-panel/assets/{responsiveObserve-DwYJKWhG.js → responsiveObserve-W8zBp_Wb.js} +1 -1
  135. package/src/assets/web-panel/assets/{slide-DFxU8IG1.js → slide-VrrEqbsQ.js} +1 -1
  136. package/src/assets/web-panel/assets/{statusUtils-DPAkc9NC.js → statusUtils-rEzF15_8.js} +1 -1
  137. package/src/assets/web-panel/assets/{styleChecker-D-ByG8n4.js → styleChecker-BIjl0JAf.js} +1 -1
  138. package/src/assets/web-panel/assets/{useFlexGapSupport-DwVLaYMd.js → useFlexGapSupport-BEg-Dj0H.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFs-CSyqOEiA.js → useFs-ZdzrfiGS.js} +1 -1
  140. package/src/assets/web-panel/assets/{usePersonalDataHub-B7qEu3ar.js → usePersonalDataHub-CRGBsZ6x.js} +1 -1
  141. package/src/assets/web-panel/assets/{vnode-4YgwyfPJ.js → vnode-uuyVczKn.js} +1 -1
  142. package/src/assets/web-panel/assets/{zoom-CPUWjtMS.js → zoom-CdJXg6jf.js} +1 -1
  143. package/src/assets/web-panel/index.html +1 -1
  144. package/src/commands/hub.js +71 -11
  145. package/src/lib/git-integration.js +8 -2
  146. package/src/lib/hub-llm-client.js +86 -29
  147. package/src/assets/web-panel/assets/MobileProjects-Bfp8_lJh.js +0 -1
  148. package/src/assets/web-panel/assets/OrderTableRenderer-BdA4JzRg.js +0 -1
  149. package/src/assets/web-panel/assets/Projects-C1vdepHb.js +0 -1
  150. package/src/assets/web-panel/assets/devWarning-B9dp57_Q.js +0 -1
  151. package/src/assets/web-panel/assets/index-Bd3PIxeQ.js +0 -1
  152. package/src/assets/web-panel/assets/index-WpnbyTfq.js +0 -1
@@ -10,24 +10,29 @@
10
10
  * retrieval works but the final LLM call fails. This adapter gives the CLI the
11
11
  * same "honor the user's active provider" behavior the desktop has.
12
12
  *
13
- * Privacy: OPT-IN ONLY via env `CC_HUB_LLM`. When unset, this returns null and
13
+ * Privacy: OPT-IN ONLY. The backend is selected by env `CC_HUB_LLM` (ephemeral,
14
+ * per-invocation) OR persistent config `hub.llm` (set once via
15
+ * `cc config set hub.llm config`). When BOTH are unset this returns null and
14
16
  * the caller keeps the safe local-Ollama default (the §11.2 privacy promise:
15
17
  * personal data stays on-device unless the user explicitly opts in). The
16
18
  * client always reports `isLocal: false`, so the AnalysisEngine still refuses
17
- * to USE it unless the `ask` command is given `--accept-non-local`
18
- * (or env `CC_HUB_ALLOW_NON_LOCAL`). Two independent gates: this one chooses
19
- * the backend, that one authorizes sending data off-device.
19
+ * to USE it unless the `ask` command authorizes egress — via --accept-non-local,
20
+ * env `CC_HUB_ALLOW_NON_LOCAL`, or (for a PERSISTENT cloud backend) the standing
21
+ * consent implied by `hub.llm` being set in config (see `isCloudHubConfigured`).
22
+ * Two independent gates: this one chooses the backend, that one authorizes
23
+ * sending data off-device.
20
24
  *
21
- * CC_HUB_LLM unset / ollama / local / off / 0 -> null (local Ollama default)
22
- * CC_HUB_LLM = config | auto | on | 1 -> config.llm.{provider,model,baseUrl,apiKey}
23
- * CC_HUB_LLM = <provider> -> that provider; reuse config
24
- * creds when config.llm.provider
25
- * matches, else provider default
26
- * baseUrl + key from env/config
25
+ * value unset / ollama / local / off / 0 -> null (local Ollama default)
26
+ * value = config | auto | on | 1 -> config.llm.{provider,model,baseUrl,apiKey}
27
+ * value = <provider> -> that provider; reuse config
28
+ * creds when config.llm.provider
29
+ * matches, else provider default
30
+ * baseUrl + key from env/config
31
+ * where `value` = env CC_HUB_LLM (wins) || config.hub.llm.
27
32
  *
28
33
  * Returns null (→ caller falls back to OllamaClient) when it can't build a
29
- * usable cloud client: provider resolves to ollama, or a cloud provider has no
30
- * API key. Never throws at build time — a bad CC_HUB_LLM just keeps the local
34
+ * usable cloud client: backend resolves to ollama, or a cloud provider has no
35
+ * API key. Never throws at build time — a bad value just keeps the local
31
36
  * default rather than bricking `cc hub`.
32
37
  *
33
38
  * Contract (mirrors pdh OllamaClient): `{ name, isLocal, chat(messages, opts)
@@ -50,33 +55,68 @@ const LOCAL_SENTINELS = new Set([
50
55
  ]);
51
56
  const CONFIG_SENTINELS = new Set(["config", "auto", "on", "1", "true", "yes"]);
52
57
 
58
+ /**
59
+ * Resolve the hub-LLM "spec" — what backend the user selected and how.
60
+ * env `CC_HUB_LLM` (ephemeral) wins over persistent config `hub.llm`.
61
+ * - `hub.llm` as a STRING → "config" | "<provider>" (creds reuse config.llm/env)
62
+ * - `hub.llm` as an OBJECT → { provider, model, baseUrl, apiKey, apiKeyEnv }
63
+ * (self-contained; lets the hub use a DIFFERENT key/account than cc-wide llm)
64
+ * @returns {{kind:"string"|"object", value:any, source:"env"|"config"}|null}
65
+ */
66
+ export function resolveHubSpec(config = {}, env = process.env) {
67
+ const envVal = String((env && env.CC_HUB_LLM) || "").trim();
68
+ if (envVal)
69
+ return { kind: "string", value: envVal.toLowerCase(), source: "env" };
70
+ const h = config && config.hub && config.hub.llm;
71
+ if (h == null) return null;
72
+ if (typeof h === "object") {
73
+ return { kind: "object", value: h, source: "config" };
74
+ }
75
+ const s = String(h).trim();
76
+ if (!s) return null;
77
+ return { kind: "string", value: s.toLowerCase(), source: "config" };
78
+ }
79
+
53
80
  /**
54
81
  * @param {{config?: object, env?: object}} [args]
55
82
  * @returns {{name:string,isLocal:boolean,chat:Function}|null}
56
83
  */
57
84
  export function buildCliHubLLM({ config = {}, env = process.env } = {}) {
58
- const raw = String(env.CC_HUB_LLM || "")
59
- .trim()
60
- .toLowerCase();
61
- if (LOCAL_SENTINELS.has(raw)) return null;
85
+ const spec = resolveHubSpec(config, env);
86
+ if (!spec) return null;
62
87
 
63
88
  const cfgLlm = (config && config.llm) || {};
89
+ const sameAs = (p) => String(cfgLlm.provider || "").toLowerCase() === p;
64
90
  let provider, model, baseUrl, apiKey;
65
91
 
66
- if (CONFIG_SENTINELS.has(raw)) {
67
- provider = String(cfgLlm.provider || "").toLowerCase();
68
- model = cfgLlm.model;
69
- baseUrl = cfgLlm.baseUrl;
70
- apiKey = cfgLlm.apiKey;
92
+ if (spec.kind === "object") {
93
+ // Self-contained hub creds — key can come from an explicit apiKey, a named
94
+ // env var (apiKeyEnv → switch where the key is read from), or fall back to
95
+ // the cc-wide config.llm creds when the provider matches.
96
+ const o = spec.value || {};
97
+ provider = String(o.provider || cfgLlm.provider || "").toLowerCase();
98
+ apiKey =
99
+ o.apiKey ||
100
+ (o.apiKeyEnv ? env[o.apiKeyEnv] : null) ||
101
+ (sameAs(provider) ? cfgLlm.apiKey : null);
102
+ model = o.model || (sameAs(provider) ? cfgLlm.model : null);
103
+ baseUrl = o.baseUrl || (sameAs(provider) ? cfgLlm.baseUrl : null);
71
104
  } else {
72
- provider = raw;
73
- // Reuse the saved credentials only when they belong to the requested
74
- // provider; otherwise fall back to provider defaults + env key.
75
- const sameProvider =
76
- String(cfgLlm.provider || "").toLowerCase() === provider;
77
- model = sameProvider ? cfgLlm.model : null;
78
- baseUrl = sameProvider ? cfgLlm.baseUrl : null;
79
- apiKey = sameProvider ? cfgLlm.apiKey : null;
105
+ const raw = spec.value;
106
+ if (LOCAL_SENTINELS.has(raw)) return null;
107
+ if (CONFIG_SENTINELS.has(raw)) {
108
+ provider = String(cfgLlm.provider || "").toLowerCase();
109
+ model = cfgLlm.model;
110
+ baseUrl = cfgLlm.baseUrl;
111
+ apiKey = cfgLlm.apiKey;
112
+ } else {
113
+ provider = raw;
114
+ // Reuse the saved credentials only when they belong to the requested
115
+ // provider; otherwise fall back to provider defaults + env key.
116
+ model = sameAs(provider) ? cfgLlm.model : null;
117
+ baseUrl = sameAs(provider) ? cfgLlm.baseUrl : null;
118
+ apiKey = sameAs(provider) ? cfgLlm.apiKey : null;
119
+ }
80
120
  }
81
121
 
82
122
  if (!provider || provider === "ollama") return null;
@@ -115,6 +155,23 @@ export function buildCliHubLLM({ config = {}, env = process.env } = {}) {
115
155
  };
116
156
  }
117
157
 
158
+ /**
159
+ * True when a PERSISTENT config (`hub.llm`, NOT the ephemeral env var) selects
160
+ * a usable non-local cloud backend. The `ask` command uses this as standing
161
+ * consent to send data off-device — a deliberate `cc config set hub.llm …` is
162
+ * the informed opt-in, so the user need not also pass --accept-non-local on
163
+ * every call. The ephemeral env path (CC_HUB_LLM) is deliberately NOT covered:
164
+ * a one-off backend override still requires an explicit egress flag.
165
+ * @returns {boolean}
166
+ */
167
+ export function isCloudHubConfigured(config = {}) {
168
+ const h = config && config.hub && config.hub.llm;
169
+ if (h == null) return false;
170
+ // Resolve config-only (env stripped) and confirm it builds a non-local client.
171
+ const llm = buildCliHubLLM({ config, env: {} });
172
+ return !!(llm && llm.isLocal === false);
173
+ }
174
+
118
175
  function trimBase(base) {
119
176
  return String(base).replace(/\/+$/, "");
120
177
  }
@@ -1 +0,0 @@
1
- import{I as n,J as g,c as l,K as r,N as u,P as h,U as o,R as t,Q as b}from"./vendor-BvqAck49.js";import{_ as v,b as m}from"./index-BrruO38Y.js";import{a7 as y,M}from"./icons-DP3uiYxy.js";const B={__name:"MobileProjects",setup(p,{expose:i}){i();const c=u(),{t:e}=m();function a(){c.push("/projects")}function _(){c.push("/mobile-bridge")}const s={router:c,t:e,goToProjects:a,goToMobileBridge:_,get useRouter(){return u},get useI18n(){return m},get MobileOutlined(){return M},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},x={class:"mobile-projects-placeholder"},O={class:"title"},k={class:"subtitle"},w={class:"explainer"};function T(p,i,c,e,a,_){const s=n("a-alert"),d=n("a-button"),f=n("a-space"),P=n("a-empty"),j=n("a-card");return h(),g("div",x,[l(j,null,{default:r(()=>[l(P,{description:!1},{image:r(()=>[l(e.MobileOutlined,{style:{fontSize:"64px",color:"#bfbfbf"}})]),default:r(()=>[o("h2",O,t(e.t("mobileProjects.title")),1),o("p",k,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",w,[o("h3",null,t(e.t("mobileProjects.currentDirection")),1),o("p",null,t(e.t("mobileProjects.currentDirectionBody")),1),o("ul",null,[o("li",null,t(e.t("mobileProjects.stepPhone")),1),o("li",null,t(e.t("mobileProjects.stepTap")),1),o("li",null,t(e.t("mobileProjects.stepPull")),1)]),o("h3",null,t(e.t("mobileProjects.reverseDirection")),1),o("p",null,t(e.t("mobileProjects.reverseDirectionBody")),1)]),l(f,{class:"actions"},{default:r(()=>[l(d,{type:"primary",onClick:e.goToProjects},{default:r(()=>[l(e.FolderOutlined),b(" "+t(e.t("mobileProjects.viewLocalProjects")),1)]),_:1}),l(d,{onClick:e.goToMobileBridge},{default:r(()=>[l(e.MobileOutlined),b(" "+t(e.t("mobileProjects.checkBridge")),1)]),_:1})]),_:1})]),_:1})]),_:1})])}const N=v(B,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-8vQYzk/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{N as default};
@@ -1 +0,0 @@
1
- import{I as k,P as l,J as u,U as s,R as n,c as i,K as v,Q as _,V as g,b as a}from"./vendor-BvqAck49.js";import{_ as w}from"./index-BrruO38Y.js";import"./icons-DP3uiYxy.js";const S={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const o=p,e=a(()=>o.event.content||{}),d=a(()=>o.event.extra||{}),m=a(()=>d.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=a(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),y=a(()=>{const t=e.value.amount??e.value.price??e.value.total;return t==null?"—":`${e.value.currency||"¥"} ${typeof t=="number"?t.toFixed(2):t}`}),T=a(()=>d.value.orderNo||e.value.orderNo||e.value.orderId),f=a(()=>e.value.status||e.value.state),b=a(()=>{const t=(f.value||"").toLowerCase();return t.includes("成功")||t.includes("succe")||t.includes("paid")?"green":t.includes("退")||t.includes("refund")?"orange":t.includes("失败")||t.includes("fail")?"red":"default"}),h=a(()=>{if(!o.event.occurredAt)return"";const t=new Date(o.event.occurredAt);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}),x={props:o,c:e,e:d,merchantText:m,itemText:c,amountText:y,orderNo:T,statusText:f,statusColor:b,formattedTime:h,computed:a};return Object.defineProperty(x,"__isScriptSetup",{enumerable:!1,value:!0}),x}},N={class:"order-card"},C={class:"head"},O={class:"time"},V={class:"row"},R={class:"val"},B={class:"row"},D={class:"val"},I={class:"row amount-row"},j={class:"val amount"},A={key:0,class:"row"},F={class:"val mono"},M={key:1,class:"row"};function P(p,r,o,e,d,m){const c=k("a-tag");return l(),u("div",N,[s("div",C,[s("span",O,n(e.formattedTime),1),i(c,{color:"gold"},{default:v(()=>[_(n(o.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(o.event.subtype),1)]),_:1})]),s("div",V,[r[0]||(r[0]=s("span",{class:"key"},"商户",-1)),s("span",R,n(e.merchantText),1)]),s("div",B,[r[1]||(r[1]=s("span",{class:"key"},"商品/项目",-1)),s("span",D,n(e.itemText),1)]),s("div",I,[r[2]||(r[2]=s("span",{class:"key"},"金额",-1)),s("span",j,n(e.amountText),1)]),e.orderNo?(l(),u("div",A,[r[3]||(r[3]=s("span",{class:"key"},"单号",-1)),s("span",F,n(e.orderNo),1)])):g("v-if",!0),e.statusText?(l(),u("div",M,[r[4]||(r[4]=s("span",{class:"key"},"状态",-1)),i(c,{color:e.statusColor},{default:v(()=>[_(n(e.statusText),1)]),_:1},8,["color"])])):g("v-if",!0)])}const E=w(S,[["render",P],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-8vQYzk/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{E 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-BvqAck49.js";import{_ as we,b as re,u as ie,d}from"./index-BrruO38Y.js";import{u as de}from"./useShellMode-CgR0wCYM.js";import{aM as ke,aN as Fe,aO as be,f as je,a4 as Ce,a7 as xe,as as Oe,R as Se}from"./icons-DP3uiYxy.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),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"}],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 Q(o){switch(o){case"synced":return"green";case"pending":return"orange";case"conflict":return"red";case"error":return"red";default:return"default"}}function K(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 Y(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 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:M,filteredProjects:J,statusColor:g,syncColor:Q,formatTime:K,loadAll:C,onRowClick:Y,openDetail:V,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"),M=i("a-popconfirm"),J=i("a-table"),g=i("a-descriptions-item"),Q=i("a-descriptions"),K=i("a-divider"),C=i("a-empty"),Y=i("a-list-item"),V=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(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(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(Q,{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(K,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(Y,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(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",Le],["__scopeId","data-v-019ac5aa"],["__file","/tmp/cc-web-panel-8vQYzk/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
@@ -1 +0,0 @@
1
- import{O as r}from"./index-BrruO38Y.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-Bht2QpqM.js";import{U as t}from"./index-BrruO38Y.js";import"./vendor-BvqAck49.js";import"./index-BRlkm8k6.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-BwL7ApAT.js";import{U as t}from"./index-BrruO38Y.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-DwYJKWhG.js";import"./useFlexGapSupport-DwVLaYMd.js";import"./styleChecker-D-ByG8n4.js";import"./index-BRlkm8k6.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};