@nextclaw/ui 0.24.2 → 0.24.3

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 (132) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/.vite/manifest.json +517 -517
  3. package/dist/assets/{account-panel-BxMlLXYH.js → account-panel-BRTSwNvA.js} +1 -1
  4. package/dist/assets/{api-Utt-xzrT.js → api-BnUzdltV.js} +5 -5
  5. package/dist/assets/{app-data-DYXDL6X2.js → app-data-Bjh_zM45.js} +1 -1
  6. package/dist/assets/app-presenter-provider-CBt-lyr_.js +109 -0
  7. package/dist/assets/{appearance-settings-page-BfYznAK5.js → appearance-settings-page-BrOYSgG0.js} +1 -1
  8. package/dist/assets/{book-open-DDW_3XpM.js → book-open-xqEj1OLE.js} +1 -1
  9. package/dist/assets/{boxes-DwJeuK_h.js → boxes-D6uPnkGo.js} +1 -1
  10. package/dist/assets/{card-IevY2nm-.js → card-CS8su2Zh.js} +1 -1
  11. package/dist/assets/{channels-list-page-DitnqbMR.js → channels-list-page-BE0TxB3B.js} +1 -1
  12. package/dist/assets/{chevron-down-An7Km-t4.js → chevron-down-BL-yMYcX.js} +1 -1
  13. package/dist/assets/{circle-alert-CDXqELuo.js → circle-alert-lSa3LRvS.js} +1 -1
  14. package/dist/assets/{circle-dashed-CapXEpiV.js → circle-dashed-CU3yApvP.js} +1 -1
  15. package/dist/assets/{client-B0krol7A.js → client-BtGBwLTs.js} +1 -1
  16. package/dist/assets/{config-split-page-BtnkqWVp.js → config-split-page-BxDwwAGa.js} +1 -1
  17. package/dist/assets/{confirm-dialog-DFt4jpN7.js → confirm-dialog-S5JxZcS1.js} +1 -1
  18. package/dist/assets/{createLucideIcon-BTHK0Ot9.js → createLucideIcon-BNKf0_kc.js} +1 -1
  19. package/dist/assets/{desktop-capabilities-page-CCf14WId.js → desktop-capabilities-page-BwHxJpbl.js} +1 -1
  20. package/dist/assets/{desktop-update-config-DVoVgfFi.js → desktop-update-config-Bfg7OdJ2.js} +1 -1
  21. package/dist/assets/{dialog-BFN_1DBH.js → dialog-Xe73hpQz.js} +1 -1
  22. package/dist/assets/{dist-Bc9hOVNN.js → dist-BiIcnf9j.js} +1 -1
  23. package/dist/assets/{dist-CEhIDAnr.js → dist-C5I0v8Qn.js} +1 -1
  24. package/dist/assets/{dist-hkVPP1th.js → dist-czPa8xFO.js} +1 -1
  25. package/dist/assets/doc-browser-BgRP0Wni.js +1 -0
  26. package/dist/assets/{doc-browser-BNUxmwD6.js → doc-browser-C8eqJLi_.js} +1 -1
  27. package/dist/assets/{doc-browser-context-C4yQrKrH.js → doc-browser-context-BPCDFcC-.js} +1 -1
  28. package/dist/assets/{ellipsis-BRI6ROeu.js → ellipsis-C5YXdOUx.js} +1 -1
  29. package/dist/assets/{es2015-MOCbM0Eu.js → es2015-cuwbYI-l.js} +1 -1
  30. package/dist/assets/{extensions-DxUBMtHW.js → extensions-DgKQRebe.js} +1 -1
  31. package/dist/assets/{eye-cnynUDGt.js → eye-C84inPcV.js} +1 -1
  32. package/dist/assets/{form-actions-gQ0JEUwB.js → form-actions-AIdXOoCL.js} +1 -1
  33. package/dist/assets/{i18n-B9yXA8KO.js → i18n-CKvm9zyk.js} +2 -2
  34. package/dist/assets/{i18n-provider-BYBJua91.js → i18n-provider-CPV43pMX.js} +1 -1
  35. package/dist/assets/loader-circle-K1BDdHR5.js +1 -0
  36. package/dist/assets/login-page-ClcrvN04.js +1 -0
  37. package/dist/assets/{login-page-CqrHhzaN.js → login-page-DeDQjVxv.js} +1 -1
  38. package/dist/assets/{logo-badge-Cr03YceJ.js → logo-badge-C-5-zim6.js} +1 -1
  39. package/dist/assets/main-DGqlaAaI.css +1 -0
  40. package/dist/assets/main-i18n-catalog.config-CpNF5aVc.js +1 -0
  41. package/dist/assets/main-nMVfHb5K.js +2 -0
  42. package/dist/assets/{mcp-marketplace-page-CifiVgFD.js → mcp-marketplace-page-CWjJGp_D.js} +1 -1
  43. package/dist/assets/mcp-marketplace-page-fvu2NcXT.js +1 -0
  44. package/dist/assets/{model-config-page-C6jVNbSj.js → model-config-page-Dv_zE7HN.js} +1 -1
  45. package/dist/assets/{navigation-link-kbCLRSr_.js → navigation-link-BAQjgx2F.js} +1 -1
  46. package/dist/assets/panel-app-i18n-catalog.config-BzxE3tZb.js +1 -0
  47. package/dist/assets/{panelStandalone-DMBnYyTw.js → panelStandalone-CFRBHV94.js} +2 -2
  48. package/dist/assets/plus-LA8-jpxP.js +1 -0
  49. package/dist/assets/{popover-XVDgjxcl.js → popover-NkrFlWHp.js} +1 -1
  50. package/dist/assets/{privacy-settings-page-BN27MBVA.js → privacy-settings-page-D6uc9f-A.js} +1 -1
  51. package/dist/assets/projects-BD1rG75R.js +1 -0
  52. package/dist/assets/{provider-scoped-model-input-BGZMCThn.js → provider-scoped-model-input-DUa_9uwg.js} +1 -1
  53. package/dist/assets/{providers-config-page-D5aBwbOD.js → providers-config-page-DAiqxlF_.js} +1 -1
  54. package/dist/assets/{puzzle-D5Dhacmb.js → puzzle-D6gulz7u.js} +1 -1
  55. package/dist/assets/{pwa-ClQK56Qe.js → pwa-C_Zte1xe.js} +1 -1
  56. package/dist/assets/{refresh-cw-Bw5BY7vp.js → refresh-cw-h9Xq3LY3.js} +1 -1
  57. package/dist/assets/remote-BO0QP7ua.js +1 -0
  58. package/dist/assets/{rotate-cw-BksCLAeE.js → rotate-cw-B6xm41Wn.js} +1 -1
  59. package/dist/assets/runtime-config-page-w1UAkGF_.js +1 -0
  60. package/dist/assets/{save-CVi8VWzb.js → save-fff_WpY2.js} +1 -1
  61. package/dist/assets/{search-DN-f7IIC.js → search-CUe41wjm.js} +1 -1
  62. package/dist/assets/{search-config-page-BmuZTVxs.js → search-config-page-3xbhRlW2.js} +1 -1
  63. package/dist/assets/{secrets-config-page-NPHpg9sb.js → secrets-config-page-Dn8_rdOj.js} +1 -1
  64. package/dist/assets/security-config-Y1nEGM3A.js +1 -0
  65. package/dist/assets/{select-CmDTqk2C.js → select-CG5YWnwe.js} +1 -1
  66. package/dist/assets/{service-apps-panel-BYGJ9_pO.js → service-apps-panel-CGc04aMn.js} +1 -1
  67. package/dist/assets/{settings-2-B62YtZon.js → settings-2-CE3ELQyk.js} +1 -1
  68. package/dist/assets/skeleton-BL9h32W7.js +1 -0
  69. package/dist/assets/{tabs-Bk_mG7ql.js → tabs-BuE0qKMh.js} +1 -1
  70. package/dist/assets/{tag-chip-DgqKlI5D.js → tag-chip-BDzpHEli.js} +1 -1
  71. package/dist/assets/{theme-provider-CeBY2pyu.js → theme-provider-B6FinATQ.js} +1 -1
  72. package/dist/assets/{tooltip-CgGbBdYf.js → tooltip-DYcuWhuP.js} +1 -1
  73. package/dist/assets/{trash-2-CVOev8yc.js → trash-2-BPPYt2NV.js} +1 -1
  74. package/dist/assets/{use-config-b2DN67gs.js → use-config-BPUM2lbo.js} +1 -1
  75. package/dist/assets/{use-desktop-capabilities-B3tLU1yl.js → use-desktop-capabilities-BDjArQP3.js} +1 -1
  76. package/dist/assets/{use-panel-app-scroll-restoration-BekzoX6z.js → use-panel-app-scroll-restoration-DsV1IJx-.js} +1 -1
  77. package/dist/assets/{use-viewport-layout-CUA3jQsA.js → use-viewport-layout-BS18drMT.js} +1 -1
  78. package/dist/assets/{utils-UBHTdG5Q.js → utils-CBZPzC_b.js} +1 -1
  79. package/dist/assets/x-DdXOqLnX.js +1 -0
  80. package/dist/index.html +50 -50
  81. package/dist/panel-standalone.html +15 -15
  82. package/package.json +3 -3
  83. package/src/features/chat/features/message/utils/__tests__/chat-message-timeline.utils.test.ts +10 -0
  84. package/src/features/chat/features/session/components/__tests__/chat-sidebar-project-groups.test.tsx +90 -6
  85. package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +64 -2
  86. package/src/features/panel-apps/components/__tests__/panel-app-open-standalone-menu-item.test.tsx +3 -2
  87. package/src/features/panel-apps/components/panel-app-open-standalone-menu-item.tsx +4 -1
  88. package/src/features/projects/AGENTS.md +1 -2
  89. package/src/features/projects/components/project-agreement.tsx +36 -77
  90. package/src/features/projects/components/project-artifacts.test.tsx +90 -62
  91. package/src/features/projects/components/project-artifacts.tsx +81 -160
  92. package/src/features/projects/components/project-materials.test.tsx +80 -0
  93. package/src/features/projects/components/project-overview.test.tsx +50 -40
  94. package/src/features/projects/components/project-overview.tsx +5 -4
  95. package/src/features/projects/components/project-skills.tsx +24 -14
  96. package/src/features/projects/components/work/project-work-item-drawer.test.tsx +3 -2
  97. package/src/features/projects/components/work/project-work-items.test.tsx +13 -1
  98. package/src/features/projects/components/work/project-work-items.tsx +7 -7
  99. package/src/features/projects/hooks/use-project-materials.test.tsx +65 -0
  100. package/src/features/projects/hooks/use-project-materials.ts +24 -0
  101. package/src/features/projects/hooks/use-project-work.test.tsx +57 -1
  102. package/src/features/projects/hooks/use-project-work.ts +11 -5
  103. package/src/features/projects/pages/project-home-page.tsx +51 -127
  104. package/src/features/projects/pages/projects-page.test.tsx +68 -75
  105. package/src/features/projects/presenters/project-home.presenter.test.ts +1 -64
  106. package/src/features/projects/presenters/project-home.presenter.ts +17 -54
  107. package/src/features/projects/utils/project-artifact-view.utils.test.ts +0 -46
  108. package/src/features/projects/utils/project-artifact-view.utils.ts +0 -47
  109. package/src/shared/lib/i18n/locales/en-US/projects.json +8 -59
  110. package/src/shared/lib/i18n/locales/zh-CN/projects.json +8 -59
  111. package/dist/assets/app-presenter-provider-CLsFiXvV.js +0 -109
  112. package/dist/assets/doc-browser-w4eGZXLu.js +0 -1
  113. package/dist/assets/loader-circle-rWr5Yo0E.js +0 -1
  114. package/dist/assets/login-page-CfMSkOsg.js +0 -1
  115. package/dist/assets/main-8cVkMfgE.css +0 -1
  116. package/dist/assets/main-Bys58GxY.js +0 -2
  117. package/dist/assets/main-i18n-catalog.config-BSq9yiUQ.js +0 -1
  118. package/dist/assets/mcp-marketplace-page-DX5VE3mU.js +0 -1
  119. package/dist/assets/panel-app-i18n-catalog.config-C2St67SP.js +0 -1
  120. package/dist/assets/plus-BHnKwuPq.js +0 -1
  121. package/dist/assets/projects-DV3UuJMS.js +0 -1
  122. package/dist/assets/remote-Bl005fzu.js +0 -1
  123. package/dist/assets/runtime-config-page-CmktQcMW.js +0 -1
  124. package/dist/assets/security-config-Djptuyf2.js +0 -1
  125. package/dist/assets/skeleton-Eh64l4T2.js +0 -1
  126. package/dist/assets/x-C0iaOsRW.js +0 -1
  127. package/src/features/projects/components/project-requests.tsx +0 -57
  128. package/src/features/projects/components/project-runs.tsx +0 -60
  129. package/src/features/projects/hooks/use-project-observation.test.tsx +0 -93
  130. package/src/features/projects/hooks/use-project-observation.ts +0 -115
  131. package/src/features/projects/utils/project-request-response.utils.test.ts +0 -44
  132. package/src/features/projects/utils/project-request-response.utils.ts +0 -39
