@hienlh/ppm 0.18.2 → 0.18.4
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 +22 -0
- package/CLAUDE.md +1 -0
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/http-api.md +6 -1
- package/dist/web/assets/{ai-resource-editor-B6CODu6u.js → ai-resource-editor-Bb-NNlp1.js} +1 -1
- package/dist/web/assets/{angular-html-C-Kjr43S.js → angular-html-jfMqUuRd.js} +1 -1
- package/dist/web/assets/{angular-ts-CaDDbZqm.js → angular-ts-wytn9PMm.js} +1 -1
- package/dist/web/assets/api-client-CzABTreM.js +1 -0
- package/dist/web/assets/{api-settings-CAhcNpj5.js → api-settings-DfNRPr1q.js} +1 -1
- package/dist/web/assets/api-settings-DlcoR5QT.js +1 -0
- package/dist/web/assets/{api-themes-CAjg_Bt9.js → api-themes-CEyYK7AK.js} +1 -1
- package/dist/web/assets/{apl-B1WsQFAb.js → apl-i-ahKx6O.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-Bs7wzj-W.js +1 -0
- package/dist/web/assets/arrow-right-DubGFkN8.js +1 -0
- package/dist/web/assets/{astro-Bdnz7nVp.js → astro-DVBCJfG6.js} +1 -1
- package/dist/web/assets/audio-preview-DG2Tw0cO.js +1 -0
- package/dist/web/assets/{blade-B2euh8sS.js → blade-BHlL8SqU.js} +1 -1
- package/dist/web/assets/{bsl-GNeMaxd0.js → bsl-D-UOfR1F.js} +1 -1
- package/dist/web/assets/button-B4MWPjWj.js +1 -0
- package/dist/web/assets/{cairo-D7G0W7-s.js → cairo-Bn6rucli.js} +1 -1
- package/dist/web/assets/chat-tab-CgAv-crh.js +15 -0
- package/dist/web/assets/{cobol-Q6YgysnI.js → cobol-Byn9FYKu.js} +1 -1
- package/dist/web/assets/code-editor-bX4jlgMy.js +10 -0
- package/dist/web/assets/{coffee-BjufWxVc.js → coffee-DjBl4gm-.js} +1 -1
- package/dist/web/assets/{conflict-editor-DnSltcyC.js → conflict-editor-B6hVffX3.js} +3 -3
- package/dist/web/assets/{context-menu-q-RHHAWz.js → context-menu-DkQdt6YA.js} +1 -1
- package/dist/web/assets/{cpp-CqWU0gCR.js → cpp-CKzic-3E.js} +1 -1
- package/dist/web/assets/{crystal-ylayVajF.js → crystal-Bkg-Ly_g.js} +1 -1
- package/dist/web/assets/{csv-preview-DnaFdgOB.js → csv-preview-hL4Z9HS5.js} +1 -1
- package/dist/web/assets/{data-grid-overlay-editor-BzPfsCfd.js → data-grid-overlay-editor-B1mTl3KS.js} +1 -1
- package/dist/web/assets/{database-viewer-C7uLy8Z1.js → database-viewer-CTK5kMaA.js} +1 -1
- package/dist/web/assets/diff-viewer-DZxnANY4.js +4 -0
- package/dist/web/assets/{docx-preview-Dd2nTW2v.js → docx-preview-CrAc7Qjv.js} +1 -1
- package/dist/web/assets/download-D9UYwY0-.js +1 -0
- package/dist/web/assets/{edge-DX4NxQfh.js → edge-DVbZnd3Y.js} +1 -1
- package/dist/web/assets/{edit-diff-preview-DfX-9om9.js → edit-diff-preview-HTZPC9VP.js} +1 -1
- package/dist/web/assets/{elixir-CSh3NjbV.js → elixir-Dwi8Wu7W.js} +1 -1
- package/dist/web/assets/{elm-DBzwFYq9.js → elm-DtIv-HXJ.js} +1 -1
- package/dist/web/assets/{erb-yxVOb8aB.js → erb-D3HEDz1x.js} +1 -1
- package/dist/web/assets/{erlang-5XIDkYrM.js → erlang-2MjTCzGz.js} +1 -1
- package/dist/web/assets/{esm-DO4el2OJ.js → esm-CZ8B8Ba2.js} +1 -1
- package/dist/web/assets/explorer-body-DykJXCTw.js +2 -0
- package/dist/web/assets/explorer-window-content-NS8Y0v8c.js +1 -0
- package/dist/web/assets/{extension-webview-Dk_zyoXZ.js → extension-webview-D6eywKPN.js} +1 -1
- package/dist/web/assets/{fortran-fixed-form-D4tE5VWY.js → fortran-fixed-form-BLyAtyPM.js} +1 -1
- package/dist/web/assets/{fsharp-By8soj6-.js → fsharp-Bxbn_gbr.js} +1 -1
- package/dist/web/assets/{gdresource-DoSwM7Hv.js → gdresource-sFMY4D2Q.js} +1 -1
- package/dist/web/assets/{git-commit-_ZiciHIx.js → git-commit-BzB9Lio5.js} +1 -1
- package/dist/web/assets/{git-log-panel-BLQSy6rC.js → git-log-panel-DAogZ9QV.js} +1 -1
- package/dist/web/assets/{git-rebase-C3Y5N9-s.js → git-rebase-CKSVd848.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-D7i54kbM.js +1 -0
- package/dist/web/assets/glide-data-grid-DxfJRN-r.js +138 -0
- package/dist/web/assets/{glimmer-js-BPBTXVlC.js → glimmer-js-BY8aExAJ.js} +1 -1
- package/dist/web/assets/{glimmer-ts-BQSZdy_D.js → glimmer-ts-Bak54dBX.js} +1 -1
- package/dist/web/assets/{glsl-CbQdxpU-.js → glsl-nR2eaJQe.js} +1 -1
- package/dist/web/assets/{graphql-GMlKikpY.js → graphql-CGPPFAU6.js} +1 -1
- package/dist/web/assets/group-chat-tab-DkVi6qL2.js +1 -0
- package/dist/web/assets/{hack-DyshcLec.js → hack-CXIMX-Ol.js} +1 -1
- package/dist/web/assets/{haml-rqCqWzsq.js → haml-tPY-9Pfm.js} +1 -1
- package/dist/web/assets/{handlebars-BCKwSWjR.js → handlebars-BuW1LT7T.js} +1 -1
- package/dist/web/assets/{html-Cg29xPR1.js → html-bgVcwZ-t.js} +1 -1
- package/dist/web/assets/{html-derivative-geltIVg8.js → html-derivative-D6-IxTgn.js} +1 -1
- package/dist/web/assets/{http-pG7Vp237.js → http-CJ1zyB-h.js} +1 -1
- package/dist/web/assets/{hurl-Di3Uu_Mc.js → hurl-CmoT7l3T.js} +1 -1
- package/dist/web/assets/{hxml-CRy4lbv8.js → hxml-CztOsL8o.js} +1 -1
- package/dist/web/assets/{image-preview-KubLSLNO.js → image-preview-Byjx8MoL.js} +1 -1
- package/dist/web/assets/index-Bucbpby-.css +2 -0
- package/dist/web/assets/index-CcN0TBm4.js +52 -0
- package/dist/web/assets/info-3K5VOQVL-BV41AzR9.js +1 -0
- package/dist/web/assets/{jinja-C8GyVnvd.js → jinja-B1pq3jJq.js} +1 -1
- package/dist/web/assets/{jison-BywnqPn6.js → jison-D8B5pCwA.js} +1 -1
- package/dist/web/assets/{julia-DTrO3T3B.js → julia-D0K3bwpU.js} +1 -1
- package/dist/web/assets/{just-CA3KSHPi.js → just-B9Jlddu-.js} +1 -1
- package/dist/web/assets/keybindings-store-DJIHqbLM.js +1 -0
- package/dist/web/assets/{latex-BC5xUMpc.js → latex-BPJSSE6j.js} +1 -1
- package/dist/web/assets/{liquid-Chd8tSyQ.js → liquid-lv10fo4U.js} +1 -1
- package/dist/web/assets/{lua-DHaEtwLv.js → lua-PNuaIBEF.js} +1 -1
- package/dist/web/assets/{markdown-renderer-B4uL6GVA.js → markdown-renderer-CXlEe3ma.js} +3 -3
- package/dist/web/assets/markdown-renderer-pYznJDbh.js +1 -0
- package/dist/web/assets/{marko-Desx_bC-.js → marko-Du3frD6X.js} +1 -1
- package/dist/web/assets/{mdc-DahWHc1t.js → mdc-BeDVcFRl.js} +1 -1
- package/dist/web/assets/media-url-C5vA0ha9.js +1 -0
- package/dist/web/assets/{mobile-bottom-sheet-BQt45q9T.js → mobile-bottom-sheet-CS3XMwFw.js} +1 -1
- package/dist/web/assets/mobile-explorer-sheet-BuqBlP3o.js +1 -0
- package/dist/web/assets/{nextflow-3A7lutCA.js → nextflow-DkcXP71s.js} +1 -1
- package/dist/web/assets/{nginx-XQda6Hdy.js → nginx-C5n8N_bt.js} +1 -1
- package/dist/web/assets/{nim-DHqlpwP1.js → nim-CIhyfs-A.js} +1 -1
- package/dist/web/assets/notification-store-Bcl5efY2.js +1 -0
- package/dist/web/assets/{number-overlay-editor-DgZtViPO.js → number-overlay-editor-NgOsWJ7x.js} +1 -1
- package/dist/web/assets/packet-RMMSAZCW-CaJoP44m.js +1 -0
- package/dist/web/assets/{panel-store-s6Qx49RK.js → panel-store-DCD82zc1.js} +1 -1
- package/dist/web/assets/{pdf-preview-xZQVUtaV.js → pdf-preview-F2DWVB85.js} +1 -1
- package/dist/web/assets/{perl-M-ncjACb.js → perl-Cf31sZYE.js} +1 -1
- package/dist/web/assets/{php-CKIajrZi.js → php-Dzl_MDIW.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-DSGZmNw2.js +1 -0
- package/dist/web/assets/plus-DmjC2iRB.js +1 -0
- package/dist/web/assets/{postgres-viewer-Ds0FxBel.js → postgres-viewer-KZqPYfOB.js} +3 -3
- package/dist/web/assets/{project-store-DyaEpHVG.js → project-store-B8BkHXy5.js} +1 -1
- package/dist/web/assets/{pug-DO0u_gO4.js → pug-CxSYHrB3.js} +1 -1
- package/dist/web/assets/{qml-UEje1PAA.js → qml-DlEjGhwN.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-Be4VUTs0.js +1 -0
- package/dist/web/assets/{razor-lCs5T1Ib.js → razor-KVt5uW14.js} +1 -1
- package/dist/web/assets/{rst-CZX_O0z4.js → rst-D5BwNTnw.js} +1 -1
- package/dist/web/assets/{ruby-idycVAyE.js → ruby-D5fejQwd.js} +1 -1
- package/dist/web/assets/run-in-terminal-B8TDtaM_.js +1 -0
- package/dist/web/assets/{sas-o5gTfUwp.js → sas-Bj7B1CB2.js} +1 -1
- package/dist/web/assets/{scss-CRTk3iBQ.js → scss-BB0CUoCL.js} +1 -1
- package/dist/web/assets/send-to-chat-CuBAVC8l.js +1 -0
- package/dist/web/assets/{settings-store-ChqHdT2V.js → settings-store-CY-4_U3H.js} +2 -2
- package/dist/web/assets/settings-tab-Khj-w6Sr.js +1 -0
- package/dist/web/assets/{shaderlab-3e5ln8ci.js → shaderlab-BdjEZUMc.js} +1 -1
- package/dist/web/assets/{shellsession-CGQjQ75I.js → shellsession-Bp1OA1rR.js} +1 -1
- package/dist/web/assets/{soy-CxY0VwX2.js → soy-DlYz3wsC.js} +1 -1
- package/dist/web/assets/{sparql-CBAGAFuq.js → sparql-CdfII5Jd.js} +1 -1
- package/dist/web/assets/sql-query-editor-Cp0_e2P1.js +1 -0
- package/dist/web/assets/{sqlite-viewer-CZYDknNa.js → sqlite-viewer-CIv3sagZ.js} +1 -1
- package/dist/web/assets/{stata-BoezhOvk.js → stata-BvUA6GUW.js} +1 -1
- package/dist/web/assets/{surrealql-CHEzAhu7.js → surrealql--DLNbTyI.js} +1 -1
- package/dist/web/assets/{svelte-y6xtu2zX.js → svelte-CBfSsG4n.js} +1 -1
- package/dist/web/assets/system-monitor-tab-CrssTOf4.js +1 -0
- package/dist/web/assets/{tab-store-C42sktPo.js → tab-store-DAsvpx4t.js} +1 -1
- package/dist/web/assets/team-member-window-content-D-hXax3c.js +1 -0
- package/dist/web/assets/{templ-DbG2y5yD.js → templ-Dv8zpKZW.js} +1 -1
- package/dist/web/assets/terminal-tab-BIQDG-Ti.js +3 -0
- package/dist/web/assets/{tex-CeKQhrQG.js → tex-CsrOiqh1.js} +1 -1
- package/dist/web/assets/tool-cards-Dx-Rrpri.js +8 -0
- package/dist/web/assets/treemap-KZPCXAKY-Cu2zgbxU.js +1 -0
- package/dist/web/assets/{ts-tags-iKKOXJjG.js → ts-tags-3T98k4EJ.js} +1 -1
- package/dist/web/assets/{twig-DK8Vrp-G.js → twig-u6QZ45FH.js} +1 -1
- package/dist/web/assets/{use-blob-url-DYtOHK7u.js → use-blob-url-BmlYYZ8L.js} +1 -1
- package/dist/web/assets/use-is-mobile-B8FA4kQf.js +1 -0
- package/dist/web/assets/use-monaco-theme-Djp1_fKi.js +1 -0
- package/dist/web/assets/use-websocket-CCYA9-a2.js +1 -0
- package/dist/web/assets/{vendor-mermaid-C977xNeE.js → vendor-mermaid-Bg4vE8QA.js} +1 -1
- package/dist/web/assets/video-preview-cvjNMjWA.js +1 -0
- package/dist/web/assets/{vue-JkIEObMV.js → vue-CxIsxtwn.js} +1 -1
- package/dist/web/assets/{vue-html-D8SqnU86.js → vue-html-BGL5qnuH.js} +1 -1
- package/dist/web/assets/{vue-vine-DJj7N4WD.js → vue-vine-DHPh_gMr.js} +1 -1
- package/dist/web/assets/{xml-C-00w9Rv.js → xml-C-vM2m7J.js} +1 -1
- package/dist/web/assets/{xsl-CVdCwPHV.js → xsl-DvTXNwuO.js} +1 -1
- package/dist/web/index.html +21 -20
- package/dist/web/sw.js +1 -1
- package/docs/codebase-summary.md +1 -0
- package/package.json +1 -1
- package/scripts/dev-quick-tunnel-retry.mjs +51 -0
- package/src/providers/claude-agent-sdk.ts +6 -0
- package/src/server/helpers/media-route-handlers.ts +66 -0
- package/src/server/helpers/range-file-response.ts +86 -0
- package/src/server/index.ts +24 -17
- package/src/server/middleware/auth.ts +3 -2
- package/src/server/routes/files.ts +40 -7
- package/src/server/routes/fs-browse.ts +43 -5
- package/src/server/routes/fs-upload.ts +32 -0
- package/src/server/routes/teams.ts +34 -0
- package/src/server/ws/chat.ts +64 -16
- package/src/server/ws/team-inbox-watcher.ts +61 -22
- package/src/server/ws/terminal.ts +24 -6
- package/src/services/fs-ops/fs-ops-upload.service.ts +120 -0
- package/src/services/media-transcode/ffmpeg-capabilities.ts +89 -0
- package/src/services/media-transcode/media-probe.ts +63 -0
- package/src/services/media-transcode/transcode-stream.ts +129 -0
- package/src/services/subagent-transcript-merger.ts +1 -1
- package/src/services/team-member-activity/member-activity.service.ts +117 -0
- package/src/services/team-member-activity/outbound-message-scanner.ts +121 -0
- package/src/services/team-member-activity/subagent-transcript-index.ts +95 -0
- package/src/services/team-member-activity/transcript-tail-summary.ts +125 -0
- package/src/shared/background-agent-status.ts +79 -0
- package/src/types/api.ts +1 -0
- package/src/types/chat.ts +6 -1
- package/src/web/components/chat/chat-history-bar.tsx +4 -2
- package/src/web/components/chat/chat-tab.tsx +1 -0
- package/src/web/components/chat/message-input.tsx +13 -6
- package/src/web/components/chat/mini-markdown.tsx +17 -0
- package/src/web/components/chat/send-message-card.tsx +134 -0
- package/src/web/components/chat/send-message-parse.ts +159 -0
- package/src/web/components/chat/team-activity-panel.tsx +107 -121
- package/src/web/components/chat/team-member-activity-row.tsx +92 -0
- package/src/web/components/chat/team-member-list.tsx +43 -0
- package/src/web/components/chat/team-member-window-content.tsx +97 -0
- package/src/web/components/chat/team-message-badges.ts +18 -0
- package/src/web/components/chat/team-message-list.tsx +88 -0
- package/src/web/components/chat/team-message-preview.ts +87 -0
- package/src/web/components/chat/tool-cards.tsx +100 -23
- package/src/web/components/editor/audio-preview.tsx +6 -7
- package/src/web/components/editor/video-player/use-video-keyboard-shortcuts.ts +62 -0
- package/src/web/components/editor/video-player/video-player-controls.tsx +103 -0
- package/src/web/components/editor/video-player/video-player.tsx +190 -0
- package/src/web/components/editor/video-player/video-settings-menu.tsx +92 -0
- package/src/web/components/editor/video-player/video-transform.ts +49 -0
- package/src/web/components/editor/video-preview.tsx +75 -14
- package/src/web/components/explorer/file-tree.tsx +6 -0
- package/src/web/components/explorer/tree-node-context-menu.tsx +5 -1
- package/src/web/components/floating-window/window-content-registry.ts +5 -0
- package/src/web/components/floating-window/window-store-types.ts +1 -1
- package/src/web/components/os-explorer/actions/explorer-actions-upload.ts +96 -0
- package/src/web/components/os-explorer/actions/use-explorer-actions.ts +23 -2
- package/src/web/components/os-explorer/actions/use-explorer-upload-actions.tsx +41 -0
- package/src/web/components/os-explorer/dnd/use-drop-transfer.tsx +10 -1
- package/src/web/components/os-explorer/dnd/use-entry-row-dnd.ts +8 -1
- package/src/web/components/os-explorer/dnd/use-external-file-drop.ts +84 -0
- package/src/web/components/os-explorer/dnd/use-path-drop-target.ts +46 -3
- package/src/web/components/os-explorer/explorer-body.tsx +1 -1
- package/src/web/components/os-explorer/explorer-context-menu.tsx +10 -0
- package/src/web/components/os-explorer/explorer-dialogs.tsx +2 -0
- package/src/web/components/os-explorer/explorer-sidebar.tsx +10 -5
- package/src/web/components/os-explorer/explorer-toolbar.tsx +32 -2
- package/src/web/components/os-explorer/mobile/mobile-bottom-toolbar.tsx +5 -1
- package/src/web/components/os-explorer/upload/collect-dropped-entries.ts +81 -0
- package/src/web/components/os-explorer/upload/upload-queue.ts +79 -0
- package/src/web/components/os-explorer/upload/use-upload-picker.tsx +74 -0
- package/src/web/components/os-explorer/views/column-row.tsx +3 -1
- package/src/web/components/os-explorer/views/column-view-column.tsx +6 -1
- package/src/web/components/os-explorer/views/icons-view-tile.tsx +1 -1
- package/src/web/components/os-explorer/views/icons-view.tsx +5 -1
- package/src/web/components/os-explorer/views/list-row.tsx +1 -1
- package/src/web/components/os-explorer/views/list-view.tsx +5 -1
- package/src/web/components/shared/markdown-code-block.tsx +3 -7
- package/src/web/components/terminal/terminal-tab.tsx +19 -25
- package/src/web/hooks/use-chat.ts +77 -15
- package/src/web/hooks/use-team-activity-feed.ts +92 -0
- package/src/web/hooks/use-terminal-command-queue.ts +108 -0
- package/src/web/hooks/use-terminal.ts +45 -3
- package/src/web/lib/fs-api.ts +9 -0
- package/src/web/lib/fs-upload-xhr.ts +62 -0
- package/src/web/lib/media-url.ts +51 -0
- package/src/web/lib/open-terminal-at.ts +22 -0
- package/src/web/lib/run-in-terminal.ts +55 -0
- package/src/web/lib/send-to-chat.ts +118 -0
- package/src/web/lib/ws-auth.ts +13 -0
- package/src/web/lib/ws-client.ts +10 -5
- package/.release-run.sh +0 -5
- package/dist/web/assets/api-client-CaRE4HYh.js +0 -1
- package/dist/web/assets/api-settings-DBcXfeJ8.js +0 -1
- package/dist/web/assets/architecture-PBZL5I3N-B4J2-O8Q.js +0 -1
- package/dist/web/assets/audio-preview-BkNAEqcB.js +0 -1
- package/dist/web/assets/chat-tab-B-MEsHYp.js +0 -13
- package/dist/web/assets/code-editor-bC1KAEUA.js +0 -10
- package/dist/web/assets/dialog-CkI7rwrh.js +0 -1
- package/dist/web/assets/diff-viewer-BwElk4q9.js +0 -4
- package/dist/web/assets/explorer-body-DzdXBlWw.js +0 -2
- package/dist/web/assets/explorer-window-content-Dgl1WTNs.js +0 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-CtQ3yXN-.js +0 -1
- package/dist/web/assets/glide-data-grid-QZ_fgjIa.js +0 -138
- package/dist/web/assets/group-chat-tab-BbdVlKFv.js +0 -1
- package/dist/web/assets/index-D-xwjNyX.css +0 -2
- package/dist/web/assets/index-wd3FSHHn.js +0 -52
- package/dist/web/assets/info-3K5VOQVL-Cg0mIJn9.js +0 -1
- package/dist/web/assets/keybindings-store-Bp_c_C3z.js +0 -1
- package/dist/web/assets/markdown-renderer-2asl-3Kk.js +0 -1
- package/dist/web/assets/mobile-explorer-sheet-LWUDaNBV.js +0 -1
- package/dist/web/assets/notification-store-BasUnpt7.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-D79vAFR_.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-DYUOH68U.js +0 -1
- package/dist/web/assets/plus-9LatwJMx.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-B1eznNtd.js +0 -1
- package/dist/web/assets/settings-tab-vhatQ51-.js +0 -1
- package/dist/web/assets/sql-query-editor-BblB2Imt.js +0 -1
- package/dist/web/assets/system-monitor-tab-D8dy-RT_.js +0 -1
- package/dist/web/assets/terminal-tab-CfD22q5x.js +0 -3
- package/dist/web/assets/tool-cards-DNgw1yI6.js +0 -7
- package/dist/web/assets/treemap-KZPCXAKY-SeI2TxLs.js +0 -1
- package/dist/web/assets/use-is-mobile-DnFSkUG2.js +0 -1
- package/dist/web/assets/use-monaco-theme-DEbn-QT3.js +0 -1
- package/dist/web/assets/video-preview-DcUaFYyv.js +0 -1
- package/src/web/components/chat/team-activity-popover.tsx +0 -202
- /package/dist/web/assets/{abap-DrMyiWmK.js → abap-C1K0-wzc.js} +0 -0
- /package/dist/web/assets/{actionscript-3-BlSOyi0y.js → actionscript-3-CJhQVjLA.js} +0 -0
- /package/dist/web/assets/{ada-B_m96icB.js → ada-Bt8r9fME.js} +0 -0
- /package/dist/web/assets/{andromeeda-Ch3vOiZB.js → andromeeda-DF1I8qi3.js} +0 -0
- /package/dist/web/assets/{apache-CdsaXc1n.js → apache-CnlleE6P.js} +0 -0
- /package/dist/web/assets/{apex-0AnsBevk.js → apex-j0C6Xmk6.js} +0 -0
- /package/dist/web/assets/{api-client-rTAGdEKo.js → api-client-BSB14J4w.js} +0 -0
- /package/dist/web/assets/{applescript-CSxLolzy.js → applescript-DO7AnO8U.js} +0 -0
- /package/dist/web/assets/{apply-theme-CMQXnUAa.js → apply-theme-CNj1iA-v.js} +0 -0
- /package/dist/web/assets/{ara-DXZS0jA5.js → ara-i83AydZj.js} +0 -0
- /package/dist/web/assets/{asciidoc-DDy3pH2A.js → asciidoc-DbBA6-sF.js} +0 -0
- /package/dist/web/assets/{asm-Bd17hhqg.js → asm-B5S47Rgr.js} +0 -0
- /package/dist/web/assets/{aurora-x-C62HJRs-.js → aurora-x-De_IaSKw.js} +0 -0
- /package/dist/web/assets/{awk-Cc-nazni.js → awk-CfyLHXqS.js} +0 -0
- /package/dist/web/assets/{ayu-dark-BsfmNWCU.js → ayu-dark-DTLdZ1Si.js} +0 -0
- /package/dist/web/assets/{ayu-light-BZ4HLa4X.js → ayu-light-DTOfkzhu.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-Bhyjyiqr.js → ayu-mirage-DsAECCMv.js} +0 -0
- /package/dist/web/assets/{ballerina-QiWgir3v.js → ballerina-CumGp9A7.js} +0 -0
- /package/dist/web/assets/{bat-DxtlkwN3.js → bat-Ca2SBbYN.js} +0 -0
- /package/dist/web/assets/{beancount-Bt21X7M_.js → beancount-CqyXBwwF.js} +0 -0
- /package/dist/web/assets/{berry-Cksre7lO.js → berry-yl-kJr_H.js} +0 -0
- /package/dist/web/assets/{bibtex-DkakgDlR.js → bibtex-DoFFszjV.js} +0 -0
- /package/dist/web/assets/{bicep-8crmcyXU.js → bicep-CWPi4nfK.js} +0 -0
- /package/dist/web/assets/{bird2-CewQ2I_Z.js → bird2-DXew-ut0.js} +0 -0
- /package/dist/web/assets/{bot-nk1k3ELu.js → bot-CunPuEdW.js} +0 -0
- /package/dist/web/assets/{c-C_6zE8Ha.js → c-clbySDvd.js} +0 -0
- /package/dist/web/assets/{c3-DLWB9-dp.js → c3-B65jvSM1.js} +0 -0
- /package/dist/web/assets/{cadence-D8qYS6pR.js → cadence-Cm8tQTHN.js} +0 -0
- /package/dist/web/assets/{can-open-in-ppm-BzVXoV-d.js → can-open-in-ppm-Cu-XYIgu.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-Bh95lNRy.js → catppuccin-frappe-DLeGslh_.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-C1PlN3G0.js → catppuccin-latte-CR5GeHws.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-CldtgdK4.js → catppuccin-macchiato-p-XgjxhP.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-BiwqxX9A.js → catppuccin-mocha-B8QOAZLl.js} +0 -0
- /package/dist/web/assets/{clarity-CGiU22jY.js → clarity-DPulbvKH.js} +0 -0
- /package/dist/web/assets/{clojure-COIC3doh.js → clojure-DFuWS20u.js} +0 -0
- /package/dist/web/assets/{cmake-DWUEQfHv.js → cmake-DejCqcu4.js} +0 -0
- /package/dist/web/assets/{codeowners-BNHiAQea.js → codeowners-BwAyqWIH.js} +0 -0
- /package/dist/web/assets/{codeql-BuKaoS0j.js → codeql-DgSwFjqI.js} +0 -0
- /package/dist/web/assets/{common-lisp-D5IKbxsd.js → common-lisp-CxIVJCtf.js} +0 -0
- /package/dist/web/assets/{coq-BMVS-p94.js → coq-DLSjSnmf.js} +0 -0
- /package/dist/web/assets/{csharp-DMlbXbM4.js → csharp-C1HHzXBp.js} +0 -0
- /package/dist/web/assets/{css-CjkJC89X.js → css-VXsMY--y.js} +0 -0
- /package/dist/web/assets/{csv-DoNVBBf0.js → csv-BEbcJdHz.js} +0 -0
- /package/dist/web/assets/{csv-parser-DHvoTjMF.js → csv-parser-r-Nk1oHT.js} +0 -0
- /package/dist/web/assets/{cue-DoTRbBg-.js → cue-BkDnFqUD.js} +0 -0
- /package/dist/web/assets/{cypher-DVsNdTT3.js → cypher-1cMqojSQ.js} +0 -0
- /package/dist/web/assets/{d-EX7BBSrv.js → d-BnYjRXtH.js} +0 -0
- /package/dist/web/assets/{dark-plus-P_YTHwlh.js → dark-plus-XfbaH7kZ.js} +0 -0
- /package/dist/web/assets/{dart-Do-rgU4S.js → dart-Ca7s-8hK.js} +0 -0
- /package/dist/web/assets/{data-grid-types-CUx8cusN.js → data-grid-types-BXwlFMzs.js} +0 -0
- /package/dist/web/assets/{dax-DxOieacu.js → dax-CmuOw-mY.js} +0 -0
- /package/dist/web/assets/{desktop-CvdV7SBf.js → desktop-C2gJ6Ovb.js} +0 -0
- /package/dist/web/assets/{diff-CNOetGen.js → diff-BCEo1Ej7.js} +0 -0
- /package/dist/web/assets/{dist-CMfLpPW_.js → dist-CUPbqNnL.js} +0 -0
- /package/dist/web/assets/{dist-DduBIVkD.js → dist-DOlBnxFX.js} +0 -0
- /package/dist/web/assets/{docker-DAlG4_q-.js → docker-DN2jlyAh.js} +0 -0
- /package/dist/web/assets/{dotenv-Dh3qf6yx.js → dotenv-NExMY2kS.js} +0 -0
- /package/dist/web/assets/{dracula-baAGmJYG.js → dracula-B9lbE01y.js} +0 -0
- /package/dist/web/assets/{dracula-soft-l7ZIyums.js → dracula-soft-CMBBfKF_.js} +0 -0
- /package/dist/web/assets/{dream-maker-DeRjdBn8.js → dream-maker-DEyDwFsd.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-CB05-jQA.js → emacs-lisp-D_qP2zS6.js} +0 -0
- /package/dist/web/assets/{everforest-dark-CT-llQBT.js → everforest-dark-DbHa2U-p.js} +0 -0
- /package/dist/web/assets/{everforest-light-ByPJkTT7.js → everforest-light-BISkJchP.js} +0 -0
- /package/dist/web/assets/{fennel-CeMarbvn.js → fennel-6B22SfJR.js} +0 -0
- /package/dist/web/assets/{file-exclamation-point-COAwgNGw.js → file-exclamation-point-a8f3_w7a.js} +0 -0
- /package/dist/web/assets/{fish-BYrt6Xtb.js → fish-CubIIvJD.js} +0 -0
- /package/dist/web/assets/{fluent-Cr5VcAwh.js → fluent-DF55zQ09.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-DQmKtrLa.js → fortran-free-form-DvOu8jAt.js} +0 -0
- /package/dist/web/assets/{gdscript-QTDKjzhY.js → gdscript-DCPxdLpq.js} +0 -0
- /package/dist/web/assets/{gdshader-Chr-5UYt.js → gdshader-CTZ381FO.js} +0 -0
- /package/dist/web/assets/{genie-kWHMWnt0.js → genie-C_QDtvgU.js} +0 -0
- /package/dist/web/assets/{gherkin-DtEBQFUo.js → gherkin-BcvK42tF.js} +0 -0
- /package/dist/web/assets/{github-dark-B5aiUta2.js → github-dark-C9afs_4w.js} +0 -0
- /package/dist/web/assets/{github-dark-default-BkxtsTqR.js → github-dark-default-CKGVrl3Z.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-B9QjR_0K.js → github-dark-dimmed-C3dQZ_LC.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-D6bO-5c0.js → github-dark-high-contrast-DW78QukY.js} +0 -0
- /package/dist/web/assets/{github-light-Cg2ZW_CJ.js → github-light-BnP2dznS.js} +0 -0
- /package/dist/web/assets/{github-light-default-eD7qUVlQ.js → github-light-default-C2fPZzPG.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-CFnlSVjd.js → github-light-high-contrast-BzIuUFR2.js} +0 -0
- /package/dist/web/assets/{gleam-BpYoOqIT.js → gleam-BpeKwEIO.js} +0 -0
- /package/dist/web/assets/{gn-BxwtZPau.js → gn-nUb_Mit0.js} +0 -0
- /package/dist/web/assets/{gnuplot-CRyiZDfl.js → gnuplot-D7I0v20p.js} +0 -0
- /package/dist/web/assets/{go-Dw1Qx94W.js → go-D7Qqska7.js} +0 -0
- /package/dist/web/assets/{groovy-zq_SbWk-.js → groovy-DS-pne5-.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-DbbNy8-Q.js → gruvbox-dark-hard-C0W01fsq.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-BQZ7Kj6C.js → gruvbox-dark-medium-Bqo6fQbg.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-vNavErXi.js → gruvbox-dark-soft-D-XSM_fu.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-AOFbCd7i.js → gruvbox-light-hard-IVAwMJRl.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-DqtxND6H.js → gruvbox-light-medium-38ATiG7i.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-Cg0basu6.js → gruvbox-light-soft-DnZr3c_0.js} +0 -0
- /package/dist/web/assets/{haskell-CcsmcOez.js → haskell-uQcywkDH.js} +0 -0
- /package/dist/web/assets/{haxe-BimYY9X4.js → haxe-c6bI4_GT.js} +0 -0
- /package/dist/web/assets/{hcl-CTrXCK40.js → hcl-CQXTiEXq.js} +0 -0
- /package/dist/web/assets/{hjson-CmqqU6Qg.js → hjson-ChETf2bz.js} +0 -0
- /package/dist/web/assets/{hlsl-CuJtX_uf.js → hlsl-BMC4JGoE.js} +0 -0
- /package/dist/web/assets/{horizon-BGeSjDYJ.js → horizon-BusFlhLW.js} +0 -0
- /package/dist/web/assets/{horizon-bright-GYMgd3R0.js → horizon-bright-2oD0Mz7W.js} +0 -0
- /package/dist/web/assets/{houston--JD_5r2q.js → houston-DdbbjqFg.js} +0 -0
- /package/dist/web/assets/{hy-C9ILOiqk.js → hy-D_SOuqw9.js} +0 -0
- /package/dist/web/assets/{image-gallery-BWFpZAAP.js → image-gallery-CrM5fHKy.js} +0 -0
- /package/dist/web/assets/{imba-B6F3yus5.js → imba-BxLOHO5I.js} +0 -0
- /package/dist/web/assets/{ini-BfkQswMZ.js → ini-ox-CFcg0.js} +0 -0
- /package/dist/web/assets/{java-DEH5avQ1.js → java-Bzo8yIal.js} +0 -0
- /package/dist/web/assets/{javascript-Dr4yHuV2.js → javascript-DHuz9VXn.js} +0 -0
- /package/dist/web/assets/{json-BuR35ewf.js → json-0_y80FD5.js} +0 -0
- /package/dist/web/assets/{json5-Ny9ZiJAC.js → json5-CEQ50pGM.js} +0 -0
- /package/dist/web/assets/{jsonc-zYVuoZkR.js → jsonc-CfrLEAKA.js} +0 -0
- /package/dist/web/assets/{jsonl-B9xthb_H.js → jsonl-fKbrANC2.js} +0 -0
- /package/dist/web/assets/{jsonnet-CCoLJbMP.js → jsonnet-DKbkPaQ2.js} +0 -0
- /package/dist/web/assets/{jssm-W0GDlQXi.js → jssm-Dxxx1Hqu.js} +0 -0
- /package/dist/web/assets/{jsx-BrLJpWC-.js → jsx-DlJL-Oj3.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-CuVwt_MO.js → kanagawa-dragon-CwN4SV1c.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-B3W_617P.js → kanagawa-lotus-BHltayiE.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-CEx4MP5W.js → kanagawa-wave-D-KXPjw6.js} +0 -0
- /package/dist/web/assets/{kdl-DilRejnB.js → kdl-DvtoJdFo.js} +0 -0
- /package/dist/web/assets/{kotlin-Bq5JtKaa.js → kotlin-CTS4MLcx.js} +0 -0
- /package/dist/web/assets/{kusto-Bhp2KYog.js → kusto-HtSE_sKm.js} +0 -0
- /package/dist/web/assets/{laserwave-WA_7c5hu.js → laserwave-DaXZG9ge.js} +0 -0
- /package/dist/web/assets/{lean-AEGcXwS-.js → lean-BYtGUfWx.js} +0 -0
- /package/dist/web/assets/{less-NPqH-26u.js → less-BoxmU_Mk.js} +0 -0
- /package/dist/web/assets/{lib-BFetOULu.js → lib-BzxL1ARZ.js} +0 -0
- /package/dist/web/assets/{libesm-tR4XlhMj.js → libesm-ah-mr-sh.js} +0 -0
- /package/dist/web/assets/{light-plus-B4xW7cgY.js → light-plus-Bt5CyUuo.js} +0 -0
- /package/dist/web/assets/{llvm-CPyWNcDE.js → llvm-CSdk9q9V.js} +0 -0
- /package/dist/web/assets/{log-CeQmiQSz.js → log-B-kp_3CL.js} +0 -0
- /package/dist/web/assets/{logo-BO0VrjBm.js → logo-DdIsXFDO.js} +0 -0
- /package/dist/web/assets/{luau-B6GT9kA1.js → luau-DUBpLlzQ.js} +0 -0
- /package/dist/web/assets/{make-CwfmN7e_.js → make-B3JVjoW_.js} +0 -0
- /package/dist/web/assets/{markdown-Bbe4FlLp.js → markdown-Seon0vHs.js} +0 -0
- /package/dist/web/assets/{material-theme-iD9XbfsB.js → material-theme-Nq-ChX1P.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-u7M3XGe7.js → material-theme-darker-CPV4ayXJ.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-BGdI48zn.js → material-theme-lighter-0kyjYqEd.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-_mk62F5q.js → material-theme-ocean-DGpAp5co.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-CxFbDyAu.js → material-theme-palenight-B0AUn0NG.js} +0 -0
- /package/dist/web/assets/{matlab-Z0RUE3V_.js → matlab-C2waytxs.js} +0 -0
- /package/dist/web/assets/{mdx-BZ5wPYzV.js → mdx-DAis6R6I.js} +0 -0
- /package/dist/web/assets/{mermaid-CY1_aP-h.js → mermaid-_rnT2YGD.js} +0 -0
- /package/dist/web/assets/{min-dark-DKWtxOre.js → min-dark-BSSjchUB.js} +0 -0
- /package/dist/web/assets/{min-light-e1iwHDfP.js → min-light-DomAFQsa.js} +0 -0
- /package/dist/web/assets/{mipsasm-BiDfQ4ir.js → mipsasm-bBgtvPyG.js} +0 -0
- /package/dist/web/assets/{mojo-DteFEHsj.js → mojo-Cp9BayW0.js} +0 -0
- /package/dist/web/assets/{monokai-BgPbE9xZ.js → monokai-CL_9gbmn.js} +0 -0
- /package/dist/web/assets/{moonbit-mEbRp-mA.js → moonbit-BS_fcr-P.js} +0 -0
- /package/dist/web/assets/{move-CogqZw7A.js → move-C79AH45U.js} +0 -0
- /package/dist/web/assets/{narrat-BD2qjmy1.js → narrat-CJ5s3BDf.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-BNX8GOD_.js → nextflow-groovy-ZHa4JrPJ.js} +0 -0
- /package/dist/web/assets/{night-owl-ed3GbziD.js → night-owl-Jkf9zFQK.js} +0 -0
- /package/dist/web/assets/{night-owl-light-B0j7O0Wn.js → night-owl-light-DRPeaG5J.js} +0 -0
- /package/dist/web/assets/{nix-DFDbcQQm.js → nix-D2Jet9DN.js} +0 -0
- /package/dist/web/assets/{nord-D93TxEQi.js → nord-CREVs22j.js} +0 -0
- /package/dist/web/assets/{nushell-3_H_XKja.js → nushell-CAiDi_mR.js} +0 -0
- /package/dist/web/assets/{objective-c-BM3u6nlm.js → objective-c-CVkmJkC1.js} +0 -0
- /package/dist/web/assets/{objective-cpp-DZ73h42g.js → objective-cpp-DIKDO1Ly.js} +0 -0
- /package/dist/web/assets/{ocaml-B1PU5gmh.js → ocaml-R9qtGQhs.js} +0 -0
- /package/dist/web/assets/{odin-D14L6aRL.js → odin-DTYNQqVr.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-Bj-94Z8v.js → one-dark-pro-BSLWUJn5.js} +0 -0
- /package/dist/web/assets/{one-light-DTdGWyOZ.js → one-light-DbkRXG3t.js} +0 -0
- /package/dist/web/assets/{openscad-Ciq554Sj.js → openscad-BlPcSnmT.js} +0 -0
- /package/dist/web/assets/{pascal-Bfd4qdGi.js → pascal-B1Y46ZZB.js} +0 -0
- /package/dist/web/assets/{pkl-CTurDUfj.js → pkl-BhJSJbFv.js} +0 -0
- /package/dist/web/assets/{plastic-BLQfZXQp.js → plastic-BzxsCTpi.js} +0 -0
- /package/dist/web/assets/{plsql-DyYfP9kQ.js → plsql-DBba7dyP.js} +0 -0
- /package/dist/web/assets/{po-CgXdT8vQ.js → po-BvgLlnNo.js} +0 -0
- /package/dist/web/assets/{poimandres-DOg5fK6s.js → poimandres-DUaI_1JP.js} +0 -0
- /package/dist/web/assets/{polar-Dv4aoL6X.js → polar-C7uILwJn.js} +0 -0
- /package/dist/web/assets/{postcss-DxugHnJD.js → postcss-BgJlpFdw.js} +0 -0
- /package/dist/web/assets/{powerquery-CR3kzRyX.js → powerquery-Dn1MIpZu.js} +0 -0
- /package/dist/web/assets/{powershell-BE91xJQB.js → powershell-Bo-DYzOS.js} +0 -0
- /package/dist/web/assets/{prisma-B_3yUlRQ.js → prisma-CTLs5IdT.js} +0 -0
- /package/dist/web/assets/{prolog-DcT781Ht.js → prolog-QRGun3eG.js} +0 -0
- /package/dist/web/assets/{proto-CSf-w5k2.js → proto-B7PI7apn.js} +0 -0
- /package/dist/web/assets/{puppet-CLGO6QWl.js → puppet-CBq0tLrP.js} +0 -0
- /package/dist/web/assets/{purescript-Bah2McKd.js → purescript-DFewOQb2.js} +0 -0
- /package/dist/web/assets/{python-DUH8qy7N.js → python-iWuxKXvT.js} +0 -0
- /package/dist/web/assets/{qmldir-YIsHnjKq.js → qmldir-cXiW3AsF.js} +0 -0
- /package/dist/web/assets/{qss-CLmoVNA4.js → qss-DASwAbBL.js} +0 -0
- /package/dist/web/assets/{r-Pon-b-vz.js → r-TU2eaIPw.js} +0 -0
- /package/dist/web/assets/{racket-BA09P5Kg.js → racket-SkRKqrLY.js} +0 -0
- /package/dist/web/assets/{raku-DlpzU7Fe.js → raku-D31lthkZ.js} +0 -0
- /package/dist/web/assets/{react-w6wINGnd.js → react-I_EwPIZi.js} +0 -0
- /package/dist/web/assets/{red-l7VuCR6d.js → red-CTcQZevb.js} +0 -0
- /package/dist/web/assets/{reg-g_k7gQEr.js → reg-D8YAsTGf.js} +0 -0
- /package/dist/web/assets/{regexp-CT17B7I7.js → regexp-CD2uvAWx.js} +0 -0
- /package/dist/web/assets/{rel-DkPCS7Bp.js → rel-CAaI-1fg.js} +0 -0
- /package/dist/web/assets/{resolve-theme-DdB7Yo5Z.js → resolve-theme-CJvkL8hU.js} +0 -0
- /package/dist/web/assets/{riscv-CYuFTw30.js → riscv-DR-hJVIj.js} +0 -0
- /package/dist/web/assets/{ron-cY7u_yEu.js → ron-CuUCJ0n4.js} +0 -0
- /package/dist/web/assets/{rose-pine-Cr_h_Ubo.js → rose-pine-aFHxW48i.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-rRewaSZg.js → rose-pine-dawn-Bqz2sBRY.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-3VX5Xwca.js → rose-pine-moon-wqyh0an4.js} +0 -0
- /package/dist/web/assets/{rosmsg-Du4ie5PU.js → rosmsg-CI1ywimO.js} +0 -0
- /package/dist/web/assets/{rust-B7xWL-Eh.js → rust-p7Imk4G_.js} +0 -0
- /package/dist/web/assets/{sass-oXbOG8de.js → sass-C8JfaqCV.js} +0 -0
- /package/dist/web/assets/{save-C4z1p51e.js → save-DRPrDfTt.js} +0 -0
- /package/dist/web/assets/{scala-nlZJhKHf.js → scala-DNxCW1By.js} +0 -0
- /package/dist/web/assets/{scheme-FZ9_Zy8D.js → scheme-BYuUPJoL.js} +0 -0
- /package/dist/web/assets/{sdbl-D_lyvXiu.js → sdbl-DbPeJPUr.js} +0 -0
- /package/dist/web/assets/{shellscript-DRWRboAd.js → shellscript-DMiHlR3q.js} +0 -0
- /package/dist/web/assets/{shield-check-C5laObJv.js → shield-check-8GObuUAn.js} +0 -0
- /package/dist/web/assets/{shield-off-DULFtyLS.js → shield-off-egKAZEwR.js} +0 -0
- /package/dist/web/assets/{slack-dark-BGk2uVHu.js → slack-dark-C4xGcQXI.js} +0 -0
- /package/dist/web/assets/{slack-ochin-PAoSX041.js → slack-ochin-BzgRt_wm.js} +0 -0
- /package/dist/web/assets/{smalltalk-qP0zvICo.js → smalltalk-LDeL9PYH.js} +0 -0
- /package/dist/web/assets/{snazzy-light-B7uccpH6.js → snazzy-light-CXE7a5j_.js} +0 -0
- /package/dist/web/assets/{solarized-dark-CbICLZs3.js → solarized-dark-DgUhY74x.js} +0 -0
- /package/dist/web/assets/{solarized-light-CprWhyjj.js → solarized-light-DD9C-H-9.js} +0 -0
- /package/dist/web/assets/{solidity-B7pcm2K6.js → solidity-CAbDB4D4.js} +0 -0
- /package/dist/web/assets/{splunk-Co2LL4J_.js → splunk-kQREPfIc.js} +0 -0
- /package/dist/web/assets/{sql-cETIdGnT.js → sql-CBzeNAD8.js} +0 -0
- /package/dist/web/assets/{ssh-config-DETG6JCD.js → ssh-config-L1euxrsM.js} +0 -0
- /package/dist/web/assets/{stylus-tmTre2-O.js → stylus-DvBnYniP.js} +0 -0
- /package/dist/web/assets/{swift-BeKQbULV.js → swift-DF5NDQp6.js} +0 -0
- /package/dist/web/assets/{synthwave-84-eCL4-Xdn.js → synthwave-84-DbBhB_Hq.js} +0 -0
- /package/dist/web/assets/{system-verilog-CviwWvEx.js → system-verilog-D8s2ZW_k.js} +0 -0
- /package/dist/web/assets/{systemd-WuoFIbBS.js → systemd-a5-XZJsG.js} +0 -0
- /package/dist/web/assets/{table-CHmxuh6M.js → table-BX2ZrJfM.js} +0 -0
- /package/dist/web/assets/{talonscript-B9VBu7VI.js → talonscript-BLa0URTW.js} +0 -0
- /package/dist/web/assets/{tasl-CN7r11ky.js → tasl-DIoV4XcC.js} +0 -0
- /package/dist/web/assets/{tcl-e1cdhe3h.js → tcl-ztYAdXfQ.js} +0 -0
- /package/dist/web/assets/{terraform-BEP0mfa_.js → terraform-DvpCCiOZ.js} +0 -0
- /package/dist/web/assets/{tokyo-night-BfA_dA37.js → tokyo-night-BkHlYUv0.js} +0 -0
- /package/dist/web/assets/{toml-BrDIfNnt.js → toml-acIrxos6.js} +0 -0
- /package/dist/web/assets/{tsv-CyfGyE4i.js → tsv-BJB5EVCT.js} +0 -0
- /package/dist/web/assets/{tsx-BrFA8Iwf.js → tsx-B1MmXGT3.js} +0 -0
- /package/dist/web/assets/{turtle-9GBtR0mP.js → turtle-DFceTiqd.js} +0 -0
- /package/dist/web/assets/{typescript-BuTRZ65V.js → typescript-Dz9wU5Y1.js} +0 -0
- /package/dist/web/assets/{typespec-CRiNNRXF.js → typespec-CPuYZijj.js} +0 -0
- /package/dist/web/assets/{typst-CmpTnnkl.js → typst-CfsCIYv8.js} +0 -0
- /package/dist/web/assets/{utils-B9H0d3Fh.js → utils-DoY4yTP-.js} +0 -0
- /package/dist/web/assets/{v-DnIi2aab.js → v-CGo0jcXA.js} +0 -0
- /package/dist/web/assets/{vala-B7VxCNZP.js → vala-AsSR0hrb.js} +0 -0
- /package/dist/web/assets/{vb-DGoQ3pBT.js → vb-C7tvbXv1.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-ClRVIJ-k.js → vendor-xterm-BeaIjRrv.js} +0 -0
- /package/dist/web/assets/{verilog-zGOC4qwV.js → verilog--a33ND-p.js} +0 -0
- /package/dist/web/assets/{vesper-DXR9-06q.js → vesper-B_Z0h4pn.js} +0 -0
- /package/dist/web/assets/{vhdl-CCO0oz0l.js → vhdl-CWL5dZPN.js} +0 -0
- /package/dist/web/assets/{viml-Dxwr-QNN.js → viml-BglmT14Y.js} +0 -0
- /package/dist/web/assets/{vitesse-black-Bhah7RxE.js → vitesse-black-RKFsSqQI.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-CGK6XVwc.js → vitesse-dark-D7zDWNmc.js} +0 -0
- /package/dist/web/assets/{vitesse-light-ne5kfw8h.js → vitesse-light-MAp87W5b.js} +0 -0
- /package/dist/web/assets/{vyper-ErDFqVoP.js → vyper-CgCBYg1G.js} +0 -0
- /package/dist/web/assets/{wasm-DtWvUWGr.js → wasm-BOG7ZeTT.js} +0 -0
- /package/dist/web/assets/{wasm-Bd258nS1.js → wasm-Bwl4txwp.js} +0 -0
- /package/dist/web/assets/{wenyan-EZe1IEYT.js → wenyan-DpShPKXZ.js} +0 -0
- /package/dist/web/assets/{wgsl-B1o5_I_9.js → wgsl-BakcCblK.js} +0 -0
- /package/dist/web/assets/{wikitext-C_rwp8An.js → wikitext-NroRWVAO.js} +0 -0
- /package/dist/web/assets/{wit-gbYtF3rY.js → wit-B5CM2pg6.js} +0 -0
- /package/dist/web/assets/{wolfram-DrcQFe2n.js → wolfram-7MTFBJpR.js} +0 -0
- /package/dist/web/assets/{x-B1qHmLdR.js → x-BcqfTY_7.js} +0 -0
- /package/dist/web/assets/{yaml-CzDAObLX.js → yaml-Bwr01G2K.js} +0 -0
- /package/dist/web/assets/{zenscript-B-J1phtg.js → zenscript-Dj8GATvi.js} +0 -0
- /package/dist/web/assets/{zig-BlzNia0O.js → zig-LAE-fbS-.js} +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Roster for an agent team, working members first.
|
|
3
|
+
*
|
|
4
|
+
* Own scroll container so the roster stays put while the conversation grows —
|
|
5
|
+
* the two used to share one scroll and the members were pushed out of view.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Loader2 } from "lucide-react";
|
|
9
|
+
import { cn } from "@/lib/utils";
|
|
10
|
+
import type { TeamMemberActivity } from "@/hooks/use-team-activity-feed";
|
|
11
|
+
import { TeamMemberActivityRow } from "./team-member-activity-row";
|
|
12
|
+
|
|
13
|
+
interface TeamMemberListProps {
|
|
14
|
+
members: TeamMemberActivity[];
|
|
15
|
+
loading: boolean;
|
|
16
|
+
onOpenMember: (name: string) => void;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function TeamMemberList({ members, loading, onOpenMember, className }: TeamMemberListProps) {
|
|
21
|
+
if (members.length === 0) {
|
|
22
|
+
return (
|
|
23
|
+
<div className={cn("flex items-center justify-center gap-2 text-xs text-text-subtle py-4", className)}>
|
|
24
|
+
{loading ? (
|
|
25
|
+
<>
|
|
26
|
+
<Loader2 className="size-3 animate-spin" />
|
|
27
|
+
Reading member sessions…
|
|
28
|
+
</>
|
|
29
|
+
) : (
|
|
30
|
+
"No member sessions recorded"
|
|
31
|
+
)}
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div className={cn("overflow-y-auto space-y-0.5", className)}>
|
|
38
|
+
{members.map((member) => (
|
|
39
|
+
<TeamMemberActivityRow key={member.name} member={member} onOpen={onOpenMember} />
|
|
40
|
+
))}
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Floating-window body replaying one teammate's whole work session.
|
|
3
|
+
*
|
|
4
|
+
* The transcript is fetched on demand and only for the member being opened —
|
|
5
|
+
* a single teammate transcript reaches several MB, so loading all of a team's
|
|
6
|
+
* transcripts up front is not an option. Steps render through the same
|
|
7
|
+
* `SubagentChildren` view the inline Agent card uses, so a teammate's session
|
|
8
|
+
* looks identical wherever it is read.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
|
+
import { Loader2, RefreshCw } from "lucide-react";
|
|
13
|
+
import { api } from "@/lib/api-client";
|
|
14
|
+
import { cn } from "@/lib/utils";
|
|
15
|
+
import type { ChatEvent } from "../../../types/chat";
|
|
16
|
+
import type { WindowContentProps } from "@/components/floating-window/window-content-registry";
|
|
17
|
+
import { SubagentChildren } from "./tool-cards";
|
|
18
|
+
|
|
19
|
+
/** Payload the team panel puts on the window when opening it. */
|
|
20
|
+
export interface TeamMemberWindowPayload {
|
|
21
|
+
teamName: string;
|
|
22
|
+
memberName: string;
|
|
23
|
+
projectName?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default function TeamMemberWindowContent({ payload }: WindowContentProps) {
|
|
27
|
+
const { teamName, memberName, projectName } = (payload ?? {}) as unknown as TeamMemberWindowPayload;
|
|
28
|
+
const [events, setEvents] = useState<ChatEvent[]>([]);
|
|
29
|
+
const [loading, setLoading] = useState(true);
|
|
30
|
+
const [error, setError] = useState<string | null>(null);
|
|
31
|
+
// Bumped by the refresh button; a working teammate keeps appending steps.
|
|
32
|
+
const [reloadKey, setReloadKey] = useState(0);
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!teamName || !memberName) {
|
|
36
|
+
setError("Missing team or member");
|
|
37
|
+
setLoading(false);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
let cancelled = false;
|
|
41
|
+
setLoading(true);
|
|
42
|
+
setError(null);
|
|
43
|
+
api
|
|
44
|
+
.get<{ events?: ChatEvent[] }>(
|
|
45
|
+
`/api/teams/${encodeURIComponent(teamName)}/members/${encodeURIComponent(memberName)}/transcript`,
|
|
46
|
+
)
|
|
47
|
+
.then((res) => {
|
|
48
|
+
if (cancelled) return;
|
|
49
|
+
setEvents(res?.events ?? []);
|
|
50
|
+
})
|
|
51
|
+
.catch(() => {
|
|
52
|
+
if (!cancelled) setError("Could not read this member's session");
|
|
53
|
+
})
|
|
54
|
+
.finally(() => {
|
|
55
|
+
if (!cancelled) setLoading(false);
|
|
56
|
+
});
|
|
57
|
+
return () => { cancelled = true; };
|
|
58
|
+
}, [teamName, memberName, reloadKey]);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div className="flex flex-col h-full min-h-0 bg-surface">
|
|
62
|
+
<div className="flex items-center gap-2 px-3 py-1.5 border-b border-border/30 shrink-0">
|
|
63
|
+
<span className="text-xs font-medium truncate">{memberName}</span>
|
|
64
|
+
<span className="text-[10px] text-text-subtle">
|
|
65
|
+
{events.length > 0 ? `${events.length} steps` : ""}
|
|
66
|
+
</span>
|
|
67
|
+
<button
|
|
68
|
+
type="button"
|
|
69
|
+
onClick={() => setReloadKey((k) => k + 1)}
|
|
70
|
+
className="ml-auto text-text-subtle hover:text-foreground p-1 shrink-0"
|
|
71
|
+
aria-label="Reload session"
|
|
72
|
+
>
|
|
73
|
+
<RefreshCw className={cn("size-3", loading && "animate-spin")} />
|
|
74
|
+
</button>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
{loading && events.length === 0 ? (
|
|
78
|
+
<div className="flex-1 flex items-center justify-center gap-2 text-xs text-text-subtle">
|
|
79
|
+
<Loader2 className="size-3 animate-spin" />
|
|
80
|
+
Loading session…
|
|
81
|
+
</div>
|
|
82
|
+
) : error ? (
|
|
83
|
+
<div className="flex-1 flex items-center justify-center text-xs text-error px-4 text-center">{error}</div>
|
|
84
|
+
) : events.length === 0 ? (
|
|
85
|
+
<div className="flex-1 flex items-center justify-center text-xs text-text-subtle">
|
|
86
|
+
This member has no recorded session
|
|
87
|
+
</div>
|
|
88
|
+
) : (
|
|
89
|
+
<SubagentChildren
|
|
90
|
+
events={events}
|
|
91
|
+
projectName={projectName}
|
|
92
|
+
className="flex-1 min-h-0 overflow-y-auto px-3 py-2 space-y-1"
|
|
93
|
+
/>
|
|
94
|
+
)}
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Badge vocabulary for agent-team messages.
|
|
3
|
+
*
|
|
4
|
+
* The team activity panel, the activity popover and the SendMessage tool card all
|
|
5
|
+
* label the same message kinds, so the map lives here instead of being copied per
|
|
6
|
+
* surface. Keys match `TeamMessageItem.parsedType` (see `src/types/team.ts`) and the
|
|
7
|
+
* protocol `type` a SendMessage payload can carry.
|
|
8
|
+
*/
|
|
9
|
+
export const TYPE_BADGES: Record<string, { label: string; className: string }> = {
|
|
10
|
+
task_assignment: { label: "task", className: "bg-primary/20 text-primary" },
|
|
11
|
+
idle_notification: { label: "idle", className: "bg-warning/20 text-warning" },
|
|
12
|
+
completion: { label: "done", className: "bg-success/20 text-success" },
|
|
13
|
+
shutdown_request: { label: "shutdown", className: "bg-error/20 text-error" },
|
|
14
|
+
shutdown_approved: { label: "shutdown ✓", className: "bg-text-3/20 text-text-3" },
|
|
15
|
+
shutdown_response: { label: "shutdown reply", className: "bg-text-3/20 text-text-3" },
|
|
16
|
+
plan_approval_request: { label: "plan review", className: "bg-primary/20 text-primary" },
|
|
17
|
+
plan_approval_response: { label: "plan reply", className: "bg-primary/20 text-primary" },
|
|
18
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat history for an agent team: the lead's task assignments merged with the
|
|
3
|
+
* replies teammates sent back.
|
|
4
|
+
*
|
|
5
|
+
* Split out of the panel so Members and Messages each own their own scroll
|
|
6
|
+
* container — sharing one made the member list scroll away as soon as the
|
|
7
|
+
* conversation grew.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { useEffect, useRef } from "react";
|
|
11
|
+
import { cn } from "@/lib/utils";
|
|
12
|
+
import type { TeamMessageItem } from "@/hooks/use-chat";
|
|
13
|
+
import { TYPE_BADGES } from "./team-message-badges";
|
|
14
|
+
import { previewTeamMessage } from "./team-message-preview";
|
|
15
|
+
|
|
16
|
+
interface TeamMessageListProps {
|
|
17
|
+
messages: TeamMessageItem[];
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function TeamMessageList({ messages, className }: TeamMessageListProps) {
|
|
22
|
+
const endRef = useRef<HTMLDivElement>(null);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
endRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
26
|
+
}, [messages.length]);
|
|
27
|
+
|
|
28
|
+
if (messages.length === 0) {
|
|
29
|
+
return <p className={cn("text-xs text-text-subtle text-center py-4", className)}>No messages yet</p>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div className={cn("overflow-y-auto", className)}>
|
|
34
|
+
<div className="space-y-2">
|
|
35
|
+
{messages.map((msg, i) => {
|
|
36
|
+
const badge = msg.parsedType ? TYPE_BADGES[msg.parsedType] : null;
|
|
37
|
+
const { title, detail, taskId } = previewTeamMessage(msg.text, msg.summary);
|
|
38
|
+
return (
|
|
39
|
+
<div key={`${msg.timestamp}-${i}`} className="text-xs">
|
|
40
|
+
<div className="flex items-center gap-1 text-text-subtle">
|
|
41
|
+
<span className="font-medium" style={safeColor(msg.color)}>
|
|
42
|
+
{msg.from}
|
|
43
|
+
</span>
|
|
44
|
+
<span>→</span>
|
|
45
|
+
<span>{msg.to}</span>
|
|
46
|
+
<span className="ml-auto text-[10px]">{formatTime(msg.timestamp)}</span>
|
|
47
|
+
</div>
|
|
48
|
+
<div className="mt-0.5 text-foreground/90 break-words">
|
|
49
|
+
{badge && (
|
|
50
|
+
<span className={cn("inline-block px-1 py-0 rounded text-[9px] mr-1", badge.className)}>
|
|
51
|
+
{badge.label}
|
|
52
|
+
</span>
|
|
53
|
+
)}
|
|
54
|
+
{taskId && (
|
|
55
|
+
<span className="inline-block px-1 py-0 rounded text-[9px] mr-1 bg-surface-elevated text-text-subtle">
|
|
56
|
+
#{taskId}
|
|
57
|
+
</span>
|
|
58
|
+
)}
|
|
59
|
+
{title}
|
|
60
|
+
</div>
|
|
61
|
+
{detail && (
|
|
62
|
+
<div className="mt-0.5 text-[11px] text-text-subtle break-words line-clamp-2">{detail}</div>
|
|
63
|
+
)}
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
})}
|
|
67
|
+
<div ref={endRef} />
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function formatTime(timestamp: string): string {
|
|
74
|
+
try {
|
|
75
|
+
return new Date(timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
76
|
+
} catch {
|
|
77
|
+
return "";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Sanitize color value to prevent CSS injection */
|
|
82
|
+
function safeColor(color?: string): React.CSSProperties | undefined {
|
|
83
|
+
if (!color) return undefined;
|
|
84
|
+
if (/^#[0-9a-fA-F]{3,8}$/.test(color) || /^[a-zA-Z]{3,20}$/.test(color)) {
|
|
85
|
+
return { color };
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Readable preview for an agent-team inbox message.
|
|
3
|
+
*
|
|
4
|
+
* A teammate's `text` is usually a JSON protocol payload, not prose — a
|
|
5
|
+
* task_assignment carries `{ type, taskId, subject, description, assignedBy }`.
|
|
6
|
+
* Rendering that raw dumps a wall of escaped JSON into the activity panel, so
|
|
7
|
+
* every payload is reduced to a headline plus an optional body here.
|
|
8
|
+
*
|
|
9
|
+
* Pure module: the panel stays a thin renderer and this stays unit-testable.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** Field order for the one-line headline. First non-empty wins. */
|
|
13
|
+
const TITLE_FIELDS = ["subject", "summary", "text", "message", "content", "description", "reason", "feedback"];
|
|
14
|
+
|
|
15
|
+
/** Fields worth showing under the headline when they say more than it does. */
|
|
16
|
+
const DETAIL_FIELDS = ["description", "message", "content", "reason", "feedback"];
|
|
17
|
+
|
|
18
|
+
/** Structural keys that describe the envelope, never the content. */
|
|
19
|
+
const ENVELOPE_KEYS = new Set(["type", "taskId", "task_id", "assignedBy", "assigned_by", "timestamp", "request_id", "requestId"]);
|
|
20
|
+
|
|
21
|
+
export interface TeamMessagePreview {
|
|
22
|
+
/** One-line headline — never raw JSON. */
|
|
23
|
+
title: string;
|
|
24
|
+
/** Longer body when the payload carries one beyond the headline. */
|
|
25
|
+
detail?: string;
|
|
26
|
+
/** Task id from a task_assignment, for a compact `#4` chip. */
|
|
27
|
+
taskId?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const str = (v: unknown): string => (typeof v === "string" ? v.trim() : v == null ? "" : String(v));
|
|
31
|
+
|
|
32
|
+
/** First non-empty value among `fields`, plus the key it came from. */
|
|
33
|
+
function pick(obj: Record<string, unknown>, fields: string[], skip?: string): { key: string; value: string } | null {
|
|
34
|
+
for (const key of fields) {
|
|
35
|
+
if (key === skip) continue;
|
|
36
|
+
const value = str(obj[key]);
|
|
37
|
+
if (value) return { key, value };
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** `key: value` pairs for a payload none of the known fields matched. */
|
|
43
|
+
function describeUnknownPayload(obj: Record<string, unknown>): string {
|
|
44
|
+
return Object.entries(obj)
|
|
45
|
+
.filter(([k, v]) => !ENVELOPE_KEYS.has(k) && str(v))
|
|
46
|
+
.map(([k, v]) => `${k}: ${str(v)}`)
|
|
47
|
+
.join(" · ");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Reduce a raw inbox `text` to a headline and optional body.
|
|
52
|
+
*
|
|
53
|
+
* @param raw The message's `text` — JSON payload or plain prose.
|
|
54
|
+
* @param summary Author-supplied label; outranks anything inside the payload.
|
|
55
|
+
*/
|
|
56
|
+
export function previewTeamMessage(raw: string, summary?: string): TeamMessagePreview {
|
|
57
|
+
const authored = str(summary);
|
|
58
|
+
const text = str(raw);
|
|
59
|
+
if (!text) return { title: authored };
|
|
60
|
+
|
|
61
|
+
let parsed: unknown;
|
|
62
|
+
try {
|
|
63
|
+
parsed = JSON.parse(text);
|
|
64
|
+
} catch {
|
|
65
|
+
// Plain prose: first line is the headline, the rest is the body.
|
|
66
|
+
const [first, ...rest] = text.split("\n");
|
|
67
|
+
const detail = rest.join("\n").trim();
|
|
68
|
+
return { title: authored || str(first), ...(detail ? { detail } : {}) };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
72
|
+
return { title: authored || text };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const obj = parsed as Record<string, unknown>;
|
|
76
|
+
const taskId = str(obj.taskId) || str(obj.task_id);
|
|
77
|
+
const head = pick(obj, TITLE_FIELDS);
|
|
78
|
+
// Never repeat the headline as the body — skip whichever field supplied it.
|
|
79
|
+
const body = pick(obj, DETAIL_FIELDS, head?.key);
|
|
80
|
+
|
|
81
|
+
const title = authored || head?.value || describeUnknownPayload(obj) || str(obj.type) || text;
|
|
82
|
+
return {
|
|
83
|
+
title,
|
|
84
|
+
...(body ? { detail: body.value } : {}),
|
|
85
|
+
...(taskId ? { taskId } : {}),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -4,9 +4,13 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { useState, useEffect, useRef, useMemo, lazy, Suspense } from "react";
|
|
6
6
|
import type { BashPartialEntry } from "../../hooks/use-chat";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
import { MiniMarkdown } from "./mini-markdown";
|
|
8
|
+
import {
|
|
9
|
+
SendMessageSummary,
|
|
10
|
+
SendMessageDetails,
|
|
11
|
+
SendMessageOutcomeView,
|
|
12
|
+
} from "./send-message-card";
|
|
13
|
+
import { parseSendMessageResult } from "./send-message-parse";
|
|
10
14
|
import {
|
|
11
15
|
ChevronDown,
|
|
12
16
|
ChevronRight,
|
|
@@ -30,12 +34,33 @@ import {
|
|
|
30
34
|
Code,
|
|
31
35
|
Columns2,
|
|
32
36
|
Clock,
|
|
37
|
+
Send,
|
|
38
|
+
Users,
|
|
33
39
|
} from "lucide-react";
|
|
34
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Handle of an agent that can be addressed later, or null for a one-shot subagent.
|
|
43
|
+
*
|
|
44
|
+
* Only a spawn that passed `name` stays reachable — that name is what SendMessage
|
|
45
|
+
* takes as its `to`. Teammates therefore always carry one, so the handle is what
|
|
46
|
+
* separates "a colleague working in the background" from "a scout that answers once".
|
|
47
|
+
*/
|
|
48
|
+
function addressableAgentName(toolName: string, input: Record<string, unknown>): string | null {
|
|
49
|
+
if (toolName !== "Agent" && toolName !== "Task") return null;
|
|
50
|
+
const name = input.name;
|
|
51
|
+
return typeof name === "string" && name.trim() ? name.trim() : null;
|
|
52
|
+
}
|
|
53
|
+
|
|
35
54
|
/** Per-tool-family icon chip: 24×24 rounded-7 tinted per the design spec. */
|
|
36
|
-
function toolChip(
|
|
55
|
+
function toolChip(
|
|
56
|
+
name: string,
|
|
57
|
+
isError: boolean,
|
|
58
|
+
isAddressableAgent = false,
|
|
59
|
+
): { Icon: React.ElementType; cls: string } {
|
|
37
60
|
if (isError && (name === "Bash" || name === "PowerShell"))
|
|
38
61
|
return { Icon: Terminal, cls: "bg-error/15 text-error" };
|
|
62
|
+
// A named teammate gets its own chip so it is not mistaken for a throwaway subagent.
|
|
63
|
+
if (isAddressableAgent) return { Icon: Users, cls: "bg-accent-2/15 text-accent-2" };
|
|
39
64
|
switch (name) {
|
|
40
65
|
case "Read": case "Glob": case "LS":
|
|
41
66
|
return { Icon: FileSearch, cls: "bg-accent-wash text-primary" };
|
|
@@ -53,6 +78,8 @@ function toolChip(name: string, isError: boolean): { Icon: React.ElementType; cl
|
|
|
53
78
|
return { Icon: ListChecks, cls: "bg-warning/15 text-warning" };
|
|
54
79
|
case "Task": case "Agent":
|
|
55
80
|
return { Icon: Bot, cls: "bg-accent-wash text-primary" };
|
|
81
|
+
case "SendMessage":
|
|
82
|
+
return { Icon: Send, cls: "bg-info/15 text-info" };
|
|
56
83
|
case "AskUserQuestion":
|
|
57
84
|
return { Icon: CircleHelp, cls: "bg-accent-wash text-primary" };
|
|
58
85
|
case "ExitPlanMode":
|
|
@@ -69,6 +96,7 @@ import { useTabStore } from "@/stores/tab-store";
|
|
|
69
96
|
import { basename } from "@/lib/utils";
|
|
70
97
|
import { isImageExtension } from "../../../shared/image-extensions";
|
|
71
98
|
import { resultHasImagePlaceholder } from "../../../shared/tool-result-content";
|
|
99
|
+
import { isAsyncAgentLaunchAck } from "../../../shared/background-agent-status";
|
|
72
100
|
import { ToolImagePreview } from "./tool-image-preview";
|
|
73
101
|
|
|
74
102
|
/** Extract tool name and input from a ChatEvent */
|
|
@@ -141,7 +169,17 @@ export function ToolCard({
|
|
|
141
169
|
const isSubagent = (toolName === "Agent" || toolName === "Task") && tool.type === "tool_use";
|
|
142
170
|
const children = isSubagent ? (tool as any).children as ChatEvent[] | undefined : undefined;
|
|
143
171
|
const hasChildren = children && children.length > 0;
|
|
144
|
-
|
|
172
|
+
// A backgrounded subagent answers its tool call the instant it spawns ("Async agent
|
|
173
|
+
// launched successfully"), then runs on past the end of the turn. Neither that ack nor
|
|
174
|
+
// `completed` (which only means the parent turn stopped streaming) says the agent is
|
|
175
|
+
// finished — only the <task-notification> the SDK reports as bgStatus does. Without this
|
|
176
|
+
// the card showed a green check while its step count kept climbing.
|
|
177
|
+
const bgStatus = isSubagent && tool.type === "tool_use" ? tool.bgStatus : undefined;
|
|
178
|
+
const isBgAgent = isSubagent
|
|
179
|
+
&& (bgStatus != null || (hasResult && !isError && isAsyncAgentLaunchAck(String((result as any).output ?? ""))));
|
|
180
|
+
const bgRunning = isBgAgent && bgStatus == null;
|
|
181
|
+
const bgFailed = bgStatus === "failed" || bgStatus === "stopped";
|
|
182
|
+
const isDone = bgRunning ? false : (hasResult || hasAnswers || wasApproved || completed);
|
|
145
183
|
// File-mutation tools show their change via the inline diff/content preview — the SDK's
|
|
146
184
|
// "file updated successfully" boilerplate is noise, so suppress it (but keep error output).
|
|
147
185
|
const isFileMutation = ["Edit", "MultiEdit", "Write", "NotebookEdit"].includes(toolName);
|
|
@@ -172,7 +210,11 @@ export function ToolCard({
|
|
|
172
210
|
}
|
|
173
211
|
}, [isError, toolName]);
|
|
174
212
|
|
|
175
|
-
const { Icon: ChipIcon, cls: chipCls } = toolChip(
|
|
213
|
+
const { Icon: ChipIcon, cls: chipCls } = toolChip(
|
|
214
|
+
toolName,
|
|
215
|
+
isError,
|
|
216
|
+
!!addressableAgentName(toolName, input),
|
|
217
|
+
);
|
|
176
218
|
const isInteractive = toolName === "AskUserQuestion" || toolName === "ExitPlanMode" || isSubagent;
|
|
177
219
|
|
|
178
220
|
return (
|
|
@@ -197,7 +239,10 @@ export function ToolCard({
|
|
|
197
239
|
{hasChildren && !isStreamingBash && (
|
|
198
240
|
<span className="text-[10px] text-text-3 font-mono">{children!.length} steps</span>
|
|
199
241
|
)}
|
|
200
|
-
{
|
|
242
|
+
{bgRunning && (
|
|
243
|
+
<span className="text-[10px] text-primary">running…</span>
|
|
244
|
+
)}
|
|
245
|
+
{isError || bgFailed
|
|
201
246
|
? <XCircle className="size-3.5 text-error" />
|
|
202
247
|
: isDone
|
|
203
248
|
? <CheckCircle2 className="size-3.5 text-success" />
|
|
@@ -254,8 +299,21 @@ function ToolSummary({ name, input }: { name: string; input: Record<string, unkn
|
|
|
254
299
|
case "ToolSearch":
|
|
255
300
|
return <><Search className="size-3 inline" /> {name} <span className="text-text-subtle">{truncate(s(input.query), 50)}</span></>;
|
|
256
301
|
case "Agent":
|
|
257
|
-
case "Task":
|
|
258
|
-
|
|
302
|
+
case "Task": {
|
|
303
|
+
// Lead with the handle when there is one: it is both the identity of the
|
|
304
|
+
// teammate and the exact string SendMessage needs to reach it.
|
|
305
|
+
const handle = addressableAgentName(name, input);
|
|
306
|
+
const task = truncate(s(input.description || input.prompt), handle ? 44 : 60);
|
|
307
|
+
return (
|
|
308
|
+
<>
|
|
309
|
+
{!handle && <Bot className="size-3 inline" />} {name}{" "}
|
|
310
|
+
{handle && <span className="text-text-primary font-medium">{handle}</span>}
|
|
311
|
+
<span className="text-text-subtle">{handle ? ` · ${task}` : task}</span>
|
|
312
|
+
</>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
case "SendMessage":
|
|
316
|
+
return <SendMessageSummary name={name} input={input} />;
|
|
259
317
|
case "TodoWrite": {
|
|
260
318
|
const todos = Array.isArray(input.todos) ? input.todos as Array<{ content: string; status: string }> : [];
|
|
261
319
|
const done = todos.filter((t) => t.status === "completed").length;
|
|
@@ -393,14 +451,32 @@ function ToolDetails({
|
|
|
393
451
|
case "TodoWrite":
|
|
394
452
|
return <TodoDetails todos={(input.todos as Array<{ content: string; status: string }>) ?? []} />;
|
|
395
453
|
case "Agent":
|
|
396
|
-
case "Task":
|
|
454
|
+
case "Task": {
|
|
455
|
+
const handle = addressableAgentName(name, input);
|
|
397
456
|
return (
|
|
398
457
|
<div className="space-y-1">
|
|
458
|
+
{!!handle && (
|
|
459
|
+
<p className="flex flex-wrap items-center gap-1.5">
|
|
460
|
+
<span className="text-text-subtle">Name</span>
|
|
461
|
+
<span className="font-medium text-text-primary">{handle}</span>
|
|
462
|
+
<span className="inline-block rounded px-1.5 py-0.5 text-[10px] bg-accent-2/15 text-accent-2">
|
|
463
|
+
teammate
|
|
464
|
+
</span>
|
|
465
|
+
{input.isolation === "worktree" && (
|
|
466
|
+
<span className="inline-block rounded px-1.5 py-0.5 text-[10px] bg-panel-2 text-text-3">
|
|
467
|
+
worktree
|
|
468
|
+
</span>
|
|
469
|
+
)}
|
|
470
|
+
</p>
|
|
471
|
+
)}
|
|
399
472
|
{!!input.description && <p className="text-text-secondary font-medium">{s(input.description)}</p>}
|
|
400
473
|
{!!input.subagent_type && <p className="text-text-subtle">Type: {s(input.subagent_type)}</p>}
|
|
401
474
|
{!!input.prompt && <MiniMarkdown content={s(input.prompt)} maxHeight="max-h-48" />}
|
|
402
475
|
</div>
|
|
403
476
|
);
|
|
477
|
+
}
|
|
478
|
+
case "SendMessage":
|
|
479
|
+
return <SendMessageDetails input={input} />;
|
|
404
480
|
case "ToolSearch":
|
|
405
481
|
return (
|
|
406
482
|
<div className="space-y-0.5">
|
|
@@ -556,6 +632,13 @@ function ToolResultView({ toolName, output }: { toolName: string; output: string
|
|
|
556
632
|
return null;
|
|
557
633
|
}, [toolName, output]);
|
|
558
634
|
|
|
635
|
+
// SendMessage answers with a JSON status object nested inside the SDK's text block —
|
|
636
|
+
// a raw dump would be JSON inside JSON, so collapse it to one delivery line.
|
|
637
|
+
// Declared after every hook above so the hook order stays stable.
|
|
638
|
+
if (toolName === "SendMessage" && parseSendMessageResult(output)) {
|
|
639
|
+
return <SendMessageOutcomeView output={output} />;
|
|
640
|
+
}
|
|
641
|
+
|
|
559
642
|
// Agent with extracted markdown content
|
|
560
643
|
if (agentContent) {
|
|
561
644
|
return (
|
|
@@ -612,8 +695,12 @@ function CollapsibleOutput({ output }: { output: string }) {
|
|
|
612
695
|
);
|
|
613
696
|
}
|
|
614
697
|
|
|
615
|
-
/** Render subagent child events — nested tool_use/tool_result + text
|
|
616
|
-
|
|
698
|
+
/** Render subagent child events — nested tool_use/tool_result + text.
|
|
699
|
+
* Exported so the team member window can replay a teammate's whole work
|
|
700
|
+
* session with the same step rendering the inline Agent card uses.
|
|
701
|
+
* `className` overrides the container so a full-height surface can drop the
|
|
702
|
+
* card's fixed max-height. */
|
|
703
|
+
export function SubagentChildren({ events, projectName, className }: { events: ChatEvent[]; projectName?: string; className?: string }) {
|
|
617
704
|
// Group children similar to InterleavedEvents: pair tool_use + tool_result, merge text
|
|
618
705
|
type ChildGroup =
|
|
619
706
|
| { kind: "text"; content: string }
|
|
@@ -656,7 +743,7 @@ function SubagentChildren({ events, projectName }: { events: ChatEvent[]; projec
|
|
|
656
743
|
const el = e.currentTarget;
|
|
657
744
|
userScrolledRef.current = el.scrollTop + el.clientHeight < el.scrollHeight - 20;
|
|
658
745
|
}}
|
|
659
|
-
className="border-l-2 border-accent/20 pl-2 space-y-1 mt-1 max-h-64 md:max-h-96 overflow-y-auto"
|
|
746
|
+
className={className ?? "border-l-2 border-accent/20 pl-2 space-y-1 mt-1 max-h-64 md:max-h-96 overflow-y-auto"}
|
|
660
747
|
>
|
|
661
748
|
{groups.map((g, i) => {
|
|
662
749
|
if (g.kind === "text") {
|
|
@@ -672,16 +759,6 @@ function SubagentChildren({ events, projectName }: { events: ChatEvent[]; projec
|
|
|
672
759
|
);
|
|
673
760
|
}
|
|
674
761
|
|
|
675
|
-
/** Inline markdown renderer for tool details (prompt, result) */
|
|
676
|
-
function MiniMarkdown({ content, maxHeight = "max-h-48" }: { content: string; maxHeight?: string }) {
|
|
677
|
-
return (
|
|
678
|
-
<Suspense fallback={<div className="animate-pulse h-4 bg-muted rounded" />}>
|
|
679
|
-
<MarkdownRenderer content={content} className={`text-text-secondary overflow-auto ${maxHeight}`} />
|
|
680
|
-
</Suspense>
|
|
681
|
-
);
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
|
|
685
762
|
/** Real-time streaming bash output with auto-scroll */
|
|
686
763
|
function StreamingBashOutput({ content, lineCount }: { content: string; lineCount: number }) {
|
|
687
764
|
const preRef = useRef<HTMLPreElement>(null);
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { FileWarning, Music } from "lucide-react";
|
|
3
3
|
import { basename } from "@/lib/utils";
|
|
4
|
+
import { rawMediaUrl } from "@/lib/media-url";
|
|
4
5
|
|
|
6
|
+
/** Streams straight from the Range-capable URL — no whole-file blob, instant seek. */
|
|
5
7
|
export function AudioPreview({ filePath, projectName }: { filePath: string; projectName: string }) {
|
|
6
|
-
const
|
|
8
|
+
const [error, setError] = useState(false);
|
|
7
9
|
|
|
8
10
|
if (error) {
|
|
9
11
|
return (
|
|
@@ -13,14 +15,11 @@ export function AudioPreview({ filePath, projectName }: { filePath: string; proj
|
|
|
13
15
|
</div>
|
|
14
16
|
);
|
|
15
17
|
}
|
|
16
|
-
if (!blobUrl) {
|
|
17
|
-
return <div className="flex items-center justify-center h-full"><Loader2 className="size-5 animate-spin text-text-subtle" /></div>;
|
|
18
|
-
}
|
|
19
18
|
return (
|
|
20
19
|
<div className="flex flex-col items-center justify-center h-full gap-4 p-4 bg-surface">
|
|
21
20
|
<Music className="size-16 text-text-subtle" />
|
|
22
21
|
<p className="text-sm text-text-secondary truncate max-w-xs">{basename(filePath)}</p>
|
|
23
|
-
<audio src={
|
|
22
|
+
<audio key={filePath} src={rawMediaUrl(filePath, projectName)} controls preload="metadata" className="w-full max-w-md" onError={() => setError(true)} />
|
|
24
23
|
</div>
|
|
25
24
|
);
|
|
26
25
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { useCallback, type KeyboardEvent } from "react";
|
|
2
|
+
|
|
3
|
+
/** What the player exposes for keyboard control; the hook stays free of player state. */
|
|
4
|
+
export interface VideoPlayerActions {
|
|
5
|
+
togglePlay: () => void;
|
|
6
|
+
/** Positive = forward, seconds. */
|
|
7
|
+
seekBy: (deltaSeconds: number) => void;
|
|
8
|
+
toggleFullscreen: () => void;
|
|
9
|
+
toggleMute: () => void;
|
|
10
|
+
/** Positive = louder, in 0..1 units. */
|
|
11
|
+
volumeBy: (delta: number) => void;
|
|
12
|
+
/** +1 = next speed step, -1 = previous. */
|
|
13
|
+
speedStep: (direction: 1 | -1) => void;
|
|
14
|
+
/** +1 = clockwise, -1 = counter-clockwise. */
|
|
15
|
+
rotate: (direction: 1 | -1) => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** YouTube-style bindings, documented in the settings menu of the player. */
|
|
19
|
+
export const VIDEO_SHORTCUTS: ReadonlyArray<[keys: string, action: string]> = [
|
|
20
|
+
["Space / K", "Play / pause"],
|
|
21
|
+
["← / →", "Seek 5s"],
|
|
22
|
+
["J / L or Shift+← / →", "Seek 10s"],
|
|
23
|
+
["↑ / ↓", "Volume"],
|
|
24
|
+
["M", "Mute"],
|
|
25
|
+
["F", "Fullscreen"],
|
|
26
|
+
["< / >", "Speed"],
|
|
27
|
+
["R / Shift+R", "Rotate"],
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns an `onKeyDown` handler for the player root (which must be focusable).
|
|
32
|
+
* Keys typed into the range sliders are left alone so arrows still nudge the slider.
|
|
33
|
+
*/
|
|
34
|
+
export function useVideoKeyboardShortcuts(actions: VideoPlayerActions) {
|
|
35
|
+
return useCallback(
|
|
36
|
+
(e: KeyboardEvent<HTMLElement>) => {
|
|
37
|
+
const target = e.target as HTMLElement;
|
|
38
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable) return;
|
|
39
|
+
if (e.ctrlKey || e.metaKey || e.altKey) return;
|
|
40
|
+
|
|
41
|
+
let handled = true;
|
|
42
|
+
switch (e.key) {
|
|
43
|
+
case " ": case "k": case "K": actions.togglePlay(); break;
|
|
44
|
+
case "ArrowLeft": actions.seekBy(e.shiftKey ? -10 : -5); break;
|
|
45
|
+
case "ArrowRight": actions.seekBy(e.shiftKey ? 10 : 5); break;
|
|
46
|
+
case "j": case "J": actions.seekBy(-10); break;
|
|
47
|
+
case "l": case "L": actions.seekBy(10); break;
|
|
48
|
+
case "ArrowUp": actions.volumeBy(0.1); break;
|
|
49
|
+
case "ArrowDown": actions.volumeBy(-0.1); break;
|
|
50
|
+
case "m": case "M": actions.toggleMute(); break;
|
|
51
|
+
case "f": case "F": actions.toggleFullscreen(); break;
|
|
52
|
+
case "<": case ",": actions.speedStep(-1); break;
|
|
53
|
+
case ">": case ".": actions.speedStep(1); break;
|
|
54
|
+
case "r": actions.rotate(1); break;
|
|
55
|
+
case "R": actions.rotate(-1); break;
|
|
56
|
+
default: handled = false;
|
|
57
|
+
}
|
|
58
|
+
if (handled) e.preventDefault();
|
|
59
|
+
},
|
|
60
|
+
[actions],
|
|
61
|
+
);
|
|
62
|
+
}
|