chainlesschain 0.162.96 → 0.162.97

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 (162) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-Bo9Ux24z.js → AIOps-C1YvIYh5.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-CExgXSQT.js → ActionButton-jqcXEakj.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-BNnZhRTZ.js → Analytics-C8Xwqd3_.js} +2 -2
  5. package/src/assets/web-panel/assets/{AppLayout-D9xfqFCT.js → AppLayout-Dx5ypTfA.js} +4 -4
  6. package/src/assets/web-panel/assets/{Audit-Cpgu8uCw.js → Audit-1GZ4Tv2f.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-CHdEJnNE.js → Backup-CexR2hyk.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-Cbw-PxBq.js → BaseInput-DwAruKdy.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-ChHTZK_6.js → Chat-W2FkU5BY.js} +6 -6
  10. package/src/assets/web-panel/assets/{ChatBubbleRenderer-Dl6z6ZH7.js → ChatBubbleRenderer-BCLnhLfu.js} +1 -1
  11. package/src/assets/web-panel/assets/{Checkbox-Cj8d9bru.js → Checkbox-Dkh5JY5B.js} +1 -1
  12. package/src/assets/web-panel/assets/{Codegen-C2YobW4j.js → Codegen-LfYOgsdA.js} +1 -1
  13. package/src/assets/web-panel/assets/{Col-CxfV5FGT.js → Col-DEgketAC.js} +1 -1
  14. package/src/assets/web-panel/assets/{Community-CiwOASMj.js → Community-LeFQMaZm.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compact-CTg_2iKW.js → Compact-CrlKYvBc.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compliance-HMbsTmtw.js → Compliance-ca_4PGYF.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cowork-DyNDqGR2.js → Cowork-BcMWqh2a.js} +2 -2
  18. package/src/assets/web-panel/assets/{Cron-9-x5M7qy.js → Cron-pVVEA3dw.js} +2 -2
  19. package/src/assets/web-panel/assets/{Crosschain-4msgDaYJ.js → Crosschain-CiKSGTqp.js} +1 -1
  20. package/src/assets/web-panel/assets/{DID--2Beb5Po.js → DID-B2bGzdOj.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dashboard-T6nq0Lzs.js → Dashboard-sQ6jcgCn.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dropdown-D_Q6T10v.js → Dropdown-rFx_8P04.js} +1 -1
  23. package/src/assets/web-panel/assets/{EmailListRenderer-TnN21bJx.js → EmailListRenderer-smw2hh6f.js} +1 -1
  24. package/src/assets/web-panel/assets/{FamilyGuardDashboard-kky_uIij.js → FamilyGuardDashboard-CZhg2_S2.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-C1GkNY4B.js → Federation-DQE-368G.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-5-_Fc5YV.js → FormItemContext-2XPb9izr.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-CmHiB7sr.js → GenericCardRenderer-DCGMz5E6.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-Cuci_BPI.js → Git-BFwrxK4Q.js} +2 -2
  29. package/src/assets/web-panel/assets/{Governance-BU0cO2LD.js → Governance-ChxBRwG1.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-BDFNgEcx.js → Inference-C7kyknu_.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-DITXUzHz.js → KnowledgeGraph-BsMd4XAt.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-Ea-07CRd.js → Logs-Bs3yrpow.js} +2 -2
  33. package/src/assets/web-panel/assets/{Marketplace-D6OBbRVG.js → Marketplace-Cc29jdBv.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-eiKpIJMi.js → McpTools-zYpYsUsl.js} +3 -3
  35. package/src/assets/web-panel/assets/{Memory-M-X-T8UF.js → Memory-x9r4yKtS.js} +2 -2
  36. package/src/assets/web-panel/assets/{MobileBridge-xcZb9Ekv.js → MobileBridge-CjUo8prx.js} +2 -2
  37. package/src/assets/web-panel/assets/{MobileProjects-DCfoTPRC.js → MobileProjects-Cmz4wVrF.js} +1 -1
  38. package/src/assets/web-panel/assets/{Mtc-BWfGDzD8.js → Mtc-Y-SBnNxm.js} +5 -5
  39. package/src/assets/web-panel/assets/{MtcAudit-imBuld-U.js → MtcAudit-ogiKnrxj.js} +2 -2
  40. package/src/assets/web-panel/assets/{Multisig-C2kcsq7I.js → Multisig-C1hygkFR.js} +3 -3
  41. package/src/assets/web-panel/assets/{NLProgramming-DObvXSXP.js → NLProgramming-fWWYiTsY.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-C-6OGJMe.js → Notes-CkCNF4gC.js} +4 -4
  43. package/src/assets/web-panel/assets/{NotificationSettings-ub7Ozxci.js → NotificationSettings-DThB7WQG.js} +1 -1
  44. package/src/assets/web-panel/assets/{OrderTableRenderer-CR2W89Vk.js → OrderTableRenderer-Dh64aMq6.js} +1 -1
  45. package/src/assets/web-panel/assets/{Organization-DNA_Wty7.js → Organization-BSY16zvP.js} +4 -4
  46. package/src/assets/web-panel/assets/{Overflow-rT4Wb4rQ.js → Overflow-C_TDh18K.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-CK-hARKv.js → P2P-CvxZk6og.js} +2 -2
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-C2pbtNbT.js → PdhVaultBrowser-0JZ5JF4M.js} +5 -5
  49. package/src/assets/web-panel/assets/{Permissions-B8EIEqGJ.js → Permissions-DV8ubpjM.js} +3 -3
  50. package/src/assets/web-panel/assets/{PersonalDataHub-BxNVNU3s.js → PersonalDataHub-g2Dgls8e.js} +2 -2
  51. package/src/assets/web-panel/assets/{Pipeline-CT9pbkyY.js → Pipeline-DGp8zQ0C.js} +1 -1
  52. package/src/assets/web-panel/assets/{Privacy-DhCNd2CS.js → Privacy-C0uHrjWR.js} +1 -1
  53. package/src/assets/web-panel/assets/{ProjectInit-Qngnx-vQ.js → ProjectInit-2XGICaFt.js} +2 -2
  54. package/src/assets/web-panel/assets/{ProjectSettings-Dfn-nQc1.js → ProjectSettings-Cfy72e0Q.js} +2 -2
  55. package/src/assets/web-panel/assets/Projects-Xsvk_kKT.js +1 -0
  56. package/src/assets/web-panel/assets/{Providers-4o9B_n-X.js → Providers-vuvDVg7U.js} +1 -1
  57. package/src/assets/web-panel/assets/{QuickAsk-bs1qvF30.js → QuickAsk-BUy7kPyQ.js} +1 -1
  58. package/src/assets/web-panel/assets/{Recommend-CuEnKA2K.js → Recommend-DlzpC_JE.js} +1 -1
  59. package/src/assets/web-panel/assets/{Reputation-DbfvmRb2.js → Reputation-BiWFwPMh.js} +1 -1
  60. package/src/assets/web-panel/assets/{Row-DvMJGAI3.js → Row-dmfZBK-k.js} +1 -1
  61. package/src/assets/web-panel/assets/{RssFeed-oJ0BZvmA.js → RssFeed-Cf6tlRKq.js} +2 -2
  62. package/src/assets/web-panel/assets/{Search-DnIVrY9O.js → Search-DhzXDRAJ.js} +1 -1
  63. package/src/assets/web-panel/assets/{Security-CIWhI_Tc.js → Security-C-bTfgeJ.js} +3 -3
  64. package/src/assets/web-panel/assets/{Services-DLrnpjwm.js → Services-D3KNwBqu.js} +2 -2
  65. package/src/assets/web-panel/assets/{Skeleton-CYmqgtVb.js → Skeleton-CHH8i1xY.js} +1 -1
  66. package/src/assets/web-panel/assets/{Skills-BUzCkoeu.js → Skills-DHiONX0z.js} +1 -1
  67. package/src/assets/web-panel/assets/{Sla-DYRE4bnS.js → Sla-DwWMb-Ui.js} +1 -1
  68. package/src/assets/web-panel/assets/{SpeechSettings-_6MurdOg.js → SpeechSettings-DAq64iWB.js} +1 -1
  69. package/src/assets/web-panel/assets/{SyncSettings-UIdnF5Li.js → SyncSettings-DJU-kHko.js} +2 -2
  70. package/src/assets/web-panel/assets/{Tasks-COx2CjT8.js → Tasks-RAIzA3u-.js} +1 -1
  71. package/src/assets/web-panel/assets/{Templates-BcHAmkZo.js → Templates-By4cbadT.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tenant-CjYQS8yZ.js → Tenant-kCAXsxWu.js} +1 -1
  73. package/src/assets/web-panel/assets/{Terminal-BmfOPcWt.js → Terminal-D8pup_CO.js} +2 -2
  74. package/src/assets/web-panel/assets/{TimelineRenderer-D5HuarNQ.js → TimelineRenderer-Bk2c9TUI.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tokens-C_fbProA.js → Tokens-B0wTiZRa.js} +1 -1
  76. package/src/assets/web-panel/assets/{Trigger-JPulpRx8.js → Trigger-Ca_9t0gk.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trust-CnO-062O.js → Trust-BnfNDDDm.js} +1 -1
  78. package/src/assets/web-panel/assets/{UkeySign-HpNovvau.js → UkeySign-fnlF2-Yr.js} +1 -1
  79. package/src/assets/web-panel/assets/{VideoEditing-yMncxH7y.js → VideoEditing-Cfshhzyw.js} +1 -1
  80. package/src/assets/web-panel/assets/{Wallet-Cug-t7Np.js → Wallet-BWMpDOLG.js} +4 -4
  81. package/src/assets/web-panel/assets/{WebAuthn--U1-NR-3.js → WebAuthn-B6xeXZvw.js} +3 -3
  82. package/src/assets/web-panel/assets/{WorkflowEditor-R-XvSJ3S.js → WorkflowEditor-Cb3-FPCE.js} +1 -1
  83. package/src/assets/web-panel/assets/{chat-CCI1i6Rp.js → chat-CP_opuMK.js} +1 -1
  84. package/src/assets/web-panel/assets/{colors-C-mqoaLt.js → colors-RLzfjxRQ.js} +1 -1
  85. package/src/assets/web-panel/assets/{compact-item-De_N2iRR.js → compact-item-BTRloNKV.js} +1 -1
  86. package/src/assets/web-panel/assets/{createContext-DbTM6sjZ.js → createContext-gXgXTLlU.js} +1 -1
  87. package/src/assets/web-panel/assets/devWarning-CYlmApo_.js +1 -0
  88. package/src/assets/web-panel/assets/{hasIn-D0Adylyc.js → hasIn-CrIpxkRC.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-BtE3cw9m.js → index-AsI1SqnE.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-B6hgy5VC.js → index-B3L5vTSs.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-Ds8NJVEL.js → index-B5sN_pwd.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-T3VhH8cO.js → index-BEcRPNHv.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-BMmeiw88.js → index-BVrcoJe2.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-BU6XtnSx.js → index-BewxG36A.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-zkTiW6d6.js → index-Bi87H9yk.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-qUSZJcgw.js → index-Bl4OQ--4.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-w3f6lqkD.js → index-BlE2lCS-.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-TDY1o0w3.js → index-BlS91Ac0.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CIEiQl1j.js → index-Bm0cNeeQ.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-B7XnpLHk.js → index-Bo2Fl2j7.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-D0gBsqTX.js → index-Bsz3X-aU.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-TRy2Gc3V.js → index-BurvDWMS.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DWT18hDG.js → index-BzBLtthb.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DjQA0Vez.js → index-C0wmEN2j.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Co1UkcFX.js → index-C4bBR-Vd.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-xdMc71Kh.js → index-COhACL0I.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-jhy5KQvg.js → index-CQ-cnhZM.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-B7gw-tDm.js → index-CRr99L7q.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-C9ej-MF0.js → index-CaTkUkJp.js} +3 -3
  110. package/src/assets/web-panel/assets/{index-CKgaW9E5.js → index-CfOjPxso.js} +1 -1
  111. package/src/assets/web-panel/assets/index-Cf_SLgtj.js +1 -0
  112. package/src/assets/web-panel/assets/{index-DuP-8HWu.js → index-Ch_TYQNW.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CzP5d5LW.js → index-CisGGaF3.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-D5F6shtn.js → index-DA-_2qTs.js} +1 -1
  115. package/src/assets/web-panel/assets/index-DYBIDVGn.js +1 -0
  116. package/src/assets/web-panel/assets/{index-ftFRZbuc.js → index-DZxK7MW9.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DaXb4B9P.js → index-DiXnGU0A.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-xhX5eg2Z.js → index-DsiyfyBE.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-D0NJ5lRi.js → index-G_OgtHiC.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DwLTiJ31.js → index-IjV-dnE8.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-W1OMxCmI.js → index-Mltfj22U.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BBgDgkwW.js → index-U-kmEJdu.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-Bi7VUG0R.js → index-cgf-OVry.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DVtamtlm.js → index-ch8zcf-h.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CY0KKR5f.js → index-cqOT5RiJ.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-iGPGaORA.js → index-cywkZJ-I.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-AY937BxS.js → index-sE_I7gVL.js} +1 -1
  128. package/src/assets/web-panel/assets/{initDefaultProps-CIHqouWk.js → initDefaultProps-DMwnVZzH.js} +1 -1
  129. package/src/assets/web-panel/assets/{motion-D1iUKftk.js → motion-Dnpjpvo7.js} +1 -1
  130. package/src/assets/web-panel/assets/{move-YOpWjmjL.js → move-iuRh5U9Y.js} +1 -1
  131. package/src/assets/web-panel/assets/{omit-C_1357UY.js → omit-Bl4WRV59.js} +1 -1
  132. package/src/assets/web-panel/assets/{pickAttrs-CDb4dq6o.js → pickAttrs-B9KSXaep.js} +1 -1
  133. package/src/assets/web-panel/assets/{placementArrow-D-OGYyhd.js → placementArrow-TEGIow4r.js} +1 -1
  134. package/src/assets/web-panel/assets/{responsiveObserve-hS-j69A0.js → responsiveObserve--BECM92v.js} +1 -1
  135. package/src/assets/web-panel/assets/{slide-tnjuvphU.js → slide-Ca8G7XbL.js} +1 -1
  136. package/src/assets/web-panel/assets/{statusUtils-BERfMMcU.js → statusUtils-8QPG_T3D.js} +1 -1
  137. package/src/assets/web-panel/assets/{styleChecker-DKpl2K9E.js → styleChecker-p3FsA6mg.js} +1 -1
  138. package/src/assets/web-panel/assets/{useFlexGapSupport-C_sX4D3N.js → useFlexGapSupport-Ct0yIzrp.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFs-DBcxC1vK.js → useFs-3nlByl_3.js} +1 -1
  140. package/src/assets/web-panel/assets/{usePersonalDataHub-CeoDf2XI.js → usePersonalDataHub-N3OsoSRM.js} +1 -1
  141. package/src/assets/web-panel/assets/{vnode-DC9Pmj_u.js → vnode-Cfe3ywq3.js} +1 -1
  142. package/src/assets/web-panel/assets/{zoom-CZA58J7M.js → zoom-DVBuDS_3.js} +1 -1
  143. package/src/assets/web-panel/index.html +1 -1
  144. package/src/commands/activitypub.js +3 -18
  145. package/src/commands/agents.js +18 -4
  146. package/src/commands/command.js +12 -2
  147. package/src/commands/dao.js +3 -15
  148. package/src/commands/dlp.js +1 -6
  149. package/src/commands/hub.js +125 -0
  150. package/src/index.js +2 -0
  151. package/src/lib/a2a-protocol.js +1 -0
  152. package/src/lib/agent-core.js +2 -0
  153. package/src/lib/chat-core.js +6 -1
  154. package/src/lib/personal-data-hub-wiring.js +3 -3
  155. package/src/repl/agent-repl.js +11 -3
  156. package/src/repl/chat-repl.js +11 -2
  157. package/src/runtime/agent-core.js +7 -3
  158. package/src/runtime/headless-stream.js +69 -4
  159. package/src/assets/web-panel/assets/Projects-BKdiSaPR.js +0 -1
  160. package/src/assets/web-panel/assets/devWarning-OcLPHSl5.js +0 -1
  161. package/src/assets/web-panel/assets/index-7E_mHkDU.js +0 -1
  162. package/src/assets/web-panel/assets/index-CbV3-WlB.js +0 -1