@@ -0,0 +1 @@
1
+ import{t as e}from"./createLucideIcon-BNKf0_kc.js";var t=e(`X`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]);export{t};
package/dist/index.html CHANGED
@@ -258,62 +258,62 @@
258
258
  })();
259
259
  </script>
260
260
  <title>NextClaw</title>
261
- <script type="module" crossorigin src="/assets/main-Bys58GxY.js"></script>
261
+ <script type="module" crossorigin src="/assets/main-nMVfHb5K.js"></script>
262
262
  <link rel="modulepreload" crossorigin href="/assets/chunk-DF37yw5_.js">
263
- <link rel="modulepreload" crossorigin href="/assets/utils-UBHTdG5Q.js">
264
- <link rel="modulepreload" crossorigin href="/assets/client-B0krol7A.js">
263
+ <link rel="modulepreload" crossorigin href="/assets/utils-CBZPzC_b.js">
264
+ <link rel="modulepreload" crossorigin href="/assets/client-BtGBwLTs.js">
265
265
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-ca-nBW7U.js">
266
- <link rel="modulepreload" crossorigin href="/assets/dist-Bc9hOVNN.js">
267
- <link rel="modulepreload" crossorigin href="/assets/dist-CEhIDAnr.js">
268
- <link rel="modulepreload" crossorigin href="/assets/es2015-MOCbM0Eu.js">
269
- <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-BTHK0Ot9.js">
270
- <link rel="modulepreload" crossorigin href="/assets/chevron-down-An7Km-t4.js">
271
- <link rel="modulepreload" crossorigin href="/assets/select-CmDTqk2C.js">
272
- <link rel="modulepreload" crossorigin href="/assets/dist-hkVPP1th.js">
273
- <link rel="modulepreload" crossorigin href="/assets/x-C0iaOsRW.js">
274
- <link rel="modulepreload" crossorigin href="/assets/dialog-BFN_1DBH.js">
275
- <link rel="modulepreload" crossorigin href="/assets/popover-XVDgjxcl.js">
276
- <link rel="modulepreload" crossorigin href="/assets/tooltip-CgGbBdYf.js">
277
- <link rel="modulepreload" crossorigin href="/assets/i18n-B9yXA8KO.js">
278
- <link rel="modulepreload" crossorigin href="/assets/api-Utt-xzrT.js">
279
- <link rel="modulepreload" crossorigin href="/assets/search-DN-f7IIC.js">
280
- <link rel="modulepreload" crossorigin href="/assets/book-open-DDW_3XpM.js">
281
- <link rel="modulepreload" crossorigin href="/assets/boxes-DwJeuK_h.js">
266
+ <link rel="modulepreload" crossorigin href="/assets/dist-BiIcnf9j.js">
267
+ <link rel="modulepreload" crossorigin href="/assets/dist-C5I0v8Qn.js">
268
+ <link rel="modulepreload" crossorigin href="/assets/es2015-cuwbYI-l.js">
269
+ <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-BNKf0_kc.js">
270
+ <link rel="modulepreload" crossorigin href="/assets/chevron-down-BL-yMYcX.js">
271
+ <link rel="modulepreload" crossorigin href="/assets/select-CG5YWnwe.js">
272
+ <link rel="modulepreload" crossorigin href="/assets/dist-czPa8xFO.js">
273
+ <link rel="modulepreload" crossorigin href="/assets/x-DdXOqLnX.js">
274
+ <link rel="modulepreload" crossorigin href="/assets/dialog-Xe73hpQz.js">
275
+ <link rel="modulepreload" crossorigin href="/assets/popover-NkrFlWHp.js">
276
+ <link rel="modulepreload" crossorigin href="/assets/tooltip-DYcuWhuP.js">
277
+ <link rel="modulepreload" crossorigin href="/assets/i18n-CKvm9zyk.js">
278
+ <link rel="modulepreload" crossorigin href="/assets/api-BnUzdltV.js">
279
+ <link rel="modulepreload" crossorigin href="/assets/search-CUe41wjm.js">
280
+ <link rel="modulepreload" crossorigin href="/assets/book-open-xqEj1OLE.js">
281
+ <link rel="modulepreload" crossorigin href="/assets/boxes-D6uPnkGo.js">
282
282
  <link rel="modulepreload" crossorigin href="/assets/host-capabilities-B107nwS3.js">
