@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.
- package/CHANGELOG.md +18 -0
- package/dist/.vite/manifest.json +517 -517
- package/dist/assets/{account-panel-BxMlLXYH.js → account-panel-BRTSwNvA.js} +1 -1
- package/dist/assets/{api-Utt-xzrT.js → api-BnUzdltV.js} +5 -5
- package/dist/assets/{app-data-DYXDL6X2.js → app-data-Bjh_zM45.js} +1 -1
- package/dist/assets/app-presenter-provider-CBt-lyr_.js +109 -0
- package/dist/assets/{appearance-settings-page-BfYznAK5.js → appearance-settings-page-BrOYSgG0.js} +1 -1
- package/dist/assets/{book-open-DDW_3XpM.js → book-open-xqEj1OLE.js} +1 -1
- package/dist/assets/{boxes-DwJeuK_h.js → boxes-D6uPnkGo.js} +1 -1
- package/dist/assets/{card-IevY2nm-.js → card-CS8su2Zh.js} +1 -1
- package/dist/assets/{channels-list-page-DitnqbMR.js → channels-list-page-BE0TxB3B.js} +1 -1
- package/dist/assets/{chevron-down-An7Km-t4.js → chevron-down-BL-yMYcX.js} +1 -1
- package/dist/assets/{circle-alert-CDXqELuo.js → circle-alert-lSa3LRvS.js} +1 -1
- package/dist/assets/{circle-dashed-CapXEpiV.js → circle-dashed-CU3yApvP.js} +1 -1
- package/dist/assets/{client-B0krol7A.js → client-BtGBwLTs.js} +1 -1
- package/dist/assets/{config-split-page-BtnkqWVp.js → config-split-page-BxDwwAGa.js} +1 -1
- package/dist/assets/{confirm-dialog-DFt4jpN7.js → confirm-dialog-S5JxZcS1.js} +1 -1
- package/dist/assets/{createLucideIcon-BTHK0Ot9.js → createLucideIcon-BNKf0_kc.js} +1 -1
- package/dist/assets/{desktop-capabilities-page-CCf14WId.js → desktop-capabilities-page-BwHxJpbl.js} +1 -1
- package/dist/assets/{desktop-update-config-DVoVgfFi.js → desktop-update-config-Bfg7OdJ2.js} +1 -1
- package/dist/assets/{dialog-BFN_1DBH.js → dialog-Xe73hpQz.js} +1 -1
- package/dist/assets/{dist-Bc9hOVNN.js → dist-BiIcnf9j.js} +1 -1
- package/dist/assets/{dist-CEhIDAnr.js → dist-C5I0v8Qn.js} +1 -1
- package/dist/assets/{dist-hkVPP1th.js → dist-czPa8xFO.js} +1 -1
- package/dist/assets/doc-browser-BgRP0Wni.js +1 -0
- package/dist/assets/{doc-browser-BNUxmwD6.js → doc-browser-C8eqJLi_.js} +1 -1
- package/dist/assets/{doc-browser-context-C4yQrKrH.js → doc-browser-context-BPCDFcC-.js} +1 -1
- package/dist/assets/{ellipsis-BRI6ROeu.js → ellipsis-C5YXdOUx.js} +1 -1
- package/dist/assets/{es2015-MOCbM0Eu.js → es2015-cuwbYI-l.js} +1 -1
- package/dist/assets/{extensions-DxUBMtHW.js → extensions-DgKQRebe.js} +1 -1
- package/dist/assets/{eye-cnynUDGt.js → eye-C84inPcV.js} +1 -1
- package/dist/assets/{form-actions-gQ0JEUwB.js → form-actions-AIdXOoCL.js} +1 -1
- package/dist/assets/{i18n-B9yXA8KO.js → i18n-CKvm9zyk.js} +2 -2
- package/dist/assets/{i18n-provider-BYBJua91.js → i18n-provider-CPV43pMX.js} +1 -1
- package/dist/assets/loader-circle-K1BDdHR5.js +1 -0
- package/dist/assets/login-page-ClcrvN04.js +1 -0
- package/dist/assets/{login-page-CqrHhzaN.js → login-page-DeDQjVxv.js} +1 -1
- package/dist/assets/{logo-badge-Cr03YceJ.js → logo-badge-C-5-zim6.js} +1 -1
- package/dist/assets/main-DGqlaAaI.css +1 -0
- package/dist/assets/main-i18n-catalog.config-CpNF5aVc.js +1 -0
- package/dist/assets/main-nMVfHb5K.js +2 -0
- package/dist/assets/{mcp-marketplace-page-CifiVgFD.js → mcp-marketplace-page-CWjJGp_D.js} +1 -1
- package/dist/assets/mcp-marketplace-page-fvu2NcXT.js +1 -0
- package/dist/assets/{model-config-page-C6jVNbSj.js → model-config-page-Dv_zE7HN.js} +1 -1
- package/dist/assets/{navigation-link-kbCLRSr_.js → navigation-link-BAQjgx2F.js} +1 -1
- package/dist/assets/panel-app-i18n-catalog.config-BzxE3tZb.js +1 -0
- package/dist/assets/{panelStandalone-DMBnYyTw.js → panelStandalone-CFRBHV94.js} +2 -2
- package/dist/assets/plus-LA8-jpxP.js +1 -0
- package/dist/assets/{popover-XVDgjxcl.js → popover-NkrFlWHp.js} +1 -1
- package/dist/assets/{privacy-settings-page-BN27MBVA.js → privacy-settings-page-D6uc9f-A.js} +1 -1
- package/dist/assets/projects-BD1rG75R.js +1 -0
- package/dist/assets/{provider-scoped-model-input-BGZMCThn.js → provider-scoped-model-input-DUa_9uwg.js} +1 -1
- package/dist/assets/{providers-config-page-D5aBwbOD.js → providers-config-page-DAiqxlF_.js} +1 -1
- package/dist/assets/{puzzle-D5Dhacmb.js → puzzle-D6gulz7u.js} +1 -1
- package/dist/assets/{pwa-ClQK56Qe.js → pwa-C_Zte1xe.js} +1 -1
- package/dist/assets/{refresh-cw-Bw5BY7vp.js → refresh-cw-h9Xq3LY3.js} +1 -1
- package/dist/assets/remote-BO0QP7ua.js +1 -0
- package/dist/assets/{rotate-cw-BksCLAeE.js → rotate-cw-B6xm41Wn.js} +1 -1
- package/dist/assets/runtime-config-page-w1UAkGF_.js +1 -0
- package/dist/assets/{save-CVi8VWzb.js → save-fff_WpY2.js} +1 -1
- package/dist/assets/{search-DN-f7IIC.js → search-CUe41wjm.js} +1 -1
- package/dist/assets/{search-config-page-BmuZTVxs.js → search-config-page-3xbhRlW2.js} +1 -1
- package/dist/assets/{secrets-config-page-NPHpg9sb.js → secrets-config-page-Dn8_rdOj.js} +1 -1
- package/dist/assets/security-config-Y1nEGM3A.js +1 -0
- package/dist/assets/{select-CmDTqk2C.js → select-CG5YWnwe.js} +1 -1
- package/dist/assets/{service-apps-panel-BYGJ9_pO.js → service-apps-panel-CGc04aMn.js} +1 -1
- package/dist/assets/{settings-2-B62YtZon.js → settings-2-CE3ELQyk.js} +1 -1
- package/dist/assets/skeleton-BL9h32W7.js +1 -0
- package/dist/assets/{tabs-Bk_mG7ql.js → tabs-BuE0qKMh.js} +1 -1
- package/dist/assets/{tag-chip-DgqKlI5D.js → tag-chip-BDzpHEli.js} +1 -1
- package/dist/assets/{theme-provider-CeBY2pyu.js → theme-provider-B6FinATQ.js} +1 -1
- package/dist/assets/{tooltip-CgGbBdYf.js → tooltip-DYcuWhuP.js} +1 -1
- package/dist/assets/{trash-2-CVOev8yc.js → trash-2-BPPYt2NV.js} +1 -1
- package/dist/assets/{use-config-b2DN67gs.js → use-config-BPUM2lbo.js} +1 -1
- package/dist/assets/{use-desktop-capabilities-B3tLU1yl.js → use-desktop-capabilities-BDjArQP3.js} +1 -1
- package/dist/assets/{use-panel-app-scroll-restoration-BekzoX6z.js → use-panel-app-scroll-restoration-DsV1IJx-.js} +1 -1
- package/dist/assets/{use-viewport-layout-CUA3jQsA.js → use-viewport-layout-BS18drMT.js} +1 -1
- package/dist/assets/{utils-UBHTdG5Q.js → utils-CBZPzC_b.js} +1 -1
- package/dist/assets/x-DdXOqLnX.js +1 -0
- package/dist/index.html +50 -50
- package/dist/panel-standalone.html +15 -15
- package/package.json +3 -3
- package/src/features/chat/features/message/utils/__tests__/chat-message-timeline.utils.test.ts +10 -0
- package/src/features/chat/features/session/components/__tests__/chat-sidebar-project-groups.test.tsx +90 -6
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +64 -2
- package/src/features/panel-apps/components/__tests__/panel-app-open-standalone-menu-item.test.tsx +3 -2
- package/src/features/panel-apps/components/panel-app-open-standalone-menu-item.tsx +4 -1
- package/src/features/projects/AGENTS.md +1 -2
- package/src/features/projects/components/project-agreement.tsx +36 -77
- package/src/features/projects/components/project-artifacts.test.tsx +90 -62
- package/src/features/projects/components/project-artifacts.tsx +81 -160
- package/src/features/projects/components/project-materials.test.tsx +80 -0
- package/src/features/projects/components/project-overview.test.tsx +50 -40
- package/src/features/projects/components/project-overview.tsx +5 -4
- package/src/features/projects/components/project-skills.tsx +24 -14
- package/src/features/projects/components/work/project-work-item-drawer.test.tsx +3 -2
- package/src/features/projects/components/work/project-work-items.test.tsx +13 -1
- package/src/features/projects/components/work/project-work-items.tsx +7 -7
- package/src/features/projects/hooks/use-project-materials.test.tsx +65 -0
- package/src/features/projects/hooks/use-project-materials.ts +24 -0
- package/src/features/projects/hooks/use-project-work.test.tsx +57 -1
- package/src/features/projects/hooks/use-project-work.ts +11 -5
- package/src/features/projects/pages/project-home-page.tsx +51 -127
- package/src/features/projects/pages/projects-page.test.tsx +68 -75
- package/src/features/projects/presenters/project-home.presenter.test.ts +1 -64
- package/src/features/projects/presenters/project-home.presenter.ts +17 -54
- package/src/features/projects/utils/project-artifact-view.utils.test.ts +0 -46
- package/src/features/projects/utils/project-artifact-view.utils.ts +0 -47
- package/src/shared/lib/i18n/locales/en-US/projects.json +8 -59
- package/src/shared/lib/i18n/locales/zh-CN/projects.json +8 -59
- package/dist/assets/app-presenter-provider-CLsFiXvV.js +0 -109
- package/dist/assets/doc-browser-w4eGZXLu.js +0 -1
- package/dist/assets/loader-circle-rWr5Yo0E.js +0 -1
- package/dist/assets/login-page-CfMSkOsg.js +0 -1
- package/dist/assets/main-8cVkMfgE.css +0 -1
- package/dist/assets/main-Bys58GxY.js +0 -2
- package/dist/assets/main-i18n-catalog.config-BSq9yiUQ.js +0 -1
- package/dist/assets/mcp-marketplace-page-DX5VE3mU.js +0 -1
- package/dist/assets/panel-app-i18n-catalog.config-C2St67SP.js +0 -1
- package/dist/assets/plus-BHnKwuPq.js +0 -1
- package/dist/assets/projects-DV3UuJMS.js +0 -1
- package/dist/assets/remote-Bl005fzu.js +0 -1
- package/dist/assets/runtime-config-page-CmktQcMW.js +0 -1
- package/dist/assets/security-config-Djptuyf2.js +0 -1
- package/dist/assets/skeleton-Eh64l4T2.js +0 -1
- package/dist/assets/x-C0iaOsRW.js +0 -1
- package/src/features/projects/components/project-requests.tsx +0 -57
- package/src/features/projects/components/project-runs.tsx +0 -60
- package/src/features/projects/hooks/use-project-observation.test.tsx +0 -93
- package/src/features/projects/hooks/use-project-observation.ts +0 -115
- package/src/features/projects/utils/project-request-response.utils.test.ts +0 -44
- 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-
|
|
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-
|
|
264
|
-
<link rel="modulepreload" crossorigin href="/assets/client-
|
|
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-
|
|
267
|
-
<link rel="modulepreload" crossorigin href="/assets/dist-
|
|
268
|
-
<link rel="modulepreload" crossorigin href="/assets/es2015-
|
|
269
|
-
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-
|
|
270
|
-
<link rel="modulepreload" crossorigin href="/assets/chevron-down-
|
|
271
|
-
<link rel="modulepreload" crossorigin href="/assets/select-
|
|
272
|
-
<link rel="modulepreload" crossorigin href="/assets/dist-
|
|
273
|
-
<link rel="modulepreload" crossorigin href="/assets/x-
|
|
274
|
-
<link rel="modulepreload" crossorigin href="/assets/dialog-
|
|
275
|
-
<link rel="modulepreload" crossorigin href="/assets/popover-
|
|
276
|
-
<link rel="modulepreload" crossorigin href="/assets/tooltip-
|
|
277
|
-
<link rel="modulepreload" crossorigin href="/assets/i18n-
|
|
278
|
-
<link rel="modulepreload" crossorigin href="/assets/api-
|
|
279
|
-
<link rel="modulepreload" crossorigin href="/assets/search-
|
|
280
|
-
<link rel="modulepreload" crossorigin href="/assets/book-open-
|
|
281
|
-
<link rel="modulepreload" crossorigin href="/assets/boxes-
|
|
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-
|
|
284
|
-
<link rel="modulepreload" crossorigin href="/assets/plus-
|
|
285
|
-
<link rel="modulepreload" crossorigin href="/assets/refresh-cw-
|
|
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-
|
|
288
|
-
<link rel="modulepreload" crossorigin href="/assets/use-panel-app-scroll-restoration-
|
|
289
|
-
<link rel="modulepreload" crossorigin href="/assets/doc-browser-
|
|
290
|
-
<link rel="modulepreload" crossorigin href="/assets/circle-alert-
|
|
291
|
-
<link rel="modulepreload" crossorigin href="/assets/loader-circle-
|
|
292
|
-
<link rel="modulepreload" crossorigin href="/assets/confirm-dialog-
|
|
293
|
-
<link rel="modulepreload" crossorigin href="/assets/i18n-provider-
|
|
294
|
-
<link rel="modulepreload" crossorigin href="/assets/tag-chip-
|
|
295
|
-
<link rel="modulepreload" crossorigin href="/assets/skeleton-
|
|
296
|
-
<link rel="modulepreload" crossorigin href="/assets/mcp-marketplace-page-
|
|
297
|
-
<link rel="modulepreload" crossorigin href="/assets/puzzle-
|
|
298
|
-
<link rel="modulepreload" crossorigin href="/assets/trash-2-
|
|
299
|
-
<link rel="modulepreload" crossorigin href="/assets/app-data-
|
|
300
|
-
<link rel="modulepreload" crossorigin href="/assets/ellipsis-
|
|
301
|
-
<link rel="modulepreload" crossorigin href="/assets/eye-
|
|
302
|
-
<link rel="modulepreload" crossorigin href="/assets/tabs-
|
|
303
|
-
<link rel="modulepreload" crossorigin href="/assets/use-viewport-layout-
|
|
304
|
-
<link rel="modulepreload" crossorigin href="/assets/theme-provider-
|
|
305
|
-
<link rel="modulepreload" crossorigin href="/assets/use-desktop-capabilities-
|
|
306
|
-
<link rel="modulepreload" crossorigin href="/assets/logo-badge-
|
|
307
|
-
<link rel="modulepreload" crossorigin href="/assets/card-
|
|
308
|
-
<link rel="modulepreload" crossorigin href="/assets/use-config-
|
|
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-
|
|
311
|
-
<link rel="modulepreload" crossorigin href="/assets/provider-scoped-model-input-
|
|
312
|
-
<link rel="modulepreload" crossorigin href="/assets/settings-2-
|
|
313
|
-
<link rel="modulepreload" crossorigin href="/assets/pwa-
|
|
314
|
-
<link rel="modulepreload" crossorigin href="/assets/login-page-
|
|
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-
|
|
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-
|
|
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-
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/client-
|
|
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-
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/api-
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/dist-
|
|
16
|
-
<link rel="modulepreload" crossorigin href="/assets/es2015-
|
|
17
|
-
<link rel="modulepreload" crossorigin href="/assets/dist-
|
|
18
|
-
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-
|
|
19
|
-
<link rel="modulepreload" crossorigin href="/assets/x-
|
|
20
|
-
<link rel="modulepreload" crossorigin href="/assets/dialog-
|
|
21
|
-
<link rel="modulepreload" crossorigin href="/assets/boxes-
|
|
22
|
-
<link rel="modulepreload" crossorigin href="/assets/use-panel-app-scroll-restoration-
|
|
23
|
-
<link rel="modulepreload" crossorigin href="/assets/theme-provider-
|
|
24
|
-
<link rel="modulepreload" crossorigin href="/assets/i18n-provider-
|
|
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.
|
|
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.
|
|
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.
|
|
44
|
+
"@nextclaw/shared": "0.5.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@testing-library/react": "^16.3.0",
|
package/src/features/chat/features/message/utils/__tests__/chat-message-timeline.utils.test.ts
CHANGED
|
@@ -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", () => {
|
package/src/features/chat/features/session/components/__tests__/chat-sidebar-project-groups.test.tsx
CHANGED
|
@@ -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={[
|
|
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-
|
|
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-
|
|
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
|
|
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-
|
|
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
|
}
|
package/src/features/panel-apps/components/__tests__/panel-app-open-standalone-menu-item.test.tsx
CHANGED
|
@@ -32,7 +32,7 @@ describe("PanelAppOpenStandaloneMenuItem", () => {
|
|
|
32
32
|
setDesktopHost(undefined);
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
it("uses
|
|
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("
|
|
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
|
-
|
|
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
|
|
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 资源。
|