@rexvane/piweb 0.3.25 → 0.3.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +6 -5
  3. package/.next/build-manifest.json +4 -4
  4. package/.next/next-server.js.nft.json +1 -1
  5. package/.next/prerender-manifest.json +4 -4
  6. package/.next/react-loadable-manifest.json +14 -26
  7. package/.next/required-server-files.js +26 -26
  8. package/.next/required-server-files.json +26 -26
  9. package/.next/routes-manifest.json +6 -0
  10. package/.next/server/app/_global-error/page.js +2 -2
  11. package/.next/server/app/_global-error/page.js.nft.json +1 -1
  12. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  13. package/.next/server/app/_global-error.html +1 -1
  14. package/.next/server/app/_global-error.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  16. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  17. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  18. package/.next/server/app/_not-found/page.js +1 -1
  19. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  20. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  21. package/.next/server/app/_not-found.html +1 -1
  22. package/.next/server/app/_not-found.rsc +2 -2
  23. package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  24. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  25. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  26. package/.next/server/app/api/agent/[id]/events/route.js +2 -2
  27. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
  28. package/.next/server/app/api/agent/[id]/events/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/agent/[id]/route.js +1 -1
  30. package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
  31. package/.next/server/app/api/agent/[id]/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/agent/[id]/tree/route.js +1 -1
  33. package/.next/server/app/api/agent/[id]/tree/route.js.nft.json +1 -1
  34. package/.next/server/app/api/agent/[id]/tree/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/agent/new/route.js +1 -1
  36. package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
  37. package/.next/server/app/api/agent/new/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/agent/resources/route.js +1 -0
  39. package/.next/server/app/api/agent/resources/route.js.nft.json +1 -0
  40. package/.next/server/app/api/agent/resources/route_client-reference-manifest.js +1 -0
  41. package/.next/server/app/api/config/route.js +1 -1
  42. package/.next/server/app/api/config/route.js.nft.json +1 -1
  43. package/.next/server/app/api/config/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/files/route.js +1 -1
  45. package/.next/server/app/api/files/route.js.nft.json +1 -1
  46. package/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/fs/route.js +1 -1
  48. package/.next/server/app/api/fs/route.js.nft.json +1 -1
  49. package/.next/server/app/api/fs/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/git/route.js +4 -4
  51. package/.next/server/app/api/git/route.js.nft.json +1 -1
  52. package/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/github/route.js +4 -4
  54. package/.next/server/app/api/github/route.js.nft.json +1 -1
  55. package/.next/server/app/api/github/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/growth/route.js +1 -1
  57. package/.next/server/app/api/growth/route.js.nft.json +1 -1
  58. package/.next/server/app/api/growth/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/health/route.js +1 -1
  60. package/.next/server/app/api/health/route.js.nft.json +1 -1
  61. package/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/models/defaults/route.js +1 -1
  63. package/.next/server/app/api/models/defaults/route.js.nft.json +1 -1
  64. package/.next/server/app/api/models/defaults/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/models/route.js +1 -1
  66. package/.next/server/app/api/models/route.js.nft.json +1 -1
  67. package/.next/server/app/api/models/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/pi-settings/route.js +1 -1
  69. package/.next/server/app/api/pi-settings/route.js.nft.json +1 -1
  70. package/.next/server/app/api/pi-settings/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/plugins/route.js +1 -1
  72. package/.next/server/app/api/plugins/route.js.nft.json +1 -1
  73. package/.next/server/app/api/plugins/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/prompts/route.js +1 -1
  75. package/.next/server/app/api/prompts/route.js.nft.json +1 -1
  76. package/.next/server/app/api/prompts/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/remote/route.js +2 -2
  78. package/.next/server/app/api/remote/route.js.nft.json +1 -1
  79. package/.next/server/app/api/remote/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/security/route.js +1 -1
  81. package/.next/server/app/api/security/route.js.nft.json +1 -1
  82. package/.next/server/app/api/security/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/sessions/[id]/export/route.js +1 -1
  84. package/.next/server/app/api/sessions/[id]/export/route.js.nft.json +1 -1
  85. package/.next/server/app/api/sessions/[id]/export/route_client-reference-manifest.js +1 -1
  86. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  87. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  88. package/.next/server/app/api/sessions/[id]/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/sessions/import/route.js +2 -2
  90. package/.next/server/app/api/sessions/import/route.js.nft.json +1 -1
  91. package/.next/server/app/api/sessions/import/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/sessions/route.js +1 -1
  93. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  94. package/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/skills/route.js +2 -2
  96. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  97. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/update/route.js +2 -2
  99. package/.next/server/app/api/update/route.js.nft.json +1 -1
  100. package/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/version/route.js +1 -1
  102. package/.next/server/app/api/version/route.js.nft.json +1 -1
  103. package/.next/server/app/api/version/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/web-auth/route.js +2 -2
  105. package/.next/server/app/api/web-auth/route.js.nft.json +1 -1
  106. package/.next/server/app/api/web-auth/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/workspaces/route.js +1 -1
  108. package/.next/server/app/api/workspaces/route.js.nft.json +1 -1
  109. package/.next/server/app/api/workspaces/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/icon.svg/route.js +1 -1
  111. package/.next/server/app/icon.svg/route.js.nft.json +1 -1
  112. package/.next/server/app/index.html +1 -1
  113. package/.next/server/app/index.rsc +5 -5
  114. package/.next/server/app/index.segments/__PAGE__.segment.rsc +5 -5
  115. package/.next/server/app/index.segments/_full.segment.rsc +5 -5
  116. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  117. package/.next/server/app/login/page.js +1 -1
  118. package/.next/server/app/login/page.js.nft.json +1 -1
  119. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  120. package/.next/server/app/login.html +1 -1
  121. package/.next/server/app/login.rsc +4 -4
  122. package/.next/server/app/login.segments/_full.segment.rsc +4 -4
  123. package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  124. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
  125. package/.next/server/app/page.js +1 -1
  126. package/.next/server/app/page.js.nft.json +1 -1
  127. package/.next/server/app/page_client-reference-manifest.js +1 -1
  128. package/.next/server/app-paths-manifest.json +6 -5
  129. package/.next/server/chunks/{813.js → 1813.js} +1 -1
  130. package/.next/server/chunks/{430.js → 2430.js} +5 -5
  131. package/.next/server/chunks/{970.js → 2970.js} +1 -1
  132. package/.next/server/chunks/3924.js +6 -0
  133. package/.next/server/chunks/4807.js +1 -0
  134. package/.next/server/chunks/5393.js +1 -0
  135. package/.next/server/chunks/5802.js +2 -0
  136. package/.next/server/chunks/620.js +1 -1
  137. package/.next/server/chunks/6229.js +1 -0
  138. package/.next/server/chunks/7496.js +1 -0
  139. package/.next/server/chunks/7662.js +2 -0
  140. package/.next/server/chunks/8686.js +1 -0
  141. package/.next/server/chunks/{593.js → 974.js} +1 -1
  142. package/.next/server/chunks/{920.js → 9920.js} +1 -1
  143. package/.next/server/instrumentation.js +1 -1
  144. package/.next/server/instrumentation.js.nft.json +1 -1
  145. package/.next/server/middleware-build-manifest.js +1 -1
  146. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  147. package/.next/server/middleware.js +5 -5
  148. package/.next/server/pages/404.html +1 -1
  149. package/.next/server/pages/500.html +1 -1
  150. package/.next/server/preview-props.json +3 -3
  151. package/.next/server/server-reference-manifest.json +1 -1
  152. package/.next/server/webpack-runtime.js +1 -1
  153. package/.next/static/QJCtqgDKzGS2BdKABd9ch/_buildManifest.js +1 -0
  154. package/.next/static/chunks/2577.86c8538fbf05a8b2.js +1 -0
  155. package/.next/static/chunks/2716.fa561519675a3ff1.js +1 -0
  156. package/.next/static/chunks/2906.8a0e09bb47605cf1.js +1 -0
  157. package/.next/static/chunks/4673.ea36e55005c0f82f.js +1 -0
  158. package/.next/static/chunks/4686-4dc565817a160351.js +1 -0
  159. package/.next/static/chunks/4778.0d2c5d75b791d352.js +1 -0
  160. package/.next/static/chunks/app/_global-error/page-f2d93969c0bcf406.js +1 -0
  161. package/.next/static/chunks/app/_not-found/page-2d40d1d7d916666a.js +1 -0
  162. package/.next/static/chunks/app/api/agent/[id]/events/route-f2d93969c0bcf406.js +1 -0
  163. package/.next/static/chunks/app/api/agent/[id]/route-f2d93969c0bcf406.js +1 -0
  164. package/.next/static/chunks/app/api/agent/[id]/tree/route-f2d93969c0bcf406.js +1 -0
  165. package/.next/static/chunks/app/api/agent/new/route-f2d93969c0bcf406.js +1 -0
  166. package/.next/static/chunks/app/api/agent/resources/route-f2d93969c0bcf406.js +1 -0
  167. package/.next/static/chunks/app/api/config/route-f2d93969c0bcf406.js +1 -0
  168. package/.next/static/chunks/app/api/files/route-f2d93969c0bcf406.js +1 -0
  169. package/.next/static/chunks/app/api/fs/route-f2d93969c0bcf406.js +1 -0
  170. package/.next/static/chunks/app/api/git/route-f2d93969c0bcf406.js +1 -0
  171. package/.next/static/chunks/app/api/github/route-f2d93969c0bcf406.js +1 -0
  172. package/.next/static/chunks/app/api/growth/route-f2d93969c0bcf406.js +1 -0
  173. package/.next/static/chunks/app/api/health/route-f2d93969c0bcf406.js +1 -0
  174. package/.next/static/chunks/app/api/models/defaults/route-f2d93969c0bcf406.js +1 -0
  175. package/.next/static/chunks/app/api/models/route-f2d93969c0bcf406.js +1 -0
  176. package/.next/static/chunks/app/api/pi-settings/route-f2d93969c0bcf406.js +1 -0
  177. package/.next/static/chunks/app/api/plugins/route-f2d93969c0bcf406.js +1 -0
  178. package/.next/static/chunks/app/api/prompts/route-f2d93969c0bcf406.js +1 -0
  179. package/.next/static/chunks/app/api/remote/route-f2d93969c0bcf406.js +1 -0
  180. package/.next/static/chunks/app/api/security/route-f2d93969c0bcf406.js +1 -0
  181. package/.next/static/chunks/app/api/sessions/[id]/export/route-f2d93969c0bcf406.js +1 -0
  182. package/.next/static/chunks/app/api/sessions/[id]/route-f2d93969c0bcf406.js +1 -0
  183. package/.next/static/chunks/app/api/sessions/import/route-f2d93969c0bcf406.js +1 -0
  184. package/.next/static/chunks/app/api/sessions/route-f2d93969c0bcf406.js +1 -0
  185. package/.next/static/chunks/app/api/skills/route-f2d93969c0bcf406.js +1 -0
  186. package/.next/static/chunks/app/api/update/route-f2d93969c0bcf406.js +1 -0
  187. package/.next/static/chunks/app/api/version/route-f2d93969c0bcf406.js +1 -0
  188. package/.next/static/chunks/app/api/web-auth/route-f2d93969c0bcf406.js +1 -0
  189. package/.next/static/chunks/app/api/workspaces/route-f2d93969c0bcf406.js +1 -0
  190. package/.next/static/chunks/app/{layout-7f64fa67ea6ce980.js → layout-50d06e2078d6ce76.js} +1 -1
  191. package/.next/static/chunks/app/login/{page-00dbd2f395b364d5.js → page-5e276a1eeb8867df.js} +1 -1
  192. package/.next/static/chunks/app/page-71f2d3b3ed864b3d.js +1 -0
  193. package/.next/static/chunks/main-5403f0764579e5fe.js +5 -0
  194. package/.next/static/chunks/{main-app-56863ace24eb152f.js → main-app-e9b53f0e1c6591b2.js} +1 -1
  195. package/.next/static/chunks/next/dist/client/components/builtin/app-error-f2d93969c0bcf406.js +1 -0
  196. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-f2d93969c0bcf406.js +1 -0
  197. package/.next/static/chunks/next/dist/client/components/builtin/global-error-a7e260f8cc2582d7.js +1 -0
  198. package/.next/static/chunks/next/dist/client/components/builtin/not-found-f2d93969c0bcf406.js +1 -0
  199. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-f2d93969c0bcf406.js +1 -0
  200. package/.next/static/chunks/webpack-ffc09b5fcc8aaa6d.js +1 -0
  201. package/.next/static/css/7e3caf797e4cb19a.css +1 -0
  202. package/.next/types/app/api/agent/[id]/events/route.ts +1 -1
  203. package/.next/types/app/api/agent/[id]/route.ts +1 -1
  204. package/.next/types/app/api/agent/[id]/tree/route.ts +1 -1
  205. package/.next/types/app/api/agent/new/route.ts +1 -1
  206. package/.next/types/app/api/agent/resources/route.ts +355 -0
  207. package/.next/types/app/api/config/route.ts +1 -1
  208. package/.next/types/app/api/files/route.ts +1 -1
  209. package/.next/types/app/api/fs/route.ts +1 -1
  210. package/.next/types/app/api/git/route.ts +1 -1
  211. package/.next/types/app/api/github/route.ts +1 -1
  212. package/.next/types/app/api/growth/route.ts +1 -1
  213. package/.next/types/app/api/health/route.ts +1 -1
  214. package/.next/types/app/api/models/defaults/route.ts +1 -1
  215. package/.next/types/app/api/models/route.ts +1 -1
  216. package/.next/types/app/api/pi-settings/route.ts +1 -1
  217. package/.next/types/app/api/plugins/route.ts +1 -1
  218. package/.next/types/app/api/prompts/route.ts +1 -1
  219. package/.next/types/app/api/remote/route.ts +1 -1
  220. package/.next/types/app/api/security/route.ts +1 -1
  221. package/.next/types/app/api/sessions/[id]/export/route.ts +1 -1
  222. package/.next/types/app/api/sessions/[id]/route.ts +1 -1
  223. package/.next/types/app/api/sessions/import/route.ts +1 -1
  224. package/.next/types/app/api/sessions/route.ts +1 -1
  225. package/.next/types/app/api/skills/route.ts +1 -1
  226. package/.next/types/app/api/update/route.ts +1 -1
  227. package/.next/types/app/api/version/route.ts +1 -1
  228. package/.next/types/app/api/web-auth/route.ts +1 -1
  229. package/.next/types/app/api/workspaces/route.ts +1 -1
  230. package/.next/types/app/layout.ts +1 -1
  231. package/.next/types/app/login/page.ts +1 -1
  232. package/.next/types/app/page.ts +1 -1
  233. package/.next/types/routes.d.ts +2 -1
  234. package/.next/types/validator.ts +10 -0
  235. package/LICENSE +1 -1
  236. package/README.md +1 -1
  237. package/bin/pi.js +0 -0
  238. package/bin/piweb.js +0 -0
  239. package/package.json +1 -1
  240. package/scripts/build-output.mjs +0 -0
  241. package/scripts/dev.mjs +0 -0
  242. package/scripts/entrypoint.mjs +0 -0
  243. package/scripts/install-build.mjs +0 -0
  244. package/scripts/launcher.mjs +0 -0
  245. package/scripts/pick-folder.ps1 +0 -0
  246. package/scripts/postinstall.mjs +0 -0
  247. package/scripts/process-runner.mjs +0 -0
  248. package/scripts/release.mjs +0 -0
  249. package/scripts/sync-file-icons.mjs +0 -0
  250. package/scripts/sync-provider-icons.mjs +0 -0
  251. package/src/app/api/agent/resources/route.ts +18 -0
  252. package/src/app/api/remote/route.ts +5 -7
  253. package/src/app/api/sessions/[id]/export/route.ts +3 -1
  254. package/src/app/globals.css +16 -0
  255. package/src/components/AppShell.tsx +68 -21
  256. package/src/components/ChatInput.tsx +98 -27
  257. package/src/components/ChatWindow.tsx +68 -11
  258. package/src/components/ContextMeter.tsx +24 -4
  259. package/src/components/ExtensionUI.tsx +9 -3
  260. package/src/components/FileViewer.tsx +24 -21
  261. package/src/components/GitPanel.tsx +449 -449
  262. package/src/components/GrowthTree.tsx +3 -1
  263. package/src/components/ImageViewer.tsx +72 -0
  264. package/src/components/MarkdownBlock.tsx +6 -3
  265. package/src/components/PreviewImage.tsx +33 -0
  266. package/src/components/ProjectPanel.tsx +5 -3
  267. package/src/components/PromptPanel.tsx +322 -313
  268. package/src/components/RemoteSection.tsx +2 -1
  269. package/src/components/SessionSidebar.tsx +22 -4
  270. package/src/components/SettingsPanel.tsx +2654 -2639
  271. package/src/components/composer/ComposerImages.tsx +1 -79
  272. package/src/hooks/usePiWeb.ts +47 -2
  273. package/src/i18n.tsx +24 -0
  274. package/src/lib/agent-manager.ts +275 -18
  275. package/src/lib/chat/skill-expansion.ts +10 -0
  276. package/src/lib/extension-ui.ts +25 -1
  277. package/src/lib/git-service.ts +291 -289
  278. package/src/lib/github-identity.ts +245 -245
  279. package/src/lib/growth-turns.ts +3 -1
  280. package/src/lib/session-reader.ts +25 -13
  281. package/src/lib/session-retention.ts +11 -8
  282. package/src/lib/slash-command-token.ts +14 -0
  283. package/src/lib/trajectory.ts +17 -6
  284. package/src/lib/types.ts +24 -2
  285. package/src/lib/workspace-store.ts +36 -1
  286. package/.next/diagnostics/build-diagnostics.json +0 -6
  287. package/.next/diagnostics/framework.json +0 -1
  288. package/.next/server/chunks/229.js +0 -1
  289. package/.next/server/chunks/393.js +0 -1
  290. package/.next/server/chunks/612.js +0 -1
  291. package/.next/server/chunks/662.js +0 -2
  292. package/.next/server/chunks/686.js +0 -1
  293. package/.next/server/chunks/802.js +0 -2
  294. package/.next/server/chunks/807.js +0 -1
  295. package/.next/server/chunks/924.js +0 -6
  296. package/.next/static/4snUelZTEIiQYCkB5nTW7/_buildManifest.js +0 -1
  297. package/.next/static/chunks/1966.1560d0f43ac9a41a.js +0 -1
  298. package/.next/static/chunks/2577.eebf2cf291a811ad.js +0 -1
  299. package/.next/static/chunks/2716.a5228b0eeedbe4c8.js +0 -1
  300. package/.next/static/chunks/2906.546a64377e12dfbc.js +0 -1
  301. package/.next/static/chunks/3899.55a0943bf5e7fec7.js +0 -1
  302. package/.next/static/chunks/4673.8eff281cb63e2799.js +0 -1
  303. package/.next/static/chunks/4686-f03275819a719fd8.js +0 -1
  304. package/.next/static/chunks/4778.2dae0c6a9e396326.js +0 -1
  305. package/.next/static/chunks/app/_global-error/page-f977af7f858990a2.js +0 -1
  306. package/.next/static/chunks/app/_not-found/page-851dc3883a1937aa.js +0 -1
  307. package/.next/static/chunks/app/api/agent/[id]/events/route-f977af7f858990a2.js +0 -1
  308. package/.next/static/chunks/app/api/agent/[id]/route-f977af7f858990a2.js +0 -1
  309. package/.next/static/chunks/app/api/agent/[id]/tree/route-f977af7f858990a2.js +0 -1
  310. package/.next/static/chunks/app/api/agent/new/route-f977af7f858990a2.js +0 -1
  311. package/.next/static/chunks/app/api/config/route-f977af7f858990a2.js +0 -1
  312. package/.next/static/chunks/app/api/files/route-f977af7f858990a2.js +0 -1
  313. package/.next/static/chunks/app/api/fs/route-f977af7f858990a2.js +0 -1
  314. package/.next/static/chunks/app/api/git/route-f977af7f858990a2.js +0 -1
  315. package/.next/static/chunks/app/api/github/route-f977af7f858990a2.js +0 -1
  316. package/.next/static/chunks/app/api/growth/route-f977af7f858990a2.js +0 -1
  317. package/.next/static/chunks/app/api/health/route-f977af7f858990a2.js +0 -1
  318. package/.next/static/chunks/app/api/models/defaults/route-f977af7f858990a2.js +0 -1
  319. package/.next/static/chunks/app/api/models/route-f977af7f858990a2.js +0 -1
  320. package/.next/static/chunks/app/api/pi-settings/route-f977af7f858990a2.js +0 -1
  321. package/.next/static/chunks/app/api/plugins/route-f977af7f858990a2.js +0 -1
  322. package/.next/static/chunks/app/api/prompts/route-f977af7f858990a2.js +0 -1
  323. package/.next/static/chunks/app/api/remote/route-f977af7f858990a2.js +0 -1
  324. package/.next/static/chunks/app/api/security/route-f977af7f858990a2.js +0 -1
  325. package/.next/static/chunks/app/api/sessions/[id]/export/route-f977af7f858990a2.js +0 -1
  326. package/.next/static/chunks/app/api/sessions/[id]/route-f977af7f858990a2.js +0 -1
  327. package/.next/static/chunks/app/api/sessions/import/route-f977af7f858990a2.js +0 -1
  328. package/.next/static/chunks/app/api/sessions/route-f977af7f858990a2.js +0 -1
  329. package/.next/static/chunks/app/api/skills/route-f977af7f858990a2.js +0 -1
  330. package/.next/static/chunks/app/api/update/route-f977af7f858990a2.js +0 -1
  331. package/.next/static/chunks/app/api/version/route-f977af7f858990a2.js +0 -1
  332. package/.next/static/chunks/app/api/web-auth/route-f977af7f858990a2.js +0 -1
  333. package/.next/static/chunks/app/api/workspaces/route-f977af7f858990a2.js +0 -1
  334. package/.next/static/chunks/app/page-0159987118376f42.js +0 -1
  335. package/.next/static/chunks/main-22ccebc2da4d291e.js +0 -5
  336. package/.next/static/chunks/next/dist/client/components/builtin/app-error-f977af7f858990a2.js +0 -1
  337. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-f977af7f858990a2.js +0 -1
  338. package/.next/static/chunks/next/dist/client/components/builtin/global-error-c37b7707077f50ce.js +0 -1
  339. package/.next/static/chunks/next/dist/client/components/builtin/not-found-f977af7f858990a2.js +0 -1
  340. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-f977af7f858990a2.js +0 -1
  341. package/.next/static/chunks/webpack-c1b43c269867b64f.js +0 -1
  342. package/.next/static/css/93ed3daa6f3fbc35.css +0 -1
  343. package/.next/trace +0 -58
  344. package/.next/trace-build +0 -1
  345. /package/.next/static/{4snUelZTEIiQYCkB5nTW7 → QJCtqgDKzGS2BdKABd9ch}/_ssgManifest.js +0 -0
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\models\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/models/route.ts
2
2
  import * as entry from '../../../../../src/app/api/models/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\pi-settings\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/pi-settings/route.ts
