@nextclaw/ui 0.15.25 → 0.15.26
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/assets/{abnfDiagram-VRR7QNED-DvTjgVMf.js → abnfDiagram-VRR7QNED-BcFJp_1X.js} +1 -1
- package/dist/assets/{aiden0z-pptx-renderer.es-C1nfBAXR.js → aiden0z-pptx-renderer.es-Dp2ezlQn.js} +1 -1
- package/dist/assets/{api-FK7tikI1.js → api-CK3Fro7z.js} +6 -6
- package/dist/assets/appearance-settings-page-zqwWO8Dy.js +1 -0
- package/dist/assets/{arc-BvhODBXv.js → arc-CkgyPMyW.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-DO2x53FK.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-BKO9RgNS.js → architectureDiagram-ZJ3FMSHR-CMd4cIjI.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-DHpDXy7D.js → blockDiagram-677ZJIJ3-Bz3tbhet.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-BG_iQnDr.js → c4Diagram-LMCZKHZV-D9hFNAGv.js} +1 -1
- package/dist/assets/channel-nBvMaVyP.js +1 -0
- package/dist/assets/{channels-list-page-CocdcIko.js → channels-list-page-CVCZBlCL.js} +2 -2
- package/dist/assets/chat-page-D4wehRTz.js +1 -0
- package/dist/assets/chunk-2Q5K7J3B-CJgqFDS4.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-DR9M0LLx.js → chunk-32BRIVSS-7NrjEITq.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-698iC3BB.js → chunk-52WLFC77-viIcqj9q.js} +1 -1
- package/dist/assets/{chunk-5FCAYU7R-DikTj9Ey.js → chunk-5FCAYU7R-Vsu4J-VM.js} +1 -1
- package/dist/assets/{chunk-5HE753X5-ko0o7_q0.js → chunk-5HE753X5-C-w6CQZK.js} +1 -1
- package/dist/assets/{chunk-5JV3BV7I-CEHufhgo.js → chunk-5JV3BV7I-CuKgJQ4W.js} +1 -1
- package/dist/assets/{chunk-5TONJI2A-CGgno1cu.js → chunk-5TONJI2A-CYeiWZKb.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DkiB4cUQ.js → chunk-5VM5RSS4-DRCbfwIn.js} +1 -1
- package/dist/assets/{chunk-7BUUIJ7U-DzptcytQ.js → chunk-7BUUIJ7U-BvydOcm3.js} +1 -1
- package/dist/assets/{chunk-BIQX33UG-DMRSQJvT.js → chunk-BIQX33UG-RlppOXKo.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-Bw1BwwuY.js → chunk-C7G6YPKG-DAizzYwr.js} +1 -1
- package/dist/assets/{chunk-CQNSW5MT-C0z6eHBk.js → chunk-CQNSW5MT-5eChJHca.js} +1 -1
- package/dist/assets/{chunk-CYSBUYHQ-ByPyAouO.js → chunk-CYSBUYHQ-YHPr53fv.js} +1 -1
- package/dist/assets/{chunk-EMLP6XTP-CJlAXWZg.js → chunk-EMLP6XTP-CK4D7Hz5.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-Dqq4zKJu.js → chunk-EX3LRPZG-BmlDFIRW.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-B0SNoCmi.js → chunk-FWX5IMBZ-D0ksHZZ9.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-DG_GJih_.js → chunk-HOUHSVGY-DPkq8FCm.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-Drxk_6bE.js → chunk-ICXQ74PX-FAatv5fC.js} +1 -1
- package/dist/assets/{chunk-JG7HCLWE-DdLFPpnd.js → chunk-JG7HCLWE-DLkIi4F7.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-B8M4G76F.js → chunk-JWPE2WC7-DawOjNE3.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-XP6FJHY_.js → chunk-MOJQB5TN-Di52TorW.js} +1 -1
- package/dist/assets/{chunk-MOZMSUNE-C_6x18Qw.js → chunk-MOZMSUNE-PfyK9w1-.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-N25BzCmG.js → chunk-OGEWGWER-C3jdH3Ty.js} +1 -1
- package/dist/assets/{chunk-OSBZ3O6U-ASDEm7y0.js → chunk-OSBZ3O6U-CecHo-f0.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-CTlvAcn7.js → chunk-PUDLZKDR-f3IJh3sN.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-Da9BWfB6.js → chunk-Q4XR5HBZ-DQFeUPxZ.js} +1 -1
- package/dist/assets/{chunk-QBLGF6JB-Bi6RpTJO.js → chunk-QBLGF6JB-BhUeG0y2.js} +1 -1
- package/dist/assets/{chunk-R7FJI6CG-DkMsSPvK.js → chunk-R7FJI6CG-C3XpZ-2u.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-DZp0eU-j.js → chunk-RYQCIY6F-CAqa5klQ.js} +1 -1
- package/dist/assets/{chunk-U6XO7XAA-vfinDSrj.js → chunk-U6XO7XAA-D_WXezeD.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-C9Nksccs.js → chunk-V7JOEXUC-CZ70oOtp.js} +1 -1
- package/dist/assets/chunk-VAUOI2AC-BGvh3yIx.js +1 -0
- package/dist/assets/{chunk-VR4S4FIN-Xv6zfwXs.js → chunk-VR4S4FIN-B7AHEYYk.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-mOJNzbWl.js → chunk-WYO6CB5R-Dn9To_OI.js} +2 -2
- package/dist/assets/chunk-XXDRQBXY-DaBxG5gs.js +1 -0
- package/dist/assets/{chunk-YOTPTUD7-1-aKSu4o.js → chunk-YOTPTUD7-BYEgRBk3.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-OJ8veMpK.js → chunk-ZGVPDNZ5-C6YtZDU0.js} +1 -1
- package/dist/assets/{chunk-ZIRB5QZD-SR_Nq_PP.js → chunk-ZIRB5QZD-DMuYtnHF.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-P6N03G2R.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-B1_uLvMv.js +1 -0
- package/dist/assets/config-split-page-CceNFvlY.js +1 -0
- package/dist/assets/confirm-dialog-CWeNYWZY.js +5 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-NjVgz2Bw.js → cose-bilkent-JH36ORCC-Bc2Ex5Y3.js} +1 -1
- package/dist/assets/cynefin-VYW2F7L2-B-H8Qp-n.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-B_17LDqD.js → cynefinDiagram-TSTJHNR4-DVysQoGz.js} +1 -1
- package/dist/assets/{dagre-CMe101gk.js → dagre-CMhQ1cAG.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB-qo8nLb3B.js → dagre-VKFMJZFB-RYyWpPJZ.js} +1 -1
- package/dist/assets/desktop-update-config-Dirc3bpt.js +1 -0
- package/dist/assets/{diagram-FQU43EPY-Ba3XIklC.js → diagram-FQU43EPY-BD6KONdF.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-CG45TcUx.js → diagram-G47NLZAW-CGB2ptRR.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-2F2HrwV-.js → diagram-NH7WQ7WH-DnkOI6cU.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-CXfWH9NZ.js → diagram-OA4YK3LP-DF82RZ7P.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-CH_4yepc.js → diagram-WEI45ONY-Be2v7Ck9.js} +1 -1
- package/dist/assets/{dist-BH7W5yCi.js → dist-AYxkFx2B.js} +1 -1
- package/dist/assets/{dist-CaYdVVeO.js → dist-D9xtGgdL.js} +1 -1
- package/dist/assets/doc-browser-4Sud6dWw.js +1 -0
- package/dist/assets/doc-browser-D4x_yH5F.js +1 -0
- package/dist/assets/doc-browser-context-Cb7Z0j90.js +1 -0
- package/dist/assets/{docx-preview-CoM4JK7_.js → docx-preview-BqwAjrj3.js} +1 -1
- package/dist/assets/{ebnfDiagram-CCIWWBDH-BwiG4Ea1.js → ebnfDiagram-CCIWWBDH-CP98OYk8.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-BML3hpnQ.js → erDiagram-Q63AITRT-ZLlx8xfs.js} +1 -1
- package/dist/assets/eventmodeling-45OFAUF4-YVtShyFA.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-BeKXabVO.js +1 -0
- package/dist/assets/form-actions-B2q4jgjE.js +1 -0
- package/dist/assets/{ganttDiagram-NO4QXBWP-80enfWbD.js → ganttDiagram-NO4QXBWP-DXCDjHR2.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-jTSiBj-p.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-CVLqXr-b.js → gitGraphDiagram-IHSO6WYX-l2HWrTJp.js} +1 -1
- package/dist/assets/index-CdyTsSBu.css +1 -0
- package/dist/assets/index-Das_bw2h.js +107 -0
- package/dist/assets/info-DKCQHKI2-BIporNWb.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-Dyvs2t0i.js → infoDiagram-FWYZ7A6U-D-DjX-bn.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-sSnxDKfh.js → ishikawaDiagram-FXEZZL3T-y_Xy128F.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-D22V71Mf.js → journeyDiagram-5HDEW3XC-DJn5xYcQ.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-D3ds0p-g.js → kanban-definition-HUTT4EX6-DJVIOR21.js} +1 -1
- package/dist/assets/{line-CbyFs065.js → line-Cos7PIOj.js} +1 -1
- package/dist/assets/{linear-4DKtnZBS.js → linear-BtDLqtzF.js} +1 -1
- package/dist/assets/loader-circle-CpmBdaon.js +1 -0
- package/dist/assets/{map-CcZzEoz6.js → map-BKnQyvd0.js} +1 -1
- package/dist/assets/mcp-marketplace-page-CdOY3Sop.js +1 -0
- package/dist/assets/mcp-marketplace-page-DvjrfqEt.js +9 -0
- package/dist/assets/{mermaid-parser.core-DPmMOjXD.js → mermaid-parser.core-XUNZhr2W.js} +2 -2
- package/dist/assets/{mermaid.core-BSf-ddRa.js → mermaid.core-ySrvolIe.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-BUTwWPyx.js → mindmap-definition-LN4V7U3C-BypL9tei.js} +1 -1
- package/dist/assets/model-config-page-DfOLyQqR.js +1 -0
- package/dist/assets/{navigation-link-CVy0_kVl.js → navigation-link-MiiyoIjH.js} +2 -2
- package/dist/assets/{ordinal-BgLYtOZE.js → ordinal-CxxVWxYU.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-CuFMADV0.js +1 -0
- package/dist/assets/{pegDiagram-2B236MQR-BEu_ZBjc.js → pegDiagram-2B236MQR-D-U2KBGv.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-XUeIXhM9.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-CAwAwuBd.js → pieDiagram-ENE6RG2P-CBi3GusJ.js} +1 -1
- package/dist/assets/plus-C8FkjpSZ.js +1 -0
- package/dist/assets/provider-scoped-model-input-DXzjr5l0.js +1 -0
- package/dist/assets/providers-config-page-CaO8WfZH.js +1 -0
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-CwE6F-_2.js → quadrantDiagram-ABIIQ3AL-H0ZuvnZL.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-D-NNGh1k.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-C67_uDaM.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-BZ8Yflnd.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-B7zO7RoK.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6-R63PTgLz.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6-xgLekU3B.js → railroadDiagram-RFXS5EU6-D7Y2EqSd.js} +1 -1
- package/dist/assets/react-C8XFFvuz.js +8 -0
- package/dist/assets/{refresh-cw-j2bl79Ea.js → refresh-cw-a2VVeeAF.js} +1 -1
- package/dist/assets/remote-BJHXa4mB.js +1 -0
- package/dist/assets/{requirementDiagram-TGXJPOKE-CyVUzEX5.js → requirementDiagram-TGXJPOKE-BiXNX1NN.js} +1 -1
- package/dist/assets/rotate-cw-DJ7UF3F2.js +1 -0
- package/dist/assets/runtime-config-page-BuA4A02z.js +1 -0
- package/dist/assets/{sankeyDiagram-HTMAVEWB-JK6bFmYB.js → sankeyDiagram-HTMAVEWB-qzDeLztW.js} +1 -1
- package/dist/assets/{save-BKNrtK81.js → save-CGm23Yww.js} +1 -1
- package/dist/assets/{search-CkOm65W_.js → search-CH2t--sH.js} +1 -1
- package/dist/assets/search-config-page-BAmYqoAz.js +1 -0
- package/dist/assets/{secrets-config-page-CJjtdFAl.js → secrets-config-page-BlPOuql_.js} +2 -2
- package/dist/assets/security-config-CbDiY2xr.js +1 -0
- package/dist/assets/{select-Ea7ffKCE.js → select-DnxxDpcV.js} +2 -2
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-BR5IokXV.js → sequenceDiagram-DBY2YBRQ-BtRbPQtL.js} +1 -1
- package/dist/assets/{settings-2-CtyN3m_V.js → settings-2-agnMYc8a.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-SxG_YnMA.js → sizeCapture-X5ZJPWSS-CMYvM3SL.js} +1 -1
- package/dist/assets/skeleton-XpqeWL62.js +1 -0
- package/dist/assets/{src-vgz8E_-O.js → src-Bw-mzbQb.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-DD4OoYhn.js → stateDiagram-2N3HPSRC-BJ-mFeOz.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-BE-HqxOK.js +1 -0
- package/dist/assets/{swimlanes-5IMT3BWC-BWkFeyCT.js → swimlanes-5IMT3BWC-BsucVOO2.js} +2 -2
- package/dist/assets/swimlanesDiagram-G3AALYLV-Dr1H9LJH.js +8 -0
- package/dist/assets/{tag-chip-C9l4xsKp.js → tag-chip-CPOc8b2N.js} +1 -1
- package/dist/assets/{timeline-definition-FHXFAJF6-VTRPy6KA.js → timeline-definition-FHXFAJF6-Bicewlzo.js} +1 -1
- package/dist/assets/treeView-QDETBFTQ-npJ5dbqS.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-pYrBx6oa.js +1 -0
- package/dist/assets/{vennDiagram-L72KCM5P-Bvk42Pek.js → vennDiagram-L72KCM5P-BxOOnO9x.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-CmSRKLR8.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-DOFjx2s3.js → wardleyDiagram-EHGQE667-Cl7NltMv.js} +1 -1
- package/dist/assets/x-odTHAtLZ.js +1 -0
- package/dist/assets/{xychartDiagram-FW5EYKEG-DY5yRTUc.js → xychartDiagram-FW5EYKEG-DiMIxQ7N.js} +1 -1
- package/dist/index.html +21 -22
- package/package.json +6 -6
- package/src/features/apps/components/__tests__/app-packages-panel.test.tsx +234 -0
- package/src/features/apps/components/app-marketplace-dialog.tsx +262 -0
- package/src/features/apps/components/app-package-card.tsx +268 -0
- package/src/features/apps/components/app-packages-panel.tsx +301 -0
- package/src/features/apps/components/apps-panel.tsx +11 -4
- package/src/features/apps/hooks/use-app-marketplace.ts +95 -0
- package/src/features/apps/hooks/use-app-packages.ts +59 -0
- package/src/features/chat/components/chat-sidebar-list-mode-switch.tsx +27 -4
- package/src/features/chat/components/layout/__tests__/chat-sidebar-session-area.test.tsx +36 -5
- package/src/features/chat/components/layout/chat-sidebar-desktop-layout.tsx +12 -13
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +49 -1
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +4 -4
- package/src/features/chat/features/conversation/components/session-conversation-area.tsx +25 -4
- package/src/features/chat/features/conversation/components/session-conversation-input.tsx +3 -0
- package/src/features/chat/features/conversation/hooks/use-system-object-reference-select.ts +27 -0
- package/src/features/chat/features/conversation/utils/session-message-composer.utils.ts +5 -0
- package/src/features/chat/features/input/hooks/__tests__/use-chat-input-surface-state.test.tsx +102 -0
- package/src/features/chat/features/input/hooks/use-chat-input-surface-state.ts +71 -120
- package/src/features/chat/features/input/input-surface-plugins/__tests__/context-reference-plugin.test.ts +265 -18
- package/src/features/chat/features/input/input-surface-plugins/chat-input-product-plugin-adapters.types.ts +7 -2
- package/src/features/chat/features/input/input-surface-plugins/chat-input-product-plugin-adapters.utils.ts +124 -0
- package/src/features/chat/features/input/input-surface-plugins/context-reference-items.utils.ts +99 -15
- package/src/features/chat/features/input/input-surface-plugins/context-reference-plugin.utils.ts +143 -139
- package/src/features/chat/features/input/input-surface-plugins/panel-app-input-surface-items.utils.ts +116 -0
- package/src/features/chat/features/input/input-surface-plugins/slash-command-plugin.utils.ts +1 -1
- package/src/features/chat/features/input/utils/__tests__/chat-inline-token.utils.test.ts +53 -1
- package/src/features/chat/features/input/utils/chat-composer-token-protocol.utils.ts +5 -0
- package/src/features/chat/features/input/utils/chat-inline-token-composer.utils.ts +134 -0
- package/src/features/chat/features/input/utils/chat-inline-token.utils.ts +30 -101
- package/src/features/chat/features/input/utils/chat-system-object-reference.utils.test.ts +44 -0
- package/src/features/chat/features/input/utils/chat-system-object-reference.utils.ts +46 -0
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +82 -2
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-text-selection.test.tsx +12 -8
- package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +24 -12
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +9 -2
- package/src/features/chat/features/workspace/components/project-files/workspace-directory-tree.tsx +52 -4
- package/src/features/chat/features/workspace/hooks/use-workspace-explorer-layout.ts +8 -11
- package/src/features/chat/features/workspace/hooks/use-workspace-file-actions.ts +68 -46
- package/src/features/chat/index.ts +1 -1
- package/src/features/chat/managers/chat-draft-intent.manager.ts +18 -2
- package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +6 -0
- package/src/features/chat/stores/chat-thread.store.ts +6 -0
- package/src/features/inbox/components/inbox-reader-dialog.test.tsx +38 -5
- package/src/features/inbox/components/inbox-reader-dialog.tsx +5 -3
- package/src/features/inbox/managers/inbox.manager.test.ts +28 -3
- package/src/features/inbox/managers/inbox.manager.ts +14 -4
- package/src/features/inbox/pages/inbox-page.test.ts +121 -2
- package/src/features/inbox/pages/inbox-page.tsx +5 -3
- package/src/features/marketplace/components/__tests__/marketplace-page.test.tsx +85 -1
- package/src/features/marketplace/hooks/__tests__/use-marketplace.test.tsx +44 -1
- package/src/features/marketplace/hooks/use-marketplace-item-actions.ts +23 -2
- package/src/features/marketplace/hooks/use-marketplace.ts +10 -0
- package/src/features/marketplace/index.ts +4 -0
- package/src/features/panel-apps/index.ts +5 -1
- package/src/features/panel-apps/utils/__tests__/panel-app-doc-browser.utils.test.ts +13 -6
- package/src/features/panel-apps/utils/panel-app-doc-browser.utils.tsx +6 -3
- package/src/features/right-panel-resources/index.ts +1 -0
- package/src/features/right-panel-resources/utils/right-panel-resource-uri.utils.ts +7 -4
- package/src/features/system-status/components/__tests__/desktop-update-config.test.tsx +20 -1
- package/src/features/system-status/components/desktop-update-config.tsx +14 -13
- package/src/features/system-status/managers/__tests__/runtime-update.manager.test.ts +99 -0
- package/src/features/system-status/managers/runtime-update.manager.ts +22 -0
- package/src/features/system-status/stores/runtime-update.store.ts +1 -0
- package/src/shared/components/ui/actions/__tests__/icon-action-button.test.tsx +15 -0
- package/src/shared/components/ui/actions/icon-action-button.tsx +4 -2
- package/src/shared/hooks/use-system-object-references.ts +22 -0
- package/src/shared/lib/api/types.ts +10 -0
- package/src/shared/lib/i18n/locales/en-US/chat.json +16 -9
- package/src/shared/lib/i18n/locales/en-US/desktop-update.json +7 -4
- package/src/shared/lib/i18n/locales/en-US/doc-browser.json +40 -0
- package/src/shared/lib/i18n/locales/en-US/marketplace.json +3 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +18 -11
- package/src/shared/lib/i18n/locales/zh-CN/desktop-update.json +7 -4
- package/src/shared/lib/i18n/locales/zh-CN/doc-browser.json +40 -0
- package/src/shared/lib/i18n/locales/zh-CN/marketplace.json +3 -0
- package/dist/assets/appearance-settings-page-BYbvl2wj.js +0 -1
- package/dist/assets/architecture-TIHT7OUA-Bjp9jf0h.js +0 -1
- package/dist/assets/channel-5T3pdR-s.js +0 -1
- package/dist/assets/chat-page-C5E-LLVd.js +0 -1
- package/dist/assets/chunk-2Q5K7J3B-DTZ3tGfE.js +0 -1
- package/dist/assets/chunk-VAUOI2AC-HLGIHQ6k.js +0 -1
- package/dist/assets/chunk-XXDRQBXY-Dl0m6Ni-.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-DcDnzGNX.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-BKXKMzKM.js +0 -1
- package/dist/assets/config-split-page-CA_a0AJ5.js +0 -1
- package/dist/assets/confirm-dialog-CxZfenjK.js +0 -5
- package/dist/assets/cynefin-VYW2F7L2-BWg7U2UD.js +0 -1
- package/dist/assets/desktop-update-config-BEKC8Ly9.js +0 -1
- package/dist/assets/doc-browser-Cl2ldE3f.js +0 -1
- package/dist/assets/doc-browser-DXCSd63E.js +0 -1
- package/dist/assets/doc-browser-context-FDPs3gJf.js +0 -1
- package/dist/assets/eventmodeling-45OFAUF4-SB-J4tpq.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-BQ_u-eLM.js +0 -1
- package/dist/assets/form-actions-0c0aw_bl.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-DPxNwsFd.js +0 -1
- package/dist/assets/i18n-provider-DkITJNz8.js +0 -1
- package/dist/assets/index-CQ2LcI2p.css +0 -1
- package/dist/assets/index-CrdfvBVg.js +0 -107
- package/dist/assets/info-DKCQHKI2-DNlNGH90.js +0 -1
- package/dist/assets/loader-circle-DHtUxCIA.js +0 -1
- package/dist/assets/mcp-marketplace-page-Bc_jI5iH.js +0 -9
- package/dist/assets/mcp-marketplace-page-CzCieD9r.js +0 -1
- package/dist/assets/model-config-page-C4jw-pcj.js +0 -1
- package/dist/assets/packet-7NZHBO7P-BpeiqkBZ.js +0 -1
- package/dist/assets/pie-RZYD4A2V-Cy1yxsPd.js +0 -1
- package/dist/assets/plus-CG1RwZQq.js +0 -1
- package/dist/assets/provider-scoped-model-input-CmH4BFvc.js +0 -1
- package/dist/assets/providers-config-page-CJQjwzaw.js +0 -1
- package/dist/assets/radar-I7S5WNFK-CEcPKCj8.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-CW38eNDs.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-ByrylcXf.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-CNB6GwP-.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6-x6hnqlBG.js +0 -1
- package/dist/assets/react-DjFBVA0n.js +0 -8
- package/dist/assets/remote-BIlpD3yL.js +0 -1
- package/dist/assets/rotate-cw-bKG8zH8M.js +0 -1
- package/dist/assets/runtime-config-page-B_x2Glz5.js +0 -1
- package/dist/assets/search-config-page-BaIijtmO.js +0 -1
- package/dist/assets/security-config-DB8apj09.js +0 -1
- package/dist/assets/skeleton-Bt6zxcAB.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-ZC6dFORv.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-CRkh51Im.js +0 -8
- package/dist/assets/treeView-QDETBFTQ-Bw0DSCH7.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-DFWBFcfh.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-CoWturk0.js +0 -1
- package/dist/assets/x-CowtCu9Z.js +0 -1
- /package/dist/assets/{array-NADKd9aU.js → array-BQVzeGRt.js} +0 -0
- /package/dist/assets/{chunk-KEIR6QF5-BuyuzJJL.js → chunk-KEIR6QF5-f9psyCXK.js} +0 -0
- /package/dist/assets/{chunk-Y2CYZVJY-D_B2ZRNt.js → chunk-Y2CYZVJY-D1mAU_Po.js} +0 -0
- /package/dist/assets/{config-hints-BcfVUMij.js → config-hints-nV5HPOvq.js} +0 -0
- /package/dist/assets/{cytoscape.esm-BANTlgza.js → cytoscape.esm-0uDtdD0l.js} +0 -0
- /package/dist/assets/{defaultLocale-C4_L0aEs.js → defaultLocale-DSWXGgt0.js} +0 -0
- /package/dist/assets/{dist-DAPEIJbz.js → dist--ta5rX12.js} +0 -0
- /package/dist/assets/{graphlib-ChqXg0dI.js → graphlib-CQ6QV4yP.js} +0 -0
- /package/dist/assets/{host-capabilities-D9C4CBK5.js → host-capabilities-Tk038i04.js} +0 -0
- /package/dist/assets/{init-D8wZg9xq.js → init-Y6h9jGtZ.js} +0 -0
- /package/dist/assets/{jszip.min-CkbBfwAQ.js → jszip.min-8hyJpgpx.js} +0 -0
- /package/dist/assets/{katex-TZJFa0J_.js → katex-ARhY9PS1.js} +0 -0
- /package/dist/assets/{middleware-B3k-TSmZ.js → middleware-DXsbf9xI.js} +0 -0
- /package/dist/assets/{path-DodfxcX7.js → path-10BjdyLh.js} +0 -0
- /package/dist/assets/{rough.esm-CUaa1Rbe.js → rough.esm-DxgC_14r.js} +0 -0
- /package/dist/assets/{xlsx-CxByi7bR.js → xlsx-DrDuDNAa.js} +0 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { ChatComposerNode } from '@nextclaw/agent-chat-ui';
|
|
2
|
+
import {
|
|
3
|
+
CHAT_CONVERSATION_EXCERPT_TOKEN_KIND,
|
|
4
|
+
CHAT_PROJECT_TOKEN_KIND,
|
|
5
|
+
CHAT_SYSTEM_OBJECT_TOKEN_KIND,
|
|
6
|
+
CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND,
|
|
7
|
+
CHAT_WORKSPACE_EXCERPT_TOKEN_KIND,
|
|
8
|
+
CHAT_WORKSPACE_FILE_TOKEN_KIND,
|
|
9
|
+
type ChatInlineTokenMetadata,
|
|
10
|
+
type ChatSkillSource,
|
|
11
|
+
} from '@nextclaw/shared';
|
|
12
|
+
|
|
13
|
+
import { serializeChatComposerTokenText } from './chat-composer-token-protocol.utils';
|
|
14
|
+
import { buildConversationExcerptInlineToken } from './chat-conversation-excerpt-token.utils';
|
|
15
|
+
import { readSystemObjectResolvedReference } from './chat-system-object-reference.utils';
|
|
16
|
+
|
|
17
|
+
export type ChatSkillReferenceSnapshot = {
|
|
18
|
+
ref: string;
|
|
19
|
+
name: string;
|
|
20
|
+
source: ChatSkillSource;
|
|
21
|
+
path: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
function readOptionalString(value: unknown): string | null {
|
|
25
|
+
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function readOptionalLine(value: unknown): number | null {
|
|
29
|
+
return typeof value === 'number' && Number.isInteger(value) && value > 0
|
|
30
|
+
? value
|
|
31
|
+
: null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function dedupeInlineTokens(tokens: readonly ChatInlineTokenMetadata[]): ChatInlineTokenMetadata[] {
|
|
35
|
+
const seen = new Set<string>();
|
|
36
|
+
return tokens.filter((token) => {
|
|
37
|
+
const identity = 'ref' in token ? token.ref : token.key;
|
|
38
|
+
const dedupeKey = `${token.kind}:${identity}:${token.rawText}`;
|
|
39
|
+
if (seen.has(dedupeKey)) return false;
|
|
40
|
+
seen.add(dedupeKey);
|
|
41
|
+
return true;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function buildWorkspaceExcerptToken(
|
|
46
|
+
node: Extract<ChatComposerNode, { type: 'token' }>,
|
|
47
|
+
rawText: string,
|
|
48
|
+
): ChatInlineTokenMetadata | null {
|
|
49
|
+
const path = readOptionalString(node.data?.path);
|
|
50
|
+
const excerpt = readOptionalString(node.data?.excerpt);
|
|
51
|
+
if (!path || !excerpt) return null;
|
|
52
|
+
return {
|
|
53
|
+
kind: CHAT_WORKSPACE_EXCERPT_TOKEN_KIND,
|
|
54
|
+
key: node.tokenKey,
|
|
55
|
+
path,
|
|
56
|
+
label: node.label,
|
|
57
|
+
excerpt,
|
|
58
|
+
startLine: readOptionalLine(node.data?.startLine),
|
|
59
|
+
endLine: readOptionalLine(node.data?.endLine),
|
|
60
|
+
rawText,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function buildStructuredReferenceToken(
|
|
65
|
+
node: Extract<ChatComposerNode, { type: 'token' }>,
|
|
66
|
+
rawText: string,
|
|
67
|
+
): ChatInlineTokenMetadata | null | undefined {
|
|
68
|
+
if (node.tokenKind === CHAT_WORKSPACE_EXCERPT_TOKEN_KIND) {
|
|
69
|
+
return buildWorkspaceExcerptToken(node, rawText);
|
|
70
|
+
}
|
|
71
|
+
if (node.tokenKind === CHAT_CONVERSATION_EXCERPT_TOKEN_KIND) {
|
|
72
|
+
return buildConversationExcerptInlineToken(node, rawText);
|
|
73
|
+
}
|
|
74
|
+
if (node.tokenKind === CHAT_SYSTEM_OBJECT_TOKEN_KIND) {
|
|
75
|
+
const reference = readSystemObjectResolvedReference(node.data?.reference);
|
|
76
|
+
return reference?.uri === node.tokenKey
|
|
77
|
+
? {
|
|
78
|
+
kind: CHAT_SYSTEM_OBJECT_TOKEN_KIND,
|
|
79
|
+
key: node.tokenKey,
|
|
80
|
+
label: node.label,
|
|
81
|
+
rawText,
|
|
82
|
+
reference,
|
|
83
|
+
}
|
|
84
|
+
: null;
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function buildInlineTokensFromComposer(
|
|
90
|
+
nodes: readonly ChatComposerNode[],
|
|
91
|
+
skillRecords: readonly ChatSkillReferenceSnapshot[] = [],
|
|
92
|
+
): ChatInlineTokenMetadata[] {
|
|
93
|
+
const skillByRef = new Map(skillRecords.map((record) => [record.ref, record]));
|
|
94
|
+
const tokens: ChatInlineTokenMetadata[] = [];
|
|
95
|
+
for (const node of nodes) {
|
|
96
|
+
if (node.type !== 'token') continue;
|
|
97
|
+
const rawText = serializeChatComposerTokenText(node);
|
|
98
|
+
if (!rawText) continue;
|
|
99
|
+
if (node.tokenKind === 'skill') {
|
|
100
|
+
const skill = skillByRef.get(node.tokenKey);
|
|
101
|
+
if (skill?.path.trim()) {
|
|
102
|
+
tokens.push({
|
|
103
|
+
kind: 'skill',
|
|
104
|
+
ref: skill.ref,
|
|
105
|
+
name: skill.name,
|
|
106
|
+
source: skill.source,
|
|
107
|
+
path: skill.path,
|
|
108
|
+
label: node.label,
|
|
109
|
+
rawText,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (node.tokenKind === CHAT_PROJECT_TOKEN_KIND) {
|
|
115
|
+
tokens.push({ kind: CHAT_PROJECT_TOKEN_KIND, key: node.tokenKey, label: node.label, rawText });
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const structuredReference = buildStructuredReferenceToken(node, rawText);
|
|
119
|
+
if (structuredReference !== undefined) {
|
|
120
|
+
if (structuredReference) tokens.push(structuredReference);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (
|
|
124
|
+
node.tokenKind === CHAT_WORKSPACE_FILE_TOKEN_KIND ||
|
|
125
|
+
node.tokenKind === CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND
|
|
126
|
+
) {
|
|
127
|
+
const workspaceKind = node.tokenKind === CHAT_WORKSPACE_FILE_TOKEN_KIND
|
|
128
|
+
? CHAT_WORKSPACE_FILE_TOKEN_KIND
|
|
129
|
+
: CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND;
|
|
130
|
+
tokens.push({ kind: workspaceKind, key: node.tokenKey, label: node.label, rawText });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return dedupeInlineTokens(tokens);
|
|
134
|
+
}
|
|
@@ -1,18 +1,23 @@
|
|
|
1
|
-
import type { ChatComposerNode } from '@nextclaw/agent-chat-ui';
|
|
2
1
|
import {
|
|
3
2
|
CHAT_CONVERSATION_EXCERPT_TOKEN_KIND,
|
|
4
3
|
CHAT_INLINE_TOKENS_METADATA_KEY,
|
|
5
4
|
CHAT_INLINE_TOKENS_SCHEMA_VERSION,
|
|
6
5
|
CHAT_PROJECT_TOKEN_KIND,
|
|
6
|
+
CHAT_SYSTEM_OBJECT_TOKEN_KIND,
|
|
7
7
|
CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND,
|
|
8
8
|
CHAT_WORKSPACE_EXCERPT_TOKEN_KIND,
|
|
9
9
|
CHAT_WORKSPACE_FILE_TOKEN_KIND,
|
|
10
10
|
type ChatInlineTokenMetadata,
|
|
11
11
|
type ChatInlineTokensMetadata,
|
|
12
12
|
type ChatSkillSource,
|
|
13
|
+
type SystemObjectResolvedReference,
|
|
13
14
|
} from '@nextclaw/shared';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
15
|
+
import { readConversationExcerptInlineToken } from './chat-conversation-excerpt-token.utils';
|
|
16
|
+
import { readSystemObjectResolvedReference } from './chat-system-object-reference.utils';
|
|
17
|
+
export {
|
|
18
|
+
buildInlineTokensFromComposer,
|
|
19
|
+
type ChatSkillReferenceSnapshot,
|
|
20
|
+
} from './chat-inline-token-composer.utils';
|
|
16
21
|
|
|
17
22
|
export { CHAT_INLINE_TOKENS_METADATA_KEY };
|
|
18
23
|
const CHAT_PANEL_APP_TOKEN_PREFIX = '@panel-app:';
|
|
@@ -20,13 +25,7 @@ const CHAT_PANEL_APP_TOKEN_PATTERN = /@panel-app:([A-Za-z0-9_-]+)/g;
|
|
|
20
25
|
const CHAT_PROJECT_TOKEN_PATTERN = /@project:([^\s]+)/g;
|
|
21
26
|
const CHAT_WORKSPACE_FILE_TOKEN_PATTERN = /@file:([^\s]+)/g;
|
|
22
27
|
const CHAT_WORKSPACE_DIRECTORY_TOKEN_PATTERN = /@folder:([^\s]+)/g;
|
|
23
|
-
|
|
24
|
-
export type ChatSkillReferenceSnapshot = {
|
|
25
|
-
ref: string;
|
|
26
|
-
name: string;
|
|
27
|
-
source: ChatSkillSource;
|
|
28
|
-
path: string;
|
|
29
|
-
};
|
|
28
|
+
const CHAT_SYSTEM_OBJECT_TOKEN_PATTERN = /@object:([^\s]+)/g;
|
|
30
29
|
|
|
31
30
|
export type ChatInlineTokenSource =
|
|
32
31
|
| {
|
|
@@ -62,6 +61,13 @@ export type ChatInlineTokenSource =
|
|
|
62
61
|
key: string;
|
|
63
62
|
label: string;
|
|
64
63
|
rawText: string;
|
|
64
|
+
}
|
|
65
|
+
| {
|
|
66
|
+
kind: typeof CHAT_SYSTEM_OBJECT_TOKEN_KIND;
|
|
67
|
+
key: string;
|
|
68
|
+
label: string;
|
|
69
|
+
rawText: string;
|
|
70
|
+
reference: SystemObjectResolvedReference;
|
|
65
71
|
};
|
|
66
72
|
|
|
67
73
|
export function resolveWorkspaceReferencePath(params: {
|
|
@@ -114,100 +120,10 @@ function dedupeInlineTokens<T extends ChatInlineTokenSource>(tokens: readonly T[
|
|
|
114
120
|
return output;
|
|
115
121
|
}
|
|
116
122
|
|
|
117
|
-
function appendWorkspaceExcerptToken(
|
|
118
|
-
tokens: ChatInlineTokenMetadata[],
|
|
119
|
-
node: Extract<ChatComposerNode, { type: 'token' }>,
|
|
120
|
-
rawText: string,
|
|
121
|
-
): void {
|
|
122
|
-
const path = readOptionalString(node.data?.path);
|
|
123
|
-
const excerpt = readOptionalString(node.data?.excerpt);
|
|
124
|
-
if (!path || !excerpt) return;
|
|
125
|
-
tokens.push({
|
|
126
|
-
kind: CHAT_WORKSPACE_EXCERPT_TOKEN_KIND,
|
|
127
|
-
key: node.tokenKey,
|
|
128
|
-
path,
|
|
129
|
-
label: node.label,
|
|
130
|
-
excerpt,
|
|
131
|
-
startLine: readOptionalLine(node.data?.startLine),
|
|
132
|
-
endLine: readOptionalLine(node.data?.endLine),
|
|
133
|
-
rawText,
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export function buildInlineTokensFromComposer(
|
|
138
|
-
nodes: readonly ChatComposerNode[],
|
|
139
|
-
skillRecords: readonly ChatSkillReferenceSnapshot[] = [],
|
|
140
|
-
): ChatInlineTokenMetadata[] {
|
|
141
|
-
const skillByRef = new Map(skillRecords.map((record) => [record.ref, record]));
|
|
142
|
-
const tokens: ChatInlineTokenMetadata[] = [];
|
|
143
|
-
for (const node of nodes) {
|
|
144
|
-
if (node.type !== 'token') {
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
if (
|
|
148
|
-
node.tokenKind !== 'skill' &&
|
|
149
|
-
node.tokenKind !== CHAT_PROJECT_TOKEN_KIND &&
|
|
150
|
-
node.tokenKind !== CHAT_WORKSPACE_FILE_TOKEN_KIND &&
|
|
151
|
-
node.tokenKind !== CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND &&
|
|
152
|
-
node.tokenKind !== CHAT_WORKSPACE_EXCERPT_TOKEN_KIND &&
|
|
153
|
-
node.tokenKind !== CHAT_CONVERSATION_EXCERPT_TOKEN_KIND
|
|
154
|
-
) {
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
const rawText = serializeChatComposerTokenText(node);
|
|
158
|
-
if (!rawText) {
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
if (node.tokenKind === 'skill') {
|
|
162
|
-
const skill = skillByRef.get(node.tokenKey);
|
|
163
|
-
if (!skill?.path.trim()) {
|
|
164
|
-
continue;
|
|
165
|
-
}
|
|
166
|
-
tokens.push({
|
|
167
|
-
kind: 'skill',
|
|
168
|
-
ref: skill.ref,
|
|
169
|
-
name: skill.name,
|
|
170
|
-
source: skill.source,
|
|
171
|
-
path: skill.path,
|
|
172
|
-
label: node.label,
|
|
173
|
-
rawText,
|
|
174
|
-
});
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
if (node.tokenKind === CHAT_PROJECT_TOKEN_KIND) {
|
|
178
|
-
tokens.push({
|
|
179
|
-
kind: CHAT_PROJECT_TOKEN_KIND,
|
|
180
|
-
key: node.tokenKey,
|
|
181
|
-
label: node.label,
|
|
182
|
-
rawText,
|
|
183
|
-
});
|
|
184
|
-
continue;
|
|
185
|
-
}
|
|
186
|
-
if (node.tokenKind === CHAT_WORKSPACE_EXCERPT_TOKEN_KIND) {
|
|
187
|
-
appendWorkspaceExcerptToken(tokens, node, rawText);
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
if (node.tokenKind === CHAT_CONVERSATION_EXCERPT_TOKEN_KIND) {
|
|
191
|
-
const token = buildConversationExcerptInlineToken(node, rawText);
|
|
192
|
-
if (token) tokens.push(token);
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
const workspaceKind = node.tokenKind === CHAT_WORKSPACE_FILE_TOKEN_KIND
|
|
196
|
-
? CHAT_WORKSPACE_FILE_TOKEN_KIND
|
|
197
|
-
: CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND;
|
|
198
|
-
tokens.push({
|
|
199
|
-
kind: workspaceKind,
|
|
200
|
-
key: node.tokenKey,
|
|
201
|
-
label: node.label,
|
|
202
|
-
rawText,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
return dedupeInlineTokens(tokens);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
123
|
function appendEncodedKeyTokens(params: {
|
|
209
124
|
kind:
|
|
210
125
|
| typeof CHAT_PROJECT_TOKEN_KIND
|
|
126
|
+
| typeof CHAT_SYSTEM_OBJECT_TOKEN_KIND
|
|
211
127
|
| typeof CHAT_WORKSPACE_FILE_TOKEN_KIND
|
|
212
128
|
| typeof CHAT_WORKSPACE_DIRECTORY_TOKEN_KIND;
|
|
213
129
|
pattern: RegExp;
|
|
@@ -255,6 +171,12 @@ export function buildInlineTokensFromTextProtocol(text: string): ChatInlineToken
|
|
|
255
171
|
text,
|
|
256
172
|
tokens,
|
|
257
173
|
});
|
|
174
|
+
appendEncodedKeyTokens({
|
|
175
|
+
kind: CHAT_SYSTEM_OBJECT_TOKEN_KIND,
|
|
176
|
+
pattern: CHAT_SYSTEM_OBJECT_TOKEN_PATTERN,
|
|
177
|
+
text,
|
|
178
|
+
tokens,
|
|
179
|
+
});
|
|
258
180
|
appendEncodedKeyTokens({
|
|
259
181
|
kind: CHAT_WORKSPACE_FILE_TOKEN_KIND,
|
|
260
182
|
pattern: CHAT_WORKSPACE_FILE_TOKEN_PATTERN,
|
|
@@ -340,6 +262,13 @@ function readInlineTokenEntry(entry: unknown): ChatInlineTokenSource | null {
|
|
|
340
262
|
if (kind === CHAT_CONVERSATION_EXCERPT_TOKEN_KIND) {
|
|
341
263
|
return readConversationExcerptInlineToken({ entry, label, rawText });
|
|
342
264
|
}
|
|
265
|
+
if (kind === CHAT_SYSTEM_OBJECT_TOKEN_KIND) {
|
|
266
|
+
const key = readOptionalString(entry.key);
|
|
267
|
+
const reference = readSystemObjectResolvedReference(entry.reference);
|
|
268
|
+
return key && reference && reference.uri === key
|
|
269
|
+
? { kind, key, label, rawText, reference }
|
|
270
|
+
: null;
|
|
271
|
+
}
|
|
343
272
|
const key = readOptionalString(entry.key);
|
|
344
273
|
return key ? { kind, key, rawText, label } : null;
|
|
345
274
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { CHAT_SYSTEM_OBJECT_TOKEN_KIND, type SystemObjectResolvedReference } from '@nextclaw/shared';
|
|
3
|
+
import {
|
|
4
|
+
appendSystemObjectReferenceToken,
|
|
5
|
+
readSystemObjectReferenceFromToken,
|
|
6
|
+
} from './chat-system-object-reference.utils';
|
|
7
|
+
|
|
8
|
+
const reference: SystemObjectResolvedReference = {
|
|
9
|
+
uri: 'nextclaw://objects/cron-job/cron-1',
|
|
10
|
+
objectType: 'cron-job',
|
|
11
|
+
objectId: 'cron-1',
|
|
12
|
+
label: 'Daily review',
|
|
13
|
+
description: 'Review reports',
|
|
14
|
+
updatedAt: '2026-08-11T00:00:00.000Z',
|
|
15
|
+
version: 'a'.repeat(64),
|
|
16
|
+
assetUri: 'asset://store/cron-1',
|
|
17
|
+
fileName: 'daily-review.md',
|
|
18
|
+
mimeType: 'text/markdown',
|
|
19
|
+
sizeBytes: 42,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
describe('system object reference composer utilities', () => {
|
|
23
|
+
it('creates one visible generic token and deduplicates the same snapshot', () => {
|
|
24
|
+
const first = appendSystemObjectReferenceToken([], reference);
|
|
25
|
+
const second = appendSystemObjectReferenceToken(first, reference);
|
|
26
|
+
|
|
27
|
+
expect(second).toHaveLength(first.length);
|
|
28
|
+
expect(second.find((node) => node.type === 'token')).toMatchObject({
|
|
29
|
+
tokenKind: CHAT_SYSTEM_OBJECT_TOKEN_KIND,
|
|
30
|
+
tokenKey: reference.uri,
|
|
31
|
+
label: reference.label,
|
|
32
|
+
});
|
|
33
|
+
expect(readSystemObjectReferenceFromToken(second[0]!)).toEqual(reference);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('rejects metadata whose URI identity disagrees with its object fields', () => {
|
|
37
|
+
const [node] = appendSystemObjectReferenceToken([], {
|
|
38
|
+
...reference,
|
|
39
|
+
objectId: 'different-cron',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
expect(readSystemObjectReferenceFromToken(node!)).toBeNull();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createChatComposerTokenNode,
|
|
3
|
+
normalizeChatComposerNodes,
|
|
4
|
+
type ChatComposerNode,
|
|
5
|
+
} from '@nextclaw/agent-chat-ui';
|
|
6
|
+
import {
|
|
7
|
+
CHAT_SYSTEM_OBJECT_TOKEN_KIND,
|
|
8
|
+
readSystemObjectResolvedReference,
|
|
9
|
+
type SystemObjectResolvedReference,
|
|
10
|
+
} from '@nextclaw/shared';
|
|
11
|
+
|
|
12
|
+
export { readSystemObjectResolvedReference } from '@nextclaw/shared';
|
|
13
|
+
|
|
14
|
+
export function createSystemObjectReferenceTokenNode(
|
|
15
|
+
reference: SystemObjectResolvedReference,
|
|
16
|
+
): ChatComposerNode {
|
|
17
|
+
return createChatComposerTokenNode({
|
|
18
|
+
tokenKind: CHAT_SYSTEM_OBJECT_TOKEN_KIND,
|
|
19
|
+
tokenKey: reference.uri,
|
|
20
|
+
label: reference.label,
|
|
21
|
+
data: { reference },
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function appendSystemObjectReferenceToken(
|
|
26
|
+
nodes: readonly ChatComposerNode[],
|
|
27
|
+
reference: SystemObjectResolvedReference,
|
|
28
|
+
): ChatComposerNode[] {
|
|
29
|
+
const exists = nodes.some((node) =>
|
|
30
|
+
node.type === 'token' &&
|
|
31
|
+
node.tokenKind === CHAT_SYSTEM_OBJECT_TOKEN_KIND &&
|
|
32
|
+
node.tokenKey === reference.uri &&
|
|
33
|
+
readSystemObjectResolvedReference(node.data?.reference)?.version === reference.version
|
|
34
|
+
);
|
|
35
|
+
return exists
|
|
36
|
+
? normalizeChatComposerNodes([...nodes])
|
|
37
|
+
: normalizeChatComposerNodes([...nodes, createSystemObjectReferenceTokenNode(reference)]);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function readSystemObjectReferenceFromToken(
|
|
41
|
+
node: ChatComposerNode,
|
|
42
|
+
): SystemObjectResolvedReference | null {
|
|
43
|
+
return node.type === 'token' && node.tokenKind === CHAT_SYSTEM_OBJECT_TOKEN_KIND
|
|
44
|
+
? readSystemObjectResolvedReference(node.data?.reference)
|
|
45
|
+
: null;
|
|
46
|
+
}
|
|
@@ -169,6 +169,7 @@ beforeEach(() => {
|
|
|
169
169
|
});
|
|
170
170
|
mocks.refetchBrowse.mockResolvedValue(undefined);
|
|
171
171
|
useChatThreadStore.getState().setSnapshot({
|
|
172
|
+
workspaceExplorerOpen: false,
|
|
172
173
|
workspaceExplorerWidth: CHAT_WORKSPACE_EXPLORER_DEFAULT_WIDTH,
|
|
173
174
|
});
|
|
174
175
|
});
|
|
@@ -626,7 +627,81 @@ it('preserves project tree expansion and scroll while visiting another workspace
|
|
|
626
627
|
expect(tree.scrollTop).toBe(128);
|
|
627
628
|
});
|
|
628
629
|
|
|
629
|
-
it('
|
|
630
|
+
it('selects and reveals the active file when it is opened outside the Explorer', async () => {
|
|
631
|
+
const user = userEvent.setup();
|
|
632
|
+
const projectFilesProps = {
|
|
633
|
+
activeSelection: { kind: 'project-files' as const },
|
|
634
|
+
childSessionTabs: [],
|
|
635
|
+
filePreviewRefreshVersion: 0,
|
|
636
|
+
sessionKey: 'parent-1',
|
|
637
|
+
sessionCronJobs: [],
|
|
638
|
+
sessionProjectRoot: '/Users/peiwang/Projects/nextbot',
|
|
639
|
+
sessionWorkingDir: '/Users/peiwang/Projects/nextbot',
|
|
640
|
+
};
|
|
641
|
+
const { rerender } = render(<ChatSessionWorkspacePanelContent {...projectFilesProps} />);
|
|
642
|
+
const sourceDirectory = screen.getByRole('treeitem', { name: 'Open directory: src' });
|
|
643
|
+
const packageEntry = screen.getByRole('treeitem', { name: 'Open file: package.json' });
|
|
644
|
+
await user.click(screen.getByRole('button', { name: 'src' }));
|
|
645
|
+
expect(sourceDirectory.getAttribute('aria-selected')).toBe('true');
|
|
646
|
+
|
|
647
|
+
rerender(
|
|
648
|
+
<ChatSessionWorkspacePanelContent
|
|
649
|
+
{...projectFilesProps}
|
|
650
|
+
activeSelection={{
|
|
651
|
+
kind: 'file',
|
|
652
|
+
file: {
|
|
653
|
+
key: 'parent-1::preview::package.json',
|
|
654
|
+
parentSessionKey: 'parent-1',
|
|
655
|
+
path: 'package.json',
|
|
656
|
+
label: 'package.json',
|
|
657
|
+
viewMode: 'preview',
|
|
658
|
+
previewViewer: 'source',
|
|
659
|
+
},
|
|
660
|
+
}}
|
|
661
|
+
/>,
|
|
662
|
+
);
|
|
663
|
+
|
|
664
|
+
await waitFor(() => {
|
|
665
|
+
expect(packageEntry.getAttribute('aria-selected')).toBe('true');
|
|
666
|
+
expect(sourceDirectory.getAttribute('aria-selected')).toBe('false');
|
|
667
|
+
});
|
|
668
|
+
expect(mocks.scrollIntoView).toHaveBeenCalled();
|
|
669
|
+
expect(document.activeElement).not.toBe(screen.getByRole('button', { name: 'package.json' }));
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
it('expands active-file ancestors like an auto-revealing Explorer', async () => {
|
|
673
|
+
useChatThreadStore.getState().setSnapshot({ workspaceExplorerOpen: true });
|
|
674
|
+
render(
|
|
675
|
+
<ChatSessionWorkspacePanelContent
|
|
676
|
+
activeSelection={{
|
|
677
|
+
kind: 'file',
|
|
678
|
+
file: {
|
|
679
|
+
key: 'parent-1::preview::src/index.ts',
|
|
680
|
+
parentSessionKey: 'parent-1',
|
|
681
|
+
path: '/Users/peiwang/Projects/nextbot/src/index.ts',
|
|
682
|
+
label: 'index.ts',
|
|
683
|
+
viewMode: 'preview',
|
|
684
|
+
previewViewer: 'source',
|
|
685
|
+
},
|
|
686
|
+
}}
|
|
687
|
+
childSessionTabs={[]}
|
|
688
|
+
filePreviewRefreshVersion={0}
|
|
689
|
+
sessionKey="parent-1"
|
|
690
|
+
sessionCronJobs={[]}
|
|
691
|
+
sessionProjectRoot="/Users/peiwang/Projects/nextbot"
|
|
692
|
+
sessionWorkingDir="/Users/peiwang/Projects/nextbot"
|
|
693
|
+
/>,
|
|
694
|
+
);
|
|
695
|
+
|
|
696
|
+
const sourceDirectory = within(screen.getByTestId('workspace-shared-explorer')).getAllByRole('treeitem', {
|
|
697
|
+
name: 'Open directory: src',
|
|
698
|
+
})[0];
|
|
699
|
+
await waitFor(() => {
|
|
700
|
+
expect(sourceDirectory.getAttribute('aria-expanded')).toBe('true');
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
it('keeps the file Explorer closed by default and reuses it after an explicit open', () => {
|
|
630
705
|
const projectFilesProps = {
|
|
631
706
|
activeSelection: { kind: 'project-files' as const },
|
|
632
707
|
childSessionTabs: [],
|
|
@@ -659,6 +734,9 @@ it('reuses the Explorer beside a file and persists a dragged compact width', ()
|
|
|
659
734
|
const explorer = screen.getByTestId('workspace-shared-explorer');
|
|
660
735
|
const breadcrumbs = screen.getByTestId('workspace-file-breadcrumbs');
|
|
661
736
|
const toggle = screen.getByTestId('workspace-explorer-toggle');
|
|
737
|
+
expect(explorer.getAttribute('aria-hidden')).toBe('true');
|
|
738
|
+
fireEvent.click(toggle);
|
|
739
|
+
expect(useChatThreadStore.getState().snapshot.workspaceExplorerOpen).toBe(true);
|
|
662
740
|
expect(screen.getByRole('tree', { name: 'Project files' })).toBe(tree);
|
|
663
741
|
expect(explorer.getAttribute('data-mode')).toBe('side');
|
|
664
742
|
expect(explorer.style.width).toBe('224px');
|
|
@@ -674,7 +752,7 @@ it('reuses the Explorer beside a file and persists a dragged compact width', ()
|
|
|
674
752
|
expect(mocks.setWorkspaceExplorerWidth).toHaveBeenCalledWith(300);
|
|
675
753
|
});
|
|
676
754
|
|
|
677
|
-
it('uses an overlay only below the compact threshold and
|
|
755
|
+
it('uses an overlay only below the compact threshold and persists closing it without unmounting', () => {
|
|
678
756
|
HTMLElement.prototype.getBoundingClientRect = () => ({
|
|
679
757
|
bottom: 600,
|
|
680
758
|
height: 600,
|
|
@@ -686,6 +764,7 @@ it('uses an overlay only below the compact threshold and closes it without unmou
|
|
|
686
764
|
y: 0,
|
|
687
765
|
toJSON: () => ({}),
|
|
688
766
|
});
|
|
767
|
+
useChatThreadStore.getState().setSnapshot({ workspaceExplorerOpen: true });
|
|
689
768
|
render(
|
|
690
769
|
<ChatSessionWorkspacePanelContent
|
|
691
770
|
activeSelection={{
|
|
@@ -714,6 +793,7 @@ it('uses an overlay only below the compact threshold and closes it without unmou
|
|
|
714
793
|
expect(screen.queryByTestId('workspace-explorer-resize-handle')).toBeNull();
|
|
715
794
|
|
|
716
795
|
fireEvent.click(screen.getByTestId('workspace-explorer-scrim'));
|
|
796
|
+
expect(useChatThreadStore.getState().snapshot.workspaceExplorerOpen).toBe(false);
|
|
717
797
|
expect(explorer.getAttribute('aria-hidden')).toBe('true');
|
|
718
798
|
expect(tree.isConnected).toBe(true);
|
|
719
799
|
});
|
|
@@ -22,14 +22,18 @@ vi.mock("@/shared/hooks/use-server-path-browse", () => ({
|
|
|
22
22
|
useServerPathBrowse: () => ({ data: null, error: null, isLoading: false }),
|
|
23
23
|
}));
|
|
24
24
|
|
|
25
|
-
vi.mock("@nextclaw/agent-chat-ui", () =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}))
|
|
25
|
+
vi.mock("@nextclaw/agent-chat-ui", async (importOriginal) => {
|
|
26
|
+
const actual = await importOriginal();
|
|
27
|
+
return {
|
|
28
|
+
...(actual as object),
|
|
29
|
+
ChatMessageMarkdown: ({ text }: { text: string }) => <div>{text}</div>,
|
|
30
|
+
FileOperationCodeSurface: ({ block }: { block: ChatFileOperationBlockViewModel }) => (
|
|
31
|
+
<div data-testid="json-source-preview">
|
|
32
|
+
{block.lines.map(({ text }, index) => <span key={index}>{text}{"\n"}</span>)}
|
|
33
|
+
</div>
|
|
34
|
+
),
|
|
35
|
+
};
|
|
36
|
+
});
|
|
33
37
|
|
|
34
38
|
it("supports the first text selection in a JSON preview", async () => {
|
|
35
39
|
const onTextExcerptAdd = vi.fn();
|
package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx
CHANGED
|
@@ -24,6 +24,7 @@ import { hostCapabilityManager } from '@/shared/lib/host-capabilities';
|
|
|
24
24
|
import { t } from '@/shared/lib/i18n';
|
|
25
25
|
|
|
26
26
|
type ChatSessionWorkspaceDirectoryBrowserProps = {
|
|
27
|
+
activeRelativePath?: string | null;
|
|
27
28
|
browseQuery: ReturnType<typeof useServerPathBrowse>;
|
|
28
29
|
onFileOpen: (action: ChatFileOpenActionViewModel) => void;
|
|
29
30
|
sessionKey?: string | null;
|
|
@@ -36,6 +37,7 @@ function readPathName(path: string): string {
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
function WorkspaceDirectoryEntries({
|
|
40
|
+
activeRelativePath,
|
|
39
41
|
busy,
|
|
40
42
|
collapseVersion,
|
|
41
43
|
createTarget,
|
|
@@ -59,6 +61,7 @@ function WorkspaceDirectoryEntries({
|
|
|
59
61
|
selectedPath,
|
|
60
62
|
showRoot,
|
|
61
63
|
}: {
|
|
64
|
+
activeRelativePath: string | null;
|
|
62
65
|
busy: boolean;
|
|
63
66
|
collapseVersion: number;
|
|
64
67
|
createTarget: WorkspaceDirectoryActionTarget | null;
|
|
@@ -87,6 +90,7 @@ function WorkspaceDirectoryEntries({
|
|
|
87
90
|
}
|
|
88
91
|
return entries.map((entry) => (
|
|
89
92
|
<WorkspaceDirectoryTreeEntry
|
|
93
|
+
activeRelativePath={activeRelativePath}
|
|
90
94
|
key={entry.path}
|
|
91
95
|
browseParentRefresh={refresh}
|
|
92
96
|
busy={busy}
|
|
@@ -243,6 +247,7 @@ function WorkspaceProjectTree({
|
|
|
243
247
|
}
|
|
244
248
|
|
|
245
249
|
function WorkspaceDirectoryBrowserReady({
|
|
250
|
+
activeRelativePath,
|
|
246
251
|
browseQuery,
|
|
247
252
|
ConfirmDialog,
|
|
248
253
|
controller,
|
|
@@ -254,6 +259,7 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
254
259
|
rootPath,
|
|
255
260
|
showRoot,
|
|
256
261
|
}: {
|
|
262
|
+
activeRelativePath: string | null;
|
|
257
263
|
browseQuery: ReturnType<typeof useServerPathBrowse>;
|
|
258
264
|
ConfirmDialog: () => ReactNode;
|
|
259
265
|
controller: ReturnType<typeof useWorkspaceProjectFilesController>;
|
|
@@ -266,30 +272,32 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
266
272
|
showRoot: boolean;
|
|
267
273
|
}) {
|
|
268
274
|
const {
|
|
269
|
-
actions,
|
|
270
275
|
cancelCreateFolder,
|
|
271
276
|
clearSelection,
|
|
272
277
|
completeReveal,
|
|
273
278
|
submitCreate,
|
|
274
|
-
createError,
|
|
275
|
-
createKind,
|
|
276
|
-
createName,
|
|
277
|
-
createTarget,
|
|
278
279
|
deleteEntry,
|
|
279
|
-
fileInputRef,
|
|
280
280
|
openCreateFile,
|
|
281
281
|
openCreateFolder,
|
|
282
282
|
requestUpload,
|
|
283
283
|
renameEntry,
|
|
284
|
-
revealPath,
|
|
285
284
|
selectEntry,
|
|
286
|
-
selectedCreateTarget,
|
|
287
|
-
selectedPath,
|
|
288
285
|
setCreateError,
|
|
289
286
|
setCreateName,
|
|
290
287
|
uploadFiles,
|
|
291
|
-
} = controller;
|
|
292
|
-
const
|
|
288
|
+
} = controller.actions;
|
|
289
|
+
const { fileInputRef } = controller.refs;
|
|
290
|
+
const {
|
|
291
|
+
createError,
|
|
292
|
+
createKind,
|
|
293
|
+
createName,
|
|
294
|
+
createTarget,
|
|
295
|
+
pendingAction,
|
|
296
|
+
revealPath,
|
|
297
|
+
selectedCreateTarget,
|
|
298
|
+
selectedPath,
|
|
299
|
+
} = controller.state;
|
|
300
|
+
const busy = pendingAction !== null;
|
|
293
301
|
const [collapseVersion, setCollapseVersion] = useState(0);
|
|
294
302
|
const rootRefresh = () => browseQuery.refetch();
|
|
295
303
|
const rootTarget: WorkspaceDirectoryActionTarget | null = rootPath
|
|
@@ -300,7 +308,7 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
300
308
|
<WorkspaceNewFolderTreeItem
|
|
301
309
|
error={createError}
|
|
302
310
|
kind={createKind}
|
|
303
|
-
isCreating={
|
|
311
|
+
isCreating={pendingAction === 'create-directory' || pendingAction === 'create-file'}
|
|
304
312
|
level={level}
|
|
305
313
|
name={createName}
|
|
306
314
|
onCancel={cancelCreateFolder}
|
|
@@ -318,6 +326,7 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
318
326
|
};
|
|
319
327
|
const treeEntries = (
|
|
320
328
|
<WorkspaceDirectoryEntries
|
|
329
|
+
activeRelativePath={activeRelativePath}
|
|
321
330
|
busy={busy}
|
|
322
331
|
collapseVersion={collapseVersion}
|
|
323
332
|
createTarget={createTarget}
|
|
@@ -406,6 +415,7 @@ function WorkspaceDirectoryBrowserReady({
|
|
|
406
415
|
}
|
|
407
416
|
|
|
408
417
|
export function ChatSessionWorkspaceDirectoryBrowser({
|
|
418
|
+
activeRelativePath = null,
|
|
409
419
|
browseQuery,
|
|
410
420
|
onFileOpen,
|
|
411
421
|
sessionKey,
|
|
@@ -419,6 +429,7 @@ export function ChatSessionWorkspaceDirectoryBrowser({
|
|
|
419
429
|
const rootPath = showRoot ? (browseQuery.data?.currentPath ?? null) : null;
|
|
420
430
|
const rootLabel = rootPath ? readPathName(rootPath) : '';
|
|
421
431
|
const controller = useWorkspaceProjectFilesController({
|
|
432
|
+
activeRelativePath,
|
|
422
433
|
confirm,
|
|
423
434
|
onEntryDeleted: presenter.chatThreadManager.removeWorkspacePath,
|
|
424
435
|
onEntryRenamed: presenter.chatThreadManager.renameWorkspacePath,
|
|
@@ -457,6 +468,7 @@ export function ChatSessionWorkspaceDirectoryBrowser({
|
|
|
457
468
|
}
|
|
458
469
|
return (
|
|
459
470
|
<WorkspaceDirectoryBrowserReady
|
|
471
|
+
activeRelativePath={activeRelativePath}
|
|
460
472
|
browseQuery={browseQuery}
|
|
461
473
|
ConfirmDialog={ConfirmDialog}
|
|
462
474
|
controller={controller}
|