@thaut/claude-ide 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (559) hide show
  1. package/bin/claude-ide.js +23 -0
  2. package/package.json +75 -4
  3. package/server/add-dirs.ts +126 -0
  4. package/server/auth.test.ts +148 -0
  5. package/server/auth.ts +235 -0
  6. package/server/bang.ts +54 -0
  7. package/server/btw-instructions.ts +19 -0
  8. package/server/btw-policy.ts +17 -0
  9. package/server/btw.ts +143 -0
  10. package/server/child-env.ts +29 -0
  11. package/server/cli-control.ts +255 -0
  12. package/server/cli-files.ts +55 -0
  13. package/server/cli-info.ts +73 -0
  14. package/server/config/account.ts +65 -0
  15. package/server/config/agents.ts +186 -0
  16. package/server/config/mcp.ts +86 -0
  17. package/server/config/memory.ts +193 -0
  18. package/server/config/paths.ts +156 -0
  19. package/server/config/plugins.ts +204 -0
  20. package/server/config/routes.ts +95 -0
  21. package/server/config/settings.ts +246 -0
  22. package/server/config.ts +46 -0
  23. package/server/db.ts +121 -0
  24. package/server/directories.test.ts +180 -0
  25. package/server/directories.ts +87 -0
  26. package/server/dist-version.ts +69 -0
  27. package/server/durable-tasks.ts +61 -0
  28. package/server/file-transfers.ts +79 -0
  29. package/server/files.test.ts +127 -0
  30. package/server/files.ts +386 -0
  31. package/server/fs-queue.ts +14 -0
  32. package/server/fsutil.ts +144 -0
  33. package/server/git.ts +86 -0
  34. package/server/goal-state.test.ts +64 -0
  35. package/server/goal-state.ts +78 -0
  36. package/server/history-pages.test.ts +619 -0
  37. package/server/history-pages.ts +513 -0
  38. package/server/http-channel-manager.ts +468 -0
  39. package/server/http-channel-pull.test.ts +314 -0
  40. package/server/http-channel-push.test.ts +364 -0
  41. package/server/http-channel-registration.test.ts +291 -0
  42. package/server/http-channel-routes.ts +73 -0
  43. package/server/http-channel-store.ts +142 -0
  44. package/server/http-channel-test-fixture.ts +103 -0
  45. package/server/ide-messages-mcp.test.ts +82 -0
  46. package/server/ide-messages-mcp.ts +47 -0
  47. package/server/idecron-mcp.ts +65 -0
  48. package/server/idecron.test.ts +79 -0
  49. package/server/idecron.ts +271 -0
  50. package/server/index.ts +336 -0
  51. package/server/live-session.test.ts +1126 -0
  52. package/server/live-session.ts +1165 -0
  53. package/server/project-routes.ts +46 -0
  54. package/server/projects.test.ts +28 -0
  55. package/server/push.ts +315 -0
  56. package/server/report-cache.ts +28 -0
  57. package/server/session-aliases.test.ts +57 -0
  58. package/server/session-aliases.ts +50 -0
  59. package/server/session-branch.ts +71 -0
  60. package/server/session-dirs.ts +189 -0
  61. package/server/session-file.test.ts +134 -0
  62. package/server/session-file.ts +113 -0
  63. package/server/session-messaging.test.ts +297 -0
  64. package/server/session-messaging.ts +165 -0
  65. package/server/sessions.ts +638 -0
  66. package/server/subagents.test.ts +43 -0
  67. package/server/subagents.ts +58 -0
  68. package/server/tool-images.test.ts +76 -0
  69. package/server/tool-images.ts +45 -0
  70. package/server/turn-changes.ts +308 -0
  71. package/server/worktree-git.ts +87 -0
  72. package/server/worktrees.ts +138 -0
  73. package/server/ws.test.ts +195 -0
  74. package/server/ws.ts +197 -0
  75. package/shared/agent-model.ts +15 -0
  76. package/shared/agent-tasks.ts +12 -0
  77. package/shared/config.ts +175 -0
  78. package/shared/directories.ts +12 -0
  79. package/shared/files.ts +51 -0
  80. package/shared/http-channels.ts +63 -0
  81. package/shared/message-window.ts +189 -0
  82. package/shared/project.ts +77 -0
  83. package/shared/protocol.ts +203 -0
  84. package/shared/task-types.ts +4 -0
  85. package/shared/todos.ts +40 -0
  86. package/shared/write-policy.ts +9 -0
  87. package/web/dist/assets/AgentView-wrTKgcJ3.js +1 -0
  88. package/web/dist/assets/AnnotationSelection-BZmNmwVW.js +7 -0
  89. package/web/dist/assets/ChangesView-G1WTzh4q.js +2 -0
  90. package/web/dist/assets/FilesView-DPgAbYt_.js +6 -0
  91. package/web/dist/assets/Form-BKTwiYyw.js +1 -0
  92. package/web/dist/assets/HomePage-Dq2apjBe.js +1 -0
  93. package/web/dist/assets/Markdown-IwP-xF29.js +67 -0
  94. package/web/dist/assets/MessageList-DD9GypSy.js +15 -0
  95. package/web/dist/assets/Modal-g2rv8I_n.js +1 -0
  96. package/web/dist/assets/NotificationSettings-DpuLO_Bv.js +1 -0
  97. package/web/dist/assets/OverviewPage-Dx6miabE.js +1 -0
  98. package/web/dist/assets/ProjectHome-CousyTLL.js +1 -0
  99. package/web/dist/assets/SessionView-CPVL7_HO.js +2 -0
  100. package/web/dist/assets/SettingsPage-D_oYSnW2.js +7 -0
  101. package/web/dist/assets/WorktreesView-C7e0HV__.js +1 -0
  102. package/web/dist/assets/abap-CLvhMVsD.js +1 -0
  103. package/web/dist/assets/actionscript-3-Cs6JJXT5.js +1 -0
  104. package/web/dist/assets/ada-X3Y2mlq2.js +1 -0
  105. package/web/dist/assets/ahk-DwADkxyd.js +1 -0
  106. package/web/dist/assets/ahk2-_6rzW9BS.js +1 -0
  107. package/web/dist/assets/andromeeda-vGVdxbeo.js +1 -0
  108. package/web/dist/assets/angular-html-Cw29lun8.js +1 -0
  109. package/web/dist/assets/angular-ts-BXz-O3SJ.js +1 -0
  110. package/web/dist/assets/apache-U0d_L8uA.js +1 -0
  111. package/web/dist/assets/apex-KFGFyKwG.js +1 -0
  112. package/web/dist/assets/apl-xBchdRhy.js +1 -0
  113. package/web/dist/assets/applescript-CCn79oCD.js +1 -0
  114. package/web/dist/assets/ara-4CJ0cIlV.js +1 -0
  115. package/web/dist/assets/asciidoc-SCjQUq34.js +1 -0
  116. package/web/dist/assets/asm-Cmm7eHzH.js +1 -0
  117. package/web/dist/assets/astro-1q6DGuN3.js +1 -0
  118. package/web/dist/assets/aurora-x-CDeNXAV0.js +1 -0
  119. package/web/dist/assets/awk-BWXHIvNe.js +1 -0
  120. package/web/dist/assets/ayu-dark-DluEY0Gj.js +1 -0
  121. package/web/dist/assets/ayu-light-C3h-C4tm.js +1 -0
  122. package/web/dist/assets/ayu-mirage-Bqwy1Gya.js +1 -0
  123. package/web/dist/assets/ballerina-B7ZEbQpA.js +1 -0
  124. package/web/dist/assets/bat-qdxAdBWQ.js +1 -0
  125. package/web/dist/assets/beancount-C2IN4Vk8.js +1 -0
  126. package/web/dist/assets/berry-DKpUyyne.js +1 -0
  127. package/web/dist/assets/bibtex-Ci_nEsc7.js +1 -0
  128. package/web/dist/assets/bicep-CUHmPFLl.js +1 -0
  129. package/web/dist/assets/bird2-CYIUgYqB.js +1 -0
  130. package/web/dist/assets/blade-Cqdv4oZN.js +1 -0
  131. package/web/dist/assets/bsl-CVED6lJ1.js +1 -0
  132. package/web/dist/assets/c-D9gIxSfx.js +1 -0
  133. package/web/dist/assets/c3-D0apG41V.js +1 -0
  134. package/web/dist/assets/cadence-CQ2zXKGN.js +1 -0
  135. package/web/dist/assets/cairo-DRAZz75c.js +1 -0
  136. package/web/dist/assets/catppuccin-frappe-C9Q5zVZY.js +1 -0
  137. package/web/dist/assets/catppuccin-latte-CtsyrtPq.js +1 -0
  138. package/web/dist/assets/catppuccin-macchiato-R8nAf1vR.js +1 -0
  139. package/web/dist/assets/catppuccin-mocha-DjuaAJKi.js +1 -0
  140. package/web/dist/assets/chapel-CuseGurG.js +1 -0
  141. package/web/dist/assets/clarity-CtfBBspg.js +1 -0
  142. package/web/dist/assets/clojure-DqKBuwfJ.js +1 -0
  143. package/web/dist/assets/cmake-Bj61d0ZC.js +1 -0
  144. package/web/dist/assets/cobol-Bdpj3Qoh.js +1 -0
  145. package/web/dist/assets/codeowners-C8r90Shi.js +1 -0
  146. package/web/dist/assets/codeql-oeQT6MSM.js +1 -0
  147. package/web/dist/assets/coffee-Sk8pHFjs.js +1 -0
  148. package/web/dist/assets/common-lisp-Cv5bFMCO.js +1 -0
  149. package/web/dist/assets/coq-CGaSfhwR.js +1 -0
  150. package/web/dist/assets/core-BxI4V4-T.js +12 -0
  151. package/web/dist/assets/cpp-BQfBYKx3.js +1 -0
  152. package/web/dist/assets/crystal-B3j7DoOZ.js +1 -0
  153. package/web/dist/assets/csharp-dmMxLVLW.js +1 -0
  154. package/web/dist/assets/css-DpFbYmRh.js +1 -0
  155. package/web/dist/assets/csv-Dx-8-gkx.js +1 -0
  156. package/web/dist/assets/cue-CE9AQfxI.js +1 -0
  157. package/web/dist/assets/cypher-ClKdZ_lG.js +1 -0
  158. package/web/dist/assets/d-qD-0Kul2.js +1 -0
  159. package/web/dist/assets/dark-plus-Cs2F2srj.js +1 -0
  160. package/web/dist/assets/dart-CHZY9Xhz.js +1 -0
  161. package/web/dist/assets/dax-BkyTk9wS.js +1 -0
  162. package/web/dist/assets/desktop-Dlh5hvp9.js +1 -0
  163. package/web/dist/assets/diff-woXpYk--.js +1 -0
  164. package/web/dist/assets/docker-IyjqRm3v.js +1 -0
  165. package/web/dist/assets/dotenv-CuH5my32.js +1 -0
  166. package/web/dist/assets/dracula-BHWKrbxM.js +1 -0
  167. package/web/dist/assets/dracula-soft-5eyTD99u.js +1 -0
  168. package/web/dist/assets/dream-maker-DW3nJb8Q.js +1 -0
  169. package/web/dist/assets/edge-DXQWmXTB.js +1 -0
  170. package/web/dist/assets/elixir-CrDIY2Vo.js +1 -0
  171. package/web/dist/assets/elm-BslFEg8K.js +1 -0
  172. package/web/dist/assets/emacs-lisp-DR2vtWaj.js +1 -0
  173. package/web/dist/assets/engine-javascript-DJg3-Vu2.js +141 -0
  174. package/web/dist/assets/erb-CUYhg0Ws.js +1 -0
  175. package/web/dist/assets/erlang-BXdgHVfi.js +1 -0
  176. package/web/dist/assets/everforest-dark-sB-x3p7T.js +1 -0
  177. package/web/dist/assets/everforest-light-Df2xbC6M.js +1 -0
  178. package/web/dist/assets/fennel-DQxkIbk2.js +1 -0
  179. package/web/dist/assets/fish-BJitypiv.js +1 -0
  180. package/web/dist/assets/fluent-C03EYrpw.js +1 -0
  181. package/web/dist/assets/format-DrBC7w0A.js +1 -0
  182. package/web/dist/assets/fortran-fixed-form-D6mN0kjy.js +1 -0
  183. package/web/dist/assets/fortran-free-form-CYNrtFtB.js +1 -0
  184. package/web/dist/assets/fsharp-CwoEF39o.js +1 -0
  185. package/web/dist/assets/gdresource-CZkFGo3B.js +1 -0
  186. package/web/dist/assets/gdscript-DYvRD3hg.js +1 -0
  187. package/web/dist/assets/gdshader-CBce3t8t.js +1 -0
  188. package/web/dist/assets/genie-CV2tkWYe.js +1 -0
  189. package/web/dist/assets/gherkin-DExj1W_8.js +1 -0
  190. package/web/dist/assets/git-commit-dUGrvm6Q.js +1 -0
  191. package/web/dist/assets/git-rebase-4zCRqF28.js +1 -0
  192. package/web/dist/assets/github-dark-C-LZuMrd.js +1 -0
  193. package/web/dist/assets/github-dark-default-DXG-b-1a.js +1 -0
  194. package/web/dist/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
  195. package/web/dist/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
  196. package/web/dist/assets/github-light-EUqPIrTm.js +1 -0
  197. package/web/dist/assets/github-light-default-BXViO-2h.js +1 -0
  198. package/web/dist/assets/github-light-high-contrast-B68TUdTA.js +1 -0
  199. package/web/dist/assets/gleam-CSRkHgEL.js +1 -0
  200. package/web/dist/assets/glimmer-js-7adTRvH4.js +1 -0
  201. package/web/dist/assets/glimmer-ts-IdSskDYw.js +1 -0
  202. package/web/dist/assets/glsl-Qzy53KDt.js +1 -0
  203. package/web/dist/assets/gn-CAXYAgV-.js +1 -0
  204. package/web/dist/assets/gnuplot-7GGW24-e.js +1 -0
  205. package/web/dist/assets/go-rLFTqkRN.js +1 -0
  206. package/web/dist/assets/graphql-CV_puxbB.js +1 -0
  207. package/web/dist/assets/groovy-CacY0gHj.js +1 -0
  208. package/web/dist/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
  209. package/web/dist/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
  210. package/web/dist/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
  211. package/web/dist/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
  212. package/web/dist/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
  213. package/web/dist/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
  214. package/web/dist/assets/hack-C5GPjiLV.js +1 -0
  215. package/web/dist/assets/haml-BQ5YR1DQ.js +1 -0
  216. package/web/dist/assets/handlebars-DnhRK9A1.js +1 -0
  217. package/web/dist/assets/haskell-D8IpX4py.js +1 -0
  218. package/web/dist/assets/haxe-C8oCnwJJ.js +1 -0
  219. package/web/dist/assets/hcl-Dh228itO.js +1 -0
  220. package/web/dist/assets/highlight.worker-CY-ZeDAl.js +1 -0
  221. package/web/dist/assets/hjson-CxZEssPk.js +1 -0
  222. package/web/dist/assets/hlsl-Cvrh5tZx.js +1 -0
  223. package/web/dist/assets/horizon-CE9ld1lL.js +1 -0
  224. package/web/dist/assets/horizon-bright-DSNQnXHK.js +1 -0
  225. package/web/dist/assets/houston-CsvMBhTu.js +1 -0
  226. package/web/dist/assets/html-CmHiEKV9.js +1 -0
  227. package/web/dist/assets/html-derivative-BXE-rYIK.js +1 -0
  228. package/web/dist/assets/http-DPjjqtcL.js +1 -0
  229. package/web/dist/assets/hurl-AMBpSloO.js +1 -0
  230. package/web/dist/assets/hxml-D7Y24wKF.js +1 -0
  231. package/web/dist/assets/hy-CZbG8q4J.js +1 -0
  232. package/web/dist/assets/imba-DsUTQ-LC.js +1 -0
  233. package/web/dist/assets/index-DNPnl4sh.css +2 -0
  234. package/web/dist/assets/index-DQh72lEx.js +14 -0
  235. package/web/dist/assets/ini-B5eOa1yu.js +1 -0
  236. package/web/dist/assets/java-CEM7Tdw_.js +1 -0
  237. package/web/dist/assets/javascript-CU3PLowd.js +1 -0
  238. package/web/dist/assets/jinja-fR0x_9Xy.js +1 -0
  239. package/web/dist/assets/jison-BoKsxs5M.js +1 -0
  240. package/web/dist/assets/json-BM2FWsRB.js +1 -0
  241. package/web/dist/assets/json5-BR5RXkoi.js +1 -0
  242. package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
  243. package/web/dist/assets/jsonl-CmCQp5Yx.js +1 -0
  244. package/web/dist/assets/jsonnet-CJTPZ8u_.js +1 -0
  245. package/web/dist/assets/jssm-DXw9l8Rf.js +1 -0
  246. package/web/dist/assets/jsx-B5fTecQP.js +1 -0
  247. package/web/dist/assets/julia-DGyDG39_.js +1 -0
  248. package/web/dist/assets/just-B-RyLcSR.js +1 -0
  249. package/web/dist/assets/kanagawa-dragon-Bozd7klA.js +1 -0
  250. package/web/dist/assets/kanagawa-lotus-BmuOG9ZW.js +1 -0
  251. package/web/dist/assets/kanagawa-wave-BML5mF2J.js +1 -0
  252. package/web/dist/assets/kdl-CsD5j6eV.js +1 -0
  253. package/web/dist/assets/kotlin-DhhofPvG.js +1 -0
  254. package/web/dist/assets/kusto-C7mF5XQf.js +1 -0
  255. package/web/dist/assets/langs-CciPKqaF.js +1 -0
  256. package/web/dist/assets/laserwave-C_8bwKvT.js +1 -0
  257. package/web/dist/assets/latex-CV1pQelm.js +1 -0
  258. package/web/dist/assets/lean-CewbzKMR.js +1 -0
  259. package/web/dist/assets/less-DVTAwKKz.js +1 -0
  260. package/web/dist/assets/lib-DlcVMUqT.js +1 -0
  261. package/web/dist/assets/light-plus-DVQuIRkW.js +1 -0
  262. package/web/dist/assets/liquid-9p05RSzQ.js +1 -0
  263. package/web/dist/assets/llvm-DqHOMS-s.js +1 -0
  264. package/web/dist/assets/log-BNLmms1o.js +1 -0
  265. package/web/dist/assets/logo-Cluzi2Zq.js +1 -0
  266. package/web/dist/assets/lua-CIPVh0S-.js +1 -0
  267. package/web/dist/assets/luau-VGWVLoqX.js +1 -0
  268. package/web/dist/assets/make-Dixweg8N.js +1 -0
  269. package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
  270. package/web/dist/assets/marko-h2h6YUMS.js +1 -0
  271. package/web/dist/assets/material-theme-Bm3Qr25_.js +1 -0
  272. package/web/dist/assets/material-theme-darker-2IIEA8gg.js +1 -0
  273. package/web/dist/assets/material-theme-lighter-uhdI0v04.js +1 -0
  274. package/web/dist/assets/material-theme-ocean-CHQ94UKr.js +1 -0
  275. package/web/dist/assets/material-theme-palenight-B5W6OYN7.js +1 -0
  276. package/web/dist/assets/matlab-D7qyCx1q.js +1 -0
  277. package/web/dist/assets/mdc-yAyZMdoC.js +1 -0
  278. package/web/dist/assets/mdx-DQZ5AkYe.js +1 -0
  279. package/web/dist/assets/mermaid-BxpfTIzt.js +1 -0
  280. package/web/dist/assets/message-font-size-DoaZfwkT.js +1 -0
  281. package/web/dist/assets/min-dark-BSWPekZh.js +1 -0
  282. package/web/dist/assets/min-light-DDpmG2fV.js +1 -0
  283. package/web/dist/assets/mipsasm-BMqwQI7S.js +1 -0
  284. package/web/dist/assets/mojo-fg40_ntQ.js +1 -0
  285. package/web/dist/assets/monokai-BscAjiQZ.js +1 -0
  286. package/web/dist/assets/moonbit-D9W784E_.js +1 -0
  287. package/web/dist/assets/move-BYnGhZoM.js +1 -0
  288. package/web/dist/assets/narrat-_X_XdTYD.js +1 -0
  289. package/web/dist/assets/nextflow-BoTnSBQ_.js +1 -0
  290. package/web/dist/assets/nextflow-groovy-D7IRt6Pp.js +1 -0
  291. package/web/dist/assets/nginx-jWINucNT.js +1 -0
  292. package/web/dist/assets/night-owl-DhmEMT88.js +1 -0
  293. package/web/dist/assets/night-owl-light-eJ-hLW7d.js +1 -0
  294. package/web/dist/assets/nim-Dtt9DZ0t.js +1 -0
  295. package/web/dist/assets/nix-Cl_7024t.js +1 -0
  296. package/web/dist/assets/nord-Cb4Vim4T.js +1 -0
  297. package/web/dist/assets/nsis-CjNLYCLg.js +1 -0
  298. package/web/dist/assets/nushell--0fT3PI1.js +1 -0
  299. package/web/dist/assets/objective-c-D1A_Heim.js +1 -0
  300. package/web/dist/assets/objective-cpp-BsSzOQcm.js +1 -0
  301. package/web/dist/assets/ocaml-O90oeIOV.js +1 -0
  302. package/web/dist/assets/odin-B1RWQWA5.js +1 -0
  303. package/web/dist/assets/one-dark-pro-C6YyR8OD.js +1 -0
  304. package/web/dist/assets/one-light-D7Lr4KcI.js +1 -0
  305. package/web/dist/assets/openscad-BUDT5pXO.js +1 -0
  306. package/web/dist/assets/org-ClD5huOa.js +1 -0
  307. package/web/dist/assets/pascal-4ZHwLPI5.js +1 -0
  308. package/web/dist/assets/perl-BFegxyeJ.js +1 -0
  309. package/web/dist/assets/php-B-qOA3Y4.js +1 -0
  310. package/web/dist/assets/pkl-ot-7Btpt.js +1 -0
  311. package/web/dist/assets/plastic-DQwYfKfQ.js +1 -0
  312. package/web/dist/assets/plsql-DGHpHOYJ.js +1 -0
  313. package/web/dist/assets/po-BiJDBrnU.js +1 -0
  314. package/web/dist/assets/poimandres-DRFjx7u4.js +1 -0
  315. package/web/dist/assets/polar-C7UOKdEL.js +1 -0
  316. package/web/dist/assets/postcss-BXeXVLqQ.js +1 -0
  317. package/web/dist/assets/powerquery-DNMTfnFr.js +1 -0
  318. package/web/dist/assets/powershell-QtSnmXcu.js +1 -0
  319. package/web/dist/assets/prisma-DMgNhnYS.js +1 -0
  320. package/web/dist/assets/prolog-iXnhIJG7.js +1 -0
  321. package/web/dist/assets/proto-DB4EqR-F.js +1 -0
  322. package/web/dist/assets/pug-Cq0NBPu-.js +1 -0
  323. package/web/dist/assets/puppet-CDv2pdJW.js +1 -0
  324. package/web/dist/assets/purescript-9MfHhQsQ.js +1 -0
  325. package/web/dist/assets/python-gzcpVVnB.js +1 -0
  326. package/web/dist/assets/qml-CYUsa87k.js +1 -0
  327. package/web/dist/assets/qmldir-DCQb3MpD.js +1 -0
  328. package/web/dist/assets/qss-Fe1Jh2GI.js +1 -0
  329. package/web/dist/assets/r-4xJhgbOf.js +1 -0
  330. package/web/dist/assets/racket-DcIDlBhZ.js +1 -0
  331. package/web/dist/assets/raku-B3gFvitq.js +1 -0
  332. package/web/dist/assets/razor-BlHaOHx8.js +1 -0
  333. package/web/dist/assets/rbs-C0MpOrj4.js +1 -0
  334. package/web/dist/assets/react-B4UGpcWC.js +1 -0
  335. package/web/dist/assets/red-CYlAq2b0.js +1 -0
  336. package/web/dist/assets/reg-CRGYupPL.js +1 -0
  337. package/web/dist/assets/regexp-BUSxjv2o.js +1 -0
  338. package/web/dist/assets/rel-BtDbiS_P.js +1 -0
  339. package/web/dist/assets/riscv-Ckw8ddFX.js +1 -0
  340. package/web/dist/assets/ron-VUp2lXgN.js +1 -0
  341. package/web/dist/assets/rose-pine-aMsaMD1D.js +1 -0
  342. package/web/dist/assets/rose-pine-dawn-8PwUyIlP.js +1 -0
  343. package/web/dist/assets/rose-pine-moon-DO-qXg-I.js +1 -0
  344. package/web/dist/assets/rosmsg-CAekHB0j.js +1 -0
  345. package/web/dist/assets/rst-zjfguEh7.js +1 -0
  346. package/web/dist/assets/ruby-4oR9waBK.js +1 -0
  347. package/web/dist/assets/rust-DpiIf5JO.js +1 -0
  348. package/web/dist/assets/sas-Do4V_2i9.js +1 -0
  349. package/web/dist/assets/sass-DXrisJhu.js +1 -0
  350. package/web/dist/assets/scala-BiFt_7mu.js +1 -0
  351. package/web/dist/assets/scheme-DQCgrYNe.js +1 -0
  352. package/web/dist/assets/scss-CW6JPtag.js +1 -0
  353. package/web/dist/assets/sdbl-bTVj8UrX.js +1 -0
  354. package/web/dist/assets/shaderlab-C4rnI7x0.js +1 -0
  355. package/web/dist/assets/shellscript-zBmOMFJh.js +1 -0
  356. package/web/dist/assets/shellsession-DxGUTWaf.js +1 -0
  357. package/web/dist/assets/slack-dark-DnToyrRv.js +1 -0
  358. package/web/dist/assets/slack-ochin-B2OO5cIa.js +1 -0
  359. package/web/dist/assets/smalltalk-BHpQb5nM.js +1 -0
  360. package/web/dist/assets/smithy-Dgaz7aur.js +1 -0
  361. package/web/dist/assets/snazzy-light-4G7pJPwS.js +1 -0
  362. package/web/dist/assets/solarized-dark-b97czJOk.js +1 -0
  363. package/web/dist/assets/solarized-light-DFPxpIYQ.js +1 -0
  364. package/web/dist/assets/solidity-Bj7E1mRn.js +1 -0
  365. package/web/dist/assets/soy-DVtw20Yn.js +1 -0
  366. package/web/dist/assets/sparql-C0ia5K60.js +1 -0
  367. package/web/dist/assets/splunk-BC2Px7Mm.js +1 -0
  368. package/web/dist/assets/sql-DGCM-jag.js +1 -0
  369. package/web/dist/assets/ssh-config-BgfXC-Er.js +1 -0
  370. package/web/dist/assets/stata-DfuMOXna.js +1 -0
  371. package/web/dist/assets/stylus-B6D30XZt.js +1 -0
  372. package/web/dist/assets/surrealql-CBoRWxfR.js +1 -0
  373. package/web/dist/assets/svelte-g_uCUem5.js +1 -0
  374. package/web/dist/assets/swift-CyEgAFGc.js +1 -0
  375. package/web/dist/assets/synthwave-84-nFMaYfgc.js +1 -0
  376. package/web/dist/assets/system-verilog-Dh5ihWbf.js +1 -0
  377. package/web/dist/assets/systemd-BxMlprV5.js +1 -0
  378. package/web/dist/assets/talonscript-CohzipZa.js +1 -0
  379. package/web/dist/assets/tasl-DMoTqEGO.js +1 -0
  380. package/web/dist/assets/tcl-CZd0xW_V.js +1 -0
  381. package/web/dist/assets/templ-N5C1hJ4Y.js +1 -0
  382. package/web/dist/assets/terraform-DswuEJGm.js +1 -0
  383. package/web/dist/assets/tex-mx6xDwuK.js +1 -0
  384. package/web/dist/assets/themes-CNElGaXw.js +1 -0
  385. package/web/dist/assets/tokyo-night-oM2G3aXe.js +1 -0
  386. package/web/dist/assets/toml-CcmNWLt0.js +1 -0
  387. package/web/dist/assets/ts-tags-C-j71FRb.js +1 -0
  388. package/web/dist/assets/tsv-sltzmVWM.js +1 -0
  389. package/web/dist/assets/tsx-z04y7qR9.js +1 -0
  390. package/web/dist/assets/turtle-ByJddavk.js +1 -0
  391. package/web/dist/assets/twig-Bz57G_nl.js +1 -0
  392. package/web/dist/assets/typescript-RMqVTmzR.js +1 -0
  393. package/web/dist/assets/typespec-BGhR2SqG.js +1 -0
  394. package/web/dist/assets/typst-BgkqA2Pg.js +1 -0
  395. package/web/dist/assets/v-DBj4K9d_.js +1 -0
  396. package/web/dist/assets/vala-zf12oZj6.js +1 -0
  397. package/web/dist/assets/vb-DOwzaHZ0.js +1 -0
  398. package/web/dist/assets/verilog-B2gwz-sJ.js +1 -0
  399. package/web/dist/assets/vesper-DdrHHSXu.js +1 -0
  400. package/web/dist/assets/vhdl-BroJfC0k.js +1 -0
  401. package/web/dist/assets/viml-DvXPmvsu.js +1 -0
  402. package/web/dist/assets/vitesse-black-fwtXNY1n.js +1 -0
  403. package/web/dist/assets/vitesse-dark-BZCL-v6S.js +1 -0
  404. package/web/dist/assets/vitesse-light-VbXTXTou.js +1 -0
  405. package/web/dist/assets/vue-CQgvQytb.js +1 -0
  406. package/web/dist/assets/vue-html-Dhl6fh9l.js +1 -0
  407. package/web/dist/assets/vue-vine-Dw_uU59K.js +1 -0
  408. package/web/dist/assets/vyper-CgoNMtux.js +1 -0
  409. package/web/dist/assets/wasm-ByWQv1Qj.js +1 -0
  410. package/web/dist/assets/wenyan-C8pVoKbM.js +1 -0
  411. package/web/dist/assets/wgsl-BsKzXJz4.js +1 -0
  412. package/web/dist/assets/wikitext-ClFFjSW2.js +1 -0
  413. package/web/dist/assets/wit-DdvCle-K.js +1 -0
  414. package/web/dist/assets/wolfram-DLL8P-h_.js +1 -0
  415. package/web/dist/assets/xml-B49klYQ3.js +1 -0
  416. package/web/dist/assets/xsl-D7tnD3qq.js +1 -0
  417. package/web/dist/assets/yaml-DNQ5_xkL.js +1 -0
  418. package/web/dist/assets/zenscript-BnlCZFoB.js +1 -0
  419. package/web/dist/assets/zig-CMLA9XwU.js +1 -0
  420. package/web/dist/icons/apple-touch-icon.png +0 -0
  421. package/web/dist/icons/badge-96.png +0 -0
  422. package/web/dist/icons/icon-192.png +0 -0
  423. package/web/dist/icons/icon-512.png +0 -0
  424. package/web/dist/icons/icon.svg +4 -0
  425. package/web/dist/icons/maskable-192.png +0 -0
  426. package/web/dist/icons/maskable-512.png +0 -0
  427. package/web/dist/index.html +30 -0
  428. package/web/dist/manifest.webmanifest +20 -0
  429. package/web/dist/sw.js +176 -0
  430. package/web/dist/version.json +1 -0
  431. package/web/src/App.tsx +97 -0
  432. package/web/src/agent-history-flow.test.ts +191 -0
  433. package/web/src/agent-history-flow.ts +58 -0
  434. package/web/src/agent-owners.ts +30 -0
  435. package/web/src/annotation-selection.test.ts +36 -0
  436. package/web/src/annotation-selection.ts +123 -0
  437. package/web/src/annotations.test.ts +279 -0
  438. package/web/src/annotations.ts +191 -0
  439. package/web/src/api.ts +27 -0
  440. package/web/src/auth-events.ts +11 -0
  441. package/web/src/auth-lifecycle.test.ts +105 -0
  442. package/web/src/clipboard.ts +32 -0
  443. package/web/src/components/ActivityNotifier.tsx +22 -0
  444. package/web/src/components/AnnotationEditor.tsx +135 -0
  445. package/web/src/components/AnnotationSelection.tsx +122 -0
  446. package/web/src/components/Automation.tsx +390 -0
  447. package/web/src/components/CodeView.tsx +121 -0
  448. package/web/src/components/Composer.tsx +552 -0
  449. package/web/src/components/ComposerAnnotations.tsx +45 -0
  450. package/web/src/components/Confirmation.tsx +91 -0
  451. package/web/src/components/CopyButton.tsx +23 -0
  452. package/web/src/components/DiffView.tsx +94 -0
  453. package/web/src/components/DirectoryPicker.tsx +230 -0
  454. package/web/src/components/FileCopyMenu.tsx +58 -0
  455. package/web/src/components/FileEntryActions.tsx +95 -0
  456. package/web/src/components/ImagePreview.tsx +68 -0
  457. package/web/src/components/Items.tsx +608 -0
  458. package/web/src/components/Markdown.tsx +73 -0
  459. package/web/src/components/MessageList.tsx +458 -0
  460. package/web/src/components/Modal.tsx +72 -0
  461. package/web/src/components/NotificationEntry.tsx +31 -0
  462. package/web/src/components/NotificationSettings.tsx +226 -0
  463. package/web/src/components/NotificationToasts.tsx +59 -0
  464. package/web/src/components/OpenTabs.tsx +112 -0
  465. package/web/src/components/Pending.tsx +175 -0
  466. package/web/src/components/ProjectExtras.tsx +299 -0
  467. package/web/src/components/ProjectNav.tsx +47 -0
  468. package/web/src/components/SessionActions.tsx +271 -0
  469. package/web/src/components/SessionChannels.tsx +288 -0
  470. package/web/src/components/SessionExtras.tsx +263 -0
  471. package/web/src/components/SettingsLink.tsx +21 -0
  472. package/web/src/components/Shell.tsx +320 -0
  473. package/web/src/components/SvgPreview.tsx +18 -0
  474. package/web/src/components/TodoPanel.tsx +37 -0
  475. package/web/src/components/VersionNotice.tsx +40 -0
  476. package/web/src/components/icons.tsx +43 -0
  477. package/web/src/diff.ts +62 -0
  478. package/web/src/drafts.test.ts +80 -0
  479. package/web/src/drafts.ts +64 -0
  480. package/web/src/format.ts +5 -0
  481. package/web/src/highlight.worker.ts +49 -0
  482. package/web/src/hooks.ts +59 -0
  483. package/web/src/item-view-state.test.ts +51 -0
  484. package/web/src/item-view-state.ts +43 -0
  485. package/web/src/live-history-flow.test.ts +77 -0
  486. package/web/src/live-merge.test.ts +64 -0
  487. package/web/src/live-merge.ts +50 -0
  488. package/web/src/live-message-hydration.test.ts +253 -0
  489. package/web/src/live.ts +404 -0
  490. package/web/src/main.tsx +27 -0
  491. package/web/src/markdown-assets.test.ts +70 -0
  492. package/web/src/markdown-assets.ts +78 -0
  493. package/web/src/markdown-html.test.ts +84 -0
  494. package/web/src/markdown-html.ts +60 -0
  495. package/web/src/markdown-svg.test.ts +37 -0
  496. package/web/src/markdown-svg.ts +42 -0
  497. package/web/src/markdown-tables.test.ts +34 -0
  498. package/web/src/markdown-tables.ts +17 -0
  499. package/web/src/message-bodies.ts +117 -0
  500. package/web/src/message-cache.test.ts +208 -0
  501. package/web/src/message-cache.ts +158 -0
  502. package/web/src/message-font-size.test.ts +41 -0
  503. package/web/src/message-font-size.ts +57 -0
  504. package/web/src/message-time.test.ts +32 -0
  505. package/web/src/message-time.ts +26 -0
  506. package/web/src/notify.ts +132 -0
  507. package/web/src/open-tabs.test.ts +69 -0
  508. package/web/src/open-tabs.ts +110 -0
  509. package/web/src/pages/AgentView.tsx +138 -0
  510. package/web/src/pages/ChangesView.tsx +193 -0
  511. package/web/src/pages/FilesView.tsx +406 -0
  512. package/web/src/pages/HomePage.tsx +96 -0
  513. package/web/src/pages/LoginPage.tsx +56 -0
  514. package/web/src/pages/OverviewPage.tsx +124 -0
  515. package/web/src/pages/ProjectHome.tsx +136 -0
  516. package/web/src/pages/SessionView.tsx +238 -0
  517. package/web/src/pages/WorktreesView.tsx +197 -0
  518. package/web/src/pages/settings/AccountPage.tsx +149 -0
  519. package/web/src/pages/settings/AgentsPage.tsx +182 -0
  520. package/web/src/pages/settings/ConfigPage.tsx +181 -0
  521. package/web/src/pages/settings/GeneralPage.tsx +27 -0
  522. package/web/src/pages/settings/HooksPage.tsx +244 -0
  523. package/web/src/pages/settings/McpPage.tsx +310 -0
  524. package/web/src/pages/settings/MemoryPage.tsx +309 -0
  525. package/web/src/pages/settings/PermissionsPage.tsx +160 -0
  526. package/web/src/pages/settings/PluginsPage.tsx +251 -0
  527. package/web/src/pages/settings/SettingsPage.tsx +141 -0
  528. package/web/src/pages/settings/SkillsPage.tsx +142 -0
  529. package/web/src/pages/settings/ui.tsx +165 -0
  530. package/web/src/preference-document.ts +133 -0
  531. package/web/src/project-actions.ts +18 -0
  532. package/web/src/project-files-state.test.ts +49 -0
  533. package/web/src/project-files-state.ts +64 -0
  534. package/web/src/project-images.ts +13 -0
  535. package/web/src/pwa.ts +33 -0
  536. package/web/src/queryClient.ts +5 -0
  537. package/web/src/reasoning-preference.test.ts +39 -0
  538. package/web/src/reasoning-preference.ts +42 -0
  539. package/web/src/session-confirmations.ts +36 -0
  540. package/web/src/stream-replay.test.ts +163 -0
  541. package/web/src/styles.css +231 -0
  542. package/web/src/tool-result-body.test.ts +115 -0
  543. package/web/src/transcript.test.ts +186 -0
  544. package/web/src/transcript.ts +583 -0
  545. package/web/src/turns.test.ts +338 -0
  546. package/web/src/turns.ts +178 -0
  547. package/web/src/ui/Button.tsx +60 -0
  548. package/web/src/ui/Controls.tsx +227 -0
  549. package/web/src/ui/Form.tsx +203 -0
  550. package/web/src/ui/MenuPopover.tsx +144 -0
  551. package/web/src/ui/Popover.tsx +147 -0
  552. package/web/src/ui/ResizablePane.tsx +110 -0
  553. package/web/src/ui/Select.tsx +150 -0
  554. package/web/src/ui/icons.tsx +270 -0
  555. package/web/src/unsaved.tsx +99 -0
  556. package/web/src/user-text.test.ts +60 -0
  557. package/web/src/user-text.ts +35 -0
  558. package/web/src/uuid.ts +12 -0
  559. package/README.md +0 -3
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Wire protocol between server and browser.
3
+ *
4
+ * The server owns sessions; browsers subscribe over one WebSocket and replay
5
+ * missed events by (epoch, seq). Older history comes from the CLI's jsonl via REST.
6
+ */
7
+
8
+ export type SessionState = "idle" | "running" | "requires_action";
9
+
10
+ export type ImageInput = { mediaType: string; data: string };
11
+
12
+ /** A pending decision that blocks Claude until the user answers it. */
13
+ export type PendingRequest =
14
+ | { id: string; kind: "ask"; toolUseId?: string; input: AskInput }
15
+ | { id: string; kind: "plan"; toolUseId?: string; input: { plan: string } };
16
+
17
+ export type AskQuestion = {
18
+ question: string;
19
+ header?: string;
20
+ multiSelect?: boolean;
21
+ options: { label: string; description?: string }[];
22
+ };
23
+ export type AskInput = { questions: AskQuestion[] };
24
+
25
+ export type PendingAnswer =
26
+ | { kind: "ask"; answers: Record<string, string> }
27
+ | { kind: "plan"; approve: true }
28
+ | { kind: "plan"; approve: false; feedback: string }
29
+ | { kind: "cancel"; message?: string };
30
+
31
+ /** Normalized live events. `sdk` carries raw SDK messages the client renders itself. */
32
+ export type LiveEvent =
33
+ | { k: "sdk"; m: SdkMessageLike; agentId?: string }
34
+ | { k: "delta"; msgId: string; index: number; kind: "text" | "thinking"; text: string; parent: string | null; agentId?: string; checkpoint?: boolean; truncated?: boolean }
35
+ | { k: "user"; uuid: string; text: string; images?: number; ts: number; imageData?: ImageInput[]; scheduled?: boolean }
36
+ /** A `!command` started; its output arrives as a `user` event with the same uuid. */
37
+ | { k: "bash"; uuid: string; command: string; ts: number }
38
+ | { k: "state"; state: SessionState }
39
+ | { k: "pending"; req: PendingRequest }
40
+ | { k: "resolved"; id: string }
41
+ | { k: "settings"; model?: string; effort?: string; planMode: boolean; askQuestionsEnabled?: boolean; writeEnabled?: boolean }
42
+ | { k: "error"; message: string }
43
+ /** History changed underneath (rewind): drop live events and refetch. */
44
+ | { k: "reset"; historyRevision?: string }
45
+ | { k: "crons"; crons: CronInfo[] }
46
+ | { k: "tasks"; tasks: BgTask[] }
47
+ | { k: "agent_tasks"; tasks: AgentTask[] };
48
+
49
+ /** Small lifecycle records survive eviction of the Agent tool's transcript body. */
50
+ export type AgentTask = { toolUseId: string; parentToolUseId?: string; parentTaskId?: string; taskId?: string; runId?: string; status: "pending" | "running" | "paused" | "completed" | "failed" | "stopped" | "killed"; description?: string; agentType?: string; model?: string; background?: boolean };
51
+
52
+ /** A scheduled task (CronCreate, /loop), or a durable task from .claude/scheduled_tasks.json. */
53
+ export type CronInfo = {
54
+ id: string;
55
+ schedule: string;
56
+ recurring: boolean;
57
+ prompt: string;
58
+ nextRun?: number;
59
+ /** Stored in .claude/scheduled_tasks.json, so it survives the CLI process. */
60
+ durable?: boolean;
61
+ /** The session that created a durable task, when the CLI recorded one. */
62
+ createdBySessionId?: string;
63
+ /** A server-side IDECron task rather than a task owned by the CLI process. */
64
+ server?: boolean;
65
+ /** How an IDECron task is delivered while the session is busy. */
66
+ mode?: "steer" | "next_turn" | "interrupt";
67
+ };
68
+
69
+ /** A background task: a backgrounded Bash command, Monitor, or a background subagent. */
70
+ export type BgTask = { id: string; type: string; description: string; status: string; command?: string };
71
+
72
+ /** Loose shape of SDK messages; the client narrows by `type`/`subtype`. */
73
+ export type SdkMessageLike = {
74
+ type: string;
75
+ subtype?: string;
76
+ uuid?: string;
77
+ session_id?: string;
78
+ parent_tool_use_id?: string | null;
79
+ message?: unknown;
80
+ [key: string]: unknown;
81
+ };
82
+
83
+ /** Display history, independent of the model's compacted context. */
84
+ export type HistoryPage = {
85
+ /** Identifies the current session view independently of replay availability. */
86
+ historyRevision?: string;
87
+ items: SdkMessageLike[];
88
+ older?: string;
89
+ newer?: string;
90
+ generation: string;
91
+ todos?: import("./todos.ts").Todo[];
92
+ };
93
+
94
+ export type LiveSnapshot = {
95
+ state: SessionState;
96
+ pending: PendingRequest[];
97
+ model?: string;
98
+ effort?: string;
99
+ planMode: boolean;
100
+ askQuestionsEnabled?: boolean;
101
+ writeEnabled?: boolean;
102
+ crons: CronInfo[];
103
+ /**
104
+ * The server knows there may be scheduled work, but the current CLI process has not reported
105
+ * a task list yet (after a restart, or when only durable tasks are known). The composer offers
106
+ * a one-click refresh in this state.
107
+ */
108
+ cronsStale?: boolean;
109
+ tasks: BgTask[];
110
+ agentTasks?: AgentTask[];
111
+ /** Turn-to-date usage */
112
+ costUsd?: number;
113
+ };
114
+
115
+ export type ClientMsg =
116
+ | { t: "clientVersion"; version: string }
117
+ | { t: "sub"; sessionId: string; projectId: string; epoch?: string; seq?: number; bounded?: boolean }
118
+ | { t: "unsub"; sessionId: string }
119
+ | { t: "send"; sessionId: string; projectId: string; uuid: string; text: string; images?: ImageInput[] }
120
+ | { t: "interrupt"; sessionId: string }
121
+ /** Run one refresh turn so the session's Stop hook reports the restored scheduled tasks. */
122
+ | { t: "refreshCrons"; sessionId: string; projectId: string }
123
+ /** Cancel a server-side IDECron schedule without a model turn. */
124
+ | { t: "cancelIdecron"; sessionId: string; projectId: string; id: string }
125
+ | { t: "setModel"; sessionId: string; projectId: string; model: string }
126
+ | { t: "setEffort"; sessionId: string; projectId: string; effort: string }
127
+ | { t: "setPlanMode"; sessionId: string; projectId: string; on: boolean }
128
+ | { t: "answer"; sessionId: string; requestId: string; answer: PendingAnswer }
129
+ /** The page became visible / hidden (background tabs still get push notifications). */
130
+ | { t: "visibility"; visible: boolean }
131
+ /** Liveness probe after waking up; the server answers with pong. */
132
+ | { t: "ping" }
133
+ /** `!command`: run in the project dir, add the output to the conversation without starting a turn. */
134
+ | { t: "bash"; sessionId: string; projectId: string; uuid: string; command: string };
135
+
136
+ export type ServerMsg =
137
+ | { t: "version"; version: string }
138
+ /** `reset` replaces live replay; historyRevision determines history invalidation. */
139
+ | { t: "snapshot"; sessionId: string; epoch: string; seq: number; reset: boolean; historyRevision?: string; live: LiveSnapshot; events: SeqEvent[] }
140
+ | { t: "ev"; sessionId: string; seq: number; ev: LiveEvent }
141
+ /** A session finished a turn or needs the user — for notifications. Sent to every connection. */
142
+ | { t: "activity"; projectId: string; sessionId: string; kind: "done" | "attention" | "error"; title: string }
143
+ /** Session list of a project changed (new session, title, state…). */
144
+ | { t: "sessions"; projectId: string }
145
+ | { t: "error"; message: string }
146
+ | { t: "pong" };
147
+
148
+ export type SeqEvent = { seq: number; ev: LiveEvent };
149
+
150
+ export type ProjectInfo = { id: string; path: string; name: string; exists: boolean };
151
+
152
+ export type SessionListItem = {
153
+ id: string;
154
+ title: string;
155
+ lastModified: number;
156
+ createdAt?: number;
157
+ state: SessionState;
158
+ pinned: boolean;
159
+ archived: boolean;
160
+ /** Not yet written by the CLI (no message sent). */
161
+ draft: boolean;
162
+ forkedFrom?: string;
163
+ tag?: string;
164
+ needsAttention: boolean;
165
+ /** Set for sessions that run in a git worktree of the project (M4). */
166
+ cwd?: string;
167
+ worktree?: string;
168
+ };
169
+
170
+ /** Where a session runs and where its transcript is stored on disk. */
171
+ export type SessionFileInfo = {
172
+ id: string;
173
+ /** Working directory the conversation resumes in (project, worktree, or after /cd). */
174
+ cwd: string;
175
+ /** Absolute path of the session's jsonl transcript; null until the CLI writes it. */
176
+ file: string | null;
177
+ };
178
+
179
+ /** A slash command or skill offered by the composer's `/` menu. */
180
+ export type CommandInfo = { name: string; description: string; argumentHint: string; aliases?: string[] };
181
+
182
+ /** A /btw side question: a session forked from its parent, listed only inside the parent. */
183
+ export type BtwItem = { id: string; question: string; state: SessionState; answer?: string; lastModified: number };
184
+ export type BtwInfo = { parent: string | null; children: BtwItem[] };
185
+
186
+ export type ContextCategory = { name: string; tokens: number; kind: string };
187
+ export type ContextInfo = { totalTokens: number; maxTokens: number; percentage: number; model: string; categories: ContextCategory[] };
188
+
189
+ export type ModelOption = { value: string; displayName: string; description?: string; efforts?: string[] };
190
+
191
+ /** Project ids in URLs are base64url of the absolute path. */
192
+ export function encodeProjectId(p: string): string {
193
+ const bytes = new TextEncoder().encode(p);
194
+ let bin = "";
195
+ for (const b of bytes) bin += String.fromCharCode(b);
196
+ return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
197
+ }
198
+
199
+ export function decodeProjectId(id: string): string {
200
+ const b64 = id.replace(/-/g, "+").replace(/_/g, "/");
201
+ const bin = atob(b64 + "=".repeat((4 - (b64.length % 4)) % 4));
202
+ return new TextDecoder().decode(Uint8Array.from(bin, (c) => c.charCodeAt(0)));
203
+ }
@@ -0,0 +1,4 @@
1
+ /** Stream task events use local_agent; Stop-hook summaries use subagent. */
2
+ export function isSubagentTaskType(type: unknown): boolean {
3
+ return type === "local_agent" || type === "subagent";
4
+ }
@@ -0,0 +1,40 @@
1
+ export type TodoItem = { kind: string; name?: string; input?: Record<string, unknown>; result?: { content: unknown; isError: boolean; structured?: unknown } };
2
+
3
+ export type Todo = { id: string; subject: string; status: "pending" | "in_progress" | "completed"; activeForm?: string };
4
+
5
+ /** The todo list Claude maintains, replayed from TaskCreate/TaskUpdate (or legacy TodoWrite) calls. */
6
+ export function deriveTodos(items: TodoItem[], initial: Todo[] = []): Todo[] {
7
+ let todos = new Map<string, Todo>(initial.map((t) => [t.id, t]));
8
+ let created = 0;
9
+ for (const it of items) {
10
+ if (it.kind !== "tool") continue;
11
+ const input = it.input as Record<string, unknown>;
12
+ if (it.name === "TodoWrite" && Array.isArray(input.todos)) {
13
+ todos = new Map(
14
+ (input.todos as { content: string; status: Todo["status"]; activeForm?: string }[]).map((t, i) => [
15
+ String(i),
16
+ { id: String(i), subject: t.content, status: t.status, activeForm: t.activeForm },
17
+ ]),
18
+ );
19
+ } else if (it.name === "TaskCreate") {
20
+ if (!it.result || it.result.isError) continue;
21
+ const structured = it.result?.structured as { task?: { id?: string } } | undefined;
22
+ const text = typeof it.result?.content === "string" ? it.result.content : JSON.stringify(it.result?.content ?? "");
23
+ const id = structured?.task?.id ?? text.match(/Task #(\d+)/)?.[1] ?? String(++created);
24
+ todos.set(id, { id, subject: String(input.subject ?? ""), status: "pending", activeForm: input.activeForm as string | undefined });
25
+ } else if (it.name === "TaskUpdate") {
26
+ const id = String(input.taskId ?? "");
27
+ const cur = todos.get(id);
28
+ if (!cur) continue;
29
+ if (input.status === "deleted") todos.delete(id);
30
+ else
31
+ todos.set(id, {
32
+ ...cur,
33
+ ...(input.subject ? { subject: String(input.subject) } : {}),
34
+ ...(input.activeForm ? { activeForm: String(input.activeForm) } : {}),
35
+ ...(input.status ? { status: input.status as Todo["status"] } : {}),
36
+ });
37
+ }
38
+ }
39
+ return [...todos.values()].slice(-1024);
40
+ }
@@ -0,0 +1,9 @@
1
+ /** Shell commands are disabled in full; command text is never classified. */
2
+ export const WRITE_TOOLS = new Set(["Bash", "Write", "Edit", "MultiEdit", "NotebookEdit", "EnterWorktree", "ExitWorktree"]);
3
+ /** Unknown/extension tools must not silently bypass a read-only session. Agent
4
+ * tools may be used in ordinary read-only sessions, with the same hook guarding
5
+ * their children; btw separately forbids delegation altogether. */
6
+ export const READ_ONLY_TOOLS = new Set(["Read", "Grep", "Glob", "WebSearch", "WebFetch", "ToolSearch", "Skill", "ListMcpResources", "ReadMcpResource",
7
+ "AskUserQuestion", "ExitPlanMode", "TodoWrite", "TaskCreate", "TaskUpdate", "TaskGet", "TaskList", "Agent", "Task", "mcp__IDEMessages__ide_list_alias"]);
8
+ export const SIDE_AGENT_TOOLS = new Set(["Agent", "Task", "SendMessage", "TaskOutput", "TaskStop", "mcp__IDEMessages__ide_send_message"]);
9
+ export const WRITES_DISABLED = "本会话已开启「只读」,不能使用该工具。需要执行时,请用户关闭「只读」。";
@@ -0,0 +1 @@
1
+ import{at as e,b as t,ht as n,mt as r,ut as i,vt as a,w as o}from"./Form-BKTwiYyw.js";import{v as s}from"./Modal-g2rv8I_n.js";import{a as c,g as l,h as u,t as d}from"./lib-DlcVMUqT.js";import{J as f,K as p,U as m,W as h,X as g,h as _}from"./index-DQh72lEx.js";import{c as v,d as y,l as b,p as x,r as S,s as C,t as w}from"./MessageList-DD9GypSy.js";import{c as T,d as E,t as D}from"./AnnotationSelection-BZmNmwVW.js";var O=a(n(),1),k=r(),A=[],j={before:()=>null,tail:null};function M(){let{pid:e,sid:t,tid:n}=u(),[r,a]=c(),o=f(t),_=E(e=>e.mode);(0,O.useEffect)(()=>p(t,e),[t,e]),(0,O.useEffect)(()=>T(e,t),[e,t]);let M=s().data?.find(t=>t.id===e),P=(0,O.useMemo)(()=>g(void 0,o?.events??[]),[o?.events]).find(e=>e.kind===`tool`&&e.id===n),F=l(C(e,t,()=>i(`/api/projects/${e}/sessions/${t}/subagents`))),I=o?.snapshot.agentTasks,L=I?.find(e=>e.toolUseId===n),R=y(F.data??[],n,L?.taskId??o?.agentOwners?.[n],r.get(`agent`)??void 0),z=(R&&x(I??[],R.agentId))??L,B=z?.toolUseId??n,V=(0,O.useMemo)(()=>b(n,I??[],R,o?.agentOwners),[n,I,R?.agentId,R?.toolUseId,o?.agentOwners]),H=z?.status??`unknown`,U=r.get(`agent`);(0,O.useEffect)(()=>{R&&U!==R.agentId&&a(e=>{let t=new URLSearchParams(e);return t.set(`agent`,R.agentId),t},{replace:!0})},[R?.agentId,U,a]);let W=(0,O.useRef)({pid:e,sid:t,taskStatus:H});(0,O.useEffect)(()=>{let n=W.current;W.current={pid:e,sid:t,taskStatus:H},n.pid===e&&n.sid===t&&n.taskStatus!==H&&F.refetch()},[e,t,H,F.refetch]);let G=R&&o?.history?.source===R.agentId?o.history:void 0,K=z?.model??v(B,o?.events??A,G?.items),q=o?.resetCount;(0,O.useEffect)(()=>{R&&q!==void 0&&h(t,e,`latest`,R.agentId)},[t,e,R?.agentId,q]);let J=G?.mode===`history`,Y=J?A:o?.events??A,X=(0,O.useMemo)(()=>g(G?.items,Y,{parent:B,parents:V}),[G?.items,Y,B,V]),Z=!J&&H===`running`,Q=!J&&(H===`pending`||H===`paused`),$=R?void 0:F.isError?F.error.message:F.isSuccess?`未找到该子 agent 的会话记录,请重试`:void 0;return(0,k.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col`,children:[(0,k.jsxs)(`header`,{className:`flex min-w-0 items-center gap-3 border-b border-border px-4 py-2.5 md:px-6`,children:[(0,k.jsx)(d,{to:`/p/${e}/s/${t}`,className:`shrink-0 rounded-md px-2 py-1.5 text-sm text-muted hover:bg-surface-2`,children:`← 返回会话`}),(0,k.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,k.jsx)(`h1`,{className:`truncate text-lg`,children:R?.description||z?.description||P?.input.description||`子 agent`}),(0,k.jsxs)(`p`,{className:`truncate text-xs text-muted`,title:K,"data-testid":`agent-model`,children:[`模型:`,K??([`pending`,`running`,`paused`].includes(H)?`等待响应`:`未记录`)]})]}),R?.agentType&&(0,k.jsx)(`span`,{className:`hidden shrink-0 text-xs text-muted sm:inline`,children:R.agentType}),(Z||Q||R)&&(0,k.jsxs)(`div`,{className:`ml-auto flex shrink-0 items-center gap-2`,children:[Z&&(0,k.jsx)(`span`,{className:`size-2 animate-pulse rounded-full bg-accent`,"aria-label":`运行中`}),Q&&(0,k.jsx)(`span`,{className:`text-xs text-muted`,children:H===`paused`?`已暂停`:`等待开始`}),R&&(0,k.jsx)(N,{id:R.agentId})]})]}),(0,k.jsx)(S.Provider,{value:{root:M?.path,sessionUrl:`/p/${e}/s/${t}`,viewKey:`/p/${e}/s/${t}/agent/${n}`,readImageUrl:n=>R?`/api/projects/${e}/sessions/${t}/tools/${encodeURIComponent(n)}/image?${new URLSearchParams({agent:R.agentId})}`:void 0,loadMessage:n=>R?m(t,e,n,R.agentId):Promise.reject(Error(`尚未找到子 agent 的会话记录,请重新加载`))},children:(0,k.jsx)(D,{projectId:e,sessionId:t,agentToolUseId:n,enabled:_,className:`flex min-h-0 flex-1 flex-col`,children:(0,k.jsx)(w,{items:X,loading:F.isPending||!!R&&(!G||!!G.loading&&!G.items.length),running:Z,waiting:Q,turnSlots:j,history:{older:!!G?.older,newer:!!G?.newer,historical:J,loading:F.isFetching&&!R||!!G?.loading,error:G?.error??$,load:async n=>{R?await h(t,e,n,R.agentId):await F.refetch()}}},`${e}:${t}:${n}`)})})]})}function N({id:n}){let[r,i]=(0,O.useState)(`idle`),a=(0,O.useRef)(void 0);return(0,O.useEffect)(()=>()=>clearTimeout(a.current),[]),(0,k.jsx)(e,{size:`sm`,variant:`ghost`,icon:r===`copied`?(0,k.jsx)(t,{}):(0,k.jsx)(o,{}),onClick:async()=>{clearTimeout(a.current);try{await _(n),i(`copied`)}catch{i(`error`)}a.current=setTimeout(()=>i(`idle`),1500)},title:`复制子会话 ID:${n}`,"aria-label":`复制子会话 ID`,"data-testid":`copy-agent-id`,children:r===`copied`?`已复制`:r===`error`?`复制失败`:`复制 ID`})}export{M as AgentView};
@@ -0,0 +1,7 @@
1
+ import{at as e,f as t,ht as n,mt as r,vt as i}from"./Form-BKTwiYyw.js";import{S as a,r as o,y as s}from"./Modal-g2rv8I_n.js";import{f as c,t as l}from"./lib-DlcVMUqT.js";import{t as u}from"./react-B4UGpcWC.js";import{D as d,b as f}from"./index-DQh72lEx.js";var p=[`.png`,`.jpg`,`.jpeg`,`.gif`,`.webp`,`.avif`,`.bmp`,`.ico`,`.svg`],m={".mp3":`audio/mpeg`,".wav":`audio/wav`,".wave":`audio/wav`,".ogg":`audio/ogg`,".oga":`audio/ogg`,".opus":`audio/ogg`,".m4a":`audio/mp4`,".aac":`audio/aac`,".flac":`audio/flac`,".weba":`audio/webm`,".aif":`audio/aiff`,".aiff":`audio/aiff`},h=52428800,g=i(n(),1),_=a(),v=`cide.annotations.v1`,y=u(()=>({items:[],mode:!1,recentSessions:{}})),b=!1,x=!1,S=0;function C(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function w(e){return typeof e==`string`&&e.length>0}function T(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>0}function E(e){return C(e)?e.kind===`file`?w(e.path)&&(e.startLine===void 0||T(e.startLine))&&(e.endLine===void 0||T(e.endLine))&&(e.startLine===void 0||e.endLine===void 0||e.endLine>=e.startLine):e.kind===`message`&&w(e.sessionId)&&w(e.itemKey)&&(e.agentToolUseId===void 0||w(e.agentToolUseId)):!1}function D(e){return C(e)&&w(e.id)&&w(e.projectId)&&w(e.targetSessionId)&&E(e.source)&&typeof e.quote==`string`&&typeof e.comment==`string`&&typeof e.revision==`number`&&Number.isSafeInteger(e.revision)&&e.revision>0&&typeof e.createdAt==`number`&&Number.isFinite(e.createdAt)&&e.createdAt>=0&&typeof e.updatedAt==`number`&&Number.isFinite(e.updatedAt)&&e.updatedAt>=e.createdAt}function O(e){return!C(e)||e.version!==1||!Array.isArray(e.items)||!e.items.every(D)||typeof e.mode!=`boolean`||!C(e.recentSessions)||!Object.values(e.recentSessions).every(w)?!1:new Set(e.items.map(e=>e.id)).size===e.items.length}function k(e){return{...e,source:{...e.source}}}function A(e,t){let n=t instanceof Error?t.message:String(t);return e===`load`?`无法读取已保存的批注。原数据已保留,本次修改仅保存在内存中。${n}`:`批注未能保存,当前修改仅保存在内存中。${n}`}function j(){if(!b)try{if(typeof localStorage>`u`)return;let e=localStorage.getItem(v);if(b=!0,e===null)return;let t=JSON.parse(e);if(!O(t))throw Error(`保存的批注数据格式或版本无效。`);y.setState({items:t.items.map(k),mode:t.mode,recentSessions:{...t.recentSessions},storageError:void 0})}catch(e){b=!0,x=!0,y.setState({storageError:A(`load`,e)})}}function M(){if(b=!0,x)return;let{items:e,mode:t,recentSessions:n}=y.getState();try{if(typeof localStorage>`u`)throw Error(`浏览器存储不可用。`);let r={version:1,items:e,mode:t,recentSessions:n};localStorage.setItem(v,JSON.stringify(r)),y.setState({storageError:void 0})}catch(e){y.setState({storageError:A(`save`,e)})}}function N(e){j();let t=Date.now(),n=globalThis.crypto?.randomUUID?.()??`annotation-${t}-${++S}-${Math.random().toString(36).slice(2)}`,r={...e,source:{...e.source},id:n,revision:1,createdAt:t,updatedAt:t};return y.setState(e=>({items:[...e.items,r]})),M(),k(r)}function P(e,t){j();let n=y.getState().items.find(t=>t.id===e);n&&n.comment!==t&&(y.setState(n=>({items:n.items.map(n=>n.id===e?{...n,comment:t,revision:n.revision+1,updatedAt:Math.max(Date.now(),n.updatedAt)}:n)})),M())}function F(e){j();let t=y.getState().items;t.some(t=>t.id===e)&&(y.setState({items:t.filter(t=>t.id!==e)}),M())}function I(e){j(),y.setState({mode:e}),M()}function L(e,t){j(),y.setState(n=>({recentSessions:{...n.recentSessions,[e]:t}})),M()}function R(e,t){return j(),y.getState().items.filter(n=>n.projectId===e&&n.targetSessionId===t).map(k)}function z(e){j();let t=new Map(e.map(e=>[e.id,e.revision])),n=y.getState().items,r=n.filter(e=>t.get(e.id)!==e.revision);r.length!==n.length&&(y.setState({items:r}),M())}function B(e,t){if(!t.length)return e;let n=t.map(e=>`${e.source.kind===`file`?`User comments on File ${e.source.path}:`:`User comments:`}\n${e.quote.split(`
2
+ `).map(e=>`> ${e}`).join(`
3
+ `)}\n\n${e.comment}`),r=/^[!/]/.test(e.trimStart())?`User message:\n${e}`:e;return(r?[r,...n]:n).join(`
4
+
5
+ `)}j();function V(e,t,n){let r=e.split(`
6
+ `),i=[0];for(let e=0;e<r.length-1;e++)i.push(i[e]+r[e].length+1);let a=e=>{let t=Math.max(0,Math.min(r.length-1,e.line)),n=r[t].replace(/\r$/,``).length;return i[t]+Math.max(0,Math.min(n,e.column))},o=a(t),s=a(n);if(o>=s)return null;let c=n.column===0&&n.line>t.line?n.line-1:n.line;return{quote:e.slice(o,s),startLine:t.line+1,endLine:c+1}}var H=`button, input, textarea, select, option, [role="button"], [role="menu"], [role="dialog"], [contenteditable]:not([contenteditable="false"]), [data-annotation-exclude], [data-line-number], .line-number, [data-testid="show-all"], [aria-hidden="true"], script, style`;function U(e){return e.nodeType===1?e:e.parentElement}function W(e,t){if(!e.contains(t.startContainer)||!e.contains(t.endContainer)||U(t.startContainer)?.closest(H)||U(t.endContainer)?.closest(H))return!1;for(let n of e.querySelectorAll(H))if(t.intersectsNode(n))return!1;return!0}function G(e,t,n,r){let i=U(n)?.closest(`.line`);if(i&&i.parentElement===e){let a=t.indexOf(i);if(a<0)return null;let o=e.ownerDocument.createRange();return o.selectNodeContents(i),o.setEnd(n,r),{line:a,column:o.toString().length}}if(n===e){let n=e.childNodes[r];if(n){let e=t.findIndex(e=>e===n||e.contains(n));if(e>=0)return{line:e,column:0}}if(r===e.childNodes.length&&t.length)return{line:t.length-1,column:t.at(-1).textContent?.length??0}}return null}function K(e,t,n){if(!t||t.isCollapsed||t.rangeCount!==1)return null;let r=t.getRangeAt(0);if(!W(e,r))return null;let i,a;if(n.filePath!==void 0){let t=U(r.startContainer)?.closest(`.code-view code`);if(!t||!e.contains(t)||!t.contains(r.endContainer))return null;let o=[...t.children].filter(e=>e.classList.contains(`line`)),s=G(t,o,r.startContainer,r.startOffset),c=G(t,o,r.endContainer,r.endOffset);if(!s||!c)return null;let l=V(n.fileContent??o.map(e=>e.textContent??``).join(`
7
+ `),s,c);if(!l)return null;a=l.quote,i={kind:`file`,path:n.filePath,startLine:l.startLine,endLine:l.endLine}}else{if(!n.sessionId)return null;let o=U(r.startContainer)?.closest(`[data-annotation-item]`),s=U(r.endContainer)?.closest(`[data-annotation-item]`),c=o?.dataset.annotationItem;if(!o||!c||o!==s||!e.contains(o))return null;a=t.toString(),i={kind:`message`,sessionId:n.sessionId,itemKey:c,...n.agentToolUseId?{agentToolUseId:n.agentToolUseId}:{}}}if(!a.trim())return null;let o=r.getBoundingClientRect();return!o.width&&!o.height?null:{source:i,quote:a,rect:{left:o.left,right:o.right,top:o.top,bottom:o.bottom}}}function q(e,t){let n=Math.min(112,Math.max(0,t.width-16)),r=t.left+8,i=t.top+8,a=Math.max(r,t.left+t.width-n-8),o=Math.max(i,t.top+t.height-40-8),s=e.bottom+8;return{width:n,left:Math.max(r,Math.min(a,(e.left+e.right-n)/2)),top:Math.max(i,Math.min(o,s+40>t.top+t.height-8?e.top-40-8:s))}}var J=r();function Y(e){let t=e.startLine?`:${e.startLine}${e.endLine&&e.endLine!==e.startLine?`–${e.endLine}`:``}`:``;return`${e.path}${t}`}function X({projectId:e,source:t}){if(t.kind!==`file`)return null;let n=`${`/p/${encodeURIComponent(e)}`}/files/${f(t.path)}${t.startLine?`?line=${t.startLine}`:``}`;return(0,J.jsx)(l,{to:n,title:Y(t),className:`min-w-0 truncate text-xs text-accent hover:underline`,children:Y(t)})}function Z({projectId:n,sessionId:r,source:i,quote:a,annotation:c,onClose:l}){let u=s(n),f=y(e=>e.recentSessions[n]),p=y(e=>e.storageError),[m,h]=(0,g.useState)(c?.comment??``),[v,b]=(0,g.useState)(f??``),[x,S]=(0,g.useState)(``),C=(0,g.useId)(),w=(0,g.useId)(),T=c?.targetSessionId??r,E=u.data??[],D=E.find(e=>e.id===v),O=T??D?.id,k=E.find(e=>e.id===T)?.title,A=!!v&&!D&&u.isSuccess,M=new Map;for(let e of E){let t=e.title.trim()||`未命名会话`;M.set(t,(M.get(t)??0)+1)}let F=E.map(e=>{let t=e.title.trim()||`未命名会话`,n=new Date(e.createdAt??e.lastModified).toLocaleString(`zh-CN`,{year:`numeric`,month:`numeric`,day:`numeric`,hour:`2-digit`,minute:`2-digit`});return{id:e.id,label:(M.get(t)??0)>1?`${t} · ${n}`:t}});(0,g.useEffect)(()=>{j()},[]);function I(){if(m.trim()&&O)try{c?P(c.id,m.trim()):N({projectId:n,targetSessionId:O,source:i,quote:a,comment:m.trim()}),L(n,O),l()}catch(e){S(e instanceof Error?e.message:`无法保存批注,请重试。`)}}return(0,_.createPortal)((0,J.jsx)(o,{title:c?`编辑批注`:`添加批注`,onClose:l,testId:`annotation-editor`,children:(0,J.jsxs)(`div`,{className:`space-y-4`,"data-annotation-exclude":!0,children:[(0,J.jsxs)(`div`,{children:[i.kind===`file`&&(0,J.jsxs)(`div`,{className:`mb-1.5 flex min-w-0 items-center gap-2`,children:[(0,J.jsx)(`span`,{className:`shrink-0 text-xs text-muted`,children:`来源`}),(0,J.jsx)(X,{projectId:n,source:i})]}),(0,J.jsx)(`pre`,{"data-testid":`annotation-quote`,className:`max-h-40 overflow-auto whitespace-pre-wrap break-words rounded-md border border-border bg-surface-2/60 px-3 py-2 font-mono text-xs leading-relaxed`,children:a})]}),(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`label`,{htmlFor:C,className:`mb-1.5 block text-xs font-medium text-muted`,children:`发送到会话`}),T?(0,J.jsx)(`div`,{id:C,"data-testid":`annotation-target`,"data-value":T,className:`rounded-md border border-border bg-surface-2/60 px-3 py-2 text-sm`,children:(0,J.jsx)(`span`,{className:`block truncate`,children:k?.trim()||`当前会话`})}):(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(d,{id:C,label:`发送到会话`,testId:`annotation-target`,value:D?.id??``,onChange:b,options:F.map(e=>({value:e.id,label:e.label})),placeholder:u.isPending?`正在加载会话…`:`请选择会话`,emptyText:`此项目暂无会话`,disabled:u.isPending||u.isError||E.length===0,className:`w-full min-w-0`}),u.isError&&(0,J.jsxs)(`p`,{role:`alert`,className:`mt-1 text-xs text-danger`,children:[`会话列表加载失败:`,u.error.message]}),u.isSuccess&&E.length===0&&(0,J.jsx)(`p`,{className:`mt-1 text-xs text-muted`,children:`此项目暂无会话。请先打开或创建一个会话,再添加批注。`}),A&&(0,J.jsx)(`p`,{className:`mt-1 text-xs text-muted`,children:`最近使用的会话已不可用,请重新选择。`})]})]}),(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`label`,{htmlFor:w,className:`mb-1.5 block text-xs font-medium text-muted`,children:`批注内容`}),(0,J.jsx)(`textarea`,{id:w,"data-testid":`annotation-comment`,autoFocus:!0,rows:4,value:m,onChange:e=>{h(e.target.value),S(``)},onKeyDown:e=>{(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&!e.nativeEvent.isComposing&&(e.preventDefault(),I())},placeholder:`写下希望 agent 处理的内容…`,className:t}),(0,J.jsx)(`p`,{className:`mt-1 text-xs text-muted`,children:`保存后会随该会话的下一条消息发送。`})]}),(x||p)&&(0,J.jsx)(`p`,{role:`alert`,className:`text-xs text-danger`,children:x||p}),(0,J.jsxs)(`div`,{className:`flex justify-end gap-2`,children:[(0,J.jsx)(e,{onClick:l,children:`取消`}),(0,J.jsx)(e,{variant:`primary`,onClick:I,disabled:!m.trim()||!O,"data-testid":`annotation-save`,children:`保存批注`})]})]})}),document.body)}function Q({projectId:t,sessionId:n,agentToolUseId:r,filePath:i,fileContent:a,enabled:o=!0,children:s,className:l}){let u=(0,g.useRef)(null),d=(0,g.useRef)(null),[f,p]=(0,g.useState)(null),[m,h]=(0,g.useState)(null),v=y(e=>e.storageError),b=c();(0,g.useEffect)(()=>{p(null),h(null)},[t,n,r,i,b.key]),(0,g.useEffect)(()=>{if(!o||m){p(null);return}let e=0,t=!1,s=()=>{e=0,!t&&u.current&&p(K(u.current,window.getSelection(),{sessionId:n,agentToolUseId:r,filePath:i,fileContent:a}))},c=()=>{e&&cancelAnimationFrame(e),e=requestAnimationFrame(s)},l=e=>{e.target instanceof Node&&d.current?.contains(e.target)||(t=e.target instanceof Node&&!!u.current?.contains(e.target),p(null))},f=()=>{let e=t;t=!1,e&&c()},h=()=>{t=!1,e&&cancelAnimationFrame(e),e=0,p(null)},g=e=>{e.key===`Escape`&&h()};return document.addEventListener(`selectionchange`,c),document.addEventListener(`pointerdown`,l),document.addEventListener(`pointerup`,f),document.addEventListener(`pointercancel`,h),document.addEventListener(`scroll`,h,!0),document.addEventListener(`keydown`,g),window.addEventListener(`resize`,h),window.visualViewport?.addEventListener(`resize`,h),window.visualViewport?.addEventListener(`scroll`,h),()=>{e&&cancelAnimationFrame(e),document.removeEventListener(`selectionchange`,c),document.removeEventListener(`pointerdown`,l),document.removeEventListener(`pointerup`,f),document.removeEventListener(`pointercancel`,h),document.removeEventListener(`scroll`,h,!0),document.removeEventListener(`keydown`,g),window.removeEventListener(`resize`,h),window.visualViewport?.removeEventListener(`resize`,h),window.visualViewport?.removeEventListener(`scroll`,h)}},[o,m,n,r,i,a]);let x=typeof window<`u`?window.visualViewport:null,S=typeof window<`u`?{left:x?.offsetLeft??0,top:x?.offsetTop??0,width:x?.width??window.innerWidth,height:x?.height??window.innerHeight}:null,C=f&&S?q(f.rect,S):null;return(0,J.jsxs)(`div`,{ref:u,className:l,children:[i!==void 0&&v&&(0,J.jsx)(`p`,{role:`alert`,"data-testid":`annotation-storage-error`,"data-annotation-exclude":!0,className:`shrink-0 border-b border-danger/30 bg-danger/5 px-3 py-2 text-xs text-danger`,children:v}),s,f&&C&&S&&(0,_.createPortal)((0,J.jsx)(e,{ref:d,variant:`primary`,"data-testid":`annotation-add`,className:`fixed z-40 shadow-lg`,style:{width:`min(${C.width}px, calc(100vw - max(8px, env(safe-area-inset-left)) - max(8px, env(safe-area-inset-right))))`,left:`clamp(max(${S.left+8}px, env(safe-area-inset-left)), ${C.left}px, min(${S.left+S.width-C.width-8}px, calc(100vw - ${C.width}px - max(8px, env(safe-area-inset-right)))))`,top:`clamp(max(${S.top+8}px, env(safe-area-inset-top)), ${C.top}px, min(${S.top+S.height-48}px, calc(100dvh - 40px - max(8px, env(safe-area-inset-bottom)))))`},onPointerDown:e=>e.preventDefault(),onClick:()=>{h(f),p(null)},children:`添加批注`}),document.body),m&&(0,J.jsx)(Z,{projectId:t,sessionId:n,source:m.source,quote:m.quote,onClose:()=>h(null)})]})}export{F as a,L as c,y as d,m as f,z as i,I as l,h as m,Z as n,j as o,p,X as r,B as s,Q as t,R as u};
@@ -0,0 +1,2 @@
1
+ import{K as e,O as t,T as n,a as r,at as i,b as a,ct as o,ht as s,lt as c,m as l,mt as u,n as d,s as f,ut as p,v as m,vt as h}from"./Form-BKTwiYyw.js";import{I as g,a as _,g as v,h as y,t as b}from"./lib-DlcVMUqT.js";import{E as x,b as S,x as C,y as w}from"./index-DQh72lEx.js";var T=h(s(),1),E=u();function D(e){let t=[],n=0,r=0,i=!1,a=e.split(`
2
+ `);a[a.length-1]===``&&a.pop();for(let e of a){if(e.startsWith(`diff --git `)){i=!1;continue}let a=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@(.*)$/.exec(e);a?(n=Number(a[1]),r=Number(a[2]),i=!0,t.push({kind:`hunk`,text:e})):i?e.startsWith(`+`)?t.push({kind:`add`,text:e.slice(1),new:r++}):e.startsWith(`-`)?t.push({kind:`del`,text:e.slice(1),old:n++}):e.startsWith(`\\`)?t.push({kind:`meta`,text:e}):t.push({kind:`ctx`,text:e.slice(1),old:n++,new:r++}):/^(Binary files|new file mode|deleted file mode|old mode|new mode|similarity|rename )/.test(e)&&t.push({kind:`meta`,text:e})}return t}var O={add:`bg-ok/15`,del:`bg-danger/15`,ctx:``,hunk:`bg-accent/5 text-muted border-y border-border`,meta:`text-muted italic`},k={add:`+`,del:`-`,ctx:` `,hunk:``,meta:``};function A(e){let t=0,n=0;for(let r of D(e))r.kind===`add`?t++:r.kind===`del`&&n++;return{add:t,del:n}}function j({diff:e}){let t=(0,T.useMemo)(()=>D(e),[e]);return t.length===0?(0,E.jsx)(`p`,{className:`m-4 rounded-xl border border-dashed border-border px-6 py-8 text-center text-sm text-muted`,children:`没有可显示的差异。文件可能只改了权限,或者改动已经还原。`}):(0,E.jsx)(`div`,{className:`overflow-x-auto`,"data-testid":`diff-view`,children:(0,E.jsx)(`table`,{className:`diff-table min-w-full border-collapse font-mono text-[12.5px] leading-5`,children:(0,E.jsx)(`tbody`,{children:t.map((e,t)=>e.kind===`hunk`||e.kind===`meta`?(0,E.jsx)(`tr`,{className:O[e.kind],children:(0,E.jsx)(`td`,{colSpan:4,className:`whitespace-pre px-3 py-1`,children:e.text})},t):(0,E.jsxs)(`tr`,{className:O[e.kind],"data-kind":e.kind,children:[(0,E.jsx)(`td`,{className:`diff-ln`,children:e.old??``}),(0,E.jsx)(`td`,{className:`diff-ln`,children:e.new??``}),(0,E.jsx)(`td`,{className:`w-4 select-none pl-1 text-center ${e.kind===`add`?`text-ok`:e.kind===`del`?`text-danger`:`text-muted`}`,children:k[e.kind]}),(0,E.jsx)(`td`,{className:`whitespace-pre pr-4`,children:e.text})]},t))})})})}var M={M:`text-accent`,A:`text-ok`,D:`text-danger`,U:`text-danger`,"??":`text-ok`},N={M:`accent`,A:`ok`,D:`danger`,U:`danger`,"??":`ok`},P={M:`已修改`,A:`新增`,D:`已删除`,U:`冲突`,"??":`未跟踪`},F=[`U`,`M`,`A`,`??`,`D`];function I(){let{pid:t}=y(),[s]=_(),c=g(),l=v({queryKey:[`git-status`,t],queryFn:()=>p(`/api/projects/${t}/git/status`),refetchOnWindowFocus:!0}),u=l.data?.isRepo===!1?``:s.get(`path`)??``,h=()=>{c.invalidateQueries({queryKey:[`git-status`,t]}),c.invalidateQueries({queryKey:[`git-diff`,t]})},S=l.data?.isRepo?l.data.changes:[],C=(0,T.useMemo)(()=>{let e=new Map;for(let t of S)e.set(t.status,(e.get(t.status)??0)+1);return F.filter(t=>e.get(t)).map(t=>[t,e.get(t)])},[S]);return(0,E.jsxs)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col`,children:[(0,E.jsx)(w,{projectId:t,children:(0,E.jsx)(i,{variant:`ghost`,size:`sm`,icon:(0,E.jsx)(e,{}),onClick:h,loading:l.isFetching,children:`刷新`})}),(0,E.jsxs)(`div`,{className:`flex min-h-0 min-w-0 flex-1`,children:[(0,E.jsx)(x,{storageKey:`claude-ide:changes-width`,label:`调整变更列表宽度`,defaultWidth:320,className:o(u?`hidden md:flex`:`flex`,`min-h-0 w-full flex-col border-border bg-surface-2/30 md:border-r`),children:l.isPending?(0,E.jsx)(`div`,{className:`p-3`,children:(0,E.jsx)(r,{rows:5})}):l.isError?(0,E.jsx)(`p`,{className:`p-4 text-sm text-danger`,children:l.error.message}):l.data.isRepo?(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`div`,{className:`space-y-1.5 border-b border-border px-3 py-2.5`,children:[(0,E.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1.5 text-xs text-muted`,children:[(0,E.jsx)(m,{className:`shrink-0`}),l.data.branch?(0,E.jsx)(`span`,{className:`truncate font-mono text-text`,children:l.data.branch}):`分离的 HEAD`,(0,E.jsxs)(`span`,{className:`ml-auto shrink-0`,children:[l.data.changes.length,` 个文件有变更`]})]}),C.length>0&&(0,E.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:C.map(([e,t])=>(0,E.jsxs)(f,{tone:N[e],children:[P[e],` `,t]},e))})]}),(0,E.jsxs)(`ul`,{className:`min-h-0 flex-1 overflow-y-auto py-1`,"aria-label":`变更文件`,children:[l.data.changes.map(e=>{let n=e.path.lastIndexOf(`/`);return(0,E.jsx)(`li`,{children:(0,E.jsxs)(b,{to:`/p/${t}/changes?path=${encodeURIComponent(e.path)}`,"aria-current":u===e.path?`page`:void 0,className:o(`flex items-center gap-2 px-3 py-2 text-sm md:py-1.5`,u===e.path?`bg-accent/10 font-medium`:`hover:bg-surface-2/80`),"data-testid":`change-item`,title:`${e.path} · ${P[e.status]}${e.staged?` · 已暂存`:``}`,children:[(0,E.jsx)(`span`,{className:o(`w-5 shrink-0 text-center font-mono text-xs font-semibold`,M[e.status]),title:P[e.status],"data-status":e.status,children:e.status}),(0,E.jsxs)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[13px]`,dir:`ltr`,children:[n>0&&(0,E.jsx)(`span`,{className:`text-muted`,children:e.path.slice(0,n+1)}),e.path.slice(n+1)]}),e.staged&&(0,E.jsx)(`span`,{className:`shrink-0 text-[11px] text-ok`,title:`已暂存(git add)`,children:`已暂存`})]})},`${e.path}:${e.status}`)}),l.data.changes.length===0&&(0,E.jsx)(`li`,{className:`p-3`,children:(0,E.jsx)(d,{icon:(0,E.jsx)(a,{size:16}),title:`工作区是干净的,没有变更`,compact:!0,children:`Claude 改动文件后,这里会列出每个文件,点开即可看 diff。`})})]})]}):(0,E.jsx)(`div`,{className:`p-4`,children:(0,E.jsxs)(d,{icon:(0,E.jsx)(n,{size:16}),title:`不是 git 仓库`,testId:`not-git`,compact:!0,children:[`这个项目不是 git 仓库,无法查看变更。在项目目录里运行 `,(0,E.jsx)(`code`,{className:`font-mono`,children:`git init`}),` 后刷新即可。`]})})}),(0,E.jsx)(`section`,{className:o(u?`flex`:`hidden md:flex`,`min-h-0 min-w-0 flex-1 flex-col`),children:u?(0,E.jsx)(L,{pid:t,path:u}):(0,E.jsx)(`div`,{className:`m-auto w-full max-w-md p-6`,children:(0,E.jsx)(d,{icon:(0,E.jsx)(n,{size:16}),title:S.length?`选择左侧的文件查看 diff`:`没有可查看的 diff`,children:S.length?`共 ${S.length} 个文件有未提交的改动(相对 HEAD,包括未跟踪的新文件)。`:`这里显示工作区相对 HEAD 的改动。每一轮对话改了哪些文件,也可以在会话里的“本轮改动”查看。`})})})]})]})}function L({pid:e,path:n}){let i=v({queryKey:[`git-diff`,e,n],queryFn:()=>p(C(e,`git/diff`,{path:n}))}),a=(0,T.useMemo)(()=>i.data?A(i.data.diff):null,[i.data]),o=n.lastIndexOf(`/`),s=i.data?.status;return(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 border-b border-border px-2 py-1.5 md:px-4`,children:[(0,E.jsxs)(b,{to:`/p/${e}/changes`,className:`inline-flex h-10 shrink-0 items-center gap-1.5 rounded-md px-2.5 text-sm text-muted hover:bg-surface-2 hover:text-text md:hidden`,"aria-label":`返回变更列表`,children:[(0,E.jsx)(l,{}),`返回`]}),(0,E.jsxs)(`div`,{className:`min-w-0 flex-1 truncate font-mono text-sm`,title:n,children:[o>0&&(0,E.jsx)(`span`,{className:`text-muted`,children:n.slice(0,o+1)}),(0,E.jsx)(`span`,{className:`font-medium`,children:n.slice(o+1)})]}),s&&(0,E.jsx)(f,{tone:N[s],children:P[s]}),a&&(a.add>0||a.del>0)&&(0,E.jsxs)(`span`,{className:`hidden shrink-0 font-mono text-xs sm:inline`,children:[(0,E.jsxs)(`span`,{className:`text-ok`,children:[`+`,a.add]}),` `,(0,E.jsxs)(`span`,{className:`text-danger`,children:[`−`,a.del]})]}),s!==`D`&&(0,E.jsxs)(b,{to:`/p/${e}/files/${S(n)}`,className:`inline-flex h-8 shrink-0 items-center gap-1.5 rounded-md border border-border bg-surface px-2.5 text-xs font-medium hover:bg-surface-2 md:h-7`,children:[(0,E.jsx)(t,{}),`查看文件`]})]}),(0,E.jsx)(`div`,{className:`min-h-0 min-w-0 flex-1 overflow-y-auto`,children:i.isPending?(0,E.jsx)(`div`,{className:`p-4`,children:(0,E.jsx)(r,{rows:6})}):i.isError?(0,E.jsx)(`p`,{className:`m-4 rounded-md border border-danger/30 bg-danger/5 px-3 py-2 text-sm text-danger`,role:`alert`,children:i.error instanceof c?i.error.message:`读取失败`}):(0,E.jsxs)(E.Fragment,{children:[i.data.truncated&&(0,E.jsx)(`p`,{className:`border-b border-border bg-surface-2 px-4 py-2 text-xs text-muted`,children:`diff 太大,只显示了一部分。`}),(0,E.jsx)(j,{diff:i.data.diff})]})})]})}export{I as ChangesView};
@@ -0,0 +1,6 @@
1
+ import{E as e,F as t,O as n,P as r,R as i,S as a,a as o,at as s,b as c,ct as l,dt as u,ht as d,i as f,it as p,k as m,l as h,lt as g,m as _,mt as v,n as y,p as b,q as ee,st as te,tt as x,ut as S,vt as ne,w as C,x as w}from"./Form-BKTwiYyw.js";import{b as re,d as T,o as E,s as ie,v as D}from"./Modal-g2rv8I_n.js";import{I as ae,a as oe,g as O,h as se,m as k,t as A}from"./lib-DlcVMUqT.js";import{C as ce,E as le,T as j,_ as ue,b as M,h as N,w as P,x as F,y as de}from"./index-DQh72lEx.js";import{t as fe}from"./Markdown-IwP-xF29.js";import{f as pe,p as me,t as he}from"./AnnotationSelection-BZmNmwVW.js";import{t as I}from"./format-DrBC7w0A.js";var L=ne(d(),1),R=v(),ge=3e5,z=3e3,_e={mjs:`js`,cjs:`js`,mts:`ts`,cts:`ts`,htm:`html`,h:`c`,hpp:`cpp`,cc:`cpp`,hh:`cpp`,conf:`ini`,cfg:`ini`,env:`dotenv`,lock:`json`,svg:`xml`},B={dockerfile:`docker`,makefile:`make`,gnumakefile:`make`,cmakelists:`cmake`,".gitignore":`text`,".bashrc":`bash`,".zshrc":`zsh`};function V(e){let t=e.slice(e.lastIndexOf(`/`)+1).toLowerCase();if(B[t])return B[t];let n=t.replace(/\.txt$/,``);if(B[n])return B[n];let r=t.lastIndexOf(`.`);if(r<=0)return`text`;let i=t.slice(r+1);return _e[i]??i}var H,ve=0,U=new Map;function ye(e,t){H||(H=new Worker(new URL(`/assets/highlight.worker-CY-ZeDAl.js`,``+import.meta.url),{type:`module`}),H.onmessage=e=>{U.get(e.data.id)?.(e.data.html),U.delete(e.data.id)});let n=ve++;return new Promise(r=>{U.set(n,r),H.postMessage({id:n,code:e,lang:t})})}function be({code:e,path:t,line:n}){let[r,i]=(0,L.useState)(null),[a,o]=(0,L.useState)(!1),s=(0,L.useRef)(null),c=V(t),l=(0,L.useMemo)(()=>{let t=e.split(`
2
+ `);return t.length>1&&t[t.length-1]===``&&t.pop(),t},[e]),u=a||l.length<=z||(n??0)>z?l.length:z,d=(0,L.useMemo)(()=>u===l.length?e:l.slice(0,u).join(`
3
+ `),[e,l,u]);return(0,L.useEffect)(()=>{if(i(null),c===`text`||d.length>ge)return;let e=!1;return ye(d,c).then(t=>!e&&i(t)).catch(()=>void 0),()=>{e=!0}},[d,c]),(0,L.useEffect)(()=>{let e=s.current;if(!e||!n)return;e.querySelectorAll(`.line-target`).forEach(e=>e.classList.remove(`line-target`));let t=e.children[n-1];t&&(t.classList.add(`line-target`),t.scrollIntoView({block:`center`}))},[n,r,l]),(0,R.jsxs)(`pre`,{className:`code-view`,"data-testid":`code-view`,"data-lang":c,"data-highlighted":r?`true`:`false`,children:[r?(0,R.jsx)(`code`,{ref:s,dangerouslySetInnerHTML:{__html:r}}):(0,R.jsx)(`code`,{ref:s,children:l.slice(0,u).map((e,t)=>(0,R.jsx)(`span`,{className:`line`,children:e},t))}),u<l.length&&(0,R.jsxs)(`button`,{className:`mt-2 text-xs text-accent hover:underline`,onClick:()=>o(!0),"data-testid":`show-all`,children:[`显示全部(共 `,l.length,` 行)`]})]})}function xe({pid:e,path:t,root:n,file:r}){let i=(0,L.useRef)(null),[a,o]=(0,L.useState)(``),[l,u]=(0,L.useState)(!1),[d,f]=(0,L.useState)(!1),[p,m]=(0,L.useState)();(0,L.useEffect)(()=>()=>i.current?.abort(),[]),(0,L.useEffect)(()=>{if(!d)return;let e=setTimeout(()=>f(!1),1500);return()=>clearTimeout(e)},[d]);let h=n?`${n.replace(/[\\/]+$/,``)}/${t}`:void 0,g=r?.content!==void 0&&!r.binary,_=async n=>{i.current?.abort();let o=new AbortController;i.current=o,u(!0),f(!1),m(void 0);try{let i=n===`absolute`?h:n===`relative`?t:n===`selection`?a:r?.content;if(n===`file`&&r?.truncated){let n=await S(F(e,`file`,{path:t,full:`1`}),{signal:o.signal});if(n.binary||n.truncated||n.content===void 0)throw Error(`无法复制这个文件的全文。`);i=n.content}if(o.signal.aborted)return;if(i===void 0)throw Error(`没有可复制的内容。`);await N(i),o.signal.aborted||f(!0)}catch(e){o.signal.aborted||m(e instanceof Error?e.message:`复制失败`)}finally{o.signal.aborted||u(!1)}};return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(T,{label:`文件复制选项`,beforeOpen:()=>o(window.getSelection()?.toString()??``),width:240,testId:`file-copy-menu`,trigger:e=>(0,R.jsxs)(s,{...e,variant:`ghost`,size:`sm`,"aria-busy":l,icon:l?(0,R.jsx)(te,{}):p?(0,R.jsx)(b,{className:`text-danger`}):d?(0,R.jsx)(c,{className:`text-ok`}):(0,R.jsx)(C,{}),title:p,children:[l?`复制中…`:p?`复制失败`:d?`已复制`:`复制`,(0,R.jsx)(w,{size:12})]}),children:[p&&(0,R.jsx)(`p`,{className:`px-3 py-2 text-xs text-danger`,children:p}),(0,R.jsx)(E,{disabled:!h,onClick:()=>void _(`absolute`),children:`复制完整路径`}),(0,R.jsx)(E,{onClick:()=>void _(`relative`),children:`复制相对路径`}),(0,R.jsx)(E,{disabled:!g,onClick:()=>void _(`file`),children:`复制全文`}),(0,R.jsx)(E,{disabled:!a,onClick:()=>void _(`selection`),hint:a?void 0:`请先选择文字`,children:`复制页面选中文本`})]}),p&&(0,R.jsx)(`span`,{className:`sr-only`,role:`alert`,children:p})]})}var W=new Map,G=new Set,Se=e=>(G.add(e),()=>{G.delete(e)});function Ce(e){W.set(e,(W.get(e)??0)+1),G.forEach(e=>e())}function we(e){return(0,L.useSyncExternalStore)(Se,()=>W.get(e)??0,()=>0)}var K=(0,L.createContext)(null);function Te({pid:e,children:t}){let n=(0,L.useRef)(null),r=(0,L.useRef)(``),i=ue(),a=ae(),o=D().data?.find(t=>t.id===e),[s,c]=(0,L.useState)(``),l=re({mutationFn:async({selected:t,target:n})=>{if(t.length>100||t.reduce((e,t)=>e+t.size,0)>52428800)throw Error(`单次最多上传 100 个文件,总大小不超过 50 MiB。`);let r=new Set,a=[],s=t;for(;s.length;){let t=new FormData;s.forEach(e=>t.append(`files`,e)),r.forEach(e=>t.append(`overwrite`,e));let c=await u(F(e,`files/upload`,{path:n}),{method:`POST`,body:t}),l=await c.json();if(!c.ok&&(c.status!==409||!l.conflicts?.length))throw new g(c.status,l.error??`上传失败`);a.push(...l.files);let d=new Set(l.files.map(e=>e.split(`/`).at(-1)));if(s=s.filter(e=>!d.has(e.name)),!l.conflicts.length||!(await i({title:`覆盖同名文件?`,description:`目标:${o?.path??e}${n?`/${n}`:``}\n\n${l.conflicts.join(`
4
+ `)}`,confirmLabel:`覆盖并上传`,danger:!0})).confirmed)break;l.conflicts.forEach(e=>r.add(e))}return a.length},onMutate:()=>c(``),onSuccess:e=>c(e?`已上传 ${e} 个文件`:`已取消上传`),onSettled:()=>{Ce(e);for(let t of[`files`,`file`,`search-files`,`search-content`,`git-status`,`git-diff`])a.invalidateQueries({queryKey:[t,e]})}});return(0,R.jsxs)(K.Provider,{value:{root:o?.path,busy:l.isPending,choose:e=>{r.current=e,n.current?.click()}},children:[(0,R.jsx)(`input`,{ref:n,type:`file`,multiple:!0,hidden:!0,"aria-label":`选择上传文件`,disabled:l.isPending,onChange:e=>{let t=Array.from(e.currentTarget.files??[]);e.currentTarget.value=``,t.length&&l.mutate({selected:t,target:r.current})}}),t,(l.isPending||l.error||s)&&(0,R.jsx)(`div`,{role:l.error?`alert`:`status`,className:`shrink-0 border-t border-border px-3 py-2 text-xs ${l.error?`text-danger`:`text-muted`}`,children:l.isPending?`正在上传…`:l.error?.message??s})]})}function q({directory:e=``,primary:t=!1}){let n=(0,L.useContext)(K);return(0,R.jsx)(s,{size:`sm`,variant:t?`primary`:`secondary`,icon:(0,R.jsx)(x,{}),disabled:!n||n.busy,onClick:()=>n?.choose(e),children:`上传文件`})}function J({pid:t,path:n,directory:r}){let a=(0,L.useContext)(K),[o,l]=(0,L.useState)(!1),[u,d]=(0,L.useState)();(0,L.useEffect)(()=>{if(!o)return;let e=setTimeout(()=>l(!1),1500);return()=>clearTimeout(e)},[o]);let f=a?.root?n?`${a.root.replace(/[\\/]+$/,``)}/${n}`:a.root:void 0,p=async e=>{l(!1),d(void 0);try{await N(e),l(!0)}catch(e){d(e instanceof Error?e.message:`复制失败`)}},m=n.split(`/`).at(-1)||`项目根目录`;return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(T,{label:`${m} 更多操作`,trigger:e=>(0,R.jsx)(s,{...e,variant:`ghost`,size:`sm`,iconOnly:!0,title:u??(o?`已复制`:`${m} 更多操作`),"data-copied":o||void 0,children:u?(0,R.jsx)(b,{className:`text-danger`}):o?(0,R.jsx)(c,{className:`text-ok`}):(0,R.jsx)(i,{})}),children:[(0,R.jsx)(E,{icon:(0,R.jsx)(C,{}),disabled:!f,onClick:()=>f&&void p(f),children:`复制绝对路径`}),(0,R.jsx)(E,{icon:(0,R.jsx)(C,{}),onClick:()=>void p(n||`.`),children:`复制相对路径`}),(0,R.jsx)(ie,{}),r?(0,R.jsx)(E,{icon:(0,R.jsx)(x,{}),disabled:!a||a.busy,onClick:()=>a?.choose(n),children:`上传文件`}):(0,R.jsx)(E,{icon:(0,R.jsx)(e,{}),onClick:()=>{let e=document.createElement(`a`);e.href=F(t,`file/download`,{path:n}),e.download=m,document.body.appendChild(e),e.click(),e.remove()},children:`下载文件`})]}),(0,R.jsx)(`span`,{className:`sr-only`,role:u?`alert`:`status`,children:u??(o?`已复制`:``)})]})}function Ee(){let e=se(),t=e.pid,n=e[`*`]??``,[r]=oe(),i=Number(r.get(`line`))||void 0,a=j(t),o=(0,L.useMemo)(()=>new Set(a.expanded),[a.expanded]);return(0,L.useEffect)(()=>{ce(t,n)},[t,n]),(0,R.jsx)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col`,children:(0,R.jsxs)(Te,{pid:t,children:[(0,R.jsxs)(de,{projectId:t,children:[o.size>0&&(0,R.jsx)(s,{variant:`ghost`,size:`sm`,onClick:()=>P(t,{expanded:[]}),className:`hidden md:inline-flex`,title:`收起所有目录`,children:`全部收起`}),(0,R.jsx)(J,{pid:t,path:``,directory:!0})]}),(0,R.jsxs)(`div`,{className:`flex min-h-0 min-w-0 flex-1`,children:[(0,R.jsx)(le,{storageKey:`claude-ide:files-width`,label:`调整文件列表宽度`,defaultWidth:320,className:l(n?`hidden md:flex`:`flex`,`min-h-0 w-full flex-col border-border md:bg-surface-2/30 md:border-r`),children:(0,R.jsx)(ke,{pid:t,file:n,expanded:o,toggle:e=>P(t,t=>{let n=new Set(t.expanded);return n.has(e)?n.delete(e):n.add(e),{expanded:[...n]}})})}),(0,R.jsx)(`section`,{className:l(n?`flex`:`hidden md:flex`,`min-h-0 min-w-0 flex-1 flex-col`),children:n?(0,R.jsx)($,{pid:t,path:n,line:i},`${t}:${n}`):(0,R.jsx)(De,{pid:t})})]})]},t)})}function De({pid:e}){let t=O({queryKey:[`files`,e,``],queryFn:()=>S(F(e,`files`,{path:``}))}),r=t.data?.entries.find(e=>e.type===`file`&&/^readme(\.md|\.markdown)?$/i.test(e.name)),i=t.data?.entries.filter(e=>e.type===`dir`).length??0,a=t.data?.entries.filter(e=>e.type===`file`).length??0;return t.data?.entries.length===0?(0,R.jsxs)(`div`,{className:`m-auto flex max-w-md flex-col items-center gap-4 p-6 text-center`,children:[(0,R.jsx)(y,{icon:(0,R.jsx)(m,{size:16}),title:`项目目录还是空的`,children:`上传图片、音频、文档或其他文件,开始使用这个工作区。`}),(0,R.jsx)(q,{primary:!0})]}):r?(0,R.jsx)($,{pid:e,path:r.path},`${e}:${r.path}`):(0,R.jsx)(`div`,{className:`m-auto w-full max-w-md p-6`,children:(0,R.jsxs)(y,{icon:(0,R.jsx)(n,{size:16}),title:`选择左侧的文件查看`,children:[t.data?`根目录下有 ${i} 个目录、${a} 个文件。`:``,`可以按文件名模糊搜索,或切到“内容”在所有文件里查找文字,点结果直接跳到那一行。`]})})}function Oe(e,t){let[n,r]=(0,L.useState)(e);return(0,L.useEffect)(()=>{let n=setTimeout(()=>r(e),t);return()=>clearTimeout(n)},[e,t]),n}function ke({pid:e,file:t,expanded:n,toggle:r}){let i=j(e),a=i.search,o=i.searchMode,s=t=>P(e,{search:t}),c=t=>P(e,{searchMode:t}),u=Oe(a.trim(),200);return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`div`,{className:`space-y-2 border-b border-border p-2.5`,children:[(0,R.jsxs)(`span`,{className:`relative block`,children:[(0,R.jsx)(ee,{className:`pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-muted`}),(0,R.jsx)(`input`,{type:`search`,"aria-label":`搜索文件`,placeholder:o===`name`?`按文件名搜索`:`按内容搜索`,value:a,onChange:e=>s(e.target.value),onKeyDown:e=>e.key===`Escape`&&s(``),className:l(h,`pl-8 pr-9 [&::-webkit-search-cancel-button]:hidden`)}),a&&(0,R.jsx)(`button`,{type:`button`,"aria-label":`清空搜索`,onClick:()=>s(``),className:`absolute right-1 top-1/2 flex size-8 -translate-y-1/2 items-center justify-center rounded text-muted hover:text-text md:size-6`,children:(0,R.jsx)(p,{size:12})})]}),(0,R.jsx)(f,{label:`搜索方式`,size:`sm`,stretch:!0,value:o,onChange:c,options:[{value:`name`,label:`文件名`},{value:`content`,label:`内容`}]})]}),(0,R.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto py-1`,children:u?o===`name`?(0,R.jsx)(Me,{pid:e,q:u}):(0,R.jsx)(Ne,{pid:e,q:u}):(0,R.jsx)(`nav`,{"aria-label":`文件树`,children:(0,R.jsx)(Y,{pid:e,dir:``,depth:0,file:t,expanded:n,toggle:r})})})]})}function Y({pid:e,dir:t,depth:n,file:r,expanded:i,toggle:a}){let o=O({queryKey:[`files`,e,t],queryFn:()=>S(F(e,`files`,{path:t}))}),s={paddingLeft:`${n*14+30}px`};return o.isPending?(0,R.jsx)(`div`,{className:`py-1.5 text-xs text-muted`,style:s,children:`加载中…`}):o.isError?(0,R.jsx)(`div`,{className:`py-1.5 text-xs text-danger`,style:s,children:o.error.message}):(0,R.jsxs)(`ul`,{role:n===0?`tree`:`group`,children:[o.data.entries.map(t=>(0,R.jsx)(Ae,{pid:e,e:t,depth:n,file:r,expanded:i,toggle:a},t.path)),o.data.entries.length===0&&(t?(0,R.jsx)(`li`,{className:`py-1.5 text-xs text-muted`,style:s,children:`空目录`}):(0,R.jsxs)(`li`,{className:`space-y-3 p-4 text-sm text-muted`,children:[(0,R.jsx)(`p`,{children:`目录还是空的`}),(0,R.jsx)(`div`,{className:`md:hidden`,children:(0,R.jsx)(q,{primary:!0})})]})),o.data.truncated&&(0,R.jsx)(`li`,{className:`py-1.5 text-xs text-muted`,style:s,children:`条目过多,只显示了一部分`})]})}var X=e=>me.some(t=>e.toLowerCase().endsWith(t)),Z=e=>/\.(md|markdown|mdx)$/i.test(e);function Ae({pid:e,e:i,depth:o,file:s,expanded:c,toggle:u}){let d=k(),f=i.type===`dir`,p=f&&c.has(i.path),h=i.outside||i.type===`other`,g=s===i.path;return(0,R.jsxs)(`li`,{role:`treeitem`,"aria-expanded":f?p:void 0,"aria-selected":g,children:[(0,R.jsxs)(`div`,{className:l(`group flex min-w-0 items-center pr-1`,g?`bg-accent/10 font-medium text-text`:`hover:bg-surface-2/80`,(i.ignored||h)&&`opacity-55`),children:[(0,R.jsxs)(`button`,{disabled:h,onClick:()=>f?u(i.path):d(`/p/${e}/files/${M(i.path)}`),title:i.outside?`链接指向项目之外`:i.path,"data-path":i.path,className:l(`flex min-w-0 flex-1 items-center gap-1.5 py-2 pr-2 text-left text-sm md:py-1`),style:{paddingLeft:`${o*14+8}px`},children:[(0,R.jsx)(`span`,{className:`flex w-3.5 shrink-0 justify-center text-muted`,children:f?(0,R.jsx)(a,{size:12,className:l(`transition-transform`,p&&`rotate-90`)}):null}),(0,R.jsx)(`span`,{className:l(`shrink-0`,f?`text-accent/80`:`text-muted`),children:f?(0,R.jsx)(m,{}):X(i.name)?(0,R.jsx)(r,{}):(0,R.jsx)(n,{})}),(0,R.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:i.name}),i.link&&(0,R.jsx)(t,{size:12,className:`shrink-0 text-muted`,"aria-label":`符号链接`}),!f&&i.size!==void 0&&(0,R.jsx)(`span`,{className:`shrink-0 text-[11px] tabular-nums text-muted opacity-0 transition-opacity group-hover:opacity-100`,children:I(i.size)})]}),!h&&(0,R.jsx)(J,{pid:e,path:i.path,directory:f})]}),p&&(0,R.jsx)(Y,{pid:e,dir:i.path,depth:o+1,file:s,expanded:c,toggle:u})]})}function je({path:e}){let t=e.lastIndexOf(`/`);return(0,R.jsxs)(`span`,{className:`min-w-0 truncate`,children:[(0,R.jsx)(`span`,{children:e.slice(t+1)}),t>0&&(0,R.jsx)(`span`,{className:`ml-1.5 text-xs text-muted`,children:e.slice(0,t)})]})}function Q({children:e,danger:t}){return(0,R.jsx)(`p`,{className:l(`px-3 py-4 text-center text-sm`,t?`text-danger`:`text-muted`),children:e})}function Me({pid:e,q:t}){let r=O({queryKey:[`search-files`,e,t],queryFn:()=>S(F(e,`search/files`,{q:t}))});return r.isPending?(0,R.jsx)(`div`,{className:`px-2`,children:(0,R.jsx)(o,{rows:4})}):r.isError?(0,R.jsx)(Q,{danger:!0,children:r.error.message}):r.data.matches.length?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`p`,{className:`px-3 pb-1 pt-1.5 text-[11px] text-muted`,children:[r.data.matches.length,` 个文件`]}),(0,R.jsx)(`ul`,{"aria-label":`文件名搜索结果`,children:r.data.matches.map(t=>(0,R.jsxs)(`li`,{className:`flex items-center pr-1 hover:bg-surface-2`,children:[(0,R.jsxs)(A,{to:`/p/${e}/files/${M(t.path)}`,className:`flex min-w-0 flex-1 items-center gap-2 px-3 py-2 text-sm md:py-1.5`,"data-testid":`file-result`,children:[(0,R.jsx)(n,{className:`shrink-0 text-muted`}),(0,R.jsx)(je,{path:t.path})]}),(0,R.jsx)(J,{pid:e,path:t.path})]},t.path))})]}):(0,R.jsxs)(Q,{children:[`没有匹配“`,t,`”的文件。试试切到“内容”搜索。`]})}function Ne({pid:e,q:t}){let r=O({queryKey:[`search-content`,e,t],queryFn:()=>S(F(e,`search/content`,{q:t}))}),i=(0,L.useMemo)(()=>{let e=new Map;for(let t of r.data?.matches??[])e.set(t.path,[...e.get(t.path)??[],t]);return[...e.entries()]},[r.data]);return r.isPending?(0,R.jsx)(`div`,{className:`px-2`,children:(0,R.jsx)(o,{rows:4})}):r.isError?(0,R.jsx)(Q,{danger:!0,children:r.error.message}):i.length?(0,R.jsxs)(`div`,{"aria-label":`内容搜索结果`,children:[(0,R.jsxs)(`p`,{className:`px-3 pb-1 pt-1.5 text-[11px] text-muted`,children:[r.data.matches.length,` 处,`,i.length,` 个文件`]}),i.map(([t,r])=>(0,R.jsxs)(`div`,{className:`mb-1`,children:[(0,R.jsxs)(`div`,{className:`flex items-center gap-1.5 px-3 pb-0.5 pt-2 text-xs font-medium text-muted`,title:t,children:[(0,R.jsx)(n,{size:12,className:`shrink-0`}),(0,R.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:t}),(0,R.jsx)(`span`,{className:`shrink-0 tabular-nums`,children:r.length}),(0,R.jsx)(J,{pid:e,path:t})]}),r.map(t=>(0,R.jsxs)(A,{to:`/p/${e}/files/${M(t.path)}?line=${t.line}`,className:`flex gap-2 px-3 py-1.5 font-mono text-xs hover:bg-surface-2`,"data-testid":`content-result`,children:[(0,R.jsx)(`span`,{className:`w-8 shrink-0 text-right text-muted`,children:t.line}),(0,R.jsx)(`span`,{className:`min-w-0 truncate`,children:t.start!==void 0&&t.end!==void 0?(0,R.jsxs)(R.Fragment,{children:[t.text.slice(Math.max(0,t.start-40),t.start),(0,R.jsx)(`mark`,{className:`rounded-sm bg-accent/25 text-text`,children:t.text.slice(t.start,t.end)}),t.text.slice(t.end)]}):t.text})]},t.line))]},t)),r.data.truncated&&(0,R.jsxs)(`p`,{className:`p-3 text-xs text-muted`,children:[`结果过多,只显示了前 `,r.data.matches.length,` 条`]})]}):(0,R.jsxs)(Q,{children:[`没有文件包含“`,t,`”。`]})}function $({pid:e,path:t,line:r}){let i=X(t),a=!!pe[`.${t.split(`.`).at(-1)?.toLowerCase()}`],c=we(e),l=Z(t),u=j(e).source,d=t=>{P(e,{source:t})};(0,L.useEffect)(()=>{r&&d(!0)},[r,e]);let f=D().data?.find(t=>t.id===e),p=O({queryKey:[`file`,e,t],queryFn:()=>S(F(e,`file`,{path:t})),enabled:!i&&!a}),m=p.data?.content?p.data.content.split(`
5
+ `).length-+!!p.data.content.endsWith(`
6
+ `):0,h=t.lastIndexOf(`/`),v=V(t);return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 border-b border-border px-2 py-1.5 md:px-4`,children:[(0,R.jsxs)(A,{to:`/p/${e}/files`,className:`inline-flex h-10 shrink-0 items-center gap-1.5 rounded-md px-2.5 text-sm text-muted hover:bg-surface-2 hover:text-text md:hidden`,"aria-label":`返回文件列表`,children:[(0,R.jsx)(_,{}),`返回`]}),(0,R.jsxs)(`div`,{className:`min-w-0 flex-1 truncate font-mono text-sm`,title:t,"data-testid":`file-path`,children:[h>0&&(0,R.jsx)(`span`,{className:`text-muted`,children:t.slice(0,h+1)}),(0,R.jsx)(`span`,{className:`font-medium`,children:t.slice(h+1)})]}),(0,R.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1`,"data-testid":`file-actions`,children:[(0,R.jsx)(xe,{pid:e,path:t,root:f?.path,file:p.data},`${e}:${t}`),l&&(0,R.jsxs)(`div`,{className:`flex items-center border-l border-border pl-1`,role:`group`,"aria-label":`文件显示方式`,children:[(0,R.jsx)(s,{variant:`ghost`,size:`sm`,"aria-pressed":!u,className:u?void 0:`bg-surface-2 text-text`,onClick:()=>d(!1),children:`预览`}),(0,R.jsx)(s,{variant:`ghost`,size:`sm`,"aria-pressed":u,className:u?`bg-surface-2 text-text`:void 0,onClick:()=>d(!0),children:`源码`})]})]})]}),(0,R.jsxs)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col`,children:[(0,R.jsx)(`div`,{className:`relative h-12 shrink-0`,children:(0,R.jsx)(Pe,{file:p.data,image:i,lang:v,lines:m})}),(0,R.jsx)(`div`,{className:`min-h-0 min-w-0 flex-1 overflow-auto`,"data-testid":`file-content`,children:a?(0,R.jsxs)(`div`,{className:`mx-auto flex w-full max-w-xl flex-col gap-4 p-6`,"data-testid":`audio-preview`,children:[(0,R.jsx)(`p`,{className:`break-words text-sm`,children:t.split(`/`).at(-1)}),(0,R.jsx)(`audio`,{controls:!0,preload:`metadata`,src:F(e,`file`,{path:t}),className:`w-full`,"aria-label":`音频预览`}),(0,R.jsx)(`a`,{className:`text-sm text-accent underline`,href:F(e,`file/download`,{path:t}),download:!0,children:`下载音频`})]}):i?(0,R.jsx)(`div`,{className:`flex justify-center bg-[repeating-conic-gradient(var(--surface-2)_0_25%,transparent_0_50%)] bg-[length:16px_16px] p-6`,children:(0,R.jsx)(`img`,{src:F(e,`file`,{path:t,...c?{v:String(c)}:{}}),alt:t,className:`max-h-[80dvh] max-w-full object-contain shadow-sm`})}):p.isPending?(0,R.jsx)(`div`,{className:`p-4`,children:(0,R.jsx)(o,{rows:6})}):p.isError?(0,R.jsx)(`p`,{className:`m-4 rounded-md border border-danger/30 bg-danger/5 px-3 py-2 text-sm text-danger`,role:`alert`,children:p.error instanceof g?p.error.message:`读取失败`}):p.data.binary?(0,R.jsx)(`div`,{className:`m-auto max-w-md p-6`,children:(0,R.jsxs)(y,{icon:(0,R.jsx)(n,{size:16}),title:`二进制文件,无法预览`,children:[I(p.data.size),`。可以让 Claude 用命令行工具查看它的内容。`]})}):(0,R.jsxs)(R.Fragment,{children:[p.data.truncated&&(0,R.jsx)(`p`,{className:`border-b border-border bg-surface-2 px-4 py-2 text-xs text-muted`,children:`文件较大,只显示前 1 MB。`}),l&&!u?(0,R.jsx)(`div`,{className:`mx-auto max-w-3xl px-4 py-4 md:px-6`,"data-testid":`markdown-view`,children:(0,R.jsx)(fe,{text:p.data.content??``,assetContext:{projectId:e,filePath:t,root:f?.path,version:c}})}):p.data.content?(0,R.jsx)(he,{projectId:e,filePath:t,fileContent:p.data.content,enabled:!0,children:(0,R.jsx)(be,{code:p.data.content,path:t,line:r})}):(0,R.jsx)(`p`,{className:`p-6 text-center text-sm text-muted`,children:`空文件。`})]})})]})]})}function Pe({file:e,image:t,lang:n,lines:r}){return(0,R.jsxs)(`details`,{open:!0,className:`group absolute right-3 top-2 z-10 w-44 max-w-[calc(100%_-_1.5rem)] rounded-lg border border-border bg-bg/95 text-xs shadow-sm backdrop-blur-sm`,"data-testid":`file-info`,children:[(0,R.jsxs)(`summary`,{className:`flex min-h-8 cursor-pointer list-none select-none items-center justify-between gap-3 px-3 text-muted hover:text-text [&::-webkit-details-marker]:hidden`,children:[`文件信息`,(0,R.jsx)(w,{size:12,className:`transition-transform group-open:rotate-180`})]}),(0,R.jsxs)(`dl`,{className:`grid grid-cols-[auto_minmax(0,1fr)] gap-x-5 gap-y-1 px-3 pb-3 pt-1`,children:[(0,R.jsx)(`dt`,{className:`text-muted`,children:`类型`}),(0,R.jsx)(`dd`,{className:`break-words text-right font-mono`,children:t?`图片 · ${n}`:n}),e&&!e.binary&&(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`dt`,{className:`text-muted`,children:e.truncated?`已显示行数`:`行数`}),(0,R.jsxs)(`dd`,{className:`text-right tabular-nums`,children:[r,` 行`]})]}),e&&(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(`dt`,{className:`text-muted`,children:`大小`}),(0,R.jsx)(`dd`,{className:`text-right tabular-nums`,children:I(e.size)})]})]})]})}export{Ee as FilesView};
@@ -0,0 +1 @@
1
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,o)=>(o=n==null?{}:e(i(n)),c(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n)),u=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.for(`react.view_transition`),m=Symbol.iterator;function h(e){return typeof e!=`object`||!e?null:(e=m&&e[m]||e[`@@iterator`],typeof e==`function`?e:null)}var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_=Object.assign,v={};function y(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}y.prototype.isReactComponent={},y.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},y.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function b(){}b.prototype=y.prototype;function x(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}var S=x.prototype=new b;S.constructor=x,_(S,y.prototype),S.isPureReactComponent=!0;var C=Array.isArray;function w(){}var T={H:null,A:null,T:null,S:null},E=Object.prototype.hasOwnProperty;function D(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function O(e,t){return D(e.type,t,e.props)}function k(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function A(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var j=/\/+/g;function M(e,t){return typeof e==`object`&&e&&e.key!=null?A(``+e.key):t.toString(36)}function N(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(w,w):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function P(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,P(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+M(e,0):a,C(o)?(i=``,c!=null&&(i=c.replace(j,`$&/`)+`/`),P(o,r,i,``,function(e){return e})):o!=null&&(k(o)&&(o=O(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(j,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(C(e))for(var u=0;u<e.length;u++)a=e[u],s=l+M(a,u),c+=P(a,r,i,s,o);else if(u=h(e),typeof u==`function`)for(e=u.call(e),u=0;!(a=e.next()).done;)a=a.value,s=l+M(a,u++),c+=P(a,r,i,s,o);else if(s===`object`){if(typeof e.then==`function`)return P(N(e),r,i,a,o);throw r=String(e),Error(`Objects are not valid as a React child (found: `+(r===`[object Object]`?`object with keys {`+Object.keys(e).join(`, `)+`}`:r)+`). If you meant to render a collection of children, use an array instead.`)}return c}function F(e,t,n){if(e==null)return e;var r=[],i=0;return P(e,r,``,``,function(e){return t.call(n,e,i++)}),r}function I(e){if(e._status===-1){var t=e._result,n=t();n.then(function(t){(e._status===0||e._status===-1)&&(e._status=1,e._result=t,n.status===void 0&&(n.status=`fulfilled`,n.value=t))},function(t){(e._status===0||e._status===-1)&&(e._status=2,e._result=t,n.status===void 0&&(n.status=`rejected`,n.reason=t))}),e._status===-1&&(e._status=0,e._result=n)}if(e._status===1)return e._result.default;throw e._result}var L=typeof reportError==`function`?reportError:function(e){if(typeof window==`object`&&typeof window.ErrorEvent==`function`){var t=new window.ErrorEvent(`error`,{bubbles:!0,cancelable:!0,message:typeof e==`object`&&e&&typeof e.message==`string`?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if(typeof process==`object`&&typeof process.emit==`function`){process.emit(`uncaughtException`,e);return}console.error(e)};function R(e){var t=T.T,n={};n.types=t===null?null:t.types,T.T=n;try{var r=e(),i=T.S;i!==null&&i(n,r),typeof r==`object`&&r&&typeof r.then==`function`&&r.then(w,L)}catch(e){L(e)}finally{t!==null&&n.types!==null&&(t.types=n.types),T.T=t}}function z(e){var t=T.T;if(t!==null){var n=t.types;n===null?t.types=[e]:n.indexOf(e)===-1&&n.push(e)}else R(z.bind(null,e))}var B={map:F,forEach:function(e,t,n){F(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return F(e,function(){t++}),t},toArray:function(e){return F(e,function(e){return e})||[]},only:function(e){if(!k(e))throw Error(`React.Children.only expected to receive a single React element child.`);return e}};e.Activity=f,e.Children=B,e.Component=y,e.Fragment=r,e.Profiler=a,e.PureComponent=x,e.StrictMode=i,e.Suspense=l,e.ViewTransition=p,e.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=T,e.__COMPILER_RUNTIME={__proto__:null,c:function(e){return T.H.useMemoCache(e)}},e.addTransitionType=z,e.cache=function(e){return function(){return e.apply(null,arguments)}},e.cacheSignal=function(){return null},e.cloneElement=function(e,t,n){if(e==null)throw Error(`The argument must be a React element, but you passed `+e+`.`);var r=_({},e.props),i=e.key;if(t!=null)for(a in t.key!==void 0&&(i=``+t.key),t)!E.call(t,a)||a===`key`||a===`__self`||a===`__source`||a===`ref`&&t.ref===void 0||(r[a]=t[a]);var a=arguments.length-2;if(a===1)r.children=n;else if(1<a){for(var o=Array(a),s=0;s<a;s++)o[s]=arguments[s+2];r.children=o}return D(e.type,i,r)},e.createContext=function(e){return e={$$typeof:s,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null},e.Provider=e,e.Consumer={$$typeof:o,_context:e},e},e.createElement=function(e,t,n){var r,i={},a=null;if(t!=null)for(r in t.key!==void 0&&(a=``+t.key),t)E.call(t,r)&&r!==`key`&&r!==`__self`&&r!==`__source`&&(i[r]=t[r]);var o=arguments.length-2;if(o===1)i.children=n;else if(1<o){for(var s=Array(o),c=0;c<o;c++)s[c]=arguments[c+2];i.children=s}if(e&&e.defaultProps)for(r in o=e.defaultProps,o)i[r]===void 0&&(i[r]=o[r]);return D(e,a,i)},e.createRef=function(){return{current:null}},e.forwardRef=function(e){return{$$typeof:c,render:e}},e.isValidElement=k,e.lazy=function(e){return{$$typeof:d,_payload:{_status:-1,_result:e},_init:I}},e.memo=function(e,t){return{$$typeof:u,type:e,compare:t===void 0?null:t}},e.startTransition=R,e.unstable_useCacheRefresh=function(){return T.H.useCacheRefresh()},e.use=function(e){return T.H.use(e)},e.useActionState=function(e,t,n){return T.H.useActionState(e,t,n)},e.useCallback=function(e,t){return T.H.useCallback(e,t)},e.useContext=function(e){return T.H.useContext(e)},e.useDebugValue=function(){},e.useDeferredValue=function(e,t){return T.H.useDeferredValue(e,t)},e.useEffect=function(e,t){return T.H.useEffect(e,t)},e.useEffectEvent=function(e){return T.H.useEffectEvent(e)},e.useId=function(){return T.H.useId()},e.useImperativeHandle=function(e,t,n){return T.H.useImperativeHandle(e,t,n)},e.useInsertionEffect=function(e,t){return T.H.useInsertionEffect(e,t)},e.useLayoutEffect=function(e,t){return T.H.useLayoutEffect(e,t)},e.useMemo=function(e,t){return T.H.useMemo(e,t)},e.useOptimistic=function(e,t){return T.H.useOptimistic(e,t)},e.useReducer=function(e,t,n){return T.H.useReducer(e,t,n)},e.useRef=function(e){return T.H.useRef(e)},e.useState=function(e){return T.H.useState(e)},e.useSyncExternalStore=function(e,t,n){return T.H.useSyncExternalStore(e,t,n)},e.useTransition=function(){return T.H.useTransition()},e.version=`19.3.0`})),d=o(((e,t)=>{t.exports=u()})),f=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),p=o(((e,t)=>{t.exports=f()})),m=new Set;function h(e){return m.add(e),()=>{m.delete(e)}}function g(){for(let e of m)e()}var _=class extends Error{status;constructor(e,t){super(t),this.status=e}};async function v(e,t){let n=await fetch(e,{...t,credentials:`same-origin`});return n.status===401&&e.split(`?`)[0]!==`/api/login`&&g(),n}async function y(e,t){let{json:n,...r}=t??{},i=await v(e,{...r,headers:{...n===void 0?{}:{"content-type":`application/json`},...r.headers},body:n===void 0?r.body:JSON.stringify(n)}),a=await i.json().catch(()=>({}));if(!i.ok)throw new _(i.status,a.error??i.statusText);return a}var b=l(d(),1),x=p();function S(...e){return e.filter(Boolean).join(` `)}var C={sm:`h-8 md:h-7 px-2.5 text-xs gap-1.5`,md:`h-10 md:h-8 px-3 text-sm gap-2`},w={primary:`bg-accent text-accent-text hover:bg-accent-hover border border-transparent shadow-sm`,secondary:`bg-surface text-text border border-border hover:bg-surface-2 hover:border-muted/40`,ghost:`text-muted hover:text-text hover:bg-surface-2 border border-transparent`,danger:`bg-danger text-bg border border-transparent hover:opacity-90`,"outline-danger":`text-danger border border-border bg-surface hover:border-danger/60 hover:bg-danger/5`},T=(0,b.forwardRef)(function({variant:e=`secondary`,size:t=`md`,icon:n,iconOnly:r,loading:i,className:a,children:o,disabled:s,type:c=`button`,...l},u){return(0,x.jsxs)(`button`,{ref:u,type:c,disabled:s||i,className:S(`inline-flex shrink-0 select-none items-center justify-center whitespace-nowrap rounded-md font-medium transition-colors [&>svg]:shrink-0`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40 disabled:pointer-events-none disabled:opacity-45`,C[t],r&&(t===`sm`?`w-8 px-0! md:w-7`:`w-10 px-0! md:w-8`),w[e],a),...l,children:[i?(0,x.jsx)(E,{}):n,o]})});function E({className:e}){return(0,x.jsx)(`span`,{className:S(`inline-block size-3.5 animate-spin rounded-full border-2 border-current border-t-transparent`,e),"aria-hidden":!0})}function D({size:e=16,...t}){return(0,x.jsx)(`svg`,{width:e,height:e,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.75`,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":!0,...t})}var O=e=>(0,x.jsxs)(D,{...e,children:[(0,x.jsx)(`rect`,{x:`9`,y:`3`,width:`6`,height:`12`,rx:`3`}),(0,x.jsx)(`path`,{d:`M5 10v2a7 7 0 0 0 14 0v-2M12 19v3M8 22h8`})]}),k=e=>(0,x.jsx)(D,{...e,children:(0,x.jsx)(`path`,{d:`M11 5 6 9H3v6h3l5 4V5ZM17 9l5 6M22 9l-5 6`})}),A=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M6 9l6 6 6-6`})}),j=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M5 12.5l4.5 4.5L19 7.5`})}),M=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M6 6l12 12M18 6L6 18`})}),N=e=>(0,x.jsxs)(D,{...e,children:[(0,x.jsx)(`circle`,{cx:`5.5`,cy:`12`,r:`1.6`,fill:`currentColor`,stroke:`none`}),(0,x.jsx)(`circle`,{cx:`12`,cy:`12`,r:`1.6`,fill:`currentColor`,stroke:`none`}),(0,x.jsx)(`circle`,{cx:`18.5`,cy:`12`,r:`1.6`,fill:`currentColor`,stroke:`none`})]}),P=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M9 5h.01M15 5h.01M9 12h.01M15 12h.01M9 19h.01M15 19h.01`,strokeWidth:3})}),F=e=>(0,x.jsx)(D,{...e,children:(0,x.jsx)(`path`,{d:`M12 3v12m-4-4 4 4 4-4M4 16v5h16v-5`})}),I=e=>(0,x.jsx)(D,{...e,children:(0,x.jsx)(`path`,{d:`M12 16V4m-4 4 4-4 4 4M4 16v5h16v-5`})}),L=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`circle`,{cx:`12`,cy:`12`,r:`8`}),(0,x.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3.5`})]}),R=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`circle`,{cx:`12`,cy:`12`,r:`8.5`}),(0,x.jsx)(`path`,{d:`M9.5 9a2.5 2.5 0 1 1 4.2 1.8c-1 .7-1.7 1-1.7 2.2M12 16.5h.01`})]}),z=e=>(0,x.jsx)(D,{size:14,strokeWidth:3,...e,children:(0,x.jsx)(`path`,{d:`M8 7.5a4 4 0 1 1 6.7 3c-1.5 1-2.7 1.6-2.7 3.5M12 18h.01`})}),B=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`circle`,{cx:`12`,cy:`12`,r:`8.5`}),(0,x.jsx)(`path`,{d:`M12 7.5V12l3 2`})]}),ee=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M5 8l4 4-4 4M12 16h7`})}),te=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M9 6h11M9 12h11M9 18h11M4.5 6h.01M4.5 12h.01M4.5 18h.01`})}),ne=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M12 3v4M12 17v4M3 12h4M17 12h4M6 6l2.5 2.5M15.5 15.5L18 18M6 18l2.5-2.5M15.5 8.5L18 6`})}),re=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M9 4a3 3 0 0 0-3 3v.5A3 3 0 0 0 4 10.5 3 3 0 0 0 5 13a3 3 0 0 0 1 5 3 3 0 0 0 3 2V4zM15 4a3 3 0 0 1 3 3v.5a3 3 0 0 1 2 3 3 3 0 0 1-1 2.5 3 3 0 0 1-1 5 3 3 0 0 1-3 2V4z`})}),ie=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`path`,{d:`M8 4h8l3 3v13H5V4h3z`}),(0,x.jsx)(`path`,{d:`M9 11h6M9 15h4`})]}),V=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M3.5 7.5A1.5 1.5 0 0 1 5 6h4l2 2h8a1.5 1.5 0 0 1 1.5 1.5v8A1.5 1.5 0 0 1 19 19H5a1.5 1.5 0 0 1-1.5-1.5z`})}),H=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`circle`,{cx:`6`,cy:`6`,r:`2`}),(0,x.jsx)(`circle`,{cx:`6`,cy:`18`,r:`2`}),(0,x.jsx)(`circle`,{cx:`18`,cy:`8`,r:`2`}),(0,x.jsx)(`path`,{d:`M6 8v8M18 10c0 4-6 3-11 6`})]}),U=e=>(0,x.jsx)(D,{size:13,...e,children:(0,x.jsx)(`path`,{d:`M9 4h6l-1 5 3 3v2H7v-2l3-3zM12 14v6`})}),W=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`circle`,{cx:`11`,cy:`11`,r:`6.5`}),(0,x.jsx)(`path`,{d:`M20 20l-4-4`})]}),G=e=>(0,x.jsx)(D,{...e,children:(0,x.jsx)(`path`,{d:`M12 5v14M5 12h14`})}),K=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M12 5v14M5 12h14`})}),q=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`path`,{d:`M7 3.5h7l4.5 4.5v12.5H7z`}),(0,x.jsx)(`path`,{d:`M14 3.5V8h4.5`})]}),J=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`path`,{d:`M19.5 12a7.5 7.5 0 1 1-2.2-5.3`}),(0,x.jsx)(`path`,{d:`M19.5 4.5v4h-4`})]}),Y=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M4.5 7h15M9.5 7V4.5h5V7M6.5 7l1 12.5h9l1-12.5`})}),ae=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M4.5 19.5l1-4L16 5a2 2 0 0 1 3 3L8.5 18.5z`})}),oe=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M19 12H5M11 6l-6 6 6 6`})}),se=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M9 6l6 6-6 6`})}),ce=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`rect`,{x:`8.5`,y:`8.5`,width:`11`,height:`11`,rx:`1.5`}),(0,x.jsx)(`path`,{d:`M15.5 8.5V5.5a1 1 0 0 0-1-1h-9a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h3`})]}),le=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M14 4.5h5.5V10M19.5 4.5L11 13M17 14v5.5H4.5V7H10`})}),ue=e=>(0,x.jsxs)(D,{...e,children:[(0,x.jsx)(`path`,{d:`M6 9a6 6 0 1 1 12 0c0 5 2 6.5 2 6.5H4S6 14 6 9Z`}),(0,x.jsx)(`path`,{d:`M10 19a2 2 0 0 0 4 0`})]}),de=e=>(0,x.jsxs)(D,{...e,children:[(0,x.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3`}),(0,x.jsx)(`path`,{d:`M12 3.5v2M12 18.5v2M3.5 12h2M18.5 12h2M6 6l1.4 1.4M16.6 16.6L18 18M6 18l1.4-1.4M16.6 7.4L18 6`})]}),fe=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M12 3.5l7 2.5v5.5c0 4.5-3 7.5-7 9-4-1.5-7-4.5-7-9V6z`})}),pe=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`rect`,{x:`4`,y:`4.5`,width:`16`,height:`6`,rx:`1.5`}),(0,x.jsx)(`rect`,{x:`4`,y:`13.5`,width:`16`,height:`6`,rx:`1.5`}),(0,x.jsx)(`path`,{d:`M7.5 7.5h.01M7.5 16.5h.01`})]}),me=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M5 8h3.5a2 2 0 1 1 4 0H16v3.5a2 2 0 1 1 0 4V19H5v-3.5a2 2 0 1 0 0-4z`})}),he=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`path`,{d:`M12 3.5v10a4 4 0 1 1-8 0v-1.5M12 3.5l-2 2M12 3.5l2 2`}),(0,x.jsx)(`circle`,{cx:`17`,cy:`15`,r:`2.5`})]}),ge=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`rect`,{x:`5`,y:`8`,width:`14`,height:`11`,rx:`2`}),(0,x.jsx)(`path`,{d:`M12 4.5V8M9.5 13h.01M14.5 13h.01M3 13v2M21 13v2`})]}),_e=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`path`,{d:`M5 7h9M18 7h1M5 17h1M10 17h9`}),(0,x.jsx)(`circle`,{cx:`16`,cy:`7`,r:`2`}),(0,x.jsx)(`circle`,{cx:`8`,cy:`17`,r:`2`})]}),ve=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`circle`,{cx:`12`,cy:`8.5`,r:`3.5`}),(0,x.jsx)(`path`,{d:`M5 19.5c1-3.5 3.8-5 7-5s6 1.5 7 5`})]}),ye=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M8 4.5v7M4.5 8h7M4.5 17.5h7M16 4.5v15M13 16.5l3 3 3-3`})}),be=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M5 5.5h14v10H10l-4 3.5v-3.5H5z`})}),xe=e=>(0,x.jsx)(D,{size:14,...e,children:(0,x.jsx)(`path`,{d:`M10 14a4 4 0 0 0 5.7 0l2.8-2.8a4 4 0 0 0-5.7-5.7L11.5 6.8M14 10a4 4 0 0 0-5.7 0l-2.8 2.8a4 4 0 0 0 5.7 5.7l1.3-1.3`})}),Se=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`path`,{d:`M12 4l8.5 15h-17z`}),(0,x.jsx)(`path`,{d:`M12 10v4M12 17h.01`})]}),Ce=e=>(0,x.jsxs)(D,{size:14,...e,children:[(0,x.jsx)(`rect`,{x:`4`,y:`5`,width:`16`,height:`14`,rx:`1.5`}),(0,x.jsx)(`circle`,{cx:`9`,cy:`10`,r:`1.5`}),(0,x.jsx)(`path`,{d:`M20 16l-4.5-4.5L8 19`})]}),X=`h-10 md:h-8 w-full min-w-0 rounded-md border border-border bg-surface px-3 text-base md:text-sm text-text outline-none transition-colors placeholder:text-muted/80 hover:border-muted/40 focus:border-accent/60 focus:ring-2 focus:ring-accent/20 disabled:opacity-50`,we=`${X} font-mono placeholder:font-sans`,Z=`block w-full min-w-0 rounded-md border border-border bg-surface px-3 py-2 text-base md:text-sm text-text outline-none transition-colors placeholder:text-muted/80 hover:border-muted/40 focus:border-accent/60 focus:ring-2 focus:ring-accent/20`,Q=`${Z} font-mono text-[13px] md:text-[13px] leading-relaxed placeholder:font-sans`;function Te({label:e,children:t,hint:n,className:r,group:i}){return(0,x.jsxs)(i?`div`:`label`,{className:S(`block min-w-0`,r),children:[(0,x.jsx)(`span`,{className:`mb-1.5 block text-xs font-medium text-muted`,children:e}),t,n&&(0,x.jsx)(`span`,{className:`mt-1 block text-xs leading-relaxed text-muted`,children:n})]})}function $({checked:e,onChange:t,label:n,disabled:r}){return(0,x.jsx)(`button`,{type:`button`,role:`switch`,"aria-checked":e,"aria-label":n,disabled:r,onClick:()=>t(!e),className:`group inline-flex h-10 shrink-0 items-center rounded-md px-1 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40 disabled:opacity-45 md:h-8`,children:(0,x.jsx)(`span`,{className:S(`relative h-5 w-9 rounded-full transition-colors`,e?`bg-accent`:`bg-border group-hover:bg-muted/40`),"aria-hidden":!0,children:(0,x.jsx)(`span`,{className:S(`absolute top-0.5 size-4 rounded-full bg-white shadow-sm transition-all`,e?`left-[18px]`:`left-0.5`)})})})}function Ee({checked:e,onChange:t,label:n,desc:r,disabled:i,testId:a}){return(0,x.jsxs)(`div`,{className:`flex items-center gap-3 py-1`,"data-testid":a,children:[(0,x.jsxs)(`div`,{className:`min-w-0 flex-1 cursor-pointer select-none`,onClick:()=>!i&&t(!e),children:[(0,x.jsx)(`div`,{className:`text-sm`,children:n}),r&&(0,x.jsx)(`div`,{className:`text-xs leading-relaxed text-muted`,children:r})]}),(0,x.jsx)($,{checked:e,onChange:t,label:n,disabled:i})]})}function De({value:e,options:t,onChange:n,label:r,size:i=`md`,className:a,stretch:o,disabled:s}){return(0,x.jsx)(`div`,{role:`radiogroup`,"aria-label":r,className:S(`inline-flex max-w-full gap-0.5 rounded-lg border border-border bg-surface-2/60 p-0.5`,o&&`flex w-full`,a),children:t.map(t=>{let r=t.value===e;return(0,x.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":r,disabled:s,onClick:()=>n(t.value),className:S(`inline-flex min-w-0 items-center justify-center whitespace-nowrap rounded-md transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40 disabled:pointer-events-none disabled:opacity-45`,C[i],i===`md`?`h-9 md:h-7`:`h-7 md:h-6`,o&&`flex-1`,r?`bg-surface font-medium text-text shadow-sm ring-1 ring-border`:`text-muted hover:text-text`),children:[t.icon,(0,x.jsx)(`span`,{className:`truncate`,children:t.label})]},t.value)})})}var Oe={neutral:`border-border text-muted bg-surface-2/50`,accent:`border-accent/35 text-accent bg-accent/5`,ok:`border-ok/35 text-ok bg-ok/5`,warn:`border-amber-500/40 text-amber-700 dark:text-amber-400 bg-amber-500/5`,danger:`border-danger/35 text-danger bg-danger/5`};function ke({children:e,tone:t=`neutral`,mono:n,title:r,icon:i,className:a,...o}){return(0,x.jsxs)(`span`,{title:r,className:S(`inline-flex h-5 max-w-full shrink-0 items-center gap-1 rounded border px-1.5 text-[11px] leading-none`,Oe[t],n&&`font-mono`,a),...o,children:[i,(0,x.jsx)(`span`,{className:`truncate`,children:e})]})}function Ae({icon:e,title:t,children:n,action:r,compact:i,testId:a}){return(0,x.jsxs)(`div`,{className:S(`flex flex-col items-center rounded-xl border border-dashed border-border text-center`,i?`px-4 py-5`:`px-6 py-10`),"data-testid":a,children:[e&&(0,x.jsx)(`span`,{className:`mb-2 flex size-9 items-center justify-center rounded-full bg-surface-2 text-muted`,children:e}),(0,x.jsx)(`p`,{className:`text-sm font-medium`,children:t}),n&&(0,x.jsx)(`div`,{className:`mt-1 max-w-md text-xs leading-relaxed text-muted`,children:n}),r&&(0,x.jsx)(`div`,{className:`mt-3`,children:r})]})}function je({children:e,confirmText:t,onConfirm:n,danger:r=!0,disabled:i,label:a,size:o=`sm`,icon:s,variant:c}){let[l,u]=(0,b.useState)(!1);return l?(0,x.jsxs)(`span`,{className:`inline-flex flex-wrap items-center gap-1.5 rounded-md bg-surface-2/70 py-0.5 pl-2 pr-0.5`,role:`group`,"aria-label":`确认操作`,children:[(0,x.jsx)(`span`,{className:`text-xs text-muted`,children:t}),(0,x.jsx)(T,{variant:r?`danger`:`primary`,size:o,autoFocus:!0,onClick:()=>{u(!1),n()},children:`确认`}),(0,x.jsx)(T,{variant:`ghost`,size:o,onClick:()=>u(!1),onKeyDown:e=>e.key===`Escape`&&u(!1),children:`取消`})]}):(0,x.jsx)(T,{variant:c??(r?`outline-danger`:`secondary`),size:o,icon:s,onClick:()=>u(!0),disabled:i,"aria-label":a,children:e})}function Me({rows:e=3}){return(0,x.jsx)(`div`,{className:`space-y-2 py-2`,"aria-label":`加载中`,role:`status`,children:Array.from({length:e},(e,t)=>(0,x.jsx)(`div`,{className:`h-9 animate-pulse rounded-md bg-surface-2/70`,style:{opacity:1-t*.2}},t))})}export{ee as $,de as A,U as B,B as C,le as D,F as E,xe as F,z as G,G as H,te as I,pe as J,J as K,O as L,R as M,he as N,q as O,Ce as P,L as Q,N as R,se as S,ye as T,K as U,ie as V,me as W,_e as X,fe as Y,ne as Z,re as _,s as _t,Me as a,T as at,j as b,$ as c,S as ct,Q as d,v as dt,Y as et,Z as f,g as ft,ge as g,o as gt,ue as h,d as ht,De as i,M as it,P as j,V as k,X as l,_ as lt,oe as m,p as mt,Ae as n,ve as nt,Ee as o,C as ot,Se as p,h as pt,W as q,Te as r,k as rt,ke as s,E as st,je as t,I as tt,we as u,y as ut,H as v,l as vt,ce as w,A as x,be as y,ae as z};
@@ -0,0 +1 @@
1
+ import{at as e,ht as t,k as n,mt as r,vt as i}from"./Form-BKTwiYyw.js";import{_ as a,i as o,m as s,o as c,v as l,y as u}from"./Modal-g2rv8I_n.js";import{t as d}from"./lib-DlcVMUqT.js";import{M as f,d as p,f as m,g as h}from"./index-DQh72lEx.js";var g=i(t(),1),_=r();function v(){let t=l(),n=a(),[r,i]=(0,g.useState)(!1),o=n.data??[],s=t.data??[];return(0,_.jsx)(`main`,{className:`min-h-0 flex-1 overflow-y-auto`,children:(0,_.jsxs)(`div`,{className:`mx-auto max-w-4xl px-4 py-8 md:px-8 md:py-10`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,_.jsx)(`h1`,{className:`flex-1 text-3xl`,children:`项目`}),!r&&(0,_.jsx)(e,{icon:(0,_.jsx)(f,{}),onClick:()=>i(!0),children:`添加项目`})]}),o.length>0&&(0,_.jsxs)(d,{to:`/overview`,className:`mt-6 flex items-center gap-3 rounded-xl border border-accent/30 bg-accent/5 px-4 py-3 text-sm transition-colors hover:border-accent/60`,children:[(0,_.jsx)(m,{state:o.some(e=>e.waitingFor.length||e.state===`requires_action`)?`requires_action`:`running`}),(0,_.jsxs)(`span`,{className:`flex-1`,children:[o.filter(e=>e.state===`running`).length,` 个会话运行中`,o.some(e=>e.waitingFor.length)&&`,${o.filter(e=>e.waitingFor.length).length} 个等你处理`]}),(0,_.jsx)(`span`,{className:`text-muted`,children:`运行总览 →`})]}),r&&(0,_.jsx)(p,{onDone:()=>i(!1),onCancel:()=>i(!1)}),t.isSuccess&&s.length===0&&(0,_.jsxs)(`section`,{className:`mt-6 rounded-xl border border-border bg-surface p-4 md:max-w-lg`,children:[(0,_.jsx)(`h2`,{className:`text-base`,children:`暂无项目`}),(0,_.jsx)(`p`,{className:`mt-1 text-xs text-muted`,children:`点击右上角添加项目,选择或创建项目目录。`})]}),(0,_.jsx)(`ul`,{className:`mt-6 grid gap-3 md:grid-cols-2`,children:s.map(e=>(0,_.jsx)(`li`,{className:`min-w-0`,children:(0,_.jsx)(y,{p:e})},e.id))})]})})}function y({p:e}){let t=u(e.id),r=h(),i=(t.data??[]).filter(e=>!e.archived),a=i.reduce((e,t)=>Math.max(e,t.lastModified),0),l=i.filter(e=>e.state!==`idle`).length;return(0,_.jsxs)(`div`,{className:`relative flex h-full min-w-0 flex-col rounded-xl border border-border bg-surface transition-colors hover:border-muted/40`,"data-testid":`project-card`,"data-project-id":e.id,children:[(0,_.jsxs)(d,{to:`/p/${e.id}`,className:`flex min-w-0 flex-1 flex-col rounded-xl px-4 py-3.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent/40`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,_.jsx)(n,{className:`shrink-0 text-muted`}),(0,_.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-medium`,children:e.name}),!e.exists&&(0,_.jsx)(`span`,{className:`text-xs text-danger`,children:`目录不存在`})]}),(0,_.jsx)(`div`,{className:`mt-1 truncate font-mono text-xs text-muted`,children:e.path}),(0,_.jsxs)(`div`,{className:`mt-3 flex min-h-7 flex-wrap items-center gap-x-3 gap-y-1 pr-8 text-xs text-muted md:min-h-6`,children:[(0,_.jsx)(`span`,{children:t.isSuccess?`${i.length} 个会话`:`…`}),a>0&&(0,_.jsxs)(`span`,{children:[`最近 `,s(a)]}),l>0&&(0,_.jsxs)(`span`,{className:`flex items-center gap-1 text-accent`,children:[(0,_.jsx)(m,{state:`running`}),l,` 个运行中`]})]})]}),r.error&&(0,_.jsx)(`p`,{role:`alert`,className:`break-words px-4 pb-3 pr-12 text-xs text-danger`,children:r.error.message}),(0,_.jsx)(`div`,{className:`absolute bottom-3 right-2`,children:(0,_.jsx)(o,{label:`${e.name} 更多操作`,testId:`project-menu`,children:t=>(0,_.jsx)(c,{danger:!0,onClick:()=>{t(),r.isPending||r.mutate(e)},children:r.isPending?`正在移除…`:`移除项目`})})})]})}export{v as HomePage};