@pi-harness/pi-harness 0.1.7 → 0.1.8

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 (248) hide show
  1. package/apps/web/dist/assets/index-CCZGqUaU.css +2 -0
  2. package/apps/web/dist/assets/index-DZjjpslQ.js +20 -0
  3. package/apps/web/dist/index.html +2 -2
  4. package/apps/web/package.json +6 -6
  5. package/apps/web/src/style.css +148 -41
  6. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/agent-teams.json +1 -1
  7. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/anchored-standard.json +1 -1
  8. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/annotation.json +1 -1
  9. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/archify.json +1 -1
  10. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/at-file.json +1 -1
  11. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/auto-mode.json +1 -1
  12. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/better-sidebar.json +1 -1
  13. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/browser-fetch.json +1 -1
  14. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/browser-session.json +1 -1
  15. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/canvas-draw.json +1 -1
  16. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/change-verifier.json +1 -1
  17. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cleaner.json +1 -1
  18. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cli-notifier.json +1 -1
  19. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/code2skill.json +1 -1
  20. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/colleague-skill.json +1 -1
  21. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/context-doctor.json +1 -1
  22. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/context.json +1 -1
  23. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cost-meter.json +1 -1
  24. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/dependency-checker.json +1 -1
  25. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +1 -1
  26. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/fail-logger.json +1 -1
  27. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/genui.json +1 -1
  28. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +1 -1
  29. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/graph-memory.json +1 -1
  30. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/history-compressor.json +1 -1
  31. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/hol-guard.json +1 -1
  32. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/i18n-pair.json +1 -1
  33. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/image-compressor.json +1 -1
  34. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/llm-verifier.json +1 -1
  35. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mcp-client.json +1 -1
  36. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mcp-panel.json +1 -1
  37. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/memory.json +1 -1
  38. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +1 -1
  39. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mock-server.json +1 -1
  40. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/modlens.json +1 -1
  41. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/module-search.json +1 -1
  42. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +1 -1
  43. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/openpets.json +1 -1
  44. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plan-execute.json +1 -1
  45. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-check.json +1 -1
  46. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-dev.json +1 -1
  47. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-finder.json +1 -1
  48. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-radar.json +1 -1
  49. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-stars.json +1 -1
  50. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/prompt-guard.json +1 -1
  51. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/prompt-library.json +1 -1
  52. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/readme-gen.json +1 -1
  53. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/recall-unread.json +1 -1
  54. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/reverse-skill.json +1 -1
  55. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +1 -1
  56. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +1 -1
  57. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/secure-audit.json +1 -1
  58. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +1 -1
  59. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-bridge.json +1 -1
  60. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-compare.json +1 -1
  61. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-export.json +1 -1
  62. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-insights.json +1 -1
  63. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-search.json +1 -1
  64. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/skill-catalog.json +1 -1
  65. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/skill-guard.json +1 -1
  66. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/sql-lens.json +1 -1
  67. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/synapse.json +1 -1
  68. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/tab-manager.json +1 -1
  69. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/taskboard.json +1 -1
  70. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +1 -1
  71. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/test-harness.json +1 -1
  72. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/theme-studio.json +1 -1
  73. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/token-guard.json +1 -1
  74. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/turn-rewind.json +1 -1
  75. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +1 -1
  76. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +1 -1
  77. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/web-research.json +1 -1
  78. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +1 -1
  79. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/workspace-search.json +1 -1
  80. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/yaml-validator.json +1 -1
  81. package/node_modules/@pi-harness/api-gateway/package.json +1 -1
  82. package/node_modules/@pi-harness/cli/package.json +1 -1
  83. package/node_modules/@pi-harness/core/package.json +1 -1
  84. package/node_modules/@pi-harness/host-webserver/package.json +1 -1
  85. package/node_modules/@pi-harness/web-app/package.json +1 -1
  86. package/package.json +6 -6
  87. package/packages/api-gateway/dist/marketplace-entries/official/agent-teams.json +1 -1
  88. package/packages/api-gateway/dist/marketplace-entries/official/anchored-standard.json +1 -1
  89. package/packages/api-gateway/dist/marketplace-entries/official/annotation.json +1 -1
  90. package/packages/api-gateway/dist/marketplace-entries/official/archify.json +1 -1
  91. package/packages/api-gateway/dist/marketplace-entries/official/at-file.json +1 -1
  92. package/packages/api-gateway/dist/marketplace-entries/official/auto-mode.json +1 -1
  93. package/packages/api-gateway/dist/marketplace-entries/official/better-sidebar.json +1 -1
  94. package/packages/api-gateway/dist/marketplace-entries/official/browser-fetch.json +1 -1
  95. package/packages/api-gateway/dist/marketplace-entries/official/browser-session.json +1 -1
  96. package/packages/api-gateway/dist/marketplace-entries/official/canvas-draw.json +1 -1
  97. package/packages/api-gateway/dist/marketplace-entries/official/change-verifier.json +1 -1
  98. package/packages/api-gateway/dist/marketplace-entries/official/cleaner.json +1 -1
  99. package/packages/api-gateway/dist/marketplace-entries/official/cli-notifier.json +1 -1
  100. package/packages/api-gateway/dist/marketplace-entries/official/code2skill.json +1 -1
  101. package/packages/api-gateway/dist/marketplace-entries/official/colleague-skill.json +1 -1
  102. package/packages/api-gateway/dist/marketplace-entries/official/context-doctor.json +1 -1
  103. package/packages/api-gateway/dist/marketplace-entries/official/context.json +1 -1
  104. package/packages/api-gateway/dist/marketplace-entries/official/cost-meter.json +1 -1
  105. package/packages/api-gateway/dist/marketplace-entries/official/dependency-checker.json +1 -1
  106. package/packages/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +1 -1
  107. package/packages/api-gateway/dist/marketplace-entries/official/fail-logger.json +1 -1
  108. package/packages/api-gateway/dist/marketplace-entries/official/genui.json +1 -1
  109. package/packages/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +1 -1
  110. package/packages/api-gateway/dist/marketplace-entries/official/graph-memory.json +1 -1
  111. package/packages/api-gateway/dist/marketplace-entries/official/history-compressor.json +1 -1
  112. package/packages/api-gateway/dist/marketplace-entries/official/hol-guard.json +1 -1
  113. package/packages/api-gateway/dist/marketplace-entries/official/i18n-pair.json +1 -1
  114. package/packages/api-gateway/dist/marketplace-entries/official/image-compressor.json +1 -1
  115. package/packages/api-gateway/dist/marketplace-entries/official/llm-verifier.json +1 -1
  116. package/packages/api-gateway/dist/marketplace-entries/official/mcp-client.json +1 -1
  117. package/packages/api-gateway/dist/marketplace-entries/official/mcp-panel.json +1 -1
  118. package/packages/api-gateway/dist/marketplace-entries/official/memory.json +1 -1
  119. package/packages/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +1 -1
  120. package/packages/api-gateway/dist/marketplace-entries/official/mock-server.json +1 -1
  121. package/packages/api-gateway/dist/marketplace-entries/official/modlens.json +1 -1
  122. package/packages/api-gateway/dist/marketplace-entries/official/module-search.json +1 -1
  123. package/packages/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +1 -1
  124. package/packages/api-gateway/dist/marketplace-entries/official/openpets.json +1 -1
  125. package/packages/api-gateway/dist/marketplace-entries/official/plan-execute.json +1 -1
  126. package/packages/api-gateway/dist/marketplace-entries/official/plugin-check.json +1 -1
  127. package/packages/api-gateway/dist/marketplace-entries/official/plugin-dev.json +1 -1
  128. package/packages/api-gateway/dist/marketplace-entries/official/plugin-finder.json +1 -1
  129. package/packages/api-gateway/dist/marketplace-entries/official/plugin-radar.json +1 -1
  130. package/packages/api-gateway/dist/marketplace-entries/official/plugin-stars.json +1 -1
  131. package/packages/api-gateway/dist/marketplace-entries/official/prompt-guard.json +1 -1
  132. package/packages/api-gateway/dist/marketplace-entries/official/prompt-library.json +1 -1
  133. package/packages/api-gateway/dist/marketplace-entries/official/readme-gen.json +1 -1
  134. package/packages/api-gateway/dist/marketplace-entries/official/recall-unread.json +1 -1
  135. package/packages/api-gateway/dist/marketplace-entries/official/reverse-skill.json +1 -1
  136. package/packages/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +1 -1
  137. package/packages/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +1 -1
  138. package/packages/api-gateway/dist/marketplace-entries/official/secure-audit.json +1 -1
  139. package/packages/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +1 -1
  140. package/packages/api-gateway/dist/marketplace-entries/official/session-bridge.json +1 -1
  141. package/packages/api-gateway/dist/marketplace-entries/official/session-compare.json +1 -1
  142. package/packages/api-gateway/dist/marketplace-entries/official/session-export.json +1 -1
  143. package/packages/api-gateway/dist/marketplace-entries/official/session-insights.json +1 -1
  144. package/packages/api-gateway/dist/marketplace-entries/official/session-search.json +1 -1
  145. package/packages/api-gateway/dist/marketplace-entries/official/skill-catalog.json +1 -1
  146. package/packages/api-gateway/dist/marketplace-entries/official/skill-guard.json +1 -1
  147. package/packages/api-gateway/dist/marketplace-entries/official/sql-lens.json +1 -1
  148. package/packages/api-gateway/dist/marketplace-entries/official/synapse.json +1 -1
  149. package/packages/api-gateway/dist/marketplace-entries/official/tab-manager.json +1 -1
  150. package/packages/api-gateway/dist/marketplace-entries/official/taskboard.json +1 -1
  151. package/packages/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +1 -1
  152. package/packages/api-gateway/dist/marketplace-entries/official/test-harness.json +1 -1
  153. package/packages/api-gateway/dist/marketplace-entries/official/theme-studio.json +1 -1
  154. package/packages/api-gateway/dist/marketplace-entries/official/token-guard.json +1 -1
  155. package/packages/api-gateway/dist/marketplace-entries/official/turn-rewind.json +1 -1
  156. package/packages/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +1 -1
  157. package/packages/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +1 -1
  158. package/packages/api-gateway/dist/marketplace-entries/official/web-research.json +1 -1
  159. package/packages/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +1 -1
  160. package/packages/api-gateway/dist/marketplace-entries/official/workspace-search.json +1 -1
  161. package/packages/api-gateway/dist/marketplace-entries/official/yaml-validator.json +1 -1
  162. package/packages/api-gateway/package.json +1 -1
  163. package/packages/api-gateway/src/marketplace-entries/official/agent-teams.json +1 -1
  164. package/packages/api-gateway/src/marketplace-entries/official/anchored-standard.json +1 -1
  165. package/packages/api-gateway/src/marketplace-entries/official/annotation.json +1 -1
  166. package/packages/api-gateway/src/marketplace-entries/official/archify.json +1 -1
  167. package/packages/api-gateway/src/marketplace-entries/official/at-file.json +1 -1
  168. package/packages/api-gateway/src/marketplace-entries/official/auto-mode.json +1 -1
  169. package/packages/api-gateway/src/marketplace-entries/official/better-sidebar.json +1 -1
  170. package/packages/api-gateway/src/marketplace-entries/official/browser-fetch.json +1 -1
  171. package/packages/api-gateway/src/marketplace-entries/official/browser-session.json +1 -1
  172. package/packages/api-gateway/src/marketplace-entries/official/canvas-draw.json +1 -1
  173. package/packages/api-gateway/src/marketplace-entries/official/change-verifier.json +1 -1
  174. package/packages/api-gateway/src/marketplace-entries/official/cleaner.json +1 -1
  175. package/packages/api-gateway/src/marketplace-entries/official/cli-notifier.json +1 -1
  176. package/packages/api-gateway/src/marketplace-entries/official/code2skill.json +1 -1
  177. package/packages/api-gateway/src/marketplace-entries/official/colleague-skill.json +1 -1
  178. package/packages/api-gateway/src/marketplace-entries/official/context-doctor.json +1 -1
  179. package/packages/api-gateway/src/marketplace-entries/official/context.json +1 -1
  180. package/packages/api-gateway/src/marketplace-entries/official/cost-meter.json +1 -1
  181. package/packages/api-gateway/src/marketplace-entries/official/dependency-checker.json +1 -1
  182. package/packages/api-gateway/src/marketplace-entries/official/docker-sandbox.json +1 -1
  183. package/packages/api-gateway/src/marketplace-entries/official/fail-logger.json +1 -1
  184. package/packages/api-gateway/src/marketplace-entries/official/genui.json +1 -1
  185. package/packages/api-gateway/src/marketplace-entries/official/git-time-capsule.json +1 -1
  186. package/packages/api-gateway/src/marketplace-entries/official/graph-memory.json +1 -1
  187. package/packages/api-gateway/src/marketplace-entries/official/history-compressor.json +1 -1
  188. package/packages/api-gateway/src/marketplace-entries/official/hol-guard.json +1 -1
  189. package/packages/api-gateway/src/marketplace-entries/official/i18n-pair.json +1 -1
  190. package/packages/api-gateway/src/marketplace-entries/official/image-compressor.json +1 -1
  191. package/packages/api-gateway/src/marketplace-entries/official/llm-verifier.json +1 -1
  192. package/packages/api-gateway/src/marketplace-entries/official/mcp-client.json +1 -1
  193. package/packages/api-gateway/src/marketplace-entries/official/mcp-panel.json +1 -1
  194. package/packages/api-gateway/src/marketplace-entries/official/memory.json +1 -1
  195. package/packages/api-gateway/src/marketplace-entries/official/mirage-bridge.json +1 -1
  196. package/packages/api-gateway/src/marketplace-entries/official/mock-server.json +1 -1
  197. package/packages/api-gateway/src/marketplace-entries/official/modlens.json +1 -1
  198. package/packages/api-gateway/src/marketplace-entries/official/module-search.json +1 -1
  199. package/packages/api-gateway/src/marketplace-entries/official/obsidian-sync.json +1 -1
  200. package/packages/api-gateway/src/marketplace-entries/official/openpets.json +1 -1
  201. package/packages/api-gateway/src/marketplace-entries/official/plan-execute.json +1 -1
  202. package/packages/api-gateway/src/marketplace-entries/official/plugin-check.json +1 -1
  203. package/packages/api-gateway/src/marketplace-entries/official/plugin-dev.json +1 -1
  204. package/packages/api-gateway/src/marketplace-entries/official/plugin-finder.json +1 -1
  205. package/packages/api-gateway/src/marketplace-entries/official/plugin-radar.json +1 -1
  206. package/packages/api-gateway/src/marketplace-entries/official/plugin-stars.json +1 -1
  207. package/packages/api-gateway/src/marketplace-entries/official/prompt-guard.json +1 -1
  208. package/packages/api-gateway/src/marketplace-entries/official/prompt-library.json +1 -1
  209. package/packages/api-gateway/src/marketplace-entries/official/readme-gen.json +1 -1
  210. package/packages/api-gateway/src/marketplace-entries/official/recall-unread.json +1 -1
  211. package/packages/api-gateway/src/marketplace-entries/official/reverse-skill.json +1 -1
  212. package/packages/api-gateway/src/marketplace-entries/official/reviewer-bot.json +1 -1
  213. package/packages/api-gateway/src/marketplace-entries/official/runtime-doctor.json +1 -1
  214. package/packages/api-gateway/src/marketplace-entries/official/secure-audit.json +1 -1
  215. package/packages/api-gateway/src/marketplace-entries/official/session-bookmarks.json +1 -1
  216. package/packages/api-gateway/src/marketplace-entries/official/session-bridge.json +1 -1
  217. package/packages/api-gateway/src/marketplace-entries/official/session-compare.json +1 -1
  218. package/packages/api-gateway/src/marketplace-entries/official/session-export.json +1 -1
  219. package/packages/api-gateway/src/marketplace-entries/official/session-insights.json +1 -1
  220. package/packages/api-gateway/src/marketplace-entries/official/session-search.json +1 -1
  221. package/packages/api-gateway/src/marketplace-entries/official/skill-catalog.json +1 -1
  222. package/packages/api-gateway/src/marketplace-entries/official/skill-guard.json +1 -1
  223. package/packages/api-gateway/src/marketplace-entries/official/sql-lens.json +1 -1
  224. package/packages/api-gateway/src/marketplace-entries/official/synapse.json +1 -1
  225. package/packages/api-gateway/src/marketplace-entries/official/tab-manager.json +1 -1
  226. package/packages/api-gateway/src/marketplace-entries/official/taskboard.json +1 -1
  227. package/packages/api-gateway/src/marketplace-entries/official/telemetry-blocker.json +1 -1
  228. package/packages/api-gateway/src/marketplace-entries/official/test-harness.json +1 -1
  229. package/packages/api-gateway/src/marketplace-entries/official/theme-studio.json +1 -1
  230. package/packages/api-gateway/src/marketplace-entries/official/token-guard.json +1 -1
  231. package/packages/api-gateway/src/marketplace-entries/official/turn-rewind.json +1 -1
  232. package/packages/api-gateway/src/marketplace-entries/official/undo-savepoint.json +1 -1
  233. package/packages/api-gateway/src/marketplace-entries/official/vision-toolkit.json +1 -1
  234. package/packages/api-gateway/src/marketplace-entries/official/web-research.json +1 -1
  235. package/packages/api-gateway/src/marketplace-entries/official/workspace-navigator.json +1 -1
  236. package/packages/api-gateway/src/marketplace-entries/official/workspace-search.json +1 -1
  237. package/packages/api-gateway/src/marketplace-entries/official/yaml-validator.json +1 -1
  238. package/packages/bundle-web-app/package.json +1 -1
  239. package/packages/cli/package.json +1 -1
  240. package/packages/client-web/dist/react-room.d.ts.map +1 -1
  241. package/packages/client-web/dist/react-room.js +128 -38
  242. package/packages/client-web/dist/react-room.js.map +1 -1
  243. package/packages/client-web/package.json +1 -1
  244. package/packages/client-web/src/react-room.tsx +220 -73
  245. package/packages/core/package.json +1 -1
  246. package/packages/host-webserver/package.json +1 -1
  247. package/apps/web/dist/assets/index-CkGv0zrr.css +0 -2
  248. package/apps/web/dist/assets/index-pMtwuwHh.js +0 -20
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/client-web",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "description": "Browser-side Cordis client plugins for the Pi Harness web surface",
6
6
  "homepage": "https://github.com/pi-harness/pi-harness#readme",