283
- <link rel="modulepreload" crossorigin href="/assets/navigation-link-kbCLRSr_.js">
284
- <link rel="modulepreload" crossorigin href="/assets/plus-BHnKwuPq.js">
285
- <link rel="modulepreload" crossorigin href="/assets/refresh-cw-Bw5BY7vp.js">
283
+ <link rel="modulepreload" crossorigin href="/assets/navigation-link-BAQjgx2F.js">
284
+ <link rel="modulepreload" crossorigin href="/assets/plus-LA8-jpxP.js">
285
+ <link rel="modulepreload" crossorigin href="/assets/refresh-cw-h9Xq3LY3.js">
286
286
  <link rel="modulepreload" crossorigin href="/assets/middleware-0o3JF3tS.js">
287
- <link rel="modulepreload" crossorigin href="/assets/doc-browser-context-C4yQrKrH.js">
288
- <link rel="modulepreload" crossorigin href="/assets/use-panel-app-scroll-restoration-BekzoX6z.js">
289
- <link rel="modulepreload" crossorigin href="/assets/doc-browser-BNUxmwD6.js">
290
- <link rel="modulepreload" crossorigin href="/assets/circle-alert-CDXqELuo.js">
291
- <link rel="modulepreload" crossorigin href="/assets/loader-circle-rWr5Yo0E.js">
292
- <link rel="modulepreload" crossorigin href="/assets/confirm-dialog-DFt4jpN7.js">
293
- <link rel="modulepreload" crossorigin href="/assets/i18n-provider-BYBJua91.js">
294
- <link rel="modulepreload" crossorigin href="/assets/tag-chip-DgqKlI5D.js">
295
- <link rel="modulepreload" crossorigin href="/assets/skeleton-Eh64l4T2.js">
296
- <link rel="modulepreload" crossorigin href="/assets/mcp-marketplace-page-CifiVgFD.js">
297
- <link rel="modulepreload" crossorigin href="/assets/puzzle-D5Dhacmb.js">
298
- <link rel="modulepreload" crossorigin href="/assets/trash-2-CVOev8yc.js">
299
- <link rel="modulepreload" crossorigin href="/assets/app-data-DYXDL6X2.js">
300
- <link rel="modulepreload" crossorigin href="/assets/ellipsis-BRI6ROeu.js">
301
- <link rel="modulepreload" crossorigin href="/assets/eye-cnynUDGt.js">
302
- <link rel="modulepreload" crossorigin href="/assets/tabs-Bk_mG7ql.js">
303
- <link rel="modulepreload" crossorigin href="/assets/use-viewport-layout-CUA3jQsA.js">
304
- <link rel="modulepreload" crossorigin href="/assets/theme-provider-CeBY2pyu.js">
305
- <link rel="modulepreload" crossorigin href="/assets/use-desktop-capabilities-B3tLU1yl.js">
306
- <link rel="modulepreload" crossorigin href="/assets/logo-badge-Cr03YceJ.js">
307
- <link rel="modulepreload" crossorigin href="/assets/card-IevY2nm-.js">
308
- <link rel="modulepreload" crossorigin href="/assets/use-config-b2DN67gs.js">
287
+ <link rel="modulepreload" crossorigin href="/assets/doc-browser-context-BPCDFcC-.js">
288
+ <link rel="modulepreload" crossorigin href="/assets/use-panel-app-scroll-restoration-DsV1IJx-.js">
289
+ <link rel="modulepreload" crossorigin href="/assets/doc-browser-C8eqJLi_.js">
290
+ <link rel="modulepreload" crossorigin href="/assets/circle-alert-lSa3LRvS.js">
291
+ <link rel="modulepreload" crossorigin href="/assets/loader-circle-K1BDdHR5.js">
292
+ <link rel="modulepreload" crossorigin href="/assets/confirm-dialog-S5JxZcS1.js">
293
+ <link rel="modulepreload" crossorigin href="/assets/i18n-provider-CPV43pMX.js">
294
+ <link rel="modulepreload" crossorigin href="/assets/tag-chip-BDzpHEli.js">
295
+ <link rel="modulepreload" crossorigin href="/assets/skeleton-BL9h32W7.js">
296
+ <link rel="modulepreload" crossorigin href="/assets/mcp-marketplace-page-CWjJGp_D.js">
297
+ <link rel="modulepreload" crossorigin href="/assets/puzzle-D6gulz7u.js">
298
+ <link rel="modulepreload" crossorigin href="/assets/trash-2-BPPYt2NV.js">
299
+ <link rel="modulepreload" crossorigin href="/assets/app-data-Bjh_zM45.js">
300
+ <link rel="modulepreload" crossorigin href="/assets/ellipsis-C5YXdOUx.js">
301
+ <link rel="modulepreload" crossorigin href="/assets/eye-C84inPcV.js">
302
+ <link rel="modulepreload" crossorigin href="/assets/tabs-BuE0qKMh.js">
303
+ <link rel="modulepreload" crossorigin href="/assets/use-viewport-layout-BS18drMT.js">
304
+ <link rel="modulepreload" crossorigin href="/assets/theme-provider-B6FinATQ.js">
305
+ <link rel="modulepreload" crossorigin href="/assets/use-desktop-capabilities-BDjArQP3.js">
306
+ <link rel="modulepreload" crossorigin href="/assets/logo-badge-C-5-zim6.js">
307
+ <link rel="modulepreload" crossorigin href="/assets/card-CS8su2Zh.js">
308
+ <link rel="modulepreload" crossorigin href="/assets/use-config-BPUM2lbo.js">
309
309
  <link rel="modulepreload" crossorigin href="/assets/provider-models-5PGHb6mP.js">