2
2
  import * as entry from '../../../../../src/app/api/pi-settings/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\plugins\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/plugins/route.ts
2
2
  import * as entry from '../../../../../src/app/api/plugins/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\prompts\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/prompts/route.ts
2
2
  import * as entry from '../../../../../src/app/api/prompts/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\remote\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/remote/route.ts
2
2
  import * as entry from '../../../../../src/app/api/remote/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\security\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/security/route.ts
2
2
  import * as entry from '../../../../../src/app/api/security/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\sessions\[id]\export\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/sessions/[id]/export/route.ts
2
2
  import * as entry from '../../../../../../../src/app/api/sessions/[id]/export/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\sessions\[id]\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/sessions/[id]/route.ts
2
2
  import * as entry from '../../../../../../src/app/api/sessions/[id]/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\sessions\import\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/sessions/import/route.ts
2
2
  import * as entry from '../../../../../../src/app/api/sessions/import/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\sessions\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/sessions/route.ts
2
2
  import * as entry from '../../../../../src/app/api/sessions/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\skills\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/skills/route.ts
2
2
  import * as entry from '../../../../../src/app/api/skills/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\update\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/update/route.ts
2
2
  import * as entry from '../../../../../src/app/api/update/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\version\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/version/route.ts
2
2
  import * as entry from '../../../../../src/app/api/version/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\web-auth\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/web-auth/route.ts