@@ -26,7 +26,7 @@ import { loadMarketplaceCatalog } from "./marketplace-catalog.js";
26
26
  import { pluginStarsRows } from "./plugin-stars-view.js";
27
27
  import { browserSessionTabs } from "./browser-session-view.js";
28
28
  import { matchesPluginQuery } from "./plugin-search.js";
29
- import { installedPluginDetailPath, readInstalledPluginDetailId } from "./plugin-navigation.js";
29
+ import { readInstalledPluginDetailId } from "./plugin-navigation.js";
30
30
  import { installedPluginCardContent } from "./plugin-card.js";
31
31
 
32
32
  export type { ClientApi } from "./control-room.js";
@@ -741,12 +741,12 @@ function Details({ event, onClose, onCopy }: { event: Record<string, unknown> |
741
741
  <aside className="details-panel">
742
742
  <header>
743
743
  <strong>{eventLabel(event)}</strong>
744
- <button aria-label="关闭事件详情" onClick={onClose} type="button">
744
+ <button aria-label={fileDetail ? "关闭文件差异" : "关闭事件详情"} onClick={onClose} type="button">
745
745
  ×
746
746
  </button>
747
747
  </header>
748
748
  <div className="details-body">
749
- <div className="detail-stats">
749
+ <div className={`detail-stats ${fileDetail ? "is-file" : ""}`}>
750
750
  {stats.map(([key, item]) => (
751
751
  <div key={key}>
752
752
  <small>{key}</small>
@@ -845,11 +845,22 @@ function Trajectory({ events, onSelect }: { events: readonly Record<string, unkn
845
845
  );
846
846
  }
847
847
 
848
- function Files({ files, api, onDiff, onRefresh }: { files: readonly ClientFile[]; api: ClientApi; onDiff: (path: string) => void; onRefresh: () => void }) {
848
+ function Files({
849
+ files,
850
+ api,
851
+ onDiff,
852
+ onRefresh,
853
+ }: {
854
+ files: readonly ClientFile[];
855
+ api: ClientApi;
856
+ onDiff: (path: string) => Promise<void>;
857
+ onRefresh: () => void;
858
+ }) {
849
859
  const additions = files.filter((file) => file.status.includes("A") || file.status === "??").length;
850
860
  const deletions = files.filter((file) => file.status.includes("D")).length;
851
861
  const [message, setMessage] = useState("");
852
862
  const [busy, setBusy] = useState(false);
863
+ const [diffPending, setDiffPending] = useState<string>();
853
864
  const [error, setError] = useState("");
854
865
  const [revertConfirmOpen, setRevertConfirmOpen] = useState(false);
855
866
  const commit = () => {
@@ -880,6 +891,14 @@ function Files({ files, api, onDiff, onRefresh }: { files: readonly ClientFile[]
880
891
  .catch((cause: unknown) => setError(cause instanceof Error ? cause.message : String(cause)))
881
892
  .finally(() => setBusy(false));
882
893
  };
894
+ const openDiff = (path: string) => {
895
+ if (busy || diffPending) return;
896
+ setDiffPending(path);
897
+ setError("");
898
+ void onDiff(path)
899
+ .catch((cause: unknown) => setError(cause instanceof Error ? cause.message : String(cause)))
900
+ .finally(() => setDiffPending(undefined));
901
+ };
883
902
  return (
884
903
  <section className="view-panel files-view">
885
904
  <div className="files-content">
@@ -895,8 +914,14 @@ function Files({ files, api, onDiff, onRefresh }: { files: readonly ClientFile[]
895
914
  <b className={`file-kind ${file.label === "untracked" ? "new" : ""}`}>{file.label}</b>
896
915
  <code>{file.path}</code>
897
916
  <span className={file.status.includes("D") ? "del" : "add"}>{file.status}</span>
898
- <button className="diff-button" onClick={() => onDiff(file.path)} type="button">
899
- 查看差异
917
+ <button
918
+ aria-label={`${diffPending === file.path ? "正在读取" : "查看"}${file.path}的差异`}
919
+ className="diff-button"
920
+ disabled={busy || diffPending !== undefined}
921
+ onClick={() => openDiff(file.path)}
922
+ type="button"
923
+ >
924
+ {diffPending === file.path ? "读取中…" : "查看差异"}
900
925
  </button>
901
926
  </div>
902
927
  ))
@@ -4071,6 +4096,77 @@ function PluginUninstallDialog({
4071
4096
  );
4072
4097
  }
4073
4098
 
4099
+ function PluginCategoryNav({
4100
+ label,
4101
+ categories,
4102
+ activeCategory,
4103
+ onChange,
4104
+ }: {
4105
+ label: string;
4106
+ categories: readonly ClientMarketplaceCategory[];
4107
+ activeCategory: string;
4108
+ onChange: (category: string) => void;
4109
+ }) {
4110
+ const navRef = useRef<HTMLElement>(null);
4111
+ const [canScrollLeft, setCanScrollLeft] = useState(false);
4112
+ const [canScrollRight, setCanScrollRight] = useState(false);
4113
+ const updateScrollState = useCallback(() => {
4114
+ const nav = navRef.current;
4115
+ if (!nav) return;
4116
+ const maximum = Math.max(0, nav.scrollWidth - nav.clientWidth);
4117
+ setCanScrollLeft(nav.scrollLeft > 1);
4118
+ setCanScrollRight(nav.scrollLeft < maximum - 1);
4119
+ }, []);
4120
+ useEffect(() => {
4121
+ const nav = navRef.current;
4122
+ if (!nav) return;
4123
+ updateScrollState();
4124
+ const observer = typeof ResizeObserver === "undefined" ? undefined : new ResizeObserver(updateScrollState);
4125
+ observer?.observe(nav);
4126
+ window.addEventListener("resize", updateScrollState);
4127
+ return () => {
4128
+ observer?.disconnect();
4129
+ window.removeEventListener("resize", updateScrollState);
4130
+ };
4131
+ }, [categories, updateScrollState]);
4132
+ const scroll = (direction: -1 | 1) => {
4133
+ const nav = navRef.current;
4134
+ if (!nav) return;
4135
+ nav.scrollBy({ behavior: "smooth", left: direction * Math.max(180, nav.clientWidth * 0.72) });
4136
+ };
4137
+ return (
4138
+ <div className={`marketplace-categories-shell ${canScrollLeft ? "can-scroll-left" : ""} ${canScrollRight ? "can-scroll-right" : ""}`}>
4139
+ {canScrollLeft && (
4140
+ <button aria-label="向左查看更多分类" className="marketplace-category-scroll previous" onClick={() => scroll(-1)} type="button">
4141
+
4142
+ </button>
4143
+ )}
4144
+ <nav aria-label={label} className="marketplace-categories" onScroll={updateScrollState} ref={navRef}>
4145
+ {categories.map((category) => {
4146
+ const active = activeCategory === category.id;
4147
+ return (
4148
+ <button
4149
+ aria-pressed={active}
4150
+ className={`marketplace-category ${active ? "active" : ""}`}
4151
+ key={category.id || "all"}
4152
+ onClick={() => onChange(category.id)}
4153
+ type="button"
4154
+ >
4155
+ <span>{category.label}</span>
4156
+ <span className={active ? "font-mono text-[10px] text-[#3565c5]" : "font-mono text-[10px] text-[#687381]"}>{category.count}</span>
4157
+ </button>
4158
+ );
4159
+ })}
4160
+ </nav>
4161
+ {canScrollRight && (
4162
+ <button aria-label="向右查看更多分类" className="marketplace-category-scroll next" onClick={() => scroll(1)} type="button">
4163
+
4164
+ </button>
4165
+ )}
4166
+ </div>
4167
+ );
4168
+ }
4169
+
4074
4170
  function Plugins({
4075
4171
  plugins,
4076
4172
  panels,
@@ -4179,23 +4275,7 @@ function Plugins({
4179
4275
  {query.trim() || categoryFilter ? `${visiblePlugins.length} / ${installedPlugins.length}` : `${installedPlugins.length}`} 个插件
4180
4276
  </span>
4181
4277
  </div>
4182
- <nav aria-label="已安装插件分类" className="marketplace-categories">
4183
- {installedCategories.map((category) => {
4184
- const active = categoryFilter === category.id;
4185
- return (
4186
- <button
4187
- aria-pressed={active}
4188
- className={`marketplace-category ${active ? "active" : ""}`}
4189
- key={category.id || "all"}
4190
- onClick={() => setCategoryFilter(category.id)}
4191
- type="button"
4192
- >
4193
- <span>{category.label}</span>
4194
- <span className={active ? "font-mono text-[10px] text-[#3565c5]" : "font-mono text-[10px] text-[#687381]"}>{category.count}</span>
4195
- </button>
4196
- );
4197
- })}
4198
- </nav>
4278
+ <PluginCategoryNav activeCategory={categoryFilter} categories={installedCategories} label="已安装插件分类" onChange={setCategoryFilter} />
4199
4279
  <div className="plugins-scroll" ref={scrollRef}>
4200
4280
  <div className="plugins-list">
4201
4281
  {visiblePlugins.map((plugin) => {
@@ -4262,16 +4342,9 @@ function Plugins({
4262
4342
  </div>
4263
4343
  </div>
4264
4344
  <footer className="plugin-card-footer">
4265
- <a
4266
- className="plugin-detail-link"
4267
- href={installedPluginDetailPath(plugin.name)}
4268
- onClick={(event) => {
4269
- event.preventDefault();
4270
- onOpenDetail(plugin);
4271
- }}
4272
- >
4345
+ <button aria-label={`查看 ${pluginTitle} 详情`} className="plugin-detail-link" onClick={() => onOpenDetail(plugin)} type="button">
4273
4346
  查看详情 →
4274
- </a>
4347
+ </button>
4275
4348
  {panelPluginIds.has(plugin.name) ? <span>实时面板</span> : null}
4276
4349
  </footer>
4277
4350
  </article>
@@ -4552,7 +4625,7 @@ function Marketplace({
4552
4625
  const [installing, setInstalling] = useState<string>();
4553
4626
  const [installError, setInstallError] = useState("");
4554
4627
  const [installNotice, setInstallNotice] = useState("");
4555
- const categoryTabs = marketplaceCategoryTabs(categories);
4628
+ const categoryTabs = useMemo(() => marketplaceCategoryTabs(categories), [categories]);
4556
4629
  const install = async (plugin: ClientMarketplacePlugin) => {
4557
4630
  setInstallError("");
4558
4631
  setInstallNotice("");
@@ -4607,23 +4680,7 @@ function Marketplace({
4607
4680
  </select>
4608
4681
  <span className="marketplace-count">{total} 个已审核条目 · 推荐排序</span>
4609
4682
  </div>
4610
- <nav aria-label="插件分类" className="marketplace-categories">
4611
- {categoryTabs.map((category) => {
4612
- const active = categoryFilter === category.id;
4613
- return (
4614
- <button
4615
- aria-pressed={active}
4616
- className={`marketplace-category ${active ? "active" : ""}`}
4617
- key={category.id || "all"}
4618
- onClick={() => onCategoryChange(category.id)}
4619
- type="button"
4620
- >
4621
- <span>{category.label}</span>
4622
- <span className={active ? "font-mono text-[10px] text-[#3565c5]" : "font-mono text-[10px] text-[#687381]"}>{category.count}</span>
4623
- </button>
4624
- );
4625
- })}
4626
- </nav>
4683
+ <PluginCategoryNav activeCategory={categoryFilter} categories={categoryTabs} label="插件分类" onChange={onCategoryChange} />
4627
4684
  <div className="marketplace-scroll">
4628
4685
  <div className="marketplace-grid">
4629
4686
  {plugins.map((plugin) => (
@@ -4673,7 +4730,7 @@ function Marketplace({
4673
4730
  ))}
4674
4731
  </div>
4675
4732
  {plugin.statistics && (
4676
- <div className="mt-3 grid grid-cols-3 divide-x divide-[#e3e7ee] rounded-md border border-[#e3e7ee] bg-[#f8f9fb]">
4733
+ <div className="marketplace-statistics mt-3 grid grid-cols-3 divide-x divide-[#e3e7ee] rounded-md border border-[#e3e7ee] bg-[#f8f9fb]">
4677
4734
  {marketplaceStatisticItems(plugin.statistics).map((item) => (
4678
4735
  <span className="min-w-0 px-2 py-1.5" key={item.label} title={`${item.label} ${item.value}`}>
4679
4736
  <small className="block truncate text-[9px] text-[#687381]">{item.label}</small>
@@ -5622,7 +5679,7 @@ function PromptCompletionPopover({
5622
5679
  ? filterCommands(commands, query).slice(0, 12)
5623
5680
  : files.filter((file) => `${file.path} ${file.label} ${file.status}`.toLowerCase().includes(query.trim().toLowerCase())).slice(0, 12);
5624
5681
  return (
5625
- <div aria-label={kind === "command" ? "命令补全" : "文件补全"} className="prompt-completion" role="listbox">
5682
+ <div aria-label={kind === "command" ? "命令补全" : "文件补全"} className="prompt-completion" id="prompt-completion-list" role="listbox">
5626
5683
  <small>{kind === "command" ? "命令" : "文件"}</small>
5627
5684
  {items.length ? (
5628
5685
  items.slice(0, 12).map((item, index) => {
@@ -5632,6 +5689,7 @@ function PromptCompletionPopover({
5632
5689
  return (
5633
5690
  <button
5634
5691
  aria-selected={index === activeIndex}
5692
+ id={`prompt-completion-option-${index}`}
5635
5693
  key={`${kind}:${label}`}
5636
5694
  onClick={() => onUse(label)}
5637
5695
  onMouseEnter={() => onActiveIndexChange(index)}
@@ -5686,6 +5744,8 @@ function GlobalSearch({
5686
5744
  .map((session) => ({ kind: "session" as const, session })),
5687
5745
  ...files.filter((file) => matches(`${file.path} ${file.label} ${file.status}`)).map((file) => ({ kind: "file" as const, file })),
5688
5746
  ];
5747
+ const selectedIndex = items.length ? Math.min(activeIndex, items.length - 1) : -1;
5748
+ const activeItemId = selectedIndex >= 0 ? `global-search-option-${selectedIndex}` : undefined;
5689
5749
  useEffect(() => setActiveIndex(0), [query]);
5690
5750
  const execute = (item: GlobalSearchItem | undefined) => {
5691
5751
  if (!item) return;
@@ -5705,8 +5765,15 @@ function GlobalSearch({
5705
5765
  <div className="global-search-heading">
5706
5766
  <strong>全局搜索</strong>
5707
5767
  <small>命令 · 会话 · 文件</small>
5768
+ <button aria-label="关闭全局搜索" onClick={onClose} type="button">
5769
+ ×
5770
+ </button>
5708
5771
  </div>
5709
5772
  <input
5773
+ aria-activedescendant={activeItemId}
5774
+ aria-autocomplete="list"
5775
+ aria-controls="global-search-results"
5776
+ aria-expanded="true"
5710
5777
  aria-label="全局搜索"
5711
5778
  data-dialog-initial-focus
5712
5779
  onChange={(event) => setQuery(event.target.value)}
@@ -5722,21 +5789,22 @@ function GlobalSearch({
5722
5789
  setActiveIndex((index) => (index - 1 + items.length) % items.length);
5723
5790
  } else if (event.key === "Enter") {
5724
5791
  event.preventDefault();
5725
- execute(items[activeIndex]);
5792
+ execute(items[selectedIndex]);
5726
5793
  }
5727
5794
  }}
5728
5795
  placeholder="搜索命令、会话或文件"
5796
+ role="combobox"
5729
5797
  value={query}
5730
5798
  />
5731
- <div className="global-search-results" role="listbox">
5799
+ <div className="global-search-results" id="global-search-results" role="listbox">
5732
5800
  {items.length ? (
5733
5801
  (["command", "session", "file"] as const).map((kind) => {
5734
5802
  const group = items.filter((item) => item.kind === kind);
5735
5803
  if (!group.length) return null;
5736
5804
  const label = kind === "command" ? "命令" : kind === "session" ? "会话" : "文件";
5737
5805
  return (
5738
- <section className="global-search-group" key={kind}>
5739
- <small>{label}</small>
5806
+ <section aria-label={label} className="global-search-group" key={kind} role="group">
5807
+ <small aria-hidden="true">{label}</small>
5740
5808
  {group.map((item) => {
5741
5809
  const index = items.indexOf(item);
5742
5810
  const title =
@@ -5753,7 +5821,8 @@ function GlobalSearch({
5753
5821
  : `${item.file.path} · ${item.file.status}`;
5754
5822
  return (
5755
5823
  <button
5756
- aria-selected={index === activeIndex}
5824
+ aria-selected={index === selectedIndex}
5825
+ id={`global-search-option-${index}`}
5757
5826
  key={`${item.kind}:${title}:${index}`}
5758
5827
  onClick={() => execute(item)}
5759
5828
  onMouseEnter={() => setActiveIndex(index)}
@@ -5881,6 +5950,7 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
5881
5950
  .slice(0, 12);
5882
5951
  }, [data.commands, data.files, promptCompletion]);
5883
5952
  const promptCompletionOpen = Boolean(promptCompletion && !promptCompletionSuppressed && promptCompletionItems.length);
5953
+ const promptCompletionActiveIndex = Math.min(promptCompletionIndex, Math.max(promptCompletionItems.length - 1, 0));
5884
5954
  const installedPackages = useMemo(() => new Set(data.plugins.filter((plugin) => plugin.removable).map((plugin) => plugin.name)), [data.plugins]);
5885
5955
  const workspaceReady =
5886
5956
  !workspaceChooserOpen && Boolean(selectedWorkspacePath || data.status?.cwd || data.workspaces.find((workspace) => workspace.current)?.path || data.session);
@@ -6255,6 +6325,26 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
6255
6325
  setAnnotationSelection("");
6256
6326
  setAnnotationNote("");
6257
6327
  };
6328
+ const openCommandCompletion = () => {
6329
+ const input = promptInputRef.current;
6330
+ const caret = input?.selectionStart ?? draft.length;
6331
+ const existing = getPromptCompletion(draft, caret);
6332
+ let nextCaret = caret;
6333
+ if (existing?.kind !== "command") {
6334
+ const separator = caret > 0 && !/\s/.test(draft[caret - 1] ?? "") ? " " : "";
6335
+ const insertion = `${separator}/`;
6336
+ const nextDraft = `${draft.slice(0, caret)}${insertion}${draft.slice(caret)}`;
6337
+ nextCaret = caret + insertion.length;
6338
+ setDraft(nextDraft);
6339
+ }
6340
+ setPromptCaret(nextCaret);
6341
+ setPromptCompletionSuppressed(false);
6342
+ setPromptCompletionIndex(0);
6343
+ window.requestAnimationFrame(() => {
6344
+ input?.focus();
6345
+ input?.setSelectionRange(nextCaret, nextCaret);
6346
+ });
6347
+ };
6258
6348
  const openSession = (session: Record<string, unknown>) => {
6259
6349
  const path = typeof session.path === "string" ? session.path : "";
6260
6350
  if (!path) return;
@@ -6299,6 +6389,7 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
6299
6389
  });
6300
6390
  };
6301
6391
  const openSessionMenu = (path: string, name?: string) => {
6392
+ setSessionToolsOpen(false);
6302
6393
  setSelectedSessionPath(path);
6303
6394
  setSessionNameDraft(name ?? "");
6304
6395
  setSessionMenuPath(path);
@@ -6623,6 +6714,11 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
6623
6714
  ) : null}
6624
6715
  <form className="composer" onSubmit={submit}>
6625
6716
  <textarea
6717
+ aria-activedescendant={promptCompletionOpen ? `prompt-completion-option-${promptCompletionActiveIndex}` : undefined}
6718
+ aria-autocomplete="list"
6719
+ aria-controls={promptCompletionOpen ? "prompt-completion-list" : undefined}
6720
+ aria-expanded={promptCompletionOpen}
6721
+ aria-haspopup="listbox"
6626
6722
  aria-label="Prompt"
6627
6723
  onChange={(event) => {
6628
6724
  setDraft(event.target.value);
@@ -6649,7 +6745,7 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
6649
6745
  }
6650
6746
  if (popupOpen && (event.key === "Enter" || event.key === "Tab")) {
6651
6747
  event.preventDefault();
6652
- const item = items[promptCompletionIndex];
6748
+ const item = items[Math.min(promptCompletionIndex, items.length - 1)];
6653
6749
  if (item && completion) {
6654
6750
  const value = completion.kind === "command" ? `/${(item as ClientCommand).invocationName}` : `@${(item as ClientFile).path}`;
6655
6751
  const replacement = replacePromptCompletion(event.currentTarget.value, completion, `${value} `);
@@ -6691,7 +6787,7 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
6691
6787
  ></textarea>
6692
6788
  {promptCompletionOpen && promptCompletion && (
6693
6789
  <PromptCompletionPopover
6694
- activeIndex={promptCompletionIndex}
6790
+ activeIndex={promptCompletionActiveIndex}
6695
6791
  commands={data.commands}
6696
6792
  files={data.files}
6697
6793
  kind={promptCompletion.kind}
@@ -6716,8 +6812,14 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
6716
6812
  disabled={!data.models.length || promptBusy}
6717
6813
  value={data.status?.model ?? ""}
6718
6814
  onChange={(event) => {
6719
- const [provider, model] = event.target.value.split("/");
6720
- if (provider && model) void api.selectModel(provider, model);
6815
+ const [provider, ...modelParts] = event.target.value.split("/");
6816
+ const model = modelParts.join("/");
6817
+ if (!provider || !model) return;
6818
+ setPromptError("");
6819
+ void api
6820
+ .selectModel(provider, model)
6821
+ .then(refresh)
6822
+ .catch((cause: unknown) => setPromptError(cause instanceof Error ? cause.message : String(cause)));
6721
6823
  }}
6722
6824
  >
6723
6825
  {data.models.length ? (
@@ -6733,7 +6835,7 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
6733
6835
  <button className="tool-chip" onClick={() => setPermission((current) => !current)} type="button">
6734
6836
  ● {permission ? "改动前询问" : "自动允许"}
6735
6837
  </button>
6736
- <button className="tool-chip" onClick={() => setCommandOpen(true)} type="button">
6838
+ <button className="tool-chip" onClick={openCommandCompletion} type="button">
6737
6839
  / 命令
6738
6840
  </button>
6739
6841
  <span className="composer-hint">⌘↵ 发送 · ⌘K 命令 · ⌃C 中断</span>
@@ -6757,7 +6859,14 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
6757
6859
  <Files
6758
6860
  api={api}
6759
6861
  files={data.files}
6760
- onDiff={(file) => void api.getFileDiff(file).then((diff) => setDetails({ type: "file_diff", path: diff.path, output: diff.diff }))}
6862
+ onDiff={async (file) => {
6863
+ const diff = await api.getFileDiff(file);
6864
+ setDetails({
6865
+ type: "file_diff",
6866
+ path: diff.path,
6867
+ output: diff.diff || "没有可显示的差异(工作区可能已更新)。",
6868
+ });
6869
+ }}
6761
6870
  onRefresh={() => void refresh()}
6762
6871
  />
6763
6872
  );
@@ -6871,8 +6980,10 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
6871
6980
  aria-pressed={sessionSelectionMode}
6872
6981
  className={`session-tool-button ${sessionSelectionMode ? "active" : ""}`}
6873
6982
  onClick={() => {
6874
- setSessionSelectionMode((current) => !current);
6983
+ setSessionSelectionMode(!sessionSelectionMode);
6875
6984
  setSelectedSessionPaths(new Set());
6985
+ setSessionToolsOpen(false);
6986
+ closeSessionMenu();
6876
6987
  }}
6877
6988
  type="button"
6878
6989
  >
@@ -6883,7 +6994,10 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
6883
6994
  aria-expanded={sessionToolsOpen}
6884
6995
  aria-label="会话工具"
6885
6996
  className="session-tool-button icon"
6886
- onClick={() => setSessionToolsOpen((current) => !current)}
6997
+ onClick={() => {
6998
+ closeSessionMenu();
6999
+ setSessionToolsOpen((current) => !current);
7000
+ }}
6887
7001
  type="button"
6888
7002
  >
6889
7003
 
@@ -7148,6 +7262,20 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
7148
7262
  status <b>{value(data.status?.status, "connecting")}</b>
7149
7263
  </span>
7150
7264
  </div>
7265
+ <button
7266
+ aria-label="搜索会话、文件和命令"
7267
+ className="sidebar-link compact-session-search"
7268
+ onClick={() => {
7269
+ setCommandOpen(false);
7270
+ setSessionToolsOpen(false);
7271
+ closeSessionMenu();
7272
+ setGlobalSearchOpen(true);
7273
+ }}
7274
+ title="搜索会话、文件和命令"
7275
+ type="button"
7276
+ >
7277
+
7278
+ </button>
7151
7279
  <button aria-label="新建会话" className="sidebar-link compact-new-session" onClick={beginNewSession} title="新建会话" type="button">
7152
7280
 
7153
7281
  </button>
@@ -7216,7 +7344,17 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
7216
7344
  <div className="run-indicator running">
7217
7345
  <span className="run-dot"></span>
7218
7346
  <span>运行中 · Pi agent</span>
7219
- <button className="stop-button" onClick={() => void api.abort().then(refresh)} type="button">
7347
+ <button
7348
+ className="stop-button"
7349
+ onClick={() => {
7350
+ setPromptError("");
7351
+ void api
7352
+ .abort()
7353
+ .then(refresh)
7354
+ .catch((cause: unknown) => setPromptError(cause instanceof Error ? cause.message : String(cause)));
7355
+ }}
7356
+ type="button"
7357
+ >
7220
7358
  停止
7221
7359
  </button>
7222
7360
  </div>
@@ -7253,8 +7391,14 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
7253
7391
  >
7254
7392
 
7255
7393
  </button>
7256
- <button aria-pressed={details !== undefined} className="details-toggle" onClick={() => setDetails(details ? undefined : {})} type="button">
7257
- 详情
7394
+ <button
7395
+ aria-label={details !== undefined ? "关闭详情" : "打开详情"}
7396
+ aria-pressed={details !== undefined}
7397
+ className="details-toggle"
7398
+ onClick={() => setDetails(details ? undefined : {})}
7399
+ type="button"
7400
+ >
7401
+ <span aria-hidden="true">◨</span> <span className="details-toggle-label">详情</span>
7258
7402
  </button>
7259
7403
  </>
7260
7404
  )}
@@ -7340,11 +7484,14 @@ export function ControlRoomView({ api = createClientApi(), appVersion }: { api?:
7340
7484
  </div>
7341
7485
  </section>
7342
7486
  {!settings && page === "session" && details !== undefined && (
7343
- <Details
7344
- event={Object.keys(details).length ? details : undefined}
7345
- onClose={() => setDetails(undefined)}
7346
- onCopy={() => void navigator.clipboard?.writeText(JSON.stringify(details, null, 2))}
7347
- />
7487
+ <>
7488
+ <button aria-label="关闭详情" className="details-backdrop" onClick={() => setDetails(undefined)} type="button" />
7489
+ <Details
7490
+ event={Object.keys(details).length ? details : undefined}
7491
+ onClose={() => setDetails(undefined)}
7492
+ onCopy={() => void navigator.clipboard?.writeText(JSON.stringify(details, null, 2))}
7493
+ />
7494
+ </>
7348
7495
  )}
7349
7496
  {globalSearchOpen && (
7350
7497
  <GlobalSearch
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/core",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "description": "Cordis boot and Pi runtime plugins for Pi Harness",
6
6
  "homepage": "https://github.com/pi-harness/pi-harness#readme",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/host-webserver",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "description": "Cordis route-registration service for the Pi Harness web host",
6
6
  "homepage": "https://github.com/pi-harness/pi-harness#readme",