310
- <link rel="modulepreload" crossorigin href="/assets/app-presenter-provider-CLsFiXvV.js">
311
- <link rel="modulepreload" crossorigin href="/assets/provider-scoped-model-input-BGZMCThn.js">
312
- <link rel="modulepreload" crossorigin href="/assets/settings-2-B62YtZon.js">
313
- <link rel="modulepreload" crossorigin href="/assets/pwa-ClQK56Qe.js">
314
- <link rel="modulepreload" crossorigin href="/assets/login-page-CqrHhzaN.js">
310
+ <link rel="modulepreload" crossorigin href="/assets/app-presenter-provider-CBt-lyr_.js">
311
+ <link rel="modulepreload" crossorigin href="/assets/provider-scoped-model-input-DUa_9uwg.js">
312
+ <link rel="modulepreload" crossorigin href="/assets/settings-2-CE3ELQyk.js">
313
+ <link rel="modulepreload" crossorigin href="/assets/pwa-C_Zte1xe.js">
314
+ <link rel="modulepreload" crossorigin href="/assets/login-page-DeDQjVxv.js">
315
315
  <link rel="stylesheet" crossorigin href="/assets/app-presenter-provider-D3BuuOyZ.css">
316
- <link rel="stylesheet" crossorigin href="/assets/main-8cVkMfgE.css">
316
+ <link rel="stylesheet" crossorigin href="/assets/main-DGqlaAaI.css">
317
317
  </head>