2
2
  import * as entry from '../../../../../src/app/api/web-auth/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\api\workspaces\route.ts
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/api/workspaces/route.ts
2
2
  import * as entry from '../../../../../src/app/api/workspaces/route.js'
3
3
  import type { NextRequest } from 'next/server.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\layout.tsx
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/layout.tsx
2
2
  import * as entry from '../../../src/app/layout.js'
3
3
  import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\login\page.tsx
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/login/page.tsx
2
2
  import * as entry from '../../../../src/app/login/page.js'
3
3
  import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
4
4
 
@@ -1,4 +1,4 @@
1
- // File: D:\AIApp\PiWeb\src\app\page.tsx
1
+ // File: /home/runner/work/PiWeb/PiWeb/src/app/page.tsx
2
2
  import * as entry from '../../../src/app/page.js'
3
3
  import type { ResolvingMetadata, ResolvingViewport } from 'next/dist/lib/metadata/types/metadata-interface.js'
4
4
 
@@ -2,7 +2,7 @@
2
2
  // Do not edit this file manually
3
3
 
4
4
  type AppRoutes = "/" | "/login"
5
- type AppRouteHandlerRoutes = "/api/agent/[id]" | "/api/agent/[id]/events" | "/api/agent/[id]/tree" | "/api/agent/new" | "/api/config" | "/api/files" | "/api/fs" | "/api/git" | "/api/github" | "/api/growth" | "/api/health" | "/api/models" | "/api/models/defaults" | "/api/pi-settings" | "/api/plugins" | "/api/prompts" | "/api/remote" | "/api/security" | "/api/sessions" | "/api/sessions/[id]" | "/api/sessions/[id]/export" | "/api/sessions/import" | "/api/skills" | "/api/update" | "/api/version" | "/api/web-auth" | "/api/workspaces"
5
+ type AppRouteHandlerRoutes = "/api/agent/[id]" | "/api/agent/[id]/events" | "/api/agent/[id]/tree" | "/api/agent/new" | "/api/agent/resources" | "/api/config" | "/api/files" | "/api/fs" | "/api/git" | "/api/github" | "/api/growth" | "/api/health" | "/api/models" | "/api/models/defaults" | "/api/pi-settings" | "/api/plugins" | "/api/prompts" | "/api/remote" | "/api/security" | "/api/sessions" | "/api/sessions/[id]" | "/api/sessions/[id]/export" | "/api/sessions/import" | "/api/skills" | "/api/update" | "/api/version" | "/api/web-auth" | "/api/workspaces"
6
6
  type PageRoutes = never