package/src/index.js CHANGED
@@ -62,6 +62,7 @@ import { registerContextCommand } from "./commands/context.js";
62
62
  import { registerCheckpointCommand } from "./commands/checkpoint.js";
63
63
  import { registerGoalCommand } from "./commands/goal.js";
64
64
  import { registerCommandCommand } from "./commands/command.js";
65
+ import { registerAgentsCommand } from "./commands/agents.js";
65
66
  import { registerCompactCommand } from "./commands/compact.js";
66
67
  import { registerLoopCommand } from "./commands/loop.js";
67
68
  import { registerReviewCommand } from "./commands/review.js";
@@ -478,6 +479,7 @@ export function createProgram(opts = {}) {
478
479
  registerCheckpointCommand(program);
479
480
  registerGoalCommand(program);
480
481
  registerCommandCommand(program);
482
+ registerAgentsCommand(program);
481
483
  registerCompactCommand(program);
482
484
  registerLoopCommand(program);
483
485
  registerReviewCommand(program);
@@ -5,6 +5,7 @@
5
5
  * capability negotiation, and peer discovery.
6
6
  */
7
7
 
8
+
8
9
  // Safe JSON-array parse for values read back from the DB (capabilities / skills /
9
10
  // history / artifacts are stored as JSON strings). Written via JSON.stringify so
10
11
  // normally valid, but a corrupted or externally-edited DB must not crash agent
@@ -12,6 +12,8 @@ export {
12
12
  buildSystemPrompt,
13
13
  executeTool,
14
14
  computeProposedEdit,
15
+ editNotebookCell,
16
+ renderNotebook,
15
17
  classifyError,
16
18
  isValidPackageName,
17
19
  chatWithTools,
@@ -48,7 +48,12 @@ function makeStallGuard(
48
48
  if (hintTimer) clearTimeout(hintTimer);
49
49
  hintTimer = setTimeout(() => {
50
50
  try {
51
- onHint(hintMs);
51
+ // 2nd arg = the hard abort deadline (stallMs) so the hint can tell
52
+ // the user when the silent request will time out. Note the chat path
53
+ // surfaces a stall error rather than auto-retrying (see the dispatch
54
+ // loop in chatStream), so callers should word it "will time out",
55
+ // not "will retry".
56
+ onHint(hintMs, stallMs);
52
57
  } catch {
53
58
  /* hint is best-effort — never affect the stream */
54
59
  }
@@ -1377,7 +1377,7 @@ async function initHub() {
1377
1377
 
1378
1378
  // ─── Phase 12.6.8 — WeChat account persistence helpers (cli mirror) ──────
1379
1379
 
1380
- function loadWechatAccounts(filePath) {
1380
+ export function loadWechatAccounts(filePath) {
1381
1381
  try {
1382
1382
  if (!existsSync(filePath)) return [];
1383
1383
  const raw = readFileSync(filePath, "utf-8");
@@ -1420,7 +1420,7 @@ function saveWechatAccounts(filePath, accounts) {
1420
1420
 
1421
1421
  // ─── Email account persistence (Phase 5.6) ───────────────────────────────
1422
1422
 
1423
- function loadEmailAccounts(filePath) {
1423
+ export function loadEmailAccounts(filePath) {
1424
1424
  try {
1425
1425
  if (!existsSync(filePath)) return [];
1426
1426
  const raw = readFileSync(filePath, "utf-8");
@@ -1437,7 +1437,7 @@ function saveEmailAccounts(filePath, accounts) {
1437
1437
 
1438
1438
  // ─── Alipay account persistence (Phase 6) ───────────────────────────────
1439
1439
 
1440
- function loadAlipayAccounts(filePath) {
1440
+ export function loadAlipayAccounts(filePath) {
1441
1441
  try {
1442
1442
  if (!existsSync(filePath)) return [];
1443
1443
  const raw = readFileSync(filePath, "utf-8");
@@ -3271,12 +3271,20 @@ export async function startAgentRepl(options = {}) {
3271
3271
  // the API has gone silent mid-response — tell the user we're still
3272
3272
  // waiting instead of leaving a frozen spinner. stderr so it never
3273
3273
  // corrupts the streamed answer on stdout.
3274
- onStall: (ms) =>
3274
+ onStall: (ms, timeoutMs) => {
3275
+ const silent = Math.round(ms / 1000);
3276
+ // 2.1.185: when a hard inactivity timeout is set, tell the user when
3277
+ // the stalled stream will auto-retry instead of leaving them unsure
3278
+ // whether it's hung forever.
3279
+ const retryIn =
3280
+ timeoutMs > ms ? Math.round((timeoutMs - ms) / 1000) : 0;
3281
+ const suffix = retryIn > 0 ? ` · will retry in ${retryIn}s` : "";
3275
3282
  process.stderr.write(
3276
3283
  chalk.dim(
3277
- ` ⏳ waiting for API response (silent ${Math.round(ms / 1000)}s)…\n`,
3284
+ ` ⏳ waiting for API response (silent ${silent}s)${suffix}…\n`,
3278
3285
  ),
3279
- ),
3286
+ );
3287
+ },
3280
3288
  // Hard inactivity timeout: abort + retry a dead-but-open stream instead
3281
3289
  // of hanging forever. undefined → agent-core's 180s default (matches cc
3282
3290
  // chat/ask); config.llm.streamStallTimeoutMs tunes or disables (0).
@@ -186,10 +186,19 @@ export async function startChatRepl(options = {}) {
186
186
  // Stall hint (cc agent parity): the connection is alive but the API has
187
187
  // gone silent — reassure instead of a frozen cursor. stderr so it never
188
188
  // corrupts the streamed answer on stdout.
189
- const onStall = (ms) =>
189
+ const onStall = (ms, timeoutMs) => {
190
+ const silent = Math.round(ms / 1000);
191
+ // 2.1.185: surface the abort deadline so the user knows when the silent
192
+ // request gives up. The chat path aborts (and surfaces an error) on
193
+ // stall rather than auto-retrying like the agent path, so the wording is
194
+ // "will time out", not "will retry".
195
+ const timeoutIn =
196
+ timeoutMs > ms ? Math.round((timeoutMs - ms) / 1000) : 0;
197
+ const suffix = timeoutIn > 0 ? ` · will time out in ${timeoutIn}s` : "";
190
198
  process.stderr.write(
191
- `\x1b[2m ⏳ waiting for API response (silent ${Math.round(ms / 1000)}s)…\x1b[0m\n`,
199
+ `\x1b[2m ⏳ waiting for API response (silent ${silent}s)${suffix}…\x1b[0m\n`,
192
200
  );
201
+ };
193
202
 
194
203
  if (sessionId)
195
204
  appendEvent(sessionId, "user_message", { content: trimmed });
@@ -3386,8 +3386,9 @@ function _finalizeTruncatedStream(finalize, state) {
3386
3386
  }
3387
3387
 
3388
3388
  // Wrap a ReadableStream reader so the read loop yields chunk values while a
3389
- // watchdog (a) fires `onStall(elapsedMs)` at most once per silent gap longer
3390
- // than `stallMs` (2.1.185 stream-stall hint) and (b) when `stallTimeoutMs` is
3389
+ // watchdog (a) fires `onStall(elapsedMs, stallTimeoutMs)` at most once per silent
3390
+ // gap longer than `stallMs` (2.1.185 stream-stall hint; the 2nd arg lets the hint
3391
+ // surface the auto-retry deadline, 0 when no timeout) and (b) — when `stallTimeoutMs` is
3391
3392
  // set — cancels the reader and throws a RETRYABLE ETIMEDOUT after that long a
3392
3393
  // silence, so a permanently dead-but-open connection recovers via the retry
3393
3394
  // layer instead of hanging forever. The SAME in-flight read() promise is
@@ -3454,7 +3455,10 @@ export async function* _iterateStreamWithStall(reader, opts = {}) {
3454
3455
  if (onStall && !notified && Date.now() - start >= stallMs) {
3455
3456
  notified = true;
3456
3457
  try {
3457
- onStall(Date.now() - start);
3458
+ // 2.1.185: pass the hard-timeout deadline so the hint can tell the
3459
+ // user when the dead-but-open stream will be auto-retried (0 = no
3460
+ // timeout configured → caller shows no retry deadline).
3461
+ onStall(Date.now() - start, timeoutMs || 0);
3458
3462
  } catch {
3459
3463
  /* stall hint is best-effort — never break the stream over it */
3460
3464
  }
@@ -172,13 +172,46 @@ export function parseInputEvent(line) {
172
172
  }
173
173
  }
174
174
  images = [...new Set(images)].slice(0, 8);
175
+ // §3.5.10 接线6: optional per-turn LLM override (PDH privacy-tier switch) —
176
+ // {"type":"user","text":…,"llm":{"provider","model","baseUrl"?,"apiKey"?}}.
177
+ // Switches THIS turn's model (e.g. cloud → your own PC Ollama) without
178
+ // restarting the session. Reuses the same per-turn loopOptions seam as vision.
179
+ const llm = sanitizeLlmHint(
180
+ obj && typeof obj === "object" ? obj.llm || msg.llm : null,
181
+ );
175
182
  if (typeof content !== "string" || !content.trim()) {
176
183
  // An image-only turn is valid — give the model something to act on.
177
- if (images.length)
178
- return { text: "Please look at the attached image(s).", images };
184
+ if (images.length) {
185
+ const r = { text: "Please look at the attached image(s).", images };
186
+ if (llm) r.llm = llm;
187
+ return r;
188
+ }
179
189
  return null;
180
190
  }
181
- return images.length ? { text: content, images } : { text: content };
191
+ const result = images.length ? { text: content, images } : { text: content };
192
+ if (llm) result.llm = llm;
193
+ return result;
194
+ }
195
+
196
+ /**
197
+ * §3.5.10 接线6: sanitize a per-turn LLM override hint. Requires at least a
198
+ * provider or model (string); baseUrl/apiKey optional. Returns null when absent
199
+ * or malformed (the turn then uses the session default).
200
+ */
201
+ export function sanitizeLlmHint(raw) {
202
+ if (!raw || typeof raw !== "object") return null;
203
+ const str = (v) => (typeof v === "string" && v.trim() ? v.trim() : null);
204
+ const provider = str(raw.provider);
205
+ const model = str(raw.model);
206
+ if (!provider && !model) return null;
207
+ const hint = {};
208
+ if (provider) hint.provider = provider;
209
+ if (model) hint.model = model;
210
+ const baseUrl = str(raw.baseUrl);
211
+ if (baseUrl) hint.baseUrl = baseUrl;
212
+ const apiKey = str(raw.apiKey);
213
+ if (apiKey) hint.apiKey = apiKey;
214
+ return hint;
182
215
  }
183
216
 
184
217
  /**
@@ -1141,6 +1174,18 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1141
1174
  }
1142
1175
  }
1143
1176
 
1177
+ // §3.5.10 接线6: explicit per-turn LLM override (PDH privacy-tier switch).
1178
+ // Applies to THIS turn only; the vision override (above) still wins on image
1179
+ // turns since an image needs a vision-capable model.
1180
+ const turnLlmOverride = parsed.llm || null;
1181
+ if (turnLlmOverride && !turnVisionLlm) {
1182
+ writeErr(
1183
+ ` [llm] this turn → ${turnLlmOverride.provider || provider}/${
1184
+ turnLlmOverride.model || "(session model)"
1185
+ }\n`,
1186
+ );
1187
+ }
1188
+
1144
1189
  messages.push({ role: "user", content: turnContent });
1145
1190
  if (persist) {
1146
1191
  try {
@@ -1165,8 +1210,28 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1165
1210
  messages,
1166
1211
  {
1167
1212
  ...loopOptionsBase,
1213
+ // §3.5.10 接线6: explicit per-turn LLM override (privacy-tier switch);
1214
+ // only the fields provided are overridden (e.g. provider+model+baseUrl
1215
+ // to route to your own PC Ollama for one turn).
1216
+ ...(turnLlmOverride
1217
+ ? {
1218
+ ...(turnLlmOverride.provider
1219
+ ? { provider: turnLlmOverride.provider }
1220
+ : {}),
1221
+ ...(turnLlmOverride.model
1222
+ ? { model: turnLlmOverride.model }
1223
+ : {}),
1224
+ ...(turnLlmOverride.baseUrl
1225
+ ? { baseUrl: turnLlmOverride.baseUrl }
1226
+ : {}),
1227
+ ...(turnLlmOverride.apiKey
1228
+ ? { apiKey: turnLlmOverride.apiKey }
1229
+ : {}),
1230
+ }
1231
+ : {}),
1168
1232
  // Image turn → switch this turn's provider/model/baseUrl/apiKey to
1169
- // the vision LLM (model only; same account/key/baseUrl).
1233
+ // the vision LLM (model only; same account/key/baseUrl). Wins over an
1234
+ // explicit llm override above (an image needs a vision model).
1170
1235
  ...(turnVisionLlm
1171
1236
  ? {
1172
1237
  provider: turnVisionLlm.provider,
@@ -1 +0,0 @@
1
- import{I as i,J as A,U as I,R as s,Q as r,c as t,K as a,V as _,S as x,o as oe,b as ee,r as u,P as p,F as ne,a2 as ge}from"./vendor-BvqAck49.js";import{_ as we,b as re,u as ie,d}from"./index-C9ej-MF0.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),U=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 K(o){switch(o){case"synced":return"green";case"pending":return"orange";case"conflict":return"red";case"error":return"red";default:return"default"}}function Q(o){return!o&&o!==0?"-":new Date(typeof o=="number"?o:parseInt(o,10)).toLocaleString("zh-CN",{hour12:!1})}async function C(){B.value=!0;try{const o=await w("project.list",{limit:500},"project list --limit 500 --json",1e4);y.value=Array.isArray(o?.projects)?o.projects:Array.isArray(o)?o:[]}catch(o){d.error("加载失败: "+(o.message||o)),y.value=[]}finally{B.value=!1}}function G(o){return{onClick:()=>V(o)}}async function V(o){v.value=o,P.value=!0,k.value=!0,U.value=[];try{const f=await w("project.listFiles",{projectId:o.id,limit:200},`project list-files ${o.id} --json`,8e3);U.value=Array.isArray(f?.files)?f.files:[]}catch{U.value=[]}finally{k.value=!1}}async function H(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:""},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:""}),h=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:""},h.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);U.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}'`),h.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:U,filesLoading:k,createOpen:E,creating:L,newProject:F,columns:z,countByStatus:M,filteredProjects:J,statusColor:g,syncColor:K,formatTime:Q,loadAll:C,onRowClick:G,openDetail:V,onDelete:H,onShowCreate:X,onCreate:T,createFileOpen:b,creatingFile:D,newFile:j,createFolderOpen:h,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"}},he={class:"page-title"},Ae={class:"page-sub"},Ie={class:"filter-bar",style:{"margin-bottom":"12px",display:"flex",gap:"12px","align-items":"center"}},Ue={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"),U=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"),K=i("a-descriptions"),Q=i("a-divider"),C=i("a-empty"),G=i("a-list-item"),V=i("a-list"),H=i("a-spin"),X=i("a-drawer"),T=i("a-input"),b=i("a-form-item"),D=i("a-textarea"),j=i("a-form"),h=i("a-modal"),m=i("a-select-option"),R=i("a-select");return p(),A("div",null,[I("div",ze,[I("div",null,[I("h2",he,s(e.t("projects.title")),1),I("p",Ae,[l[17]||(l[17]=r("桌面 / CLI / 手机 三端共享同一份项目数据,Phase 3d sync 自动同步 (",-1)),t(B,{to:"/project-init"},{default:a(()=>[...l[16]||(l[16]=[r("项目初始化 / 环境设置",-1)])]),_:1}),l[18]||(l[18]=r(")",-1))])]),t(O,null,{default:a(()=>[t(y,{loading:e.loading,onClick:e.loadAll},{icon:a(()=>[t(e.ReloadOutlined)]),default:a(()=>[l[19]||(l[19]=r(" 刷新 ",-1))]),_:1},8,["loading"]),t(y,{type:"primary",onClick:e.onShowCreate},{icon:a(()=>[t(e.PlusOutlined)]),default:a(()=>[l[20]||(l[20]=r(" 新建项目 ",-1))]),_:1})]),_:1})]),_(" Stats "),t(U,{gutter:[16,16],style:{"margin-bottom":"20px"}},{default:a(()=>[t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"总项目",value:e.projects.length,"value-style":{color:"#1677ff",fontSize:"20px"}},{prefix:a(()=>[t(e.FolderOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"活跃",value:e.countByStatus.active,"value-style":{color:"#52c41a",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckCircleOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"草稿",value:e.countByStatus.draft,"value-style":{color:"#8c8c8c",fontSize:"20px"}},{prefix:a(()=>[t(e.FileTextOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"已完成",value:e.countByStatus.completed,"value-style":{color:"#13c2c2",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckSquareOutlined)]),_:1},8,["value"])]),_:1})]),_:1})]),_:1}),_(" Filter "),I("div",Ie,[t(E,{value:e.statusFilter,"onUpdate:value":l[0]||(l[0]=n=>e.statusFilter=n),size:"small","button-style":"solid"},{default:a(()=>[t(k,{value:""},{default:a(()=>[...l[21]||(l[21]=[r("全部",-1)])]),_:1}),t(k,{value:"active"},{default:a(()=>[...l[22]||(l[22]=[r("活跃",-1)])]),_:1}),t(k,{value:"draft"},{default:a(()=>[...l[23]||(l[23]=[r("草稿",-1)])]),_:1}),t(k,{value:"completed"},{default:a(()=>[...l[24]||(l[24]=[r("已完成",-1)])]),_:1}),t(k,{value:"archived"},{default:a(()=>[...l[25]||(l[25]=[r("已归档",-1)])]),_:1})]),_:1},8,["value"]),t(L,{value:e.nameFilter,"onUpdate:value":l[1]||(l[1]=n=>e.nameFilter=n),placeholder:"按名称过滤",style:{"max-width":"260px"},"allow-clear":""},null,8,["value"])]),!e.projects.length&&!e.loading?(p(),x(F,{key:0,type:"info",message:"还没有项目",description:'运行 `cc project init <name>` 或点击右上角"新建项目"按钮创建。桌面 / CLI / 手机三端共享同一份数据。',"show-icon":"",style:{"margin-bottom":"16px"}})):_("v-if",!0),e.projects.length||e.loading?(p(),x(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(),A("code",Ue,s(c.id.slice(0,8))+"…",1)):n.key==="name"?(p(),A(ne,{key:1},[I("strong",null,s(c.name),1),c.description?(p(),A("div",De,s(c.description),1)):_("v-if",!0)],64)):n.key==="project_type"?(p(),x(z,{key:2},{default:a(()=>[r(s(c.project_type),1)]),_:2},1024)):n.key==="status"?(p(),x(z,{key:3,color:e.statusColor(c.status)},{default:a(()=>[r(s(c.status),1)]),_:2},1032,["color"])):n.key==="sync_status"?(p(),x(z,{key:4,color:e.syncColor(c.sync_status)},{default:a(()=>[r(s(c.sync_status||"unknown"),1)]),_:2},1032,["color"])):n.key==="updated_at"?(p(),A(ne,{key:5},[r(s(e.formatTime(c.updated_at)),1)],64)):n.key==="actions"?(p(),x(O,{key:6,onClick:l[2]||(l[2]=ge(()=>{},["stop"]))},{default:a(()=>[t(y,{size:"small",onClick:q=>e.openDetail(c)},{default:a(()=>[...l[26]||(l[26]=[r("详情",-1)])]),_:1},8,["onClick"]),t(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(()=>[I("code",null,s(e.detail.id),1)]),_:1}),t(g,{label:"名称"},{default:a(()=>[r(s(e.detail.name),1)]),_:1}),t(g,{label:"描述"},{default:a(()=>[r(s(e.detail.description||"-"),1)]),_:1}),t(g,{label:"类型"},{default:a(()=>[t(z,null,{default:a(()=>[r(s(e.detail.project_type),1)]),_:1})]),_:1}),t(g,{label:"状态"},{default:a(()=>[t(z,{color:e.statusColor(e.detail.status)},{default:a(()=>[r(s(e.detail.status),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"同步状态"},{default:a(()=>[t(z,{color:e.syncColor(e.detail.sync_status)},{default:a(()=>[r(s(e.detail.sync_status||"unknown"),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"用户"},{default:a(()=>[r(s(e.detail.user_id),1)]),_:1}),t(g,{label:"根路径"},{default:a(()=>[e.detail.root_path?(p(),A("code",Re,s(e.detail.root_path),1)):(p(),A("span",Te,"(无)"))]),_:1}),t(g,{label:"文件数"},{default:a(()=>[r(s(e.detail.file_count||0),1)]),_:1}),t(g,{label:"创建"},{default:a(()=>[r(s(e.formatTime(e.detail.created_at)),1)]),_:1}),t(g,{label:"更新"},{default:a(()=>[r(s(e.formatTime(e.detail.updated_at)),1)]),_:1})]),_:1})):_("v-if",!0),t(Q,null,{default:a(()=>[...l[28]||(l[28]=[r("文件",-1)])]),_:1}),_(" Sub-phase 7.3 (2026-05-17): 文件 CRUD toolbar "),t(O,{style:{"margin-bottom":"12px"}},{default:a(()=>[t(y,{size:"small",type:"primary",disabled:!e.detail,onClick:e.openCreateFile},{default:a(()=>[t(e.FileAddOutlined),l[29]||(l[29]=r(" 新建文件 ",-1))]),_:1},8,["disabled"]),t(y,{size:"small",disabled:!e.detail,onClick:e.openCreateFolder},{default:a(()=>[t(e.FolderAddOutlined),l[30]||(l[30]=r(" 新建文件夹 ",-1))]),_:1},8,["disabled"])]),_:1}),t(H,{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(G,null,{extra:a(()=>[t(O,null,{default:a(()=>[n.file_size?(p(),A("span",Ee,s(n.file_size)+" B",1)):_("v-if",!0),t(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(()=>[I("span",{style:{cursor:"pointer"},onClick:c=>e.openEditFile(n)},s(n.is_folder?"📁":"📄")+" "+s(n.file_path),9,Be)]),_:2},1024)]),_:1},8,["data-source"]))]),_:1},8,["spinning"])]),_:1},8,["open","title"]),_(" Sub-phase 7.3: Create file modal "),t(h,{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(h,{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(h,{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(h,{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-shrpcT/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
@@ -1 +0,0 @@
1
- import{O as r}from"./index-C9ej-MF0.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-DvMJGAI3.js";import{U as t}from"./index-C9ej-MF0.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-hS-j69A0.js";import"./useFlexGapSupport-C_sX4D3N.js";import"./styleChecker-DKpl2K9E.js";import"./index-B7gw-tDm.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-CxfV5FGT.js";import{U as t}from"./index-C9ej-MF0.js";import"./vendor-BvqAck49.js";import"./index-B7gw-tDm.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};