@nextclaw/ui 0.26.5 → 0.27.0
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 +53 -0
- package/dist/.vite/manifest.json +1271 -1227
- package/dist/assets/{abnfDiagram-VRR7QNED-Dcw10Yt1.js → abnfDiagram-VRR7QNED-DmeCRAkd.js} +1 -1
- package/dist/assets/account-panel-BYxGT4m4.js +1 -0
- package/dist/assets/{aiden0z-pptx-renderer.es--oNqetPA.js → aiden0z-pptx-renderer.es-ChX5DHqP.js} +1 -1
- package/dist/assets/api-CG22BskB.js +20 -0
- package/dist/assets/app-presenter-provider-CJFjhVYI.js +28 -0
- package/dist/assets/app-presenter-provider-D3BuuOyZ.css +1 -0
- package/dist/assets/appearance-settings-page-BcXr0vHp.js +1 -0
- package/dist/assets/{arc-DBRedCax.js → arc-Cu6Ols44.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-CLjV_xu4.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-Dufhtuv-.js → architectureDiagram-ZJ3FMSHR-DrNB0eLE.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-BUk0vtJ7.js → blockDiagram-677ZJIJ3-08rHt6DJ.js} +1 -1
- package/dist/assets/{book-open-Bcnn2_uV.js → book-open-ClbJmmxP.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-CxDcVE9p.js → c4Diagram-LMCZKHZV-CCVgRG-u.js} +1 -1
- package/dist/assets/{card-Cqs73hGI.js → card-BdC01NFF.js} +1 -1
- package/dist/assets/channel-BgpbPyEH.js +1 -0
- package/dist/assets/channels-list-page-BrIvJlop.js +8 -0
- package/dist/assets/chunk-2Q5K7J3B-DjhMPqAC.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-DSF3KElA.js → chunk-32BRIVSS-BeCaI-JN.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-Costxzr3.js → chunk-52WLFC77-ZXIcYPYs.js} +1 -1
- package/dist/assets/{chunk-5FCAYU7R-rhqzGGZo.js → chunk-5FCAYU7R-DDwTPcy8.js} +1 -1
- package/dist/assets/{chunk-5HE753X5-BsEsmIao.js → chunk-5HE753X5-WygrMYPL.js} +1 -1
- package/dist/assets/{chunk-5JV3BV7I-Dqw_DCoN.js → chunk-5JV3BV7I-o8T3KZgk.js} +1 -1
- package/dist/assets/{chunk-5TONJI2A-Cft82fp8.js → chunk-5TONJI2A-BKFbUT7J.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DqNHn9Dl.js → chunk-5VM5RSS4-DYxCRV86.js} +1 -1
- package/dist/assets/{chunk-7BUUIJ7U-A5SBEMYY.js → chunk-7BUUIJ7U-CvSeJlKZ.js} +1 -1
- package/dist/assets/{chunk-BIQX33UG-1Ng3mTrH.js → chunk-BIQX33UG-BhH3RHCY.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-DRJEy8ZI.js → chunk-C7G6YPKG-BTL0-xL3.js} +1 -1
- package/dist/assets/{chunk-CQNSW5MT-Bydv_J3J.js → chunk-CQNSW5MT-DWAU4QaD.js} +1 -1
- package/dist/assets/{chunk-CYSBUYHQ-HkMIg12u.js → chunk-CYSBUYHQ-B7ZBMXTx.js} +1 -1
- package/dist/assets/{chunk-EMLP6XTP-C5ndDvm3.js → chunk-EMLP6XTP-D92HvnHE.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-DzeloZRo.js → chunk-EX3LRPZG-DfOGKwW8.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-n_2_CLTQ.js → chunk-FWX5IMBZ-DUuJUrXJ.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-kx_slvu3.js → chunk-HOUHSVGY-i3MDyUY5.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-sQLMURqL.js → chunk-ICXQ74PX-F_pmNX6t.js} +1 -1
- package/dist/assets/{chunk-JG7HCLWE-CMUn5Elc.js → chunk-JG7HCLWE-DygOelrU.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-Cra3s-Uk.js → chunk-JWPE2WC7-BpiZMeRl.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-umcrg5Bi.js → chunk-MOJQB5TN-CV10sB1I.js} +1 -1
- package/dist/assets/{chunk-MOZMSUNE-BnljD1ig.js → chunk-MOZMSUNE-Cf1WZNm0.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-BXx5pQjU.js → chunk-OGEWGWER-DuSw54VR.js} +1 -1
- package/dist/assets/{chunk-OSBZ3O6U-D-1qfdWu.js → chunk-OSBZ3O6U-_rt_XKSZ.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-DLzX78LC.js → chunk-PUDLZKDR-BFPaAGNW.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-DTK-rtW6.js → chunk-Q4XR5HBZ-GE0v_E5y.js} +1 -1
- package/dist/assets/{chunk-QBLGF6JB-CsFeIGfr.js → chunk-QBLGF6JB-BK_FpnlJ.js} +1 -1
- package/dist/assets/{chunk-R7FJI6CG-4xNYUeng.js → chunk-R7FJI6CG-CpYh6rGo.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-DJiHiTE5.js → chunk-RYQCIY6F-htnxL_Cl.js} +1 -1
- package/dist/assets/{chunk-U6XO7XAA-BVYkauHz.js → chunk-U6XO7XAA-wDbE4BZ7.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-BsazE8cS.js → chunk-V7JOEXUC-DDRSVFTB.js} +1 -1
- package/dist/assets/chunk-VAUOI2AC-GYimZYx9.js +1 -0
- package/dist/assets/{chunk-VR4S4FIN-7RoZQffO.js → chunk-VR4S4FIN-COdhHR1o.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-DEuS6N1R.js → chunk-WYO6CB5R-DPDGhyF6.js} +3 -3
- package/dist/assets/chunk-XXDRQBXY-KKCf0HV5.js +1 -0
- package/dist/assets/{chunk-YOTPTUD7-9KBrosZL.js → chunk-YOTPTUD7-D8ir9Nx5.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-IYgN9f5A.js → chunk-ZGVPDNZ5-BuNKD836.js} +1 -1
- package/dist/assets/{chunk-ZIRB5QZD-BUo0-zcp.js → chunk-ZIRB5QZD-DyHzq8jH.js} +1 -1
- package/dist/assets/{circle-dashed-EY1ScSMe.js → circle-dashed-nDaMRmP-.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-iRMPRR8M.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-BguFy_wj.js +1 -0
- package/dist/assets/{client-CH7w6yRV.js → client-DlFB5dW5.js} +1 -1
- package/dist/assets/config-split-page-C06fU9OQ.js +1 -0
- package/dist/assets/confirm-dialog-DpcmlXhd.js +1 -0
- package/dist/assets/{app-presenter-provider-jNGlmBLe.css → context-menu-DEcVZfaU.css} +1 -1
- package/dist/assets/context-menu-DKIEaY7f.js +211 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-DhqbC1fR.js → cose-bilkent-JH36ORCC-B1I1_P6a.js} +1 -1
- package/dist/assets/{createLucideIcon-Cfo2ySi5.js → createLucideIcon-Lnt-4LMC.js} +1 -1
- package/dist/assets/cynefin-VYW2F7L2-CtbjXuCW.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-C-TBRi5V.js → cynefinDiagram-TSTJHNR4-DcOnhnCo.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB-BmafJymp.js → dagre-VKFMJZFB-hAX89lg3.js} +1 -1
- package/dist/assets/{dagre-CrgsRasE.js → dagre-nSYhf9yY.js} +1 -1
- package/dist/assets/{desktop-capabilities-page-BDYITStl.js → desktop-capabilities-page-DPORyZAu.js} +1 -1
- package/dist/assets/desktop-update-config-BMTeWZmn.js +1 -0
- package/dist/assets/{diagram-FQU43EPY-BoOMwa6D.js → diagram-FQU43EPY-C1mRMD2k.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-Le7N6Uym.js → diagram-G47NLZAW-D2XBn5al.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-Fbpj3-MO.js → diagram-NH7WQ7WH-3LmRsmkC.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-D3QuGGuu.js → diagram-OA4YK3LP-CFWn-osC.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-Cxu1uiN6.js → diagram-WEI45ONY-BqNRbUvU.js} +1 -1
- package/dist/assets/dialog-BNXSPMX_.js +1 -0
- package/dist/assets/dist-Cuiqqp1O.js +41 -0
- package/dist/assets/doc-browser-CDEapjmj.js +1 -0
- package/dist/assets/{doc-browser-context-DwgG6wrz.js → doc-browser-context-0QDWYorh.js} +1 -1
- package/dist/assets/{docx-preview-CkU2psnd.js → docx-preview-CunAATyC.js} +1 -1
- package/dist/assets/{download-BoaKzDJk.js → download-f_sPcoLZ.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-CCAjuQM6.js → ebnfDiagram-CCIWWBDH-CYb8IwqD.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-BuzUAq-d.js → erDiagram-Q63AITRT-H47mUoeK.js} +1 -1
- package/dist/assets/eventmodeling-45OFAUF4-Djd6id_u.js +1 -0
- package/dist/assets/extensions-B-0xQz3L.js +1 -0
- package/dist/assets/external-link-CbVlnlNy.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-DUrsM_ZL.js +1 -0
- package/dist/assets/{form-actions-D9JWSFQu.js → form-actions-BoTqELHB.js} +1 -1
- package/dist/assets/{ganttDiagram-NO4QXBWP-cJmWVY8F.js → ganttDiagram-NO4QXBWP-hSX45zfV.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-CU6P_2Cm.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-F58o-vtP.js → gitGraphDiagram-IHSO6WYX-Br0UW2qg.js} +1 -1
- package/dist/assets/{i18n-Bm3Ov7Fy.js → i18n-B0V5NkFj.js} +2 -2
- package/dist/assets/inbox-Bna8iUy0.js +1 -0
- package/dist/assets/info-DKCQHKI2-Bj2P_7RC.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-Gt59b83C.js → infoDiagram-FWYZ7A6U-DQmP_67w.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-1u4IAj1I.js → ishikawaDiagram-FXEZZL3T-BHAV2oes.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-CCQsfV-5.js → journeyDiagram-5HDEW3XC-CFHax4_d.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-vlB6O_Zn.js → kanban-definition-HUTT4EX6-B4ZA9rp5.js} +1 -1
- package/dist/assets/katex-BprZ-Wwb.js +1 -0
- package/dist/assets/{keyboard-shortcuts-settings-page-DZ8A1iLg.js → keyboard-shortcuts-settings-page-BluWKrSo.js} +1 -1
- package/dist/assets/{line-D_bHubTL.js → line-BboM0HLF.js} +1 -1
- package/dist/assets/{linear-ChlwuS5y.js → linear-4K_M1oYM.js} +1 -1
- package/dist/assets/login-page-BMHW0Hh0.js +1 -0
- package/dist/assets/{login-page-C-DvcG3L.js → login-page-JNr5JCEw.js} +1 -1
- package/dist/assets/main-BCX_Untx.css +1 -0
- package/dist/assets/main-C5kbmGUV.js +2 -0
- package/dist/assets/main-i18n-catalog.config-DO4wNT7T.js +1 -0
- package/dist/assets/{map-oGHTsIu8.js → map-26GpO1wn.js} +1 -1
- package/dist/assets/mcp-marketplace-page-CV-PHKTN.js +1 -0
- package/dist/assets/{mermaid-parser.core-CuRe1ZG4.js → mermaid-parser.core-BTJFnvRC.js} +2 -2
- package/dist/assets/{mermaid.core-u4YCFKRf.js → mermaid.core-B7ufoXgq.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-DeJAQYTu.js → mindmap-definition-LN4V7U3C-BHyru6KE.js} +1 -1
- package/dist/assets/model-config-page-C-wbM6Fe.js +1 -0
- package/dist/assets/{navigation-link-CjxNC8aT.js → navigation-link-DFLSVIut.js} +2 -2
- package/dist/assets/{ordinal-C6JFfkKN.js → ordinal-BqFe2ePF.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-ti5ge2jr.js +1 -0
- package/dist/assets/panel-app-CSQmm_7E.js +1 -0
- package/dist/assets/panel-app-i18n-catalog.config-Bo52dPuF.js +1 -0
- package/dist/assets/panelStandalone-PuuMF65O.js +2 -0
- package/dist/assets/panelStandalone-XRlWxbRS.css +1 -0
- package/dist/assets/{pegDiagram-2B236MQR-nVMkxShH.js → pegDiagram-2B236MQR-PVTatU5j.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-Bnep8TyV.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-8aUH44QZ.js → pieDiagram-ENE6RG2P-CGc-QCc7.js} +1 -1
- package/dist/assets/plus-CywSlIbG.js +1 -0
- package/dist/assets/privacy-settings-page-CPdEiouE.js +1 -0
- package/dist/assets/projects-D_cd_t4G.js +1 -0
- package/dist/assets/provider-models-XRArsply.js +1 -0
- package/dist/assets/provider-scoped-model-input-C8JI-hus.js +1 -0
- package/dist/assets/providers-config-page-fyMlVgvq.js +1 -0
- package/dist/assets/puzzle-Bk3ud1KI.js +1 -0
- package/dist/assets/pwa-Cx6Fnox4.js +1 -0
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-EY8hpFv8.js → quadrantDiagram-ABIIQ3AL-DGL36riv.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-BYg-icAP.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-_CHO-Fi1.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-hbQDevHe.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-v4RZkOfi.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6-bC9BqkI5.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6-CNhcIeji.js → railroadDiagram-RFXS5EU6-CyNwvhSb.js} +1 -1
- package/dist/assets/{refresh-cw-BlXDrVP0.js → refresh-cw-Ca2napNx.js} +1 -1
- package/dist/assets/remote-D5MBQNZE.js +1 -0
- package/dist/assets/{requirementDiagram-TGXJPOKE-D8Dcs-Rt.js → requirementDiagram-TGXJPOKE-C31NMKJ0.js} +1 -1
- package/dist/assets/{rotate-cw-ei6rPD6z.js → rotate-cw-DXg7sNUE.js} +1 -1
- package/dist/assets/runtime-config-page--ivCxBT4.js +1 -0
- package/dist/assets/{sankeyDiagram-HTMAVEWB-HTrb6aa-.js → sankeyDiagram-HTMAVEWB-CwrQ_7PA.js} +1 -1
- package/dist/assets/{save-DdF-bXgC.js → save-DNigywZ9.js} +1 -1
- package/dist/assets/search-U9C0oTQJ.js +1 -0
- package/dist/assets/search-config-page-Bdx_RR1q.js +1 -0
- package/dist/assets/secrets-config-page-CvMIcsfJ.js +3 -0
- package/dist/assets/security-config-CQmMqQ8v.js +1 -0
- package/dist/assets/select-DxwDeKUR.js +1 -0
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-6f_4X16Y.js → sequenceDiagram-DBY2YBRQ-EFD482_y.js} +1 -1
- package/dist/assets/service-apps-panel-CiYO1Be4.js +1 -0
- package/dist/assets/{settings-2-CrNhfInU.js → settings-2-BrBUdRoY.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-Ck9rsuwL.js → sizeCapture-X5ZJPWSS-TDvULTE1.js} +1 -1
- package/dist/assets/{src-C8AUg09O.js → src-CI2AvEMj.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-Cm33MLHu.js → stateDiagram-2N3HPSRC-JdPsIYHo.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-4_aAQfB_.js +1 -0
- package/dist/assets/{status-dot-C3SRFEta.js → status-dot-BbGsrkIX.js} +1 -1
- package/dist/assets/{swimlanes-5IMT3BWC-B107vmvM.js → swimlanes-5IMT3BWC-BnxpKeK_.js} +2 -2
- package/dist/assets/swimlanesDiagram-G3AALYLV-wCqfwsw-.js +8 -0
- package/dist/assets/tag-chip-BDbxcf6P.js +1 -0
- package/dist/assets/theme-provider-D98XGa-c.js +1 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-CJEoAj33.js → timeline-definition-FHXFAJF6-2IL22-uC.js} +1 -1
- package/dist/assets/trash-2-DwSkRfeB.js +1 -0
- package/dist/assets/treeView-QDETBFTQ-BAyOb14Z.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-DgPDM0zS.js +1 -0
- package/dist/assets/{use-config-evzage09.js → use-config-D3cNzk2k.js} +1 -1
- package/dist/assets/{use-desktop-capabilities-BYDjFlpt.js → use-desktop-capabilities-D7odgaTB.js} +1 -1
- package/dist/assets/use-viewport-layout-BANU5E1t.js +1 -0
- package/dist/assets/{vennDiagram-L72KCM5P-DzsUHk5I.js → vennDiagram-L72KCM5P-Cjf6n5Va.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-eCElh8z5.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-1NfFs5ua.js → wardleyDiagram-EHGQE667-yv4qKbBO.js} +1 -1
- package/dist/assets/x-BqGj6_Vq.js +1 -0
- package/dist/assets/{xychartDiagram-FW5EYKEG-Ci8AI3Qo.js → xychartDiagram-FW5EYKEG-Bmp8Ck8X.js} +1 -1
- package/dist/index.html +43 -106
- package/dist/panel-standalone.html +18 -12
- package/index.html +15 -66
- package/package.json +4 -4
- package/src/app/styles/design-system.css +85 -1
- package/src/app/styles/island-theme.css +8 -6
- package/src/features/agents/components/agent-details-dialog.tsx +5 -3
- package/src/features/app-data/components/app-retained-data-section.tsx +2 -2
- package/src/features/apps/components/__tests__/app-marketplace-catalog.test.tsx +2 -2
- package/src/features/apps/components/__tests__/app-packages-panel.test.tsx +94 -23
- package/src/features/apps/components/__tests__/apps-panel.test.tsx +5 -3
- package/src/features/apps/components/app-document-access-section.tsx +17 -14
- package/src/features/apps/components/app-marketplace-catalog.tsx +66 -39
- package/src/features/apps/components/app-marketplace-cover.tsx +5 -2
- package/src/features/apps/components/app-marketplace-detail.tsx +9 -6
- package/src/features/apps/components/app-marketplace-operation.tsx +8 -3
- package/src/features/apps/components/app-marketplace-panel.tsx +168 -0
- package/src/features/apps/components/app-package-card.tsx +224 -147
- package/src/features/apps/components/app-package-details-dialog.tsx +103 -0
- package/src/features/apps/components/app-packages-panel.tsx +159 -144
- package/src/features/apps/components/apps-panel.tsx +40 -11
- package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +1 -1
- package/src/features/chat/components/conversation/chat-conversation-header.tsx +1 -1
- package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +2 -2
- package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +9 -7
- package/src/features/chat/features/conversation/components/floating-session-conversation.tsx +2 -3
- package/src/features/chat/features/conversation/components/session-conversation-area.tsx +1 -0
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +33 -0
- package/src/features/chat/features/message/utils/chat-message-execution-summary.utils.ts +3 -0
- package/src/features/chat/features/message/utils/chat-message-texts.utils.ts +1 -0
- package/src/features/chat/features/message/utils/chat-message-trigger-details.utils.ts +3 -0
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +1 -1
- package/src/features/chat/features/session/components/session-header/chat-session-metadata-dialog.tsx +1 -1
- package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +2 -2
- package/src/features/chat/features/welcome/components/__tests__/chat-welcome.test.tsx +31 -6
- package/src/features/chat/features/welcome/components/chat-conversation-welcome.tsx +13 -1
- package/src/features/chat/features/welcome/components/chat-welcome-agent-picker.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +1 -1
- package/src/features/chat/features/welcome/components/chat-welcome-prompt-suggestions.tsx +56 -13
- package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +3 -3
- package/src/features/chat/features/welcome/components/chat-welcome.tsx +14 -4
- package/src/features/chat/features/welcome/utils/__tests__/chat-welcome-continuation.utils.test.ts +40 -0
- package/src/features/chat/features/welcome/utils/chat-welcome-continuation.utils.ts +21 -0
- package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +1 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +3 -7
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +5 -4
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +27 -27
- package/src/features/chat/features/workspace/components/overview/chat-session-continuous-attention.tsx +11 -11
- package/src/features/chat/features/workspace/components/overview/chat-session-token-usage.tsx +15 -15
- package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +2 -2
- package/src/features/chat/features/workspace/components/project-files/workspace-new-folder-tree-item.tsx +1 -1
- package/src/features/chat/features/workspace/components/project-files/workspace-project-files-toolbar.tsx +2 -2
- package/src/features/chat/features/workspace/components/session-cron-job-content.tsx +7 -4
- package/src/features/cron/components/cron-job-row.tsx +5 -4
- package/src/features/desktop-capabilities/components/desktop-authorization-dialog.tsx +5 -5
- package/src/features/inbox/components/inbox-reader-dialog.test.tsx +46 -6
- package/src/features/inbox/components/inbox-reader-dialog.tsx +38 -29
- package/src/features/inbox/managers/inbox.manager.test.ts +28 -0
- package/src/features/inbox/managers/inbox.manager.ts +18 -4
- package/src/features/inbox/pages/inbox-page.test.ts +4 -2
- package/src/features/inbox/pages/inbox-page.tsx +6 -5
- package/src/features/panel-apps/components/panel-app-list-item.tsx +4 -3
- package/src/features/panel-apps/components/panel-app-service-action-authorization-dialog.tsx +2 -2
- package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +5 -24
- package/src/features/projects/components/work/project-work-items.tsx +1 -1
- package/src/features/pwa/managers/__tests__/pwa-shell-theme.manager.test.ts +3 -3
- package/src/features/pwa/managers/pwa-shell-theme.manager.ts +8 -3
- package/src/features/right-panel-resources/components/__tests__/page-resource-icon.test.tsx +13 -2
- package/src/features/right-panel-resources/components/page-resource-icon.tsx +15 -7
- package/src/features/right-panel-resources/configs/right-panel-resource-routes.config.ts +1 -1
- package/src/features/right-panel-resources/index.ts +3 -0
- package/src/features/right-panel-resources/utils/__tests__/right-panel-resource-route-resolver.utils.test.ts +5 -0
- package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.ts +3 -2
- package/src/features/service-apps/components/service-action-row.tsx +4 -3
- package/src/features/service-apps/components/service-app-delete-dialog.tsx +2 -2
- package/src/features/service-apps/components/service-app-list-item.tsx +5 -4
- package/src/features/settings/components/config/provider-model-suggestions-panel.tsx +1 -1
- package/src/features/settings/pages/providers-config-page.tsx +3 -2
- package/src/index.css +42 -8
- package/src/shared/components/doc-browser/doc-browser-tab-strip.tsx +2 -2
- package/src/shared/components/path-picker/server-path-picker-dialog.tsx +5 -3
- package/src/shared/components/ui/__tests__/dialog.test.tsx +37 -1
- package/src/shared/components/ui/actions/action-feedback.ts +1 -8
- package/src/shared/components/ui/actions/icon-action-button.tsx +1 -1
- package/src/shared/components/ui/confirm-dialog.tsx +1 -2
- package/src/shared/components/ui/context-menu/context-menu-items.tsx +2 -2
- package/src/shared/components/ui/dialog.tsx +29 -7
- package/src/shared/components/ui/popover.tsx +14 -3
- package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +2 -2
- package/src/shared/components/ui/tooltip.tsx +2 -1
- package/src/shared/components/workbench/__tests__/workbench-surface.test.tsx +21 -0
- package/src/shared/components/workbench/workbench-surface-toolbar.tsx +4 -0
- package/src/shared/components/workbench/workbench-surface.tsx +4 -1
- package/src/shared/lib/i18n/locales/en-US/chat.json +13 -7
- package/src/shared/lib/i18n/locales/en-US/core.json +5 -1
- package/src/shared/lib/i18n/locales/en-US/doc-browser.json +10 -5
- package/src/shared/lib/i18n/locales/en-US/inbox.json +1 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +13 -7
- package/src/shared/lib/i18n/locales/zh-CN/core.json +5 -1
- package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +11 -6
- package/src/shared/lib/i18n/locales/zh-CN/inbox.json +1 -0
- package/src/shared/lib/theme/index.test.ts +28 -1
- package/src/shared/lib/theme/index.ts +14 -3
- package/dist/assets/account-panel-BAH7FW6z.js +0 -1
- package/dist/assets/api-DjiZvIa0.js +0 -20
- package/dist/assets/app-presenter-provider-CCRFsFYr.js +0 -232
- package/dist/assets/appearance-settings-page-CdP86QJ7.js +0 -1
- package/dist/assets/architecture-TIHT7OUA-CvnC-LeA.js +0 -1
- package/dist/assets/channel-CpMstUPF.js +0 -1
- package/dist/assets/channels-list-page-5qGagKuE.js +0 -8
- package/dist/assets/chunk-2Q5K7J3B-Djp3VF0s.js +0 -1
- package/dist/assets/chunk-VAUOI2AC-BrbiIC1Q.js +0 -1
- package/dist/assets/chunk-XXDRQBXY-Cx9N40wF.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-DFN1v3PQ.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-DRvglADa.js +0 -1
- package/dist/assets/config-split-page-CuEGQL8Z.js +0 -1
- package/dist/assets/confirm-dialog-CxfecBzO.js +0 -1
- package/dist/assets/context-menu-BsCj2fRs.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-DXUGnpJH.js +0 -1
- package/dist/assets/desktop-update-config-e-zhkJuS.js +0 -1
- package/dist/assets/dialog-QjQoKbIV.js +0 -5
- package/dist/assets/doc-browser-CLEdkH9z.js +0 -1
- package/dist/assets/es2015-Bp6cuSGh.js +0 -41
- package/dist/assets/eventmodeling-45OFAUF4-ZBfVS3ZC.js +0 -1
- package/dist/assets/extensions-CgShSIkd.js +0 -1
- package/dist/assets/eye-kisejBFH.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-CqdsKk6x.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-fHYFd9Es.js +0 -1
- package/dist/assets/info-DKCQHKI2-CSaOL_bb.js +0 -1
- package/dist/assets/katex-B4FQSo9k.js +0 -1
- package/dist/assets/loader-circle-Bd1fTm-x.js +0 -1
- package/dist/assets/login-page-D99JjH9F.js +0 -1
- package/dist/assets/main-Bt5r6b21.js +0 -2
- package/dist/assets/main-DXd_aKJV.css +0 -1
- package/dist/assets/main-i18n-catalog.config-D0Ll36J_.js +0 -1
- package/dist/assets/mcp-marketplace-page-DUoGfSmY.js +0 -1
- package/dist/assets/model-config-page-9NNf-mzK.js +0 -1
- package/dist/assets/packet-7NZHBO7P-D-YFTczs.js +0 -1
- package/dist/assets/panel-app-BYfQu_TS.js +0 -1
- package/dist/assets/panel-app-i18n-catalog.config-Ddf2Kv8A.js +0 -1
- package/dist/assets/panelStandalone-BRg7B1EI.css +0 -1
- package/dist/assets/panelStandalone-BaUzY8Wy.js +0 -2
- package/dist/assets/pie-RZYD4A2V-VEnYu9s5.js +0 -1
- package/dist/assets/privacy-settings-page-CVMBFuak.js +0 -1
- package/dist/assets/projects-BEsU3box.js +0 -1
- package/dist/assets/provider-models-Dm-pmWAA.js +0 -1
- package/dist/assets/provider-scoped-model-input-CzrXg4cX.js +0 -1
- package/dist/assets/providers-config-page-839uUADZ.js +0 -1
- package/dist/assets/puzzle-BGvD2DPZ.js +0 -1
- package/dist/assets/pwa-DNNK_8E9.js +0 -1
- package/dist/assets/radar-I7S5WNFK-BFNIekC1.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-lVqJ3Hak.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-DYaefdFC.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-CTAk6lVq.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6-Cob294tg.js +0 -1
- package/dist/assets/remote-B5qIuUbT.js +0 -1
- package/dist/assets/runtime-config-page-Bf-4JYxQ.js +0 -1
- package/dist/assets/search-config-page-C0qA3j-T.js +0 -1
- package/dist/assets/secrets-config-page-DxfZWpnk.js +0 -3
- package/dist/assets/security-config-CItfIQZ4.js +0 -1
- package/dist/assets/select-CWyjnar7.js +0 -1
- package/dist/assets/service-apps-panel-D3SOkRVv.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-BrNv-raG.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-ntcxaPXp.js +0 -8
- package/dist/assets/tag-chip-BIuavK2K.js +0 -1
- package/dist/assets/theme-provider-CWUz4yO9.js +0 -1
- package/dist/assets/trash-2-hAbJh9VZ.js +0 -1
- package/dist/assets/treeView-QDETBFTQ-DbFmr-gw.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-C8aY96pi.js +0 -1
- package/dist/assets/use-viewport-layout-D_9XWGDV.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-D8d6DbbJ.js +0 -1
- package/dist/assets/x-ChPbNv39.js +0 -1
- package/src/features/apps/components/app-marketplace-dialog.tsx +0 -168
- /package/dist/assets/{array-BV9OtnO8.js → array-DstOKG9P.js} +0 -0
- /package/dist/assets/{chunk-KEIR6QF5-Cx-8EJ4_.js → chunk-KEIR6QF5-0TA8nwgf.js} +0 -0
- /package/dist/assets/{chunk-Y2CYZVJY-Dy1ufvjf.js → chunk-Y2CYZVJY-rfGCG6pM.js} +0 -0
- /package/dist/assets/{config-hints-DbmiyTKg.js → config-hints-BfGoD7-o.js} +0 -0
- /package/dist/assets/{cytoscape.esm-CSCjuT4Z.js → cytoscape.esm-DdIcNEda.js} +0 -0
- /package/dist/assets/{defaultLocale-DWTiNsbT.js → defaultLocale-CzXix2iJ.js} +0 -0
- /package/dist/assets/{dist-BVCSkfWY.js → dist-D5dwMwKA.js} +0 -0
- /package/dist/assets/{graphlib-B1yb1Wl8.js → graphlib-BKOe0eFe.js} +0 -0
- /package/dist/assets/{host-capabilities-DuIFVsvM.js → host-capabilities-CnSVTaot.js} +0 -0
- /package/dist/assets/{init-BF6GH5oe.js → init-OCFb3zgY.js} +0 -0
- /package/dist/assets/{jszip.min-D12teKzP.js → jszip.min-B2uhSxvV.js} +0 -0
- /package/dist/assets/{katex-CsAM73R9.js → katex-dBrYsE7B.js} +0 -0
- /package/dist/assets/{middleware-B--6mAUM.js → middleware-CAXxl-af.js} +0 -0
- /package/dist/assets/{path-C56XkznJ.js → path-T5eoIRSJ.js} +0 -0
- /package/dist/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
- /package/dist/assets/{rough.esm-CGfeEbtE.js → rough.esm-DmGXmZEB.js} +0 -0
- /package/dist/assets/{xlsx-sds5nUpL.js → xlsx-CoYacou7.js} +0 -0
|
@@ -4,7 +4,8 @@ import { useRef, useState } from "react";
|
|
|
4
4
|
import { ChevronLeft, ChevronRight, Inbox } from "lucide-react";
|
|
5
5
|
import { useNavigate } from "react-router-dom";
|
|
6
6
|
import { useAppPresenter } from "@/app/components/app-presenter-provider";
|
|
7
|
-
import {
|
|
7
|
+
import { useViewportLayout } from "@/app/hooks/use-viewport-layout";
|
|
8
|
+
import { buildSessionPath, CHAT_DRAFT_SESSION_PATH } from "@/features/chat";
|
|
8
9
|
import { InboxDeliveryContent } from "@/features/inbox/components/inbox-delivery-content";
|
|
9
10
|
import { useInboxDeliveries } from "@/features/inbox/hooks/use-inbox-deliveries";
|
|
10
11
|
import { useInboxStore } from "@/features/inbox/stores/inbox.store";
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
Dialog,
|
|
14
15
|
DialogContent,
|
|
15
16
|
DialogDescription,
|
|
17
|
+
DialogHeader,
|
|
16
18
|
DialogTitle,
|
|
17
19
|
} from "@/shared/components/ui/dialog";
|
|
18
20
|
import { IconActionButton } from "@/shared/components/ui/actions/icon-action-button";
|
|
@@ -28,7 +30,8 @@ function formatPosition(current: number, total: number): string {
|
|
|
28
30
|
export function InboxReaderDialog() {
|
|
29
31
|
const titleRef = useRef<HTMLHeadingElement>(null);
|
|
30
32
|
const navigate = useNavigate();
|
|
31
|
-
const {
|
|
33
|
+
const { chatComposerIntentManager, docBrowserManager, inboxManager } = useAppPresenter();
|
|
34
|
+
const { isMobile } = useViewportLayout();
|
|
32
35
|
const { data } = useInboxDeliveries();
|
|
33
36
|
const { activeDeliveryId, readerOpen } = useInboxStore((state) => state.snapshot);
|
|
34
37
|
const [pendingAction, setPendingAction] = useState<string | null>(null);
|
|
@@ -77,9 +80,10 @@ export function InboxReaderDialog() {
|
|
|
77
80
|
return;
|
|
78
81
|
}
|
|
79
82
|
void runAction("continue", async () => {
|
|
80
|
-
const { reference } = await inboxManager.prepareChatReference(activeDelivery.id);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
const { reference, targetSessionKey } = await inboxManager.prepareChatReference(activeDelivery.id);
|
|
84
|
+
chatComposerIntentManager.requestSystemObjectReference({ targetSessionKey, reference });
|
|
85
|
+
if (isMobile) docBrowserManager.close();
|
|
86
|
+
navigate(targetSessionKey ? buildSessionPath(targetSessionKey) : CHAT_DRAFT_SESSION_PATH);
|
|
83
87
|
});
|
|
84
88
|
};
|
|
85
89
|
|
|
@@ -96,15 +100,18 @@ export function InboxReaderDialog() {
|
|
|
96
100
|
const positionControls = unreadDeliveries.length > 1 ? (
|
|
97
101
|
<div className="flex shrink-0 items-center gap-1 pr-1">
|
|
98
102
|
<span className="mr-1 text-[11px] tabular-nums text-muted-foreground">
|
|
99
|
-
{formatPosition(activeIndex + 1, unreadDeliveries.length)}
|
|
103
|
+
<span className="hidden md:inline">{formatPosition(activeIndex + 1, unreadDeliveries.length)}</span>
|
|
104
|
+
<span className="md:hidden" aria-label={formatPosition(activeIndex + 1, unreadDeliveries.length)}>{activeIndex + 1}/{unreadDeliveries.length}</span>
|
|
100
105
|
</span>
|
|
101
106
|
<IconActionButton
|
|
107
|
+
size="sm"
|
|
102
108
|
icon={<ChevronLeft className="h-4 w-4" />}
|
|
103
109
|
label={t("inboxPrevious")}
|
|
104
110
|
disabled={activeIndex <= 0 || pendingAction === "select"}
|
|
105
111
|
onClick={() => selectAt(activeIndex - 1)}
|
|
106
112
|
/>
|
|
107
113
|
<IconActionButton
|
|
114
|
+
size="sm"
|
|
108
115
|
icon={<ChevronRight className="h-4 w-4" />}
|
|
109
116
|
label={t("inboxNext")}
|
|
110
117
|
disabled={activeIndex >= unreadDeliveries.length - 1 || pendingAction === "select"}
|
|
@@ -123,7 +130,7 @@ export function InboxReaderDialog() {
|
|
|
123
130
|
}}
|
|
124
131
|
>
|
|
125
132
|
<DialogContent
|
|
126
|
-
className="flex h-[min(82vh,760px)] w-[calc(100vw-2rem)] max-w-[820px] flex-col gap-0 overflow-hidden rounded-[24px] border-border/70 bg-background p-0 shadow-[0_20px_55px_-22px_rgba(15,23,42,0.32)] max-
|
|
133
|
+
className="flex h-[min(82vh,760px)] w-[calc(100vw-2rem)] max-w-[820px] flex-col gap-0 overflow-hidden rounded-[24px] border-border/70 bg-background p-0 shadow-[0_20px_55px_-22px_rgba(15,23,42,0.32)] max-md:h-[100dvh] max-md:max-h-[100dvh] max-md:w-screen max-md:max-w-none max-md:rounded-none max-md:border-0 max-md:pt-[env(safe-area-inset-top,0px)] max-md:pb-[env(safe-area-inset-bottom,0px)]"
|
|
127
134
|
onOpenAutoFocus={(event) => {
|
|
128
135
|
event.preventDefault();
|
|
129
136
|
titleRef.current?.focus();
|
|
@@ -131,10 +138,15 @@ export function InboxReaderDialog() {
|
|
|
131
138
|
>
|
|
132
139
|
{activeDelivery ? (
|
|
133
140
|
<>
|
|
134
|
-
<
|
|
135
|
-
|
|
141
|
+
<DialogHeader
|
|
142
|
+
className="items-center gap-1 border-b border-border/50 px-3 py-2 md:gap-3 md:px-6 md:py-3"
|
|
143
|
+
actions={<>
|
|
144
|
+
{positionControls}
|
|
145
|
+
<PageResourceActionsMenu page={pageResourceFromSystemObject("inbox-delivery", activeDelivery.id, activeDelivery.title)} />
|
|
146
|
+
</>}
|
|
147
|
+
>
|
|
136
148
|
<div className="flex min-w-0 items-center gap-2">
|
|
137
|
-
<span className="
|
|
149
|
+
<span className="hidden h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-muted/70 text-muted-foreground md:flex">
|
|
138
150
|
<Inbox className="h-3.5 w-3.5" />
|
|
139
151
|
</span>
|
|
140
152
|
<DialogTitle
|
|
@@ -145,29 +157,24 @@ export function InboxReaderDialog() {
|
|
|
145
157
|
>
|
|
146
158
|
{activeDelivery.title}
|
|
147
159
|
</DialogTitle>
|
|
148
|
-
<span className="hidden shrink-0 text-muted-foreground
|
|
160
|
+
<span className="hidden shrink-0 text-muted-foreground md:inline" aria-hidden="true">·</span>
|
|
149
161
|
<time
|
|
150
|
-
className="hidden shrink-0 text-[11px] tabular-nums text-muted-foreground
|
|
162
|
+
className="hidden shrink-0 text-[11px] tabular-nums text-muted-foreground md:block"
|
|
151
163
|
dateTime={activeDelivery.createdAt}
|
|
152
164
|
>
|
|
153
165
|
{formatDateTime(activeDelivery.createdAt)}
|
|
154
166
|
</time>
|
|
155
167
|
</div>
|
|
156
|
-
<div className="flex shrink-0 items-center gap-1">
|
|
157
|
-
{positionControls}
|
|
158
|
-
<PageResourceActionsMenu page={pageResourceFromSystemObject("inbox-delivery", activeDelivery.id, activeDelivery.title)} />
|
|
159
|
-
</div>
|
|
160
|
-
</div>
|
|
161
168
|
<DialogDescription className="sr-only">
|
|
162
169
|
{activeDelivery.summary ?? t("inboxNoSummary")}
|
|
163
170
|
</DialogDescription>
|
|
164
|
-
</
|
|
171
|
+
</DialogHeader>
|
|
165
172
|
|
|
166
173
|
<div className={cn(
|
|
167
174
|
"min-h-0 flex-1",
|
|
168
175
|
isHtml
|
|
169
|
-
? "p-
|
|
170
|
-
: "custom-scrollbar overflow-y-auto px-
|
|
176
|
+
? "p-0 md:p-4"
|
|
177
|
+
: "custom-scrollbar overflow-y-auto overscroll-contain px-4 py-3 md:px-8 md:py-6",
|
|
171
178
|
)}>
|
|
172
179
|
<InboxDeliveryContent
|
|
173
180
|
className={isHtml ? "h-full" : undefined}
|
|
@@ -178,24 +185,26 @@ export function InboxReaderDialog() {
|
|
|
178
185
|
/>
|
|
179
186
|
</div>
|
|
180
187
|
|
|
181
|
-
<footer className="shrink-0 border-t border-border/50 bg-background px-
|
|
188
|
+
<footer className="shrink-0 border-t border-border/50 bg-background px-3 py-2 md:px-6 md:py-3">
|
|
182
189
|
{error ? (
|
|
183
190
|
<p role="alert" className="mb-3 text-sm text-destructive">{error}</p>
|
|
184
191
|
) : null}
|
|
185
|
-
<div className="flex
|
|
186
|
-
<div className="flex
|
|
187
|
-
<Button size="sm" variant="ghost" onClick={inboxManager.closeReader}>
|
|
192
|
+
<div className="flex items-center justify-between gap-2 [--control-touch-size:2rem]">
|
|
193
|
+
<div className="flex items-center gap-1">
|
|
194
|
+
<Button size="sm" className="px-2 md:px-3" variant="ghost" onClick={inboxManager.closeReader}>
|
|
188
195
|
{t("inboxReadLater")}
|
|
189
196
|
</Button>
|
|
190
|
-
<Button size="sm" variant="outline" disabled={pendingAction !== null} onClick={markRead}>
|
|
197
|
+
<Button size="sm" className="px-2 md:px-3" variant="outline" disabled={pendingAction !== null} onClick={markRead}>
|
|
191
198
|
{t("inboxMarkRead")}
|
|
192
199
|
</Button>
|
|
193
|
-
<Button size="sm" variant="ghost" disabled={pendingAction !== null} onClick={openInbox}>
|
|
194
|
-
{t("
|
|
200
|
+
<Button size="sm" className="px-2 md:px-3" variant="ghost" aria-label={t("inboxOpenInbox")} disabled={pendingAction !== null} onClick={openInbox}>
|
|
201
|
+
<span className="md:hidden">{t("inboxTitle")}</span>
|
|
202
|
+
<span className="hidden md:inline">{t("inboxOpenInbox")}</span>
|
|
195
203
|
</Button>
|
|
196
204
|
</div>
|
|
197
|
-
<Button size="sm" disabled={pendingAction !== null} onClick={continueInChat}>
|
|
198
|
-
{t("
|
|
205
|
+
<Button size="sm" className="px-2 md:px-3" aria-label={t("inboxContinueChat")} disabled={pendingAction !== null} onClick={continueInChat}>
|
|
206
|
+
<span className="md:hidden">{t("inboxContinueChatCompact")}</span>
|
|
207
|
+
<span className="hidden md:inline">{t("inboxContinueChat")}</span>
|
|
199
208
|
</Button>
|
|
200
209
|
</div>
|
|
201
210
|
</footer>
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { QueryClient } from "@tanstack/react-query";
|
|
2
2
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
import type { InboxDelivery } from "@nextclaw/shared";
|
|
4
|
+
import { NextClawClientError } from "@nextclaw/client-sdk";
|
|
4
5
|
import { InboxManager } from "@/features/inbox/managers/inbox.manager";
|
|
5
6
|
import { useInboxStore } from "@/features/inbox/stores/inbox.store";
|
|
6
7
|
|
|
7
8
|
const mocks = vi.hoisted(() => ({
|
|
9
|
+
getDelivery: vi.fn(),
|
|
10
|
+
getSession: vi.fn(),
|
|
8
11
|
delete: vi.fn(),
|
|
9
12
|
resolveReference: vi.fn(),
|
|
10
13
|
list: vi.fn(),
|
|
@@ -16,6 +19,7 @@ vi.mock("@/shared/lib/api", () => ({
|
|
|
16
19
|
nextclawClient: {
|
|
17
20
|
eventBus: { on: mocks.on },
|
|
18
21
|
inboxDeliveries: {
|
|
22
|
+
get: mocks.getDelivery,
|
|
19
23
|
delete: mocks.delete,
|
|
20
24
|
list: mocks.list,
|
|
21
25
|
updateState: mocks.updateState,
|
|
@@ -23,6 +27,7 @@ vi.mock("@/shared/lib/api", () => ({
|
|
|
23
27
|
systemObjectReferences: {
|
|
24
28
|
resolve: mocks.resolveReference,
|
|
25
29
|
},
|
|
30
|
+
sessions: { get: mocks.getSession },
|
|
26
31
|
},
|
|
27
32
|
}));
|
|
28
33
|
|
|
@@ -43,6 +48,8 @@ const delivery: InboxDelivery = {
|
|
|
43
48
|
describe("InboxManager", () => {
|
|
44
49
|
beforeEach(() => {
|
|
45
50
|
vi.clearAllMocks();
|
|
51
|
+
mocks.getDelivery.mockResolvedValue(delivery);
|
|
52
|
+
mocks.getSession.mockResolvedValue({ sessionId: "source-session" });
|
|
46
53
|
Object.defineProperty(document, "visibilityState", { configurable: true, value: "visible" });
|
|
47
54
|
useInboxStore.setState({
|
|
48
55
|
snapshot: { readerOpen: false, activeDeliveryId: null },
|
|
@@ -107,5 +114,26 @@ describe("InboxManager", () => {
|
|
|
107
114
|
);
|
|
108
115
|
expect(mocks.updateState).toHaveBeenCalledWith(delivery.id, "read");
|
|
109
116
|
expect(result.reference.assetUri).toBe("asset://store/report");
|
|
117
|
+
expect(result.targetSessionKey).toBeNull();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("targets the original report session", async () => {
|
|
121
|
+
mocks.getDelivery.mockResolvedValue({ ...delivery, source: { ...delivery.source, sessionId: "source-session" } });
|
|
122
|
+
const result = await new InboxManager(new QueryClient()).prepareChatReference(delivery.id);
|
|
123
|
+
expect(mocks.getSession).toHaveBeenCalledWith("source-session");
|
|
124
|
+
expect(result.targetSessionKey).toBe("source-session");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("falls back to a draft only when the source session was deleted", async () => {
|
|
128
|
+
mocks.getDelivery.mockResolvedValue({ ...delivery, source: { ...delivery.source, sessionId: "deleted" } });
|
|
129
|
+
mocks.getSession.mockRejectedValueOnce(new NextClawClientError({ message: "Missing", status: 404 }));
|
|
130
|
+
expect((await new InboxManager(new QueryClient()).prepareChatReference(delivery.id)).targetSessionKey).toBeNull();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("keeps the report unread when the source session lookup fails", async () => {
|
|
134
|
+
mocks.getDelivery.mockResolvedValue({ ...delivery, source: { ...delivery.source, sessionId: "source-session" } });
|
|
135
|
+
mocks.getSession.mockRejectedValueOnce(new NextClawClientError({ message: "Offline", status: 503 }));
|
|
136
|
+
await expect(new InboxManager(new QueryClient()).prepareChatReference(delivery.id)).rejects.toThrow("Offline");
|
|
137
|
+
expect(mocks.updateState).not.toHaveBeenCalled();
|
|
110
138
|
});
|
|
111
139
|
});
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import { appQueryClient } from "@/app-query-client";
|
|
14
14
|
import { useInboxStore } from "@/features/inbox/stores/inbox.store";
|
|
15
15
|
import { nextclawClient } from "@/shared/lib/api";
|
|
16
|
+
import { NextClawClientError } from "@nextclaw/client-sdk";
|
|
16
17
|
|
|
17
18
|
export const INBOX_DELIVERIES_QUERY_KEY = ["inbox-deliveries"] as const;
|
|
18
19
|
|
|
@@ -112,13 +113,26 @@ export class InboxManager {
|
|
|
112
113
|
prepareChatReference = async (deliveryId: string): Promise<{
|
|
113
114
|
delivery: InboxDelivery;
|
|
114
115
|
reference: SystemObjectResolvedReference;
|
|
116
|
+
targetSessionKey: string | null;
|
|
115
117
|
}> => {
|
|
116
|
-
const reference = await
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
const [reference, sourceDelivery] = await Promise.all([
|
|
119
|
+
nextclawClient.systemObjectReferences.resolve(
|
|
120
|
+
createSystemObjectReferenceUri(SYSTEM_OBJECT_TYPE_INBOX_DELIVERY, deliveryId),
|
|
121
|
+
),
|
|
122
|
+
nextclawClient.inboxDeliveries.get(deliveryId),
|
|
123
|
+
]);
|
|
124
|
+
let targetSessionKey = sourceDelivery.source.sessionId?.trim() || null;
|
|
125
|
+
if (targetSessionKey) {
|
|
126
|
+
try {
|
|
127
|
+
await nextclawClient.sessions.get(targetSessionKey);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
if (!(error instanceof NextClawClientError) || error.status !== 404) throw error;
|
|
130
|
+
targetSessionKey = null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
119
133
|
const delivery = await this.updateState(deliveryId, "read");
|
|
120
134
|
this.closeReader();
|
|
121
|
-
return { delivery, reference };
|
|
135
|
+
return { delivery, reference, targetSessionKey };
|
|
122
136
|
};
|
|
123
137
|
|
|
124
138
|
private updateState = async (
|
|
@@ -14,7 +14,8 @@ const mocks = vi.hoisted(() => ({
|
|
|
14
14
|
|
|
15
15
|
vi.mock("@/app/components/app-presenter-provider", () => ({
|
|
16
16
|
useAppPresenter: () => ({
|
|
17
|
-
|
|
17
|
+
docBrowserManager: { close: vi.fn() },
|
|
18
|
+
chatComposerIntentManager: {
|
|
18
19
|
requestSystemObjectReference: mocks.requestSystemObjectReference,
|
|
19
20
|
},
|
|
20
21
|
inboxManager: {
|
|
@@ -104,6 +105,7 @@ describe("InboxPage", () => {
|
|
|
104
105
|
vi.clearAllMocks();
|
|
105
106
|
mocks.isMobile = false;
|
|
106
107
|
mocks.prepareChatReference.mockResolvedValue({
|
|
108
|
+
targetSessionKey: null,
|
|
107
109
|
reference: {
|
|
108
110
|
uri: "nextclaw://objects/inbox-delivery/delivery-1",
|
|
109
111
|
label: "A considered report",
|
|
@@ -150,7 +152,7 @@ describe("InboxPage", () => {
|
|
|
150
152
|
});
|
|
151
153
|
expect(mocks.prepareChatReference).toHaveBeenCalledWith("delivery-1");
|
|
152
154
|
expect(mocks.requestSystemObjectReference).toHaveBeenCalledWith(
|
|
153
|
-
expect.objectContaining({ uri: "nextclaw://objects/inbox-delivery/delivery-1" }),
|
|
155
|
+
{ targetSessionKey: null, reference: expect.objectContaining({ uri: "nextclaw://objects/inbox-delivery/delivery-1" }) },
|
|
154
156
|
);
|
|
155
157
|
});
|
|
156
158
|
});
|
|
@@ -9,7 +9,7 @@ import { Link, useNavigate, useParams } from "react-router-dom";
|
|
|
9
9
|
import { useAppPresenter } from "@/app/components/app-presenter-provider";
|
|
10
10
|
import { PageHeader } from "@/app/components/layout/page-layout";
|
|
11
11
|
import { useViewportLayout } from "@/app/hooks/use-viewport-layout";
|
|
12
|
-
import { CHAT_DRAFT_SESSION_PATH } from "@/features/chat";
|
|
12
|
+
import { buildSessionPath, CHAT_DRAFT_SESSION_PATH } from "@/features/chat";
|
|
13
13
|
import { InboxDeliveryContent } from "@/features/inbox/components/inbox-delivery-content";
|
|
14
14
|
import { useInboxDeliveries } from "@/features/inbox/hooks/use-inbox-deliveries";
|
|
15
15
|
import { Button } from "@/shared/components/ui/button";
|
|
@@ -275,7 +275,7 @@ export function InboxPage() {
|
|
|
275
275
|
const navigate = useNavigate();
|
|
276
276
|
const { deliveryId } = useParams<{ deliveryId?: string }>();
|
|
277
277
|
const { isMobile } = useViewportLayout();
|
|
278
|
-
const {
|
|
278
|
+
const { chatComposerIntentManager, docBrowserManager, inboxManager } = useAppPresenter();
|
|
279
279
|
const deliveriesQuery = useInboxDeliveries();
|
|
280
280
|
const { confirm, ConfirmDialog } = useConfirmDialog();
|
|
281
281
|
const [selectedFilter, setSelectedFilter] = useState<InboxFilter | null>(null);
|
|
@@ -316,9 +316,10 @@ export function InboxPage() {
|
|
|
316
316
|
return;
|
|
317
317
|
}
|
|
318
318
|
void runAction("continue", async () => {
|
|
319
|
-
const { reference } = await inboxManager.prepareChatReference(activeDelivery.id);
|
|
320
|
-
|
|
321
|
-
|
|
319
|
+
const { reference, targetSessionKey } = await inboxManager.prepareChatReference(activeDelivery.id);
|
|
320
|
+
chatComposerIntentManager.requestSystemObjectReference({ targetSessionKey, reference });
|
|
321
|
+
if (isMobile) docBrowserManager.close();
|
|
322
|
+
navigate(targetSessionKey ? buildSessionPath(targetSessionKey) : CHAT_DRAFT_SESSION_PATH);
|
|
322
323
|
});
|
|
323
324
|
};
|
|
324
325
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ACTION_FEEDBACK, ACTION_MENU_ITEM_CLASS } from '@/shared/components/ui/actions/action-feedback';
|
|
1
2
|
import { useState, type MouseEvent } from 'react';
|
|
2
3
|
import { MoreVertical, Star, Trash2, type LucideIcon } from 'lucide-react';
|
|
3
4
|
import type { PanelAppEntryView } from '@/shared/lib/api';
|
|
@@ -127,13 +128,13 @@ function PanelAppMenuItem({
|
|
|
127
128
|
<button
|
|
128
129
|
type="button"
|
|
129
130
|
className={cn(
|
|
130
|
-
|
|
131
|
-
destructive ?
|
|
131
|
+
ACTION_MENU_ITEM_CLASS,
|
|
132
|
+
destructive ? ACTION_FEEDBACK.destructive : `text-foreground ${ACTION_FEEDBACK.item}`,
|
|
132
133
|
)}
|
|
133
134
|
disabled={disabled}
|
|
134
135
|
onClick={onClick}
|
|
135
136
|
>
|
|
136
|
-
<Icon className="h-4 w-4 shrink-0" />
|
|
137
|
+
<Icon className={cn("h-4 w-4 shrink-0", !destructive && "text-muted-foreground")} />
|
|
137
138
|
<span>{label}</span>
|
|
138
139
|
</button>
|
|
139
140
|
);
|
package/src/features/panel-apps/components/panel-app-service-action-authorization-dialog.tsx
CHANGED
|
@@ -26,8 +26,8 @@ export function PanelAppServiceActionAuthorizationDialog() {
|
|
|
26
26
|
}
|
|
27
27
|
}}
|
|
28
28
|
>
|
|
29
|
-
<DialogContent
|
|
30
|
-
<DialogHeader>
|
|
29
|
+
<DialogContent>
|
|
30
|
+
<DialogHeader showClose={false}>
|
|
31
31
|
<DialogTitle className="flex items-center gap-2">
|
|
32
32
|
<ShieldAlert className="h-4 w-4 text-amber-600" />
|
|
33
33
|
{t('serviceActionAuthorizationTitle')}
|
|
@@ -2,16 +2,15 @@ import { AppWindow, Boxes } from 'lucide-react';
|
|
|
2
2
|
import type { DocBrowserContextValue } from '@/shared/components/doc-browser/doc-browser-context';
|
|
3
3
|
import type { DocBrowserCustomTabRenderers } from '@/shared/components/doc-browser/doc-browser-renderer.types';
|
|
4
4
|
import { getPresenter } from '@/app/presenters/app.presenter';
|
|
5
|
-
import { AppsPanel
|
|
5
|
+
import { AppsPanel } from '@/features/apps';
|
|
6
6
|
import { PanelAppDocBrowserToolbar } from '@/features/panel-apps/components/panel-app-toolbar';
|
|
7
7
|
import {
|
|
8
8
|
createPanelAppRightPanelResourceTarget,
|
|
9
9
|
RIGHT_PANEL_APPS_TAB_KIND,
|
|
10
|
-
|
|
10
|
+
createRightPanelAppsUrl,
|
|
11
|
+
getRightPanelAppsTabFromUrl,
|
|
11
12
|
RIGHT_PANEL_HOME_TAB_KIND,
|
|
12
13
|
RIGHT_PANEL_PANEL_APP_TAB_KIND,
|
|
13
|
-
RIGHT_PANEL_PANEL_APPS_URL,
|
|
14
|
-
RIGHT_PANEL_SERVICE_APPS_URL,
|
|
15
14
|
RightPanelResourceHomePage,
|
|
16
15
|
} from '@/features/right-panel-resources';
|
|
17
16
|
import { t } from '@/shared/lib/i18n';
|
|
@@ -19,26 +18,8 @@ import { PANEL_APP_IFRAME_SANDBOX, focusPanelAppIframe } from './panel-app-ifram
|
|
|
19
18
|
|
|
20
19
|
export const APPS_TAB_KIND = RIGHT_PANEL_APPS_TAB_KIND;
|
|
21
20
|
export const PANEL_APP_TAB_KIND = RIGHT_PANEL_PANEL_APP_TAB_KIND;
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
function isAppsPanelTab(value: unknown): value is AppsPanelTab {
|
|
25
|
-
return value === 'apps' || value === 'panel-apps' || value === 'service-apps';
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function createAppsPanelUrl(tab: AppsPanelTab = DEFAULT_APPS_PANEL_TAB): string {
|
|
29
|
-
if (tab === 'panel-apps') return RIGHT_PANEL_PANEL_APPS_URL;
|
|
30
|
-
if (tab === 'service-apps') return RIGHT_PANEL_SERVICE_APPS_URL;
|
|
31
|
-
return RIGHT_PANEL_APPS_URL;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function getAppsPanelTabFromUrl(url: string): AppsPanelTab {
|
|
35
|
-
try {
|
|
36
|
-
const tab = new URL(url).searchParams.get('tab');
|
|
37
|
-
return isAppsPanelTab(tab) ? tab : DEFAULT_APPS_PANEL_TAB;
|
|
38
|
-
} catch {
|
|
39
|
-
return DEFAULT_APPS_PANEL_TAB;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
21
|
+
export const createAppsPanelUrl = createRightPanelAppsUrl;
|
|
22
|
+
export const getAppsPanelTabFromUrl = getRightPanelAppsTabFromUrl;
|
|
42
23
|
|
|
43
24
|
export function openApps(docBrowser: Pick<DocBrowserContextValue, 'open'>): void {
|
|
44
25
|
docBrowser.open(createAppsPanelUrl(), {
|
|
@@ -255,7 +255,7 @@ function ProjectWorkStateGroup({
|
|
|
255
255
|
<div
|
|
256
256
|
className={
|
|
257
257
|
view === "board"
|
|
258
|
-
? "min-h-0 flex-1 space-y-2 overflow-y-auto
|
|
258
|
+
? "min-h-0 flex-1 space-y-2 overflow-y-auto px-1 pb-3"
|
|
259
259
|
: "space-y-2 px-1 pb-3"
|
|
260
260
|
}
|
|
261
261
|
>
|
|
@@ -12,12 +12,12 @@ describe('PwaShellThemeManager', () => {
|
|
|
12
12
|
document.body.style.backgroundColor = '';
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
it('applies
|
|
15
|
+
it('applies plain paper shell colors when no theme is selected', () => {
|
|
16
16
|
pwaShellThemeManager.syncCurrentTheme();
|
|
17
17
|
|
|
18
18
|
const meta = document.querySelector('meta[name="theme-color"]');
|
|
19
|
-
expect(meta?.getAttribute('content')).toBe('#
|
|
20
|
-
expect(document.body.style.backgroundColor).toBe('rgb(
|
|
19
|
+
expect(meta?.getAttribute('content')).toBe('#FAF8F4');
|
|
20
|
+
expect(document.body.style.backgroundColor).toBe('rgb(250, 248, 244)');
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
it('applies natural shell colors explicitly', () => {
|
|
@@ -2,10 +2,13 @@ import {
|
|
|
2
2
|
DEFAULT_UI_THEME,
|
|
3
3
|
getThemeAppearance,
|
|
4
4
|
normalizeTheme,
|
|
5
|
+
resolveTheme,
|
|
5
6
|
type UiTheme,
|
|
6
7
|
} from '@/shared/lib/theme';
|
|
7
8
|
|
|
8
|
-
const PWA_SHELL_THEME_COLORS: Record<UiTheme, string> = {
|
|
9
|
+
const PWA_SHELL_THEME_COLORS: Record<Exclude<UiTheme, 'default'>, string> = {
|
|
10
|
+
'paper-ink': '#FAF8F4',
|
|
11
|
+
'plain-paper': '#FAF8F4',
|
|
9
12
|
natural: '#FAF9F7',
|
|
10
13
|
work: '#FFFFFF',
|
|
11
14
|
minimal: '#FFFFFF',
|
|
@@ -25,10 +28,12 @@ export class PwaShellThemeManager {
|
|
|
25
28
|
return;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
const themeColor = PWA_SHELL_THEME_COLORS[theme];
|
|
31
|
+
const themeColor = PWA_SHELL_THEME_COLORS[resolveTheme(theme)];
|
|
29
32
|
this.updateThemeMeta(themeColor);
|
|
30
33
|
this.updateSurfaceBackgrounds(themeColor);
|
|
31
|
-
|
|
34
|
+
const appearance = getThemeAppearance(theme);
|
|
35
|
+
document.documentElement.style.colorScheme = appearance;
|
|
36
|
+
document.querySelector('meta[name="color-scheme"]')?.setAttribute('content', appearance);
|
|
32
37
|
};
|
|
33
38
|
|
|
34
39
|
syncCurrentTheme = () => {
|
|
@@ -44,9 +44,9 @@ describe("resource icon precedence", () => {
|
|
|
44
44
|
);
|
|
45
45
|
expect(view.container.textContent).toBe("✎");
|
|
46
46
|
view.rerender(<PageResourceIcon uri="https://example.com" />);
|
|
47
|
-
expect(view.container.
|
|
47
|
+
expect(view.container.childElementCount).toBe(0);
|
|
48
48
|
view.rerender(<PageResourceIcon uri="nextclaw://unknown/item" />);
|
|
49
|
-
expect(view.container.
|
|
49
|
+
expect(view.container.childElementCount).toBe(0);
|
|
50
50
|
});
|
|
51
51
|
it("uses Panel object identity for its installed icon and falls back to the application icon", () => {
|
|
52
52
|
const view = render(<PageResourceIcon uri="nextclaw://objects/panel-app/source%3Anotes" />);
|
|
@@ -64,4 +64,15 @@ describe("resource icon precedence", () => {
|
|
|
64
64
|
);
|
|
65
65
|
expect(view.container.querySelector(".lucide-github")).not.toBeNull();
|
|
66
66
|
});
|
|
67
|
+
it.each([
|
|
68
|
+
"/workspace/frontmatter-test.md",
|
|
69
|
+
"./frontmatter-test.md",
|
|
70
|
+
"frontmatter-test.md:12:3",
|
|
71
|
+
"file:///workspace/frontmatter-test.md#L12",
|
|
72
|
+
"nextclaw://workspace-file?path=%2Fworkspace%2Ffrontmatter-test.md",
|
|
73
|
+
])("shows Markdown identity for %s", (uri) => {
|
|
74
|
+
const view = render(<PageResourceIcon uri={uri} />);
|
|
75
|
+
expect(view.container.querySelector('[data-file-type-icon="markdown"]')).not.toBeNull();
|
|
76
|
+
expect(view.container.querySelector('.lucide-link2')).toBeNull();
|
|
77
|
+
});
|
|
67
78
|
});
|
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
Github,
|
|
23
23
|
Globe,
|
|
24
24
|
LayoutDashboard,
|
|
25
|
-
Link2,
|
|
26
25
|
MessageSquare,
|
|
27
26
|
PanelsTopLeft,
|
|
28
27
|
Plus,
|
|
@@ -44,7 +43,7 @@ const RESOURCE_ICONS = {
|
|
|
44
43
|
app: AppWindow,
|
|
45
44
|
docs: BookOpen,
|
|
46
45
|
website: Globe,
|
|
47
|
-
generic:
|
|
46
|
+
generic: null,
|
|
48
47
|
page: PanelsTopLeft,
|
|
49
48
|
overview: LayoutDashboard,
|
|
50
49
|
"child-sessions": GitBranch,
|
|
@@ -94,7 +93,8 @@ function resourceTypeIcon(
|
|
|
94
93
|
if (
|
|
95
94
|
uri.startsWith("nextclaw://workspace-file") ||
|
|
96
95
|
uri.startsWith("file:") ||
|
|
97
|
-
uri.startsWith("nextclaw://file/")
|
|
96
|
+
uri.startsWith("nextclaw://file/") ||
|
|
97
|
+
(!/^[a-z][a-z0-9+.-]*:/i.test(uri.replace(/:\d+(?::\d+)?$/, "")) && /\.[a-z0-9]{1,16}(?::\d+(?::\d+)?)?(?:[?#]|$)/i.test(uri))
|
|
98
98
|
)
|
|
99
99
|
return "file";
|
|
100
100
|
if (
|
|
@@ -104,7 +104,7 @@ function resourceTypeIcon(
|
|
|
104
104
|
)
|
|
105
105
|
return "app";
|
|
106
106
|
if (uri.startsWith("nextclaw://docs")) return "docs";
|
|
107
|
-
return
|
|
107
|
+
return "generic";
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
function appIcon(value?: string): DocBrowserDockIcon | undefined {
|
|
@@ -222,20 +222,28 @@ function ResourceIcon({
|
|
|
222
222
|
{specific.value}
|
|
223
223
|
</span>
|
|
224
224
|
);
|
|
225
|
-
let pathname = uri;
|
|
225
|
+
let pathname = uri.replace(/:\d+(?::\d+)?$/, "");
|
|
226
226
|
try {
|
|
227
|
-
|
|
227
|
+
const url = new URL(pathname);
|
|
228
|
+
pathname = url.searchParams.get("path") ?? url.pathname;
|
|
228
229
|
} catch {
|
|
229
230
|
/* Local file link. */
|
|
230
231
|
}
|
|
232
|
+
pathname = pathname.split(/[?#]/, 1)[0].replace(/:\d+(?::\d+)?$/, "");
|
|
233
|
+
try {
|
|
234
|
+
pathname = decodeURIComponent(pathname);
|
|
235
|
+
} catch {
|
|
236
|
+
/* Keep malformed percent escapes as literal file name characters. */
|
|
237
|
+
}
|
|
231
238
|
if (
|
|
232
239
|
resourceTypeIcon(uri, appId) === "file" &&
|
|
233
|
-
/\.[a-z0-9]{1,
|
|
240
|
+
/\.[a-z0-9]{1,16}$/i.test(pathname)
|
|
234
241
|
)
|
|
235
242
|
return <FileTypeIcon fileName={pathname} size="compact" />;
|
|
236
243
|
const Icon =
|
|
237
244
|
(specific?.type === "builtin" && BUILTIN_ICONS[specific.name]) ||
|
|
238
245
|
RESOURCE_ICONS[resourceTypeIcon(uri, appId)];
|
|
246
|
+
if (!Icon) return null;
|
|
239
247
|
return (
|
|
240
248
|
<Icon
|
|
241
249
|
aria-hidden="true"
|
|
@@ -198,7 +198,7 @@ export const RIGHT_PANEL_RESOURCE_ROUTE_DEFINITIONS: RightPanelResourceRouteDefi
|
|
|
198
198
|
historyPolicy: 'managed',
|
|
199
199
|
kind: RIGHT_PANEL_APPS_TAB_KIND,
|
|
200
200
|
resourceUri: url,
|
|
201
|
-
title:
|
|
201
|
+
title: t('appsTitle'),
|
|
202
202
|
url,
|
|
203
203
|
};
|
|
204
204
|
},
|
|
@@ -2,6 +2,11 @@ import { describe, expect, it } from 'vitest';
|
|
|
2
2
|
import { RightPanelResourceRouteResolver } from '@/features/right-panel-resources';
|
|
3
3
|
|
|
4
4
|
describe('RightPanelResourceRouteResolver', () => {
|
|
5
|
+
it('preserves the app marketplace through resource normalization', () => {
|
|
6
|
+
expect(new RightPanelResourceRouteResolver().resolve('nextclaw://apps?tab=marketplace')).toMatchObject({
|
|
7
|
+
kind: 'apps', dedupeKey: 'apps', url: 'nextclaw://apps?tab=marketplace', resourceUri: 'nextclaw://apps?tab=marketplace',
|
|
8
|
+
});
|
|
9
|
+
});
|
|
5
10
|
it.each(['cron-job', 'inbox-delivery', 'skill', 'agent', 'project'])('resolves %s as an object, not an unsupported website', (type) => {
|
|
6
11
|
const uri = 'nextclaw://objects/' + type + '/' + encodeURIComponent('workspace:项目/对象');
|
|
7
12
|
expect(new RightPanelResourceRouteResolver().resolve(uri)).toMatchObject({ kind: 'system-object', url: uri, resourceUri: uri });
|
|
@@ -42,15 +42,16 @@ export function createChatUiResourceReferenceFromTab(
|
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
export type RightPanelAppsTab = 'apps' | 'panel-apps' | 'service-apps';
|
|
45
|
+
export type RightPanelAppsTab = 'apps' | 'panel-apps' | 'service-apps' | 'marketplace';
|
|
46
46
|
|
|
47
47
|
const DEFAULT_RIGHT_PANEL_APPS_TAB: RightPanelAppsTab = 'apps';
|
|
48
48
|
|
|
49
49
|
function isRightPanelAppsTab(value: unknown): value is RightPanelAppsTab {
|
|
50
|
-
return value === 'apps' || value === 'panel-apps' || value === 'service-apps';
|
|
50
|
+
return value === 'apps' || value === 'panel-apps' || value === 'service-apps' || value === 'marketplace';
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export function createRightPanelAppsUrl(tab: RightPanelAppsTab = DEFAULT_RIGHT_PANEL_APPS_TAB): string {
|
|
54
|
+
if (tab === 'marketplace') return `${RIGHT_PANEL_APPS_URL}?tab=marketplace`;
|
|
54
55
|
if (tab === 'panel-apps') return RIGHT_PANEL_PANEL_APPS_URL;
|
|
55
56
|
if (tab === 'service-apps') return RIGHT_PANEL_SERVICE_APPS_URL;
|
|
56
57
|
return RIGHT_PANEL_APPS_URL;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ACTION_FEEDBACK, ACTION_MENU_ITEM_CLASS } from '@/shared/components/ui/actions/action-feedback';
|
|
1
2
|
import { useState } from "react";
|
|
2
3
|
import type {
|
|
3
4
|
AgentProfileView,
|
|
@@ -73,7 +74,7 @@ export function ServiceActionRow({
|
|
|
73
74
|
<ShieldPlus className="h-3.5 w-3.5" />
|
|
74
75
|
</button>
|
|
75
76
|
</PopoverTrigger>
|
|
76
|
-
<PopoverContent align="end"
|
|
77
|
+
<PopoverContent align="end" variant="menu">
|
|
77
78
|
<div className="px-2 py-1.5 text-[11px] font-medium text-muted-foreground">
|
|
78
79
|
{t("serviceAppsGrantToAgent")}
|
|
79
80
|
</div>
|
|
@@ -85,9 +86,9 @@ export function ServiceActionRow({
|
|
|
85
86
|
onGrantAgent(action.id, agent.id);
|
|
86
87
|
setAgentMenuOpen(false);
|
|
87
88
|
}}
|
|
88
|
-
className=
|
|
89
|
+
className={`${ACTION_MENU_ITEM_CLASS} text-foreground ${ACTION_FEEDBACK.item}`}
|
|
89
90
|
>
|
|
90
|
-
<Bot className="h-
|
|
91
|
+
<Bot className="h-4 w-4 shrink-0 text-muted-foreground" />
|
|
91
92
|
<span className="min-w-0 truncate">
|
|
92
93
|
{agent.displayName?.trim() || agent.id}
|
|
93
94
|
</span>
|