7
7
  type LayoutRoutes = "/"
8
8
  type RedirectRoutes = never
@@ -16,6 +16,7 @@ interface ParamMap {
16
16
  "/api/agent/[id]/events": { "id": string; }
17
17
  "/api/agent/[id]/tree": { "id": string; }
18
18
  "/api/agent/new": {}
19
+ "/api/agent/resources": {}
19
20
  "/api/config": {}
20
21
  "/api/files": {}
21
22
  "/api/fs": {}
@@ -126,6 +126,16 @@ type RouteHandlerConfig<Route extends AppRouteHandlerRoutes = AppRouteHandlerRou
126
126
  type __Unused = __Check
127
127
  }
128
128
 
129
+ // Validate ../../src/app/api/agent/resources/route.ts
130
+ {
131
+ type __IsExpected<Specific extends RouteHandlerConfig<"/api/agent/resources">> = Specific
132
+ const handler = {} as typeof import("../../src/app/api/agent/resources/route.js")
133
+ type __Check = __IsExpected<typeof handler>
134
+
135
+ // @ts-ignore
136
+ type __Unused = __Check
137
+ }
138
+
129
139
  // Validate ../../src/app/api/config/route.ts
130
140
  {
131
141
  type __IsExpected<Specific extends RouteHandlerConfig<"/api/config">> = Specific
package/LICENSE CHANGED
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -110,7 +110,7 @@ is npm's default tag, so `npm install -g @rexvane/piweb` behaves identically; if
110
110
  is a mirror that syncs with a delay, add `--registry=https://registry.npmjs.org` to get a
111
111
  release the moment it is published. Restart `piweb` afterwards to serve the new version.
112
112
 
113
- Or install a specific version: `npm install -g @rexvane/piweb@0.3.25`.
113
+ Or install a specific version: `npm install -g @rexvane/piweb@0.3.26`.
114
114
 
115
115
  **Updating from the UI**: every time PiWeb starts it checks PiWeb and pi for new versions in the
116
116
  background. When one is available it prints `[更新] 有新版本:…` in the terminal and shows a notice
package/bin/pi.js CHANGED
File without changes
package/bin/piweb.js CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rexvane/piweb",
3
- "version": "0.3.25",
3
+ "version": "0.3.26",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Modern web UI for the pi coding agent, driven by the official pi SDK without modifying pi",
File without changes
package/scripts/dev.mjs CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,18 @@
1
+ import { NextResponse } from "next/server";
2
+ import { loadWorkspaceResources } from "@/lib/agent-manager";
3
+ import { BoundaryError, resolveWorkspacePath } from "@/lib/path-security";
4
+
5
+ export const dynamic = "force-dynamic";
6
+
7
+ /** 新会话/冷会话的补全数据;不建会话、不启动 MCP。 */
8
+ export async function GET(req: Request) {
9
+ try {
10
+ const cwd = await resolveWorkspacePath(new URL(req.url).searchParams.get("cwd"));
11
+ return NextResponse.json({ success: true, data: await loadWorkspaceResources(cwd) });
12
+ } catch (error) {
13
+ return NextResponse.json(
14
+ { success: false, error: error instanceof Error ? error.message : "request failed" },
15
+ { status: error instanceof BoundaryError ? 400 : 500 },
16
+ );
17
+ }
18
+ }
@@ -9,7 +9,7 @@
9
9
  * 认证没开时 proxy 一律放行,这时开出去的局域网 / 公网入口就是一个免密 shell。
10
10
  */
11
11
  import { NextResponse } from "next/server";
12
- import { remoteBlocked, remoteStatus, setRemotePluginEnabled, startLan, startPublic, stopAll, stopLan, stopPublic } from "@/lib/remote/supervisor";
12
+ import { remoteBlocked, remoteLanEnabled, remoteStatus, setRemotePluginEnabled, startLan, startPublic, stopAll, stopLan, stopPublic } from "@/lib/remote/supervisor";
13
13
  import { authEnabled } from "@/lib/web-auth";
14
14
 
15
15
  export const dynamic = "force-dynamic";
@@ -78,12 +78,10 @@ export async function POST(request: Request) {
78
78
  if (!enabled) await stopPublic();
79
79
  // 注入资源是在建监听时就烧进去的,所以必须重建监听,开关才真正生效;
80
80
  // 重建只在「原监听需要换模式」时做,避免白断一次连接。
81
- if (before.lan.running && before.lan.styled !== enabled) {
82
- await stopLan();
83
- await startLan();
84
- } else {
85
- await startLan();
86
- }
81
+ if (before.lan.running && before.lan.styled !== enabled) await stopLan();
82
+ // 起监听与启动时(instrumentation-node)同一道闸:认证没开 / 开发模式 / PIWEB_REMOTE_LAN=0 时
83
+ // 只存开关,不开局域网入口——否则拨一下开关就绕过 start-lan 的检查开出一个免密入口。
84
+ if (remoteBlocked() === null && remoteLanEnabled()) await startLan();
87
85
  return respond();
88
86
  }
89
87
  default:
@@ -18,7 +18,9 @@ export async function GET(req: Request, { params }: { params: Promise<{ id: stri
18
18
  const { id } = await params;
19
19
  const format = new URL(req.url).searchParams.get("format") === "html" ? "html" : "jsonl";
20
20
  try {
21
- const m = getManaged(await resolveSessionPath(id));
21
+ // 与 /api/agent/[id] 同一种解析(allowPending 返回原写法而不是 realpath):会话表按路径字符串做键,
22
+ // ~/.pi 经过 junction / 符号链接时两种写法不同,导出 HTML 就会给同一个文件再起一个 agent
23
+ const m = getManaged(await resolveSessionPath(id, { allowPending: true }));
22
24
  const { filename, content, contentType } = await exportSession(m, format);
23
25
  return new Response(content, {
24
26
  headers: {
@@ -2567,6 +2567,22 @@ body[data-pebrel-theme="pebrel"][data-ds-dark-theme] {
2567
2567
  .pw-image-delete:disabled {
2568
2568
  opacity: 0.4;
2569
2569
  }
2570
+ /* 聊天图片可点击,保持原图尺寸和排版;预览与输入附件共用同一套放大预览。 */
2571
+ .pw-chat-image-preview {
2572
+ display: inline-block;
2573
+ max-width: 100%;
2574
+ padding: 0;
2575
+ border: 0;
2576
+ background: transparent;
2577
+ cursor: zoom-in;
2578
+ vertical-align: top;
2579
+ }
2580
+ .pw-chat-image-preview > img { display: block; }
2581
+ .pw-chat-image-preview:focus-visible {
2582
+ outline: 2px solid var(--dsw-accent);
2583
+ outline-offset: 3px;
2584
+ border-radius: 12px;
2585
+ }
2570
2586
  /* 放大预览 */
2571
2587
  .pw-lightbox {
2572
2588
  position: fixed;
@@ -45,7 +45,11 @@ import type { ModelChoice } from "@/components/ModelSelector";
45
45
  import type { NewSessionDefaults } from "@/lib/model-defaults";
46
46
  import { readRememberedHeroModel, writeRememberedHeroModel } from "@/lib/hero-model-memory";
47
47
  import { newSessionThinkingLevel } from "@/lib/thinking-level";
48
- import type { ImageAttachment, TrajEntry } from "@/lib/types";
48
+ import { promptTitleText } from "@/lib/chat/skill-expansion";
49
+ import type { ImageAttachment, TrajEntry, WebSnapshot } from "@/lib/types";
50
+
51
+ /** 补全需要的资源清单;新会话页与冷会话都能从服务端单独发现,不必等快照 */
52
+ type WorkspaceCommands = Pick<WebSnapshot, "skills" | "promptTemplates" | "extensionCommands">;
49
53
 
50
54
  // dsh ui-layout columns.ts 几何常量
51
55
  const SIDEBAR_MIN = 264;
@@ -174,6 +178,9 @@ export function AppShell() {
174
178
  const [heroModel, setHeroModel] = useState<{ provider: string; id: string } | null>(null);
175
179
  /** 当前工作区的新会话默认值(pi 的初始模型规则 + 设置里的思考档位),切换工作区时重新取 */
176
180
  const [heroDefaults, setHeroDefaults] = useState<NewSessionDefaults | null>(null);
181
+ /** 按工作区缓存的命令清单:切会话时先用着,再后台刷新 */
182
+ const [workspaceResources, setWorkspaceResources] = useState<Record<string, WorkspaceCommands>>({});
183
+ const [resourcesVersion, setResourcesVersion] = useState(0);
177
184
  const [heroThinking, setHeroThinking] = useState("");
178
185
  const [isNarrow, setIsNarrow] = useState(false);
179
186
  const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
@@ -218,6 +225,30 @@ export function AppShell() {
218
225
  stale = true;
219
226
  };
220
227
  }, [heroCwd]);
228
+ /** 补全数据归属的工作区:有会话看会话的 cwd,新会话看 Hero 选中的工作区 */
229
+ const resourceCwd = currentId
230
+ ? sessions.find((session) => samePath(session.path, currentPath ?? ""))?.cwd ??
231
+ (state.snapshot?.sessionPath && samePath(state.snapshot.sessionPath, currentPath ?? "") ? state.snapshot.cwd : "")
232
+ : heroCwd;
233
+ // 补全不能等历史快照或 session_start/MCP:按工作区单独发现并缓存,切会话/改设置时后台刷新。
234
+ useEffect(() => {
235
+ if (!resourceCwd) return;
236
+ let stale = false;
237
+ fetch(`/api/agent/resources?cwd=${encodeURIComponent(resourceCwd)}`, { cache: "no-store" })
238
+ .then((r) => r.json() as Promise<{ success?: boolean; data?: WorkspaceCommands; error?: string }>)
239
+ .then((json) => {
240
+ if (stale) return;
241
+ if (!json.success || !json.data) throw new Error(json.error || "Failed to load workspace resources");
242
+ const data = json.data;
243
+ setWorkspaceResources((previous) => ({ ...previous, [resourceCwd]: data }));
244
+ })
245
+ .catch((error) => {
246
+ if (!stale) setError(error instanceof Error ? error.message : String(error));
247
+ });
248
+ return () => {
249
+ stale = true;
250
+ };
251
+ }, [currentId, resourceCwd, settingsOpen, resourcesVersion, setError]);
221
252
  /** 右侧抽屉开关(项目栏降级成抽屉入口后,它是"最右一列是否打开"唯一的开关) */
222
253
  const toggleDrawer = useCallback((next?: boolean) => {
223
254
  preserveChatReadingPosition();
@@ -248,7 +279,8 @@ export function AppShell() {
248
279
  };
249
280
  document.addEventListener("keydown", h);
250
281
  return () => document.removeEventListener("keydown", h);
251
- }, [drawerOpen, drawerSection, toggleDrawer, openDrawerSection]);
282
+ // selected 必须在依赖里:漏了它,打开轨迹详情后闭包里仍是旧的 null,第一下被当成「收起」,要按两次
283
+ }, [drawerOpen, drawerSection, selected, toggleDrawer, openDrawerSection]);
252
284
 
253
285
  useEffect(() => {
254
286
  const query = window.matchMedia("(max-width: 840px)");
@@ -435,18 +467,17 @@ export function AppShell() {
435
467
 
436
468
  const doRename = useCallback(async (path: string, newName: string) => {
437
469
  if (!newName.trim()) return;
438
- const result = path === currentPath
470
+ // 冷会话:临时走命令路由(会按需打开,不启动 agent 的 rename 走 appendSessionInfo)
471
+ const result = currentPath && samePath(path, currentPath)
439
472
  ? await sendCommand({ cmd: "rename", text: newName.trim() })
440
473
  : await sendCommand({ cmd: "rename", text: newName.trim() }, encodeURIComponent(b64url(path)));
441
474
  if (!result?.success) {
442
475
  throw new Error(result?.error || "failed to rename session");
443
476
  }
477
+ // 侧栏就地改名即可。不要 resync:它重连的是「当前」会话的事件流,与被改名的冷会话无关,
478
+ // 正在流式输出时还会把眼前的对话整页重载一遍
444
479
  patchSessionName(path, newName.trim());
445
- if (path !== currentPath) {
446
- // 冷会话:临时走命令路由(会按需打开,不启动 agent 的 rename 走 appendSessionInfo)
447
- resync();
448
- }
449
- }, [currentPath, sendCommand, patchSessionName, resync]);
480
+ }, [currentPath, sendCommand, patchSessionName]);
450
481
 
451
482
  const doForkSession = useCallback(
452
483
  async (path: string, _cwd: string) => {
@@ -501,13 +532,13 @@ export function AppShell() {
501
532
  const doUnarchiveSession = useCallback(
502
533
  async (path: string) => {
503
534
  try {
535
+ // 归档列表由 unarchiveSession 按服务端返回更新;不 resync 当前会话(同 doRename)
504
536
  await unarchiveSession(path);
505
- resync();
506
537
  } catch {
507
538
  // usePiWeb exposes the request failure in the shared error banner.
508
539
  }
509
540
  },
510
- [unarchiveSession, resync],
541
+ [unarchiveSession],
511
542
  );
512
543
 
513
544
  // ---------- 侧栏回调:全部 useCallback,配合 SessionSidebar 的 memo ——
@@ -546,13 +577,13 @@ export function AppShell() {
546
577
 
547
578
  const doDeleteWorkspace = useCallback(
548
579
  async (cwd: string) => {
580
+ // 工作区列表由 removeWorkspace 按服务端返回更新;不 resync 当前会话(同 doRename)
549
581
  await removeWorkspace(cwd);
550
- if (heroCwd === cwd) {
582
+ if (heroCwd && samePath(heroCwd, cwd)) {
551
583
  setHeroCwd("");
552
584
  }
553
- resync();
554
585
  },
555
- [removeWorkspace, heroCwd, resync],
586
+ [removeWorkspace, heroCwd],
556
587
  );
557
588
 
558
589
  // Hero 发送:先完整应用新会话预设,再发第一条消息。
@@ -596,6 +627,9 @@ export function AppShell() {
596
627
  [sendCommand, openSession, resync],
597
628
  );
598
629
 
630
+ const commandResources = currentId && snapshot?.sessionPath && samePath(snapshot.sessionPath, currentPath ?? "")
631
+ ? snapshot
632
+ : workspaceResources[resourceCwd];
599
633
  // 斜杠命令:Web 内置 + pi 的技能 / 提示模板 / 扩展命令(后三类原样交给 SDK 展开或执行)
600
634
  const slashCommands = useMemo(() => {
601
635
  const list: { name: string; desc: string; kind: "builtin" | "skill" | "template" | "extension"; argumentHint?: string }[] = [
@@ -605,12 +639,12 @@ export function AppShell() {
605
639
  { name: "new", desc: t.cmdNew, kind: "builtin" },
606
640
  { name: "fork", desc: t.cmdFork, kind: "builtin" },
607
641
  { name: "reload", desc: t.cmdReload, kind: "builtin" },
608
- ...(snapshot?.promptTemplates ?? []).map((p) => ({ name: p.name, desc: p.description, kind: "template" as const, argumentHint: p.argumentHint })),
609
- ...(snapshot?.extensionCommands ?? []).map((c) => ({ name: c.name, desc: c.description || c.source, kind: "extension" as const })),
610
- ...(snapshot?.skills ?? []).map((s) => ({ name: `skill:${s.name}`, desc: s.description, kind: "skill" as const })),
642
+ ...(commandResources?.promptTemplates ?? []).map((p) => ({ name: p.name, desc: p.description, kind: "template" as const, argumentHint: p.argumentHint })),
643
+ ...(commandResources?.extensionCommands ?? []).map((c) => ({ name: c.name, desc: c.description || c.source, kind: "extension" as const })),
644
+ ...(commandResources?.skills ?? []).map((s) => ({ name: `skill:${s.name}`, desc: s.description, kind: "skill" as const })),
611
645
  ];
612
646
  return list.sort((a, b) => a.name.localeCompare(b.name));
613
- }, [snapshot, t]);
647
+ }, [commandResources, t]);
614
648
 
615
649
  const runSlashCommand = useCallback(
616
650
  (name: string, args: string) => {
@@ -622,10 +656,16 @@ export function AppShell() {
622
656
  void sendCommand({ cmd: "fork" }).then((r) => {
623
657
  if (r.success && r.data?.sessionPath) openSession(r.data.sessionPath);
624
658
  });
625
- } else if (name === "reload") void sendCommand({ cmd: "reload" }).then(() => refreshModels());
626
- else setError(t.cmdUnknown.replace("{name}", name));
659
+ } else if (name === "reload") {
660
+ // 新会话页没有会话可重载:重新发现命令并刷模型目录即可
661
+ if (currentId) void sendCommand({ cmd: "reload" }).then(() => refreshModels());
662
+ else {
663
+ setResourcesVersion((version) => version + 1);
664
+ void refreshModels();
665
+ }
666
+ } else setError(t.cmdUnknown.replace("{name}", name));
627
667
  },
628
- [sendCommand, currentId, closeSession, openSession, setError, t],
668
+ [sendCommand, currentId, closeSession, openSession, refreshModels, setError, t],
629
669
  );
630
670
 
631
671
  const projectTrust = snapshot?.projectTrust;
@@ -646,11 +686,13 @@ export function AppShell() {
646
686
 
647
687
  // 当前会话名 / 工作区标题
648
688
  const currentSession = sessions.find((s) => s.path === currentPath);
649
- const firstUserMsgText = (
689
+ const firstUserText = (
650
690
  state.messages
651
691
  .find((m) => m.role === "user")
652
692
  ?.content?.find((c: any) => c.type === "text" && c.text?.trim()) as any
653
693
  )?.text?.trim();
694
+ // 技能展开的消息不能原样当标题(会露出 <skill name=…> 和 SKILL.md 正文)
695
+ const firstUserMsgText = firstUserText ? promptTitleText(firstUserText) : firstUserText;
654
696
  const title =
655
697
  snapshot?.name ||
656
698
  currentSession?.name ||
@@ -730,6 +772,8 @@ export function AppShell() {
730
772
  connected: state.connected,
731
773
  });
732
774
  const openFileNode = useCallback((node: TreeNode) => viewer.open(node.path, { from: node.from, lazy: node.lazy, kind: node.kind }), [viewer]);
775
+ // 正文行内代码里的路径走页内查看器;工具行上那个按钮仍然是本机编辑器(openInEditor)
776
+ const openPathInViewer = useCallback((filePath: string) => viewer.open(filePath), [viewer.open]);
733
777
  // 打开面板时落在最新轮:useGrowth 活在 AppShell 里、不随抽屉卸载,state 不会自己回到最新,
734
778
  // 所以每次从「关」变「开」(或换了工作区)都显式选一次最新轮。
735
779
  // 新轮次出现时不再自动跳——用户打开面板后停在哪一轮就是哪一轮。
@@ -1019,6 +1063,7 @@ export function AppShell() {
1019
1063
  cwd={panelCwd}
1020
1064
  onOpenTrajectory={openToolTrajectory}
1021
1065
  onOpenFile={openInEditor}
1066
+ onOpenPath={openPathInViewer}
1022
1067
  onFork={handleFork}
1023
1068
  onEditMessage={doEditMessage}
1024
1069
  roundBadges={roundBadges}
@@ -1333,6 +1378,8 @@ function Hero({
1333
1378
  pendingUploadCount={pendingUploadCount}
1334
1379
  pendingSend={pendingSend}
1335
1380
  onSendPendingChange={onSendPendingChange}
1381
+ // Hero 的附件占位,避免 @ 引用和图片盖住上方工作区选择器
1382
+ attachmentLayout="flow"
1336
1383
  // 新会话也能 @ 引用:候选来自上面选中的工作区
1337
1384
  cwd={cwd}
1338
1385
  commands={commands}