318
318
 
319
319
  <body>
@@ -5,23 +5,23 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta name="theme-color" content="#ffffff" />
7
7
  <title>Panel App · NextClaw</title>
8
- <script type="module" crossorigin src="/assets/panelStandalone-DMBnYyTw.js"></script>
8
+ <script type="module" crossorigin src="/assets/panelStandalone-CFRBHV94.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-DF37yw5_.js">
10
- <link rel="modulepreload" crossorigin href="/assets/utils-UBHTdG5Q.js">
11
- <link rel="modulepreload" crossorigin href="/assets/client-B0krol7A.js">
10
+ <link rel="modulepreload" crossorigin href="/assets/utils-CBZPzC_b.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/client-BtGBwLTs.js">
12
12
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-ca-nBW7U.js">
13
- <link rel="modulepreload" crossorigin href="/assets/i18n-B9yXA8KO.js">
14
- <link rel="modulepreload" crossorigin href="/assets/api-Utt-xzrT.js">
15
- <link rel="modulepreload" crossorigin href="/assets/dist-Bc9hOVNN.js">
16
- <link rel="modulepreload" crossorigin href="/assets/es2015-MOCbM0Eu.js">
17
- <link rel="modulepreload" crossorigin href="/assets/dist-hkVPP1th.js">
18
- <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-BTHK0Ot9.js">
19
- <link rel="modulepreload" crossorigin href="/assets/x-C0iaOsRW.js">
20
- <link rel="modulepreload" crossorigin href="/assets/dialog-BFN_1DBH.js">
21
- <link rel="modulepreload" crossorigin href="/assets/boxes-DwJeuK_h.js">
22
- <link rel="modulepreload" crossorigin href="/assets/use-panel-app-scroll-restoration-BekzoX6z.js">
23
- <link rel="modulepreload" crossorigin href="/assets/theme-provider-CeBY2pyu.js">
24
- <link rel="modulepreload" crossorigin href="/assets/i18n-provider-BYBJua91.js">
13
+ <link rel="modulepreload" crossorigin href="/assets/i18n-CKvm9zyk.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/api-BnUzdltV.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/dist-BiIcnf9j.js">
16
+ <link rel="modulepreload" crossorigin href="/assets/es2015-cuwbYI-l.js">
17
+ <link rel="modulepreload" crossorigin href="/assets/dist-czPa8xFO.js">
18
+ <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-BNKf0_kc.js">
19
+ <link rel="modulepreload" crossorigin href="/assets/x-DdXOqLnX.js">
20
+ <link rel="modulepreload" crossorigin href="/assets/dialog-Xe73hpQz.js">
21
+ <link rel="modulepreload" crossorigin href="/assets/boxes-D6uPnkGo.js">
22
+ <link rel="modulepreload" crossorigin href="/assets/use-panel-app-scroll-restoration-DsV1IJx-.js">
23
+ <link rel="modulepreload" crossorigin href="/assets/theme-provider-B6FinATQ.js">
24
+ <link rel="modulepreload" crossorigin href="/assets/i18n-provider-CPV43pMX.js">
25
25
  <link rel="stylesheet" crossorigin href="/assets/panelStandalone-Y91OJkgV.css">
26
26
  </head>
27
27
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/ui",
3
- "version": "0.24.2",
3
+ "version": "0.24.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -36,12 +36,12 @@
36
36
  "zustand": "^5.0.2",
37
37
  "@nextclaw/agent-chat": "0.3.14",
38
38
  "@nextclaw/agent-chat-ui": "0.7.2",
39
- "@nextclaw/client-sdk": "0.11.2",
39
+ "@nextclaw/client-sdk": "0.12.0",
40
40
  "@nextclaw/ncp": "0.10.0",
41
41
  "@nextclaw/ncp-http-agent-client": "0.4.22",
42
42
  "@nextclaw/ncp-react": "0.5.26",
43
43
  "@nextclaw/ncp-toolkit": "0.6.23",
44
- "@nextclaw/shared": "0.5.0"
44
+ "@nextclaw/shared": "0.5.1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@testing-library/react": "^16.3.0",
@@ -125,6 +125,16 @@ describe("chat message timeline visibility", () => {
125
125
  })).toBe(false);
126
126
  expect(isVisibleChatMessage(visibleMessage)).toBe(true);
127
127
  });
128
+
129
+ it("keeps a normal assistant reply visible when it explains the silent marker", () => {
130
+ expect(isVisibleChatMessage({
131
+ ...visibleMessage,
132
+ parts: [{
133
+ type: "text",
134
+ text: "空转 tick 调用一次服务,然后返回 `<noreply/>`,成本很低。",
135
+ }],
136
+ })).toBe(true);
137
+ });
128
138
  });
129
139
 
130
140
  describe("chat message continuation projection", () => {
@@ -9,7 +9,9 @@ import {
9
9
  import { useChatSessionListStore } from "@/features/chat/stores/chat-session-list.store";
10
10
 
11
11
  const mocks = vi.hoisted(() => ({
12
+ confirm: vi.fn(),
12
13
  createSession: vi.fn(),
14
+ removeProject: vi.fn(),
13
15
  toggleProjectCollapsed: vi.fn(),
14
16
  toggleProjectPinned: vi.fn(),
15
17
  }));
@@ -19,6 +21,18 @@ vi.mock("@/features/chat/components/providers/chat-presenter.provider", () => ({
19
21
  chatSessionListManager: mocks,
20
22
  }),
21
23
  }));
24
+ vi.mock("@/shared/hooks/use-projects", () => ({
25
+ useRemoveProject: () => ({
26
+ mutateAsync: mocks.removeProject,
27
+ isPending: false,
28
+ }),
29
+ }));
30
+ vi.mock("@/shared/hooks/use-confirm-dialog", () => ({
31
+ useConfirmDialog: () => ({
32
+ confirm: mocks.confirm,
33
+ ConfirmDialog: () => <div data-testid="confirm-dialog" />,
34
+ }),
35
+ }));
22
36
 
23
37
  const projectGroup: ChatSidebarProjectGroup = {
24
38
  projectId: "project-analysis",
@@ -50,9 +64,10 @@ function LocationProbe() {
50
64
  function renderProjectGroups(
51
65
  isPinned = false,
52
66
  group: ChatSidebarProjectGroup = projectGroup,
67
+ initialPath = "/chat",
53
68
  ) {
54
69
  return render(
55
- <MemoryRouter initialEntries={["/chat"]}>
70
+ <MemoryRouter initialEntries={[initialPath]}>
56
71
  <ChatSidebarProjectGroups
57
72
  groups={[{ ...group, isPinned }]}
58
73
  projectCronJobCountByRoot={new Map([[projectGroup.projectRoot, 2]])}
@@ -69,7 +84,11 @@ function renderProjectGroups(
69
84
 
70
85
  describe("ChatSidebarProjectGroups", () => {
71
86
  beforeEach(() => {
87
+ mocks.confirm.mockReset();
88
+ mocks.confirm.mockResolvedValue(true);
72
89
  mocks.createSession.mockReset();
90
+ mocks.removeProject.mockReset();
91
+ mocks.removeProject.mockResolvedValue(undefined);
73
92
  mocks.toggleProjectCollapsed.mockReset();
74
93
  mocks.toggleProjectPinned.mockReset();
75
94
  useChatSessionListStore.setState({
@@ -97,12 +116,16 @@ describe("ChatSidebarProjectGroups", () => {
97
116
  expect(projectRow?.className).toContain("hover:bg-gray-200/60");
98
117
  const projectContent = projectLink.parentElement;
99
118
  expect(projectContent?.classList.contains("pr-14")).toBe(false);
100
- expect(projectContent?.className).toContain("group-hover/project:pr-14");
119
+ expect(projectContent?.className).toContain("group-hover/project:pr-20");
101
120
  expect(projectContent?.className).toContain(
102
- "group-has-[[data-project-actions]:focus-within]/project:pr-14",
121
+ "group-has-[[data-project-actions]:focus-within]/project:pr-20",
122
+ );
123
+ expect(projectLink.querySelector("span")?.className).not.toContain(
124
+ "uppercase",
125
+ );
126
+ expect(projectLink.querySelector("span")?.className).toContain(
127
+ "text-[13px]",
103
128
  );
104
- expect(projectLink.querySelector("span")?.className).not.toContain("uppercase");
105
- expect(projectLink.querySelector("span")?.className).toContain("text-[13px]");
106
129
  expect(
107
130
  header.compareDocumentPosition(projectLink) &
108
131
  Node.DOCUMENT_POSITION_FOLLOWING,
@@ -159,7 +182,7 @@ describe("ChatSidebarProjectGroups", () => {
159
182
  expect(within(tooltip).getByText("2")).toBeTruthy();
160
183
  });
161
184
 
162
- it("keeps project creation and pinning in one trailing action cluster", () => {
185
+ it("keeps project creation, pinning, and more actions in one trailing cluster", () => {
163
186
  renderProjectGroups();
164
187
 
165
188
  fireEvent.click(screen.getByLabelText("Pin project"));
@@ -168,6 +191,67 @@ describe("ChatSidebarProjectGroups", () => {
168
191
  "/tmp/analysis-project",
169
192
  );
170
193
  expect(screen.getByLabelText("New Task · analysis-project")).not.toBeNull();
194
+ const pinButton = screen.getByLabelText("Pin project");
195
+ const moreButton = screen.getByLabelText(
196
+ "More actions for analysis-project",
197
+ );
198
+ expect(moreButton.querySelector(".lucide-ellipsis-vertical")).not.toBeNull();
199
+ expect(
200
+ pinButton.compareDocumentPosition(moreButton) &
201
+ Node.DOCUMENT_POSITION_FOLLOWING,
202
+ ).toBeTruthy();
203
+ });
204
+
205
+ it("removes a project from an ordinary more-actions menu after confirmation", async () => {
206
+ const user = userEvent.setup();
207
+ renderProjectGroups(
208
+ false,
209
+ projectGroup,
210
+ "/projects/project-analysis/overview",
211
+ );
212
+
213
+ await user.click(
214
+ screen.getByLabelText("More actions for analysis-project"),
215
+ );
216
+ const removeButton = await screen.findByRole("button", {
217
+ name: "Remove from project list",
218
+ });
219
+ expect(removeButton.className).not.toContain("text-destructive");
220
+ await user.click(removeButton);
221
+
222
+ await vi.waitFor(() =>
223
+ expect(mocks.confirm).toHaveBeenCalledWith(
224
+ expect.objectContaining({
225
+ description: expect.stringMatching(/local folder|本地目录/),
226
+ variant: "default",
227
+ }),
228
+ ),
229
+ );
230
+ await vi.waitFor(() =>
231
+ expect(mocks.removeProject).toHaveBeenCalledWith("project-analysis"),
232
+ );
233
+ await vi.waitFor(() =>
234
+ expect(screen.getByTestId("location").textContent).toBe("/projects"),
235
+ );
236
+ });
237
+
238
+ it("keeps the project when removal is cancelled from the menu", async () => {
239
+ mocks.confirm.mockResolvedValue(false);
240
+ const user = userEvent.setup();
241
+ renderProjectGroups();
242
+
243
+ await user.click(
244
+ screen.getByLabelText("More actions for analysis-project"),
245
+ );
246
+ await user.click(
247
+ await screen.findByRole("button", {
248
+ name: "Remove from project list",
249
+ }),
250
+ );
251
+
252
+ await vi.waitFor(() => expect(mocks.confirm).toHaveBeenCalledOnce());
253
+ expect(mocks.removeProject).not.toHaveBeenCalled();
254
+ expect(screen.getByRole("link", { name: "analysis-project" })).toBeTruthy();
171
255
  });
172
256
 
173
257
  it("uses the same pin control to show and clear the project pin state", () => {
@@ -1,11 +1,13 @@
1
1
  import { useMemo, useState, type ReactNode } from "react";
2
- import { Link, useLocation } from "react-router-dom";
2
+ import { Link, useLocation, useNavigate } from "react-router-dom";
3
3
  import {
4
4
  AlarmClock,
5
5
  ChevronDown,
6
6
  ChevronRight,
7
7
  Folder,
8
+ FolderMinus,
8
9
  MessageSquareText,
10
+ MoreVertical,
9
11
  Pin,
10
12
  Plus,
11
13
  } from "lucide-react";
@@ -22,6 +24,9 @@ import { t } from "@/shared/lib/i18n";
22
24
  import { ChatSidebarContextCard } from "@/features/chat/features/session/components/chat-sidebar-context-card";
23
25
  import { SessionRunBadge } from "@/features/chat/features/session/components/session-run-badge";
24
26
  import { cn } from "@/shared/lib/utils";
27
+ import { useRemoveProject } from "@/shared/hooks/use-projects";
28
+ import { useConfirmDialog } from "@/shared/hooks/use-confirm-dialog";
29
+ import { ChatSessionHeaderMenuItem } from "@/features/chat/features/session/components/session-header/chat-session-header-menu-item";
25
30
 
26
31
  export type { ChatSidebarProjectGroup };
27
32
 
@@ -57,10 +62,16 @@ export function ChatSidebarProjectGroups(props: ChatSidebarProjectGroupsProps) {
57
62
  } = props;
58
63
  const presenter = usePresenter();
59
64
  const location = useLocation();
65
+ const navigate = useNavigate();
66
+ const projectRemoval = useRemoveProject();
67
+ const { confirm, ConfirmDialog } = useConfirmDialog();
60
68
  const collapsedProjectRoots = useChatSessionListStore(
61
69
  (state) => state.snapshot.collapsedProjectRoots,
62
70
  );
63
71
  const [openProjectRoot, setOpenProjectRoot] = useState<string | null>(null);
72
+ const [openProjectMenuRoot, setOpenProjectMenuRoot] = useState<string | null>(
73
+ null,
74
+ );
64
75
  const preferredSessionType = useMemo(
65
76
  () =>
66
77
  resolveProjectGroupDefaultSessionType(
@@ -70,6 +81,25 @@ export function ChatSidebarProjectGroups(props: ChatSidebarProjectGroupsProps) {
70
81
  [defaultSessionType, sessionTypeOptions],
71
82
  );
72
83
  const supportsSessionTypeChoice = sessionTypeOptions.length > 1;
84
+ const removeProject = async (group: ChatSidebarProjectGroup) => {
85
+ if (!group.projectId) return;
86
+ setOpenProjectMenuRoot(null);
87
+ const confirmed = await confirm({
88
+ title: `${t("projectsRemoveConfirmTitle")} “${group.projectName}”`,
89
+ description: t("projectsRemoveConfirmDescription"),
90
+ confirmLabel: t("projectsRemoveConfirmAction"),
91
+ variant: "default",
92
+ });
93
+ if (!confirmed) return;
94
+ try {
95
+ await projectRemoval.mutateAsync(group.projectId);
96
+ if (location.pathname.startsWith(`/projects/${group.projectId}/`)) {
97
+ navigate("/projects");
98
+ }
99
+ } catch {
100
+ // The mutation owns the visible error and the project stays available.
101
+ }
102
+ };
73
103
 
74
104
  return (
75
105
  <div className="space-y-0.5">
@@ -116,7 +146,7 @@ export function ChatSidebarProjectGroups(props: ChatSidebarProjectGroupsProps) {
116
146
  >
117
147
  <div
118
148
  className={cn(
119
- "flex h-full w-full min-w-0 items-center group-hover/project:pr-14 group-has-[[data-project-actions]:focus-within]/project:pr-14",
149
+ "flex h-full w-full min-w-0 items-center group-hover/project:pr-20 group-has-[[data-project-actions]:focus-within]/project:pr-20",
120
150
  hasRunningSession && "pr-7",
121
151
  )}
122
152
  >
@@ -243,6 +273,37 @@ export function ChatSidebarProjectGroups(props: ChatSidebarProjectGroupsProps) {
243
273
  )
244
274
  }
245
275
  />
276
+ {group.projectId ? (
277
+ <Popover
278
+ open={openProjectMenuRoot === group.projectRoot}
279
+ onOpenChange={(nextOpen) =>
280
+ setOpenProjectMenuRoot(
281
+ nextOpen ? group.projectRoot : null,
282
+ )
283
+ }
284
+ >
285
+ <PopoverTrigger asChild>
286
+ <IconActionButton
287
+ icon={<MoreVertical className="h-3.5 w-3.5" />}
288
+ label={t("projectsMoreActions").replace(
289
+ "{name}",
290
+ group.projectName,
291
+ )}
292
+ tooltip={false}
293
+ disabled={projectRemoval.isPending}
294
+ onClick={(event) => event.stopPropagation()}
295
+ />
296
+ </PopoverTrigger>
297
+ <ChatPopoverContent align="end" className="w-56 p-2">
298
+ <ChatSessionHeaderMenuItem
299
+ icon={FolderMinus}
300
+ label={t("projectsRemoveFromList")}
301
+ disabled={projectRemoval.isPending}
302
+ onClick={() => void removeProject(group)}
303
+ />
304
+ </ChatPopoverContent>
305
+ </Popover>
306
+ ) : null}
246
307
  </div>
247
308
  </div>
248
309
  {isCollapsed ? null : (
@@ -253,6 +314,7 @@ export function ChatSidebarProjectGroups(props: ChatSidebarProjectGroupsProps) {
253
314
  </div>
254
315
  );
255
316
  })}
317
+ <ConfirmDialog key="project-remove-confirm-dialog" />
256
318
  </div>
257
319
  );
258
320
  }
@@ -32,7 +32,7 @@ describe("PanelAppOpenStandaloneMenuItem", () => {
32
32
  setDesktopHost(undefined);
33
33
  });
34
34
 
35
- it("uses a real new-tab link on the web", () => {
35
+ it("uses an auxiliary new-tab link that installed PWA navigation cannot capture", () => {
36
36
  const onSelect = vi.fn();
37
37
  setDesktopHost(undefined);
38
38
  render(
@@ -44,7 +44,8 @@ describe("PanelAppOpenStandaloneMenuItem", () => {
44
44
  "/apps/panel/publisher.todo%20board/standalone",
45
45
  );
46
46
  expect(link.getAttribute("target")).toBe("_blank");
47
- expect(link.getAttribute("rel")).toBe("noopener noreferrer");
47
+ expect(link.getAttribute("rel")).toBe("opener");
48
+ expect(link.getAttribute("referrerpolicy")).toBe("no-referrer");
48
49
  });
49
50
 
50
51
  it("describes the same link as opening in the browser inside Desktop", () => {
@@ -18,7 +18,10 @@ export function PanelAppOpenStandaloneMenuItem({
18
18
  <a
19
19
  href={href}
20
20
  target="_blank"
21
- rel="noopener noreferrer"
21
+ // Chrome captures non-auxiliary in-scope links into an installed PWA.
22
+ // `opener` keeps this trusted same-origin target auxiliary, so the current browser owns the new tab.
23
+ rel="opener"
24
+ referrerPolicy="no-referrer"
22
25
  className="flex w-full items-center gap-2 rounded-lg px-2.5 py-2 text-left text-sm text-muted-foreground transition-colors hover:bg-[var(--interaction-hover)] hover:text-accent-foreground"
23
26
  onClick={onSelect}
24
27
  >
@@ -1,7 +1,6 @@
1
1
  # Projects UI boundary
2
2
 
3
- - 本目录拥有 Projects 页面、presenter、查询状态和用户回复编排;项目观测事实来自 `client.projects` 公共快照,工作项来自 Project Work API,组件不得自行扫描文件或解析 Marker。
4
- - 页面默认只读;确认/拒绝只复用现有 agent-run 消息入口,并携带可追踪、可幂等的响应元数据,不创建第二套 response bridge。
3
+ - 本目录拥有 Projects 页面、presenter 和查询状态;工作项与产物来自 Project Work API,Skills 与工作约定来自独立的有界材料 API,组件不得读取项目配置、扫描文件或从会话正文重建项目事实。
5
4
  - Overview、列表和看板消费同一份工作项查询状态;所有工作项入口统一打开右侧详情抽屉,不得在页面内追加平铺详情。
6
5
  - `project.work.changed` 只用于失效查询;UI 不重放事件历史,也不以轮询或目录扫描代替业务存储。
7
6
  - 组件负责连接与展示,跨组件状态归 hook/presenter;用户文案必须走 Projects i18n 资源。