@deepseek-harness-tui/dsh-tui 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/README.md +92 -5
  2. package/guide/dsh-tui-guide/codex-backend.en.md +13 -3
  3. package/guide/dsh-tui-guide/codex-backend.md +9 -2
  4. package/guide/dsh-tui-guide/configuration.en.md +39 -2
  5. package/guide/dsh-tui-guide/configuration.md +34 -2
  6. package/guide/dsh-tui-guide/getting-started.en.md +15 -0
  7. package/guide/dsh-tui-guide/getting-started.md +15 -0
  8. package/guide/dsh-tui-guide/interaction.en.md +8 -1
  9. package/guide/dsh-tui-guide/interaction.md +8 -1
  10. package/guide/dsh-tui-guide/plugins.en.md +66 -5
  11. package/guide/dsh-tui-guide/plugins.md +37 -3
  12. package/guide/dsh-tui-guide/user-guide.en.md +3 -2
  13. package/guide/dsh-tui-guide/user-guide.md +3 -2
  14. package/lib/settings.json +1 -1
  15. package/lib/types/adapter/channel/projection.d.ts.map +1 -1
  16. package/lib/types/adapter/channel/projection.js +1 -0
  17. package/lib/types/adapter/channel/ui-policy.d.ts +1 -1
  18. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  19. package/lib/types/adapter/channel/ui-policy.js +1 -0
  20. package/lib/types/adapter/ports/channel-catalog.d.ts +5 -1
  21. package/lib/types/adapter/ports/channel-catalog.d.ts.map +1 -1
  22. package/lib/types/adapter/ports/channel-settings.d.ts +5 -3
  23. package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
  24. package/lib/types/adapter/ports/channel-ui.d.ts +7 -1
  25. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  26. package/lib/types/adapter/ports/channel-view.d.ts +47 -0
  27. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  28. package/lib/types/adapter/ports/channel.d.ts +2 -0
  29. package/lib/types/adapter/ports/channel.d.ts.map +1 -1
  30. package/lib/types/agent/events.d.ts +3 -2
  31. package/lib/types/agent/events.d.ts.map +1 -1
  32. package/lib/types/backends/codex/contract.d.ts +3 -0
  33. package/lib/types/backends/codex/contract.d.ts.map +1 -1
  34. package/lib/types/backends/codex/contract.js +3 -0
  35. package/lib/types/backends/codex/session/async-questions.d.ts +17 -0
  36. package/lib/types/backends/codex/session/async-questions.d.ts.map +1 -0
  37. package/lib/types/backends/codex/session/async-questions.js +89 -0
  38. package/lib/types/backends/codex/session/session.d.ts.map +1 -1
  39. package/lib/types/backends/codex/session/session.js +35 -9
  40. package/lib/types/backends/codex/text.d.ts +3 -3
  41. package/lib/types/backends/codex/text.js +1 -1
  42. package/lib/types/backends/codex/translate/items.d.ts.map +1 -1
  43. package/lib/types/backends/codex/translate/items.js +3 -1
  44. package/lib/types/backends/codex/translate/question-reply.d.ts +11 -0
  45. package/lib/types/backends/codex/translate/question-reply.d.ts.map +1 -0
  46. package/lib/types/backends/codex/translate/question-reply.js +53 -0
  47. package/lib/types/channel/projection.d.ts.map +1 -1
  48. package/lib/types/channel/projection.js +10 -0
  49. package/lib/types/commands.d.ts +10 -0
  50. package/lib/types/commands.d.ts.map +1 -1
  51. package/lib/types/commands.js +11 -2
  52. package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
  53. package/lib/types/components/CommandSuggestions.js +4 -1
  54. package/lib/types/components/LogoV2.d.ts +4 -1
  55. package/lib/types/components/LogoV2.d.ts.map +1 -1
  56. package/lib/types/components/LogoV2.js +5 -3
  57. package/lib/types/components/MessageList.d.ts.map +1 -1
  58. package/lib/types/components/MessageList.js +95 -14
  59. package/lib/types/components/PermissionsPicker.d.ts +10 -1
  60. package/lib/types/components/PermissionsPicker.d.ts.map +1 -1
  61. package/lib/types/components/PermissionsPicker.js +24 -16
  62. package/lib/types/components/PluginInstallPane.d.ts +21 -0
  63. package/lib/types/components/PluginInstallPane.d.ts.map +1 -0
  64. package/lib/types/components/PluginInstallPane.js +84 -0
  65. package/lib/types/components/PluginManagePane.d.ts +21 -0
  66. package/lib/types/components/PluginManagePane.d.ts.map +1 -0
  67. package/lib/types/components/PluginManagePane.js +69 -0
  68. package/lib/types/components/PromptInput.d.ts.map +1 -1
  69. package/lib/types/components/PromptInput.js +7 -3
  70. package/lib/types/components/SubagentCard.d.ts +13 -1
  71. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  72. package/lib/types/components/SubagentCard.js +27 -12
  73. package/lib/types/components/SubagentDashboard.d.ts +8 -1
  74. package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
  75. package/lib/types/components/SubagentDashboard.js +58 -16
  76. package/lib/types/components/launchpadLayout.d.ts +14 -1
  77. package/lib/types/components/launchpadLayout.d.ts.map +1 -1
  78. package/lib/types/components/launchpadLayout.js +36 -17
  79. package/lib/types/components/messages/TeamMessageBubble.d.ts +20 -0
  80. package/lib/types/components/messages/TeamMessageBubble.d.ts.map +1 -0
  81. package/lib/types/components/messages/TeamMessageBubble.js +15 -0
  82. package/lib/types/components/sidePanel/PanelHost.d.ts.map +1 -1
  83. package/lib/types/components/sidePanel/PanelHost.js +5 -1
  84. package/lib/types/components/sidePanel/PanelStore.d.ts +8 -0
  85. package/lib/types/components/sidePanel/PanelStore.d.ts.map +1 -1
  86. package/lib/types/components/sidePanel/PanelStore.js +11 -0
  87. package/lib/types/components/sidePanel/SidePanelColumn.d.ts.map +1 -1
  88. package/lib/types/components/sidePanel/SidePanelColumn.js +13 -1
  89. package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts +7 -0
  90. package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts.map +1 -1
  91. package/lib/types/components/sidePanel/SidePanelRuntimeContext.js +4 -0
  92. package/lib/types/components/sidePanel/btw/BtwComposer.d.ts +3 -0
  93. package/lib/types/components/sidePanel/btw/BtwComposer.d.ts.map +1 -1
  94. package/lib/types/components/sidePanel/btw/BtwComposer.js +20 -8
  95. package/lib/types/components/sidePanel/btw/BtwPanelAdapter.d.ts +2 -1
  96. package/lib/types/components/sidePanel/btw/BtwPanelAdapter.d.ts.map +1 -1
  97. package/lib/types/components/sidePanel/btw/BtwPanelAdapter.js +104 -13
  98. package/lib/types/components/sidePanel/btw/BtwThreadScene.d.ts +6 -2
  99. package/lib/types/components/sidePanel/btw/BtwThreadScene.d.ts.map +1 -1
  100. package/lib/types/components/sidePanel/btw/BtwThreadScene.js +61 -15
  101. package/lib/types/components/sidePanel/btw/BtwThreadView.d.ts +14 -4
  102. package/lib/types/components/sidePanel/btw/BtwThreadView.d.ts.map +1 -1
  103. package/lib/types/components/sidePanel/btw/BtwThreadView.js +90 -5
  104. package/lib/types/components/sidePanel/btw/threads.d.ts +18 -0
  105. package/lib/types/components/sidePanel/btw/threads.d.ts.map +1 -1
  106. package/lib/types/components/sidePanel/btw/threads.js +51 -0
  107. package/lib/types/components/sidePanel/builtinPanels.d.ts.map +1 -1
  108. package/lib/types/components/sidePanel/builtinPanels.js +5 -1
  109. package/lib/types/components/sidePanel/companion/SplashMascot.d.ts +5 -1
  110. package/lib/types/components/sidePanel/companion/SplashMascot.d.ts.map +1 -1
  111. package/lib/types/components/sidePanel/companion/SplashMascot.js +19 -4
  112. package/lib/types/components/sidePanel/companion/skins.d.ts +8 -0
  113. package/lib/types/components/sidePanel/companion/skins.d.ts.map +1 -1
  114. package/lib/types/components/sidePanel/companion/skins.js +57 -12
  115. package/lib/types/components/sidePanel/types.d.ts +6 -0
  116. package/lib/types/components/sidePanel/types.d.ts.map +1 -1
  117. package/lib/types/components/splashArtRows.d.ts +29 -0
  118. package/lib/types/components/splashArtRows.d.ts.map +1 -0
  119. package/lib/types/components/splashArtRows.js +31 -0
  120. package/lib/types/components/teamRoster.d.ts +70 -0
  121. package/lib/types/components/teamRoster.d.ts.map +1 -0
  122. package/lib/types/components/teamRoster.js +78 -0
  123. package/lib/types/dsh-adapter/admission-loader.d.ts +82 -0
  124. package/lib/types/dsh-adapter/admission-loader.d.ts.map +1 -1
  125. package/lib/types/dsh-adapter/admission-loader.js +73 -28
  126. package/lib/types/dsh-adapter/agent-view.d.ts.map +1 -1
  127. package/lib/types/dsh-adapter/agent-view.js +3 -1
  128. package/lib/types/dsh-adapter/approvals.d.ts +7 -0
  129. package/lib/types/dsh-adapter/approvals.d.ts.map +1 -1
  130. package/lib/types/dsh-adapter/approvals.js +45 -1
  131. package/lib/types/dsh-adapter/backend/translate.d.ts.map +1 -1
  132. package/lib/types/dsh-adapter/backend/translate.js +68 -8
  133. package/lib/types/dsh-adapter/backend-assembly.d.ts +31 -0
  134. package/lib/types/dsh-adapter/backend-assembly.d.ts.map +1 -0
  135. package/lib/types/dsh-adapter/backend-assembly.js +225 -0
  136. package/lib/types/dsh-adapter/backend-contribution.d.ts +36 -0
  137. package/lib/types/dsh-adapter/backend-contribution.d.ts.map +1 -1
  138. package/lib/types/dsh-adapter/backend-contribution.js +41 -0
  139. package/lib/types/dsh-adapter/backend-registry.d.ts.map +1 -1
  140. package/lib/types/dsh-adapter/backend-registry.js +22 -3
  141. package/lib/types/dsh-adapter/backends.d.ts.map +1 -1
  142. package/lib/types/dsh-adapter/backends.js +4 -5
  143. package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -1
  144. package/lib/types/dsh-adapter/bundled-presets.js +60 -3
  145. package/lib/types/dsh-adapter/channel/binding-events.d.ts +1 -0
  146. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  147. package/lib/types/dsh-adapter/channel/binding-events.js +1 -0
  148. package/lib/types/dsh-adapter/channel/command-completions.d.ts.map +1 -1
  149. package/lib/types/dsh-adapter/channel/command-completions.js +64 -7
  150. package/lib/types/dsh-adapter/channel/compaction.d.ts +7 -2
  151. package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
  152. package/lib/types/dsh-adapter/channel/compaction.js +100 -26
  153. package/lib/types/dsh-adapter/channel/core/binding-feed.d.ts +3 -0
  154. package/lib/types/dsh-adapter/channel/core/binding-feed.d.ts.map +1 -1
  155. package/lib/types/dsh-adapter/channel/core/binding-feed.js +2 -1
  156. package/lib/types/dsh-adapter/channel/core/compose.d.ts.map +1 -1
  157. package/lib/types/dsh-adapter/channel/core/compose.js +12 -0
  158. package/lib/types/dsh-adapter/channel/extensions.d.ts.map +1 -1
  159. package/lib/types/dsh-adapter/channel/extensions.js +68 -8
  160. package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts +6 -0
  161. package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -1
  162. package/lib/types/dsh-adapter/channel/mode-permission-actions.js +104 -12
  163. package/lib/types/dsh-adapter/channel/model-actions.d.ts.map +1 -1
  164. package/lib/types/dsh-adapter/channel/model-actions.js +8 -1
  165. package/lib/types/dsh-adapter/channel/permissions.d.ts.map +1 -1
  166. package/lib/types/dsh-adapter/channel/permissions.js +4 -1
  167. package/lib/types/dsh-adapter/channel/projection-helpers.d.ts.map +1 -1
  168. package/lib/types/dsh-adapter/channel/projection-helpers.js +2 -0
  169. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
  170. package/lib/types/dsh-adapter/channel/session-metadata.js +4 -3
  171. package/lib/types/dsh-adapter/channel/session-reset.js +2 -2
  172. package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
  173. package/lib/types/dsh-adapter/channel/session-resume.js +7 -0
  174. package/lib/types/dsh-adapter/channel/settings-host.d.ts +3 -0
  175. package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
  176. package/lib/types/dsh-adapter/channel/settings-host.js +135 -5
  177. package/lib/types/dsh-adapter/channel/state.d.ts +6 -0
  178. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  179. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  180. package/lib/types/dsh-adapter/channel/subagent-projection.js +18 -6
  181. package/lib/types/dsh-adapter/channel/transcript.d.ts +7 -0
  182. package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -1
  183. package/lib/types/dsh-adapter/channel/transcript.js +19 -2
  184. package/lib/types/dsh-adapter/compat/agent-team-0.2.0.d.ts +55 -0
  185. package/lib/types/dsh-adapter/compat/agent-team-0.2.0.d.ts.map +1 -0
  186. package/lib/types/dsh-adapter/compat/agent-team-0.2.0.js +96 -0
  187. package/lib/types/dsh-adapter/contract.d.ts +4 -4
  188. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  189. package/lib/types/dsh-adapter/contract.js +5 -5
  190. package/lib/types/dsh-adapter/effect-ledger.d.ts +7 -0
  191. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
  192. package/lib/types/dsh-adapter/effect-ledger.js +8 -1
  193. package/lib/types/dsh-adapter/entry-slot.d.ts +3 -1
  194. package/lib/types/dsh-adapter/entry-slot.d.ts.map +1 -1
  195. package/lib/types/dsh-adapter/entry-slot.js +2 -2
  196. package/lib/types/dsh-adapter/fresh-agent.d.ts.map +1 -1
  197. package/lib/types/dsh-adapter/fresh-agent.js +6 -1
  198. package/lib/types/dsh-adapter/host-access.d.ts.map +1 -1
  199. package/lib/types/dsh-adapter/host-access.js +95 -0
  200. package/lib/types/dsh-adapter/host-contract.d.ts +1 -1
  201. package/lib/types/dsh-adapter/host-contract.d.ts.map +1 -1
  202. package/lib/types/dsh-adapter/host-contract.js +3 -2
  203. package/lib/types/dsh-adapter/host-dsh.d.ts +8 -2
  204. package/lib/types/dsh-adapter/host-dsh.d.ts.map +1 -1
  205. package/lib/types/dsh-adapter/host-dsh.js +45 -30
  206. package/lib/types/dsh-adapter/host-entry.js +35 -10
  207. package/lib/types/dsh-adapter/index.d.ts +9 -10
  208. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  209. package/lib/types/dsh-adapter/index.js +8 -6
  210. package/lib/types/dsh-adapter/invariant.d.ts +7 -2
  211. package/lib/types/dsh-adapter/invariant.d.ts.map +1 -1
  212. package/lib/types/dsh-adapter/invariant.js +6 -3
  213. package/lib/types/dsh-adapter/migrate/index.js +2 -2
  214. package/lib/types/dsh-adapter/panels.d.ts.map +1 -1
  215. package/lib/types/dsh-adapter/panels.js +6 -0
  216. package/lib/types/dsh-adapter/plugin-declaration.d.ts +99 -1
  217. package/lib/types/dsh-adapter/plugin-declaration.d.ts.map +1 -1
  218. package/lib/types/dsh-adapter/plugin-declaration.js +132 -2
  219. package/lib/types/dsh-adapter/plugin-feed.d.ts +94 -0
  220. package/lib/types/dsh-adapter/plugin-feed.d.ts.map +1 -0
  221. package/lib/types/dsh-adapter/plugin-feed.js +135 -0
  222. package/lib/types/dsh-adapter/plugin-guard.d.ts +115 -0
  223. package/lib/types/dsh-adapter/plugin-guard.d.ts.map +1 -0
  224. package/lib/types/dsh-adapter/plugin-guard.js +108 -0
  225. package/lib/types/dsh-adapter/plugin-install.d.ts +160 -0
  226. package/lib/types/dsh-adapter/plugin-install.d.ts.map +1 -0
  227. package/lib/types/dsh-adapter/plugin-install.js +545 -0
  228. package/lib/types/dsh-adapter/plugin-manage.d.ts +178 -0
  229. package/lib/types/dsh-adapter/plugin-manage.d.ts.map +1 -0
  230. package/lib/types/dsh-adapter/plugin-manage.js +468 -0
  231. package/lib/types/dsh-adapter/plugin-manager.d.ts +78 -2
  232. package/lib/types/dsh-adapter/plugin-manager.d.ts.map +1 -1
  233. package/lib/types/dsh-adapter/plugin-manager.js +32 -0
  234. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  235. package/lib/types/dsh-adapter/plugin.js +49 -2
  236. package/lib/types/dsh-adapter/plugins-info.d.ts +87 -1
  237. package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -1
  238. package/lib/types/dsh-adapter/plugins-info.js +131 -26
  239. package/lib/types/dsh-adapter/process-exit.d.ts +1 -1
  240. package/lib/types/dsh-adapter/process-exit.d.ts.map +1 -1
  241. package/lib/types/dsh-adapter/process-exit.js +1 -1
  242. package/lib/types/dsh-adapter/session-projection-store.d.ts +66 -0
  243. package/lib/types/dsh-adapter/session-projection-store.d.ts.map +1 -0
  244. package/lib/types/dsh-adapter/session-projection-store.js +149 -0
  245. package/lib/types/dsh-adapter/settingsEditor.js +2 -2
  246. package/lib/types/dsh-adapter/sideQuestion.d.ts +21 -0
  247. package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
  248. package/lib/types/dsh-adapter/sideQuestion.js +53 -0
  249. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  250. package/lib/types/dsh-adapter/subagents.js +2 -1
  251. package/lib/types/dsh-adapter/team-mode.d.ts +74 -0
  252. package/lib/types/dsh-adapter/team-mode.d.ts.map +1 -0
  253. package/lib/types/dsh-adapter/team-mode.js +188 -0
  254. package/lib/types/dsh-adapter/team-roster.d.ts +67 -0
  255. package/lib/types/dsh-adapter/team-roster.d.ts.map +1 -0
  256. package/lib/types/dsh-adapter/team-roster.js +136 -0
  257. package/lib/types/dsh-adapter/team-tools.d.ts +58 -0
  258. package/lib/types/dsh-adapter/team-tools.d.ts.map +1 -0
  259. package/lib/types/dsh-adapter/team-tools.js +208 -0
  260. package/lib/types/dsh-adapter/types.d.ts +1 -1
  261. package/lib/types/dsh-adapter/types.d.ts.map +1 -1
  262. package/lib/types/i18n.d.ts +607 -16
  263. package/lib/types/i18n.d.ts.map +1 -1
  264. package/lib/types/i18n.js +295 -9
  265. package/lib/types/ink/components/ScrollBox.d.ts +9 -0
  266. package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
  267. package/lib/types/ink/components/ScrollBox.js +23 -0
  268. package/lib/types/ink/dom.d.ts.map +1 -1
  269. package/lib/types/kernelPrefs.d.ts +1 -1
  270. package/lib/types/kernelPrefs.d.ts.map +1 -1
  271. package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -1
  272. package/lib/types/native-ts/yoga-layout/index.js +8 -1
  273. package/lib/types/permissionPresetLabels.d.ts +25 -0
  274. package/lib/types/permissionPresetLabels.d.ts.map +1 -0
  275. package/lib/types/permissionPresetLabels.js +33 -0
  276. package/lib/types/preset-patch.d.ts +22 -0
  277. package/lib/types/preset-patch.d.ts.map +1 -0
  278. package/lib/types/preset-patch.js +14 -0
  279. package/lib/types/screens/Chat.d.ts +33 -1
  280. package/lib/types/screens/Chat.d.ts.map +1 -1
  281. package/lib/types/screens/Chat.js +301 -9
  282. package/lib/types/screens/Launchpad.d.ts +7 -1
  283. package/lib/types/screens/Launchpad.d.ts.map +1 -1
  284. package/lib/types/screens/Launchpad.js +19 -4
  285. package/lib/types/screens/Settings.d.ts.map +1 -1
  286. package/lib/types/screens/Settings.js +1 -0
  287. package/lib/types/screens/chat/usePluginWriteFlow.d.ts +68 -0
  288. package/lib/types/screens/chat/usePluginWriteFlow.d.ts.map +1 -0
  289. package/lib/types/screens/chat/usePluginWriteFlow.js +92 -0
  290. package/lib/types/screens/chatOverlay.d.ts +19 -1
  291. package/lib/types/screens/chatOverlay.d.ts.map +1 -1
  292. package/lib/types/sessionModes.d.ts +5 -3
  293. package/lib/types/sessionModes.d.ts.map +1 -1
  294. package/lib/types/sessionModes.js +9 -3
  295. package/lib/types/tips.js +2 -2
  296. package/lib/types/utils/paths.d.ts +11 -0
  297. package/lib/types/utils/paths.d.ts.map +1 -1
  298. package/lib/types/utils/paths.js +13 -0
  299. package/package.json +126 -120
  300. package/tui-profile/feed/README.md +63 -0
  301. package/tui-profile/feed/first-party.json +10 -0
@@ -16,7 +16,7 @@ import { existsSync, readFileSync } from 'node:fs';
16
16
  import { fileURLToPath } from 'node:url';
17
17
  import { join } from 'node:path';
18
18
  import { Box, Text, Image, useTerminalImages, useTerminalImageProtocol, useTerminalImageCellSize } from '../../../ui.js';
19
- import { WhaleArt, renderSpriteRows } from '../../Whale.js';
19
+ import { WhaleArt, renderSpriteRows, renderCellRows } from '../../Whale.js';
20
20
  import { loadSharp } from '../../../dsh-adapter/sharp.js';
21
21
  import { DEEPY_CELLS, DEEPY_MOOD_ANIMATION, DEEPY_SEMANTIC_ANIMATION, frameAt, loadDeepyKit, loadWhaleGirlKit, renderedDeepyAnimation, } from './deepy.js';
22
22
  /** deepy 小鲸鱼(默认):语义/心情 → 动画,elapsed → frameAt 确定性选帧。 */
@@ -122,14 +122,31 @@ export function resolveWhaleGirlAnimationKey(pose, animationSemantic, hasKey) {
122
122
  * 回归锁「全部帧内容 ⊆ [5, 5+31)」防素材更新后悄悄越窗被截。 */
123
123
  const WHALE_GIRL_LETTER_WINDOW_START = 5;
124
124
  const whaleGirlWindowCache = new Map();
125
- function renderedWhaleGirlWindowRows(kit, key) {
125
+ function renderedWhaleGirlWindowRows(kit, key, imageBox) {
126
126
  const animation = kit.byKey[key];
127
127
  if (animation === undefined)
128
128
  return undefined;
129
- const cacheKey = kit.id + ':window:' + key;
129
+ const cacheKey = kit.id + ':window:' + key + (imageBox === undefined ? '' : `:${imageBox.columns}x${imageBox.rows}`);
130
130
  let rendered = whaleGirlWindowCache.get(cacheKey);
131
131
  if (rendered === undefined) {
132
- rendered = Object.freeze(animation.frames.map(frame => renderSpriteRows(frame.rows.map(row => row.slice(WHALE_GIRL_LETTER_WINDOW_START, WHALE_GIRL_LETTER_WINDOW_START + WHALE_GIRL_CELLS.columns)), kit.palette)));
132
+ rendered = Object.freeze(animation.frames.map(frame => {
133
+ if (imageBox === undefined)
134
+ return renderSpriteRows(frame.rows.map(row => row.slice(WHALE_GIRL_LETTER_WINDOW_START, WHALE_GIRL_LETTER_WINDOW_START + WHALE_GIRL_CELLS.columns)), kit.palette);
135
+ // 解码前/失败时整幅字母格 contain 进同一个槽,不裁掉头脚,也不换画跳高。
136
+ const pixelRows = imageBox.rows * 2;
137
+ const scale = Math.min(imageBox.columns / WHALE_GIRL_CELLS.columns, pixelRows / kit.rows);
138
+ const width = Math.max(1, Math.floor(WHALE_GIRL_CELLS.columns * scale));
139
+ const height = Math.max(1, Math.floor(kit.rows * scale));
140
+ const left = Math.floor((imageBox.columns - width) / 2);
141
+ const top = Math.floor((pixelRows - height) / 2);
142
+ return renderCellRows(imageBox.columns, pixelRows, (x, y) => {
143
+ if (x < left || x >= left + width || y < top || y >= top + height)
144
+ return undefined;
145
+ const sx = Math.min(WHALE_GIRL_CELLS.columns - 1, Math.floor((x - left) * WHALE_GIRL_CELLS.columns / width));
146
+ const sy = Math.min(kit.rows - 1, Math.floor((y - top) * kit.rows / height));
147
+ return kit.palette[frame.rows[sy]?.[sx + WHALE_GIRL_LETTER_WINDOW_START] ?? '.'];
148
+ });
149
+ }));
133
150
  whaleGirlWindowCache.set(cacheKey, rendered);
134
151
  }
135
152
  return rendered;
@@ -146,14 +163,14 @@ function renderWhaleGirlLetterGrid(input) {
146
163
  const animationKey = resolveWhaleGirlAnimationKey(pose, animationSemantic, key => kit.byKey[key] !== undefined);
147
164
  if (animationKey === undefined)
148
165
  return DeepySkin.render({ ...input, width: WHALE_GIRL_CELLS.columns });
149
- const rendered = renderedWhaleGirlWindowRows(kit, animationKey);
166
+ const rendered = renderedWhaleGirlWindowRows(kit, animationKey, input.imageBox);
150
167
  const animation = kit.byKey[animationKey];
151
168
  if (rendered === undefined || animation === undefined) {
152
169
  return DeepySkin.render({ ...input, width: WHALE_GIRL_CELLS.columns });
153
170
  }
154
171
  const frameIndex = frameAt(animation, now - moodSince);
155
172
  const rows = rendered[frameIndex] ?? rendered[0] ?? [];
156
- return (_jsx(Box, { flexDirection: "column", flexShrink: 0, width: WHALE_GIRL_CELLS.columns, children: rows.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, index))) }));
173
+ return (_jsx(Box, { flexDirection: "column", flexShrink: 0, width: input.imageBox?.columns ?? WHALE_GIRL_CELLS.columns, children: rows.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, index))) }));
157
174
  }
158
175
  export const WhaleGirlSkin = {
159
176
  id: 'whaleGirl',
@@ -210,8 +227,25 @@ export function loadWhaleGirlImageKit() {
210
227
  continue;
211
228
  const kit = parseWhaleGirlImageKit(JSON.parse(readFileSync(join(dir, 'timings.json'), 'utf8')), dir);
212
229
  if (kit !== undefined) {
213
- whaleGirlImageKitCache = kit;
214
- return kit;
230
+ const first = kit.byKey.idle?.frames[0];
231
+ let canvas;
232
+ if (first !== undefined) {
233
+ try {
234
+ const png = readFileSync(join(dir, 'idle', first.file));
235
+ if (png.length >= 24 && png.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))
236
+ && png.toString('ascii', 12, 16) === 'IHDR') {
237
+ const width = png.readUInt32BE(16);
238
+ const height = png.readUInt32BE(20);
239
+ if (width > 0 && height > 0 && width <= 4096 && height <= 4096)
240
+ canvas = { width, height };
241
+ }
242
+ }
243
+ catch {
244
+ // 缺失/坏帧仍走原来的异步解码失败与字母格回退。
245
+ }
246
+ }
247
+ whaleGirlImageKitCache = { ...kit, ...(canvas === undefined ? {} : { canvas }) };
248
+ return whaleGirlImageKitCache;
215
249
  }
216
250
  }
217
251
  catch {
@@ -537,17 +571,28 @@ function WhaleGirlRasterSkin(input) {
537
571
  const frameRatio = source.width / source.height;
538
572
  // 盒宽=图宽(钳在 cells.columns 内;超宽像元比下 contain 收行不裁剪)。
539
573
  const rawColumns = Math.max(1, Math.round(cellRatio * WHALE_GIRL_CELLS.rows * frameRatio));
540
- const columns = whaleGirlImageBoxColumns(cellSize, frameRatio);
541
- const rows = rawColumns > columns
574
+ const columns = input.imageBox?.columns ?? whaleGirlImageBoxColumns(cellSize, frameRatio);
575
+ const rows = input.imageBox?.rows ?? (rawColumns > columns
542
576
  ? Math.max(1, Math.round(columns / (cellRatio * frameRatio)))
543
- : WHALE_GIRL_CELLS.rows;
577
+ : WHALE_GIRL_CELLS.rows);
544
578
  image = (_jsx(Image, { transparent: true, source: source, width: columns, height: rows, alt: "", presentation: "transcript", children: _jsx(Text, { children: Array.from({ length: rows }, () => ' '.repeat(columns)).join('\n') }) }));
545
579
  }
546
580
  }
547
581
  // 本次候选或上一帧;都没有(冷启动)时画字母格。切到还没解码的键时
548
582
  // 保持上一帧,不闪回字母格。
549
583
  const [visibleImage] = useHeldCommittedImage(image);
550
- return (_jsx(Box, { ref: boxRef, flexDirection: "column", flexShrink: 0, alignItems: "center", justifyContent: "center", width: WHALE_GIRL_CELLS.columns, height: WHALE_GIRL_CELLS.rows, children: visibleImage !== undefined ? visibleImage : renderWhaleGirlLetterGrid(input) }));
584
+ let raster = visibleImage;
585
+ // 换键等待解码时保留旧像素,但 resize 后不能把旧的大 Image 盒塞进新小槽。
586
+ if (input.imageBox !== undefined && React.isValidElement(raster)
587
+ && (raster.props.width !== input.imageBox.columns || raster.props.height !== input.imageBox.rows)) {
588
+ const { columns, rows } = input.imageBox;
589
+ raster = React.cloneElement(raster, {
590
+ width: columns,
591
+ height: rows,
592
+ children: _jsx(Text, { children: Array.from({ length: rows }, () => ' '.repeat(columns)).join('\n') }),
593
+ });
594
+ }
595
+ return (_jsx(Box, { ref: boxRef, flexDirection: "column", flexShrink: 0, alignItems: "center", justifyContent: "center", width: input.imageBox?.columns ?? WHALE_GIRL_CELLS.columns, height: input.imageBox?.rows ?? WHALE_GIRL_CELLS.rows, children: raster !== undefined ? raster : renderWhaleGirlLetterGrid(input) }));
551
596
  }
552
597
  const WHALE_CELLS = Object.freeze({ columns: 40, rows: 13 });
553
598
  /** 现有像素鲸鱼:直接消费 nativeWhalePose(与开屏 splash 同一规划器、
@@ -74,6 +74,12 @@ export interface PanelEntry {
74
74
  /** 同 id 重注册时递增,用于重挂 error boundary。 */
75
75
  readonly registrationId: number;
76
76
  readonly badge: PanelBadge | null;
77
+ /**
78
+ * 面板自己广告的键位片段(底栏用)。`''` = 面板明确「此刻没有要广告的键」
79
+ * (底栏连能力位那一段也不画);没设置过则由底栏按 capabilities 兜底。
80
+ * 层内状态(编辑层 vs 列表层)只有面板自己知道,所以由面板发、宿主只拼。
81
+ */
82
+ readonly hint?: string;
77
83
  readonly lastError: {
78
84
  readonly message: string;
79
85
  readonly at: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/sidePanel/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/sidePanel/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { Brand } from '../branding.js';
2
+ /** 启动页立绘槽的占行:鲸鱼自然高度、portrait 的 minimal 等高盒、吉祥物的侧栏默认盒。 */
3
+ export declare const WHALE_ART_ROWS = 13;
4
+ export declare const PORTRAIT_ART_ROWS = 11;
5
+ export declare const MASCOT_ART_ROWS = 15;
6
+ export type SplashArtForm = 'whale' | 'portrait' | 'mascot';
7
+ export interface SplashImageBox {
8
+ readonly columns: number;
9
+ readonly rows: number;
10
+ }
11
+ /** 与 LogoV2 的默认品牌及 mascot → portrait → whale 分支一致。 */
12
+ export declare function resolveSplashArtForm(input: {
13
+ readonly brand: Brand | undefined;
14
+ readonly whaleGirl: boolean;
15
+ readonly mascotSkin: string | undefined;
16
+ }): SplashArtForm;
17
+ export declare function splashArtRows(form: SplashArtForm, imageBox?: SplashImageBox): number;
18
+ /**
19
+ * 启动页图片按原生画布占位:只缩小、不预留放大后用不上的空间。
20
+ * 同一个稳定画布用于全部动画帧;不按 alpha 包围盒逐帧裁剪。
21
+ */
22
+ export declare function fitSplashImageBox(source: {
23
+ readonly width: number;
24
+ readonly height: number;
25
+ }, cell: {
26
+ readonly width: number;
27
+ readonly height: number;
28
+ }, limit: SplashImageBox): SplashImageBox;
29
+ //# sourceMappingURL=splashArtRows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splashArtRows.d.ts","sourceRoot":"","sources":["../../../src/components/splashArtRows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE3C,yDAAyD;AACzD,eAAO,MAAM,cAAc,KAAK,CAAA;AAChC,eAAO,MAAM,iBAAiB,KAAK,CAAA;AACnC,eAAO,MAAM,eAAe,KAAK,CAAA;AAEjC,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAA;AAC3D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,sDAAsD;AACtD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAAA;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC,GAAG,aAAa,CAKhB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,MAAM,CAIpF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC3D,IAAI,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACzD,KAAK,EAAE,cAAc,GACpB,cAAc,CAMhB"}
@@ -0,0 +1,31 @@
1
+ /** 启动页立绘槽的占行:鲸鱼自然高度、portrait 的 minimal 等高盒、吉祥物的侧栏默认盒。 */
2
+ export const WHALE_ART_ROWS = 13;
3
+ export const PORTRAIT_ART_ROWS = 11;
4
+ export const MASCOT_ART_ROWS = 15;
5
+ /** 与 LogoV2 的默认品牌及 mascot → portrait → whale 分支一致。 */
6
+ export function resolveSplashArtForm(input) {
7
+ const brand = input.brand ?? 'deepseek';
8
+ if (brand === 'deepseek' && (input.mascotSkin === 'deepy' || input.mascotSkin === 'whaleGirl'))
9
+ return 'mascot';
10
+ if (input.whaleGirl || brand !== 'deepseek')
11
+ return 'portrait';
12
+ return 'whale';
13
+ }
14
+ export function splashArtRows(form, imageBox) {
15
+ if (form === 'whale')
16
+ return WHALE_ART_ROWS;
17
+ if (form === 'portrait')
18
+ return PORTRAIT_ART_ROWS;
19
+ return imageBox?.rows ?? MASCOT_ART_ROWS;
20
+ }
21
+ /**
22
+ * 启动页图片按原生画布占位:只缩小、不预留放大后用不上的空间。
23
+ * 同一个稳定画布用于全部动画帧;不按 alpha 包围盒逐帧裁剪。
24
+ */
25
+ export function fitSplashImageBox(source, cell, limit) {
26
+ const scale = Math.min(1, limit.columns * cell.width / source.width, limit.rows * cell.height / source.height);
27
+ return {
28
+ columns: Math.max(1, Math.min(limit.columns, Math.ceil(source.width * scale / cell.width))),
29
+ rows: Math.max(1, Math.min(limit.rows, Math.ceil(source.height * scale / cell.height))),
30
+ };
31
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Agent Teams in the agents surfaces (issue #1241, phase 2): fold the
3
+ * session's `TeamView` and its subagent rows into what the dashboard
4
+ * renders. A teammate is a continuable subagent of the Lead whose row id is
5
+ * the member id, so the two join by id; neither side overwrites the other's
6
+ * state (see `teamMemberStatus`). Pure: no I/O, no backend import.
7
+ */
8
+ import type { TeamMember, TeamTask, TeamView } from '../adapter/ports/channel-view.js';
9
+ import type { SubagentState } from '../dsh-adapter/subagents.js';
10
+ /** A member's state as shown: durable `phase` first, then the run. `active`
11
+ * is an active member whose run this session cannot see (a teammate's own
12
+ * subagent rows never hold its siblings). */
13
+ export type TeamMemberStatus = 'provisioning' | 'running' | 'idle' | 'active' | 'failed';
14
+ /** One teammate, with its subagent row once the host has announced it. */
15
+ export interface TeamMemberRow {
16
+ readonly member: TeamMember;
17
+ readonly subagent?: SubagentState;
18
+ readonly status: TeamMemberStatus;
19
+ }
20
+ export interface TeamDashboardModel {
21
+ readonly lead?: TeamMember;
22
+ /** Whether the session on screen is the Lead (its subagent rows are the teammates). */
23
+ readonly viewedFromLead: boolean;
24
+ readonly teammates: readonly TeamMemberRow[];
25
+ /** Subagent rows that are not team members (workflow / ralph spawns). */
26
+ readonly others: readonly SubagentState[];
27
+ }
28
+ /**
29
+ * A member's shown state. A failed `phase` is durable and wins; provisioning
30
+ * has no run yet. An active member is running only while its row runs: a
31
+ * finished turn leaves the member alive and waiting (a message wakes it),
32
+ * so a completed — or failed, or absent — run reads as idle, never done.
33
+ * @param member - Roster row.
34
+ * @param subagent - The member's subagent row, if any.
35
+ * @param runKnown - Whether the subagent rows are the Lead's (default).
36
+ * @returns the state to render.
37
+ */
38
+ export declare function teamMemberStatus(member: TeamMember, subagent: SubagentState | undefined, runKnown?: boolean): TeamMemberStatus;
39
+ /**
40
+ * Join the roster with the subagent rows.
41
+ * @param team - The session's team.
42
+ * @param subagents - The session's subagent rows.
43
+ * @param sessionId - The session on screen; inside a teammate its rows are
44
+ * its own children, never joined with the roster.
45
+ * @returns the Lead, teammates in roster order, and the remaining rows.
46
+ */
47
+ export declare function teamDashboardModel(team: TeamView, subagents: readonly SubagentState[], sessionId?: string): TeamDashboardModel;
48
+ /**
49
+ * Teammates on the roster: those known to be running or provisioning, and
50
+ * those that may be running. Inside a teammate a sibling's run is not
51
+ * visible, so an active sibling is `unseen`; the teammate on screen itself
52
+ * counts in neither.
53
+ * @param team - The session's team.
54
+ * @param subagents - The session's subagent rows.
55
+ * @param sessionId - The session on screen.
56
+ * @returns the three counts.
57
+ */
58
+ export declare function teamMemberCounts(team: TeamView, subagents: readonly SubagentState[], sessionId?: string): {
59
+ readonly total: number;
60
+ readonly active: number;
61
+ readonly unseen: number;
62
+ };
63
+ /** Completed / total of the task board. */
64
+ export declare function teamTaskProgress(tasks: readonly TeamTask[]): {
65
+ readonly completed: number;
66
+ readonly total: number;
67
+ };
68
+ /** A pending task some blocker still holds back. */
69
+ export declare function isTeamTaskBlocked(task: TeamTask): boolean;
70
+ //# sourceMappingURL=teamRoster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teamRoster.d.ts","sourceRoot":"","sources":["../../../src/components/teamRoster.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAA;AACtF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAEhE;;8CAE8C;AAC9C,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAExF,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAA;IACjC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;IAC1B,uFAAuF;IACvF,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAA;IAC5C,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;CAC1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,GAAG,SAAS,EAAE,QAAQ,UAAO,GAAG,gBAAgB,CAK3H;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,aAAa,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAmB9H;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,aAAa,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAQtL;AAED,2CAA2C;AAC3C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAEnH;AAED,oDAAoD;AACpD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEzD"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * A member's shown state. A failed `phase` is durable and wins; provisioning
3
+ * has no run yet. An active member is running only while its row runs: a
4
+ * finished turn leaves the member alive and waiting (a message wakes it),
5
+ * so a completed — or failed, or absent — run reads as idle, never done.
6
+ * @param member - Roster row.
7
+ * @param subagent - The member's subagent row, if any.
8
+ * @param runKnown - Whether the subagent rows are the Lead's (default).
9
+ * @returns the state to render.
10
+ */
11
+ export function teamMemberStatus(member, subagent, runKnown = true) {
12
+ if (member.phase === 'failed')
13
+ return 'failed';
14
+ if (member.phase === 'provisioning')
15
+ return 'provisioning';
16
+ if (!runKnown)
17
+ return 'active';
18
+ return subagent?.status === 'running' || subagent?.status === 'starting' ? 'running' : 'idle';
19
+ }
20
+ /**
21
+ * Join the roster with the subagent rows.
22
+ * @param team - The session's team.
23
+ * @param subagents - The session's subagent rows.
24
+ * @param sessionId - The session on screen; inside a teammate its rows are
25
+ * its own children, never joined with the roster.
26
+ * @returns the Lead, teammates in roster order, and the remaining rows.
27
+ */
28
+ export function teamDashboardModel(team, subagents, sessionId) {
29
+ const viewedFromLead = sessionId === undefined || sessionId === team.leadSessionId;
30
+ const byId = new Map();
31
+ if (viewedFromLead)
32
+ for (const row of subagents)
33
+ byId.set(row.agentId, row);
34
+ const teammates = [];
35
+ const memberIds = new Set();
36
+ for (const member of team.members) {
37
+ if (member.role !== 'teammate')
38
+ continue;
39
+ const subagent = byId.get(member.id);
40
+ if (subagent !== undefined)
41
+ memberIds.add(member.id);
42
+ teammates.push({ member, status: teamMemberStatus(member, subagent, viewedFromLead), ...subagent === undefined ? {} : { subagent } });
43
+ }
44
+ const lead = team.members.find(member => member.role === 'lead');
45
+ return {
46
+ ...lead === undefined ? {} : { lead },
47
+ viewedFromLead,
48
+ teammates,
49
+ others: subagents.filter(row => !memberIds.has(row.agentId)),
50
+ };
51
+ }
52
+ /**
53
+ * Teammates on the roster: those known to be running or provisioning, and
54
+ * those that may be running. Inside a teammate a sibling's run is not
55
+ * visible, so an active sibling is `unseen`; the teammate on screen itself
56
+ * counts in neither.
57
+ * @param team - The session's team.
58
+ * @param subagents - The session's subagent rows.
59
+ * @param sessionId - The session on screen.
60
+ * @returns the three counts.
61
+ */
62
+ export function teamMemberCounts(team, subagents, sessionId) {
63
+ const { teammates } = teamDashboardModel(team, subagents, sessionId);
64
+ const counted = teammates.filter(row => row.member.id !== sessionId);
65
+ return {
66
+ total: teammates.length,
67
+ active: counted.filter(row => row.status === 'running' || row.status === 'provisioning').length,
68
+ unseen: counted.filter(row => row.status === 'active').length,
69
+ };
70
+ }
71
+ /** Completed / total of the task board. */
72
+ export function teamTaskProgress(tasks) {
73
+ return { completed: tasks.filter(task => task.status === 'completed').length, total: tasks.length };
74
+ }
75
+ /** A pending task some blocker still holds back. */
76
+ export function isTeamTaskBlocked(task) {
77
+ return task.status === 'pending' && !task.ready;
78
+ }
@@ -7,6 +7,55 @@
7
7
  */
8
8
  import { Context } from '@deepseek-ai/cordis';
9
9
  import { type TuiPluginHost } from './plugin-host.js';
10
+ /**
11
+ * The Loader's own ESM resolver (`cordis-plugin-loader`'s Node-internals
12
+ * adapter, or `undefined` when this runtime exposes no internals). Admission
13
+ * must resolve the entry through it: the Loader's active export conditions and
14
+ * custom hooks decide which module actually executes, and that module's
15
+ * manifest owns the identity and permissions.
16
+ *
17
+ * `import` is the same door `EntryTree.import()` uses — the module the Loader
18
+ * would execute for that specifier, out of the Loader's own cache. It is
19
+ * optional because the shape is classified by `resolveSync` alone; a
20
+ * resolution that cannot be executed is still a resolution, and the D-1
21
+ * assembly falls back to importing the URL the resolver returned.
22
+ */
23
+ export type ActiveResolver = {
24
+ readonly version: 'v1';
25
+ resolveSync(specifier: string, parentURL: string, attributes: object): {
26
+ readonly url: string;
27
+ };
28
+ import?(specifier: string, parentURL: string, attributes: object): Promise<unknown>;
29
+ } | {
30
+ readonly version: 'v2';
31
+ resolveSync(parentURL: string, request: {
32
+ specifier: string;
33
+ attributes: object;
34
+ }): {
35
+ readonly url: string;
36
+ };
37
+ import?(specifier: string, parentURL: string, attributes: object): Promise<unknown>;
38
+ };
39
+ /** The Cordis loader entry that owns a fiber (`cordis-plugin-loader`). */
40
+ interface LoaderEntryLike {
41
+ readonly options?: {
42
+ readonly name?: string;
43
+ };
44
+ readonly ctx?: {
45
+ readonly baseUrl?: string;
46
+ };
47
+ readonly fiber?: {
48
+ readonly state?: number;
49
+ } | null;
50
+ }
51
+ /** The part of the Loader's surface this package reads. Exported (D-1) because
52
+ * the backend assembly resolves a bundle's entry through the same resolver. */
53
+ export interface LoaderLike {
54
+ readonly internal?: ActiveResolver;
55
+ locate?(fiber?: object): string | undefined;
56
+ resolve?(id: string): LoaderEntryLike | undefined;
57
+ entries?(): Iterable<LoaderEntryLike>;
58
+ }
10
59
  /**
11
60
  * Watch `ctx`'s composition and admit every third-party activation that
12
61
  * carries a package-root `dsh-plugin.json`. The listeners and the retry
@@ -17,4 +66,37 @@ export declare function armAdmissionLoader(ctx: Context, options?: {
17
66
  /** @internal retry bound for the regression; production uses RETRY_ATTEMPTS. */
18
67
  retryAttempts?: number;
19
68
  }): void;
69
+ /** The Loader of `ctx`'s composition, when there is one. One accessor for both
70
+ * readers of it (the admission loader and the D-1 backend assembly), so
71
+ * "which Loader" cannot drift between them. */
72
+ export declare function compositionLoader(ctx: Context): LoaderLike | undefined;
73
+ /**
74
+ * The **URL** an entry `name` resolves to, through the exact resolver owned by
75
+ * the Loader that would execute it: its active conditions and hooks must select
76
+ * the same code and authority.
77
+ *
78
+ * `undefined` is a refusal to guess, not a "not found": a `cordis:` builtin has
79
+ * no module of its own, and a Loader without Node internals leaves the question
80
+ * open (one debug line, then out). Exported for the D-1 backend assembly, which
81
+ * resolves a *package* the same way rather than growing a second path resolver.
82
+ */
83
+ export declare function resolveEntryUrl(loader: LoaderLike, name: string, baseUrl: string | undefined): string | undefined;
84
+ /**
85
+ * Import a module through the Loader's own door (`EntryTree.import`), so the
86
+ * namespace handed back is the one the Loader executed — conditions, hooks and
87
+ * module cache included. Falls back to importing the URL the resolver already
88
+ * returned (still the Loader's answer; no second resolver) for a loader shape
89
+ * that can resolve but not import.
90
+ */
91
+ export declare function loadThroughLoader(loader: LoaderLike, name: string, url: string, baseUrl: string | undefined): Promise<Record<string, unknown>>;
92
+ /** Walk up from the entry module to its package root. A manifest counts only
93
+ * beside the `package.json` that establishes that root: a stray copy deeper
94
+ * in the tree (a build output directory, say) must not claim an outer
95
+ * package's code for its own identity. The walk stops at the first
96
+ * `package.json`, so DSH's own rows (a `package.json` one level up from
97
+ * their entry) cost one lookup instead of a climb to the filesystem root.
98
+ * Exported for the D-1 backend assembly, which reads a bundle's declaration
99
+ * through this same rule. */
100
+ export declare function findManifest(from: string): string | undefined;
101
+ export {};
20
102
  //# sourceMappingURL=admission-loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"admission-loader.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/admission-loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAA;AA6BvE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE;IACP,IAAI,CAAC,EAAE,MAAM,aAAa,GAAG,SAAS,CAAA;IACtC,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAA;CAClB,GACL,IAAI,CA8JN"}
1
+ {"version":3,"file":"admission-loader.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/admission-loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAA;AASvE;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;IACtB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/F,MAAM,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,GACvF;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;IACtB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5G,MAAM,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAA;AAE3F,0EAA0E;AAC1E,UAAU,eAAe;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7C,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CACpD;AAED;gFACgF;AAChF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;IAClC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IAC3C,OAAO,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAA;IACjD,OAAO,CAAC,IAAI,QAAQ,CAAC,eAAe,CAAC,CAAA;CACtC;AASD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE;IACP,IAAI,CAAC,EAAE,MAAM,aAAa,GAAG,SAAS,CAAA;IACtC,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAA;CAClB,GACL,IAAI,CA8JN;AAED;;gDAEgD;AAChD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAKtE;AAgCD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAgBjH;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAMlC;AAWD;;;;;;;8BAO8B;AAC9B,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAY7D"}
@@ -5,9 +5,8 @@
5
5
  * unload would rewrite the user's profile) but stays outside every mediated
6
6
  * capability. Listeners and the retry timer ride the caller's `ctx.effect`.
7
7
  */
8
- import { findPackageJSON } from 'node:module';
9
8
  import { existsSync, readFileSync } from 'node:fs';
10
- import { dirname, isAbsolute, join, resolve as resolvePath } from 'node:path';
9
+ import { dirname, join, resolve as resolvePath } from 'node:path';
11
10
  import { fileURLToPath, pathToFileURL } from 'node:url';
12
11
  import { Context } from '@deepseek-ai/cordis';
13
12
  import { componentIdentityOf } from './component-identity.js';
@@ -27,8 +26,8 @@ const RETRY_ATTEMPTS = 100;
27
26
  export function armAdmissionLoader(ctx, options = {}) {
28
27
  const root = compositionRoot(ctx);
29
28
  const retryAttempts = options.retryAttempts ?? RETRY_ATTEMPTS;
30
- const loader = root.get('loader', false);
31
- if (loader === undefined || typeof loader.locate !== 'function' || typeof loader.resolve !== 'function') {
29
+ const loader = compositionLoader(root);
30
+ if (loader === undefined) {
32
31
  logForDebugging('dsh-tui: admission loader not armed — this composition has no cordis loader');
33
32
  return;
34
33
  }
@@ -181,6 +180,15 @@ export function armAdmissionLoader(ctx, options = {}) {
181
180
  ctx.effect(() => stopTimer);
182
181
  seed();
183
182
  }
183
+ /** The Loader of `ctx`'s composition, when there is one. One accessor for both
184
+ * readers of it (the admission loader and the D-1 backend assembly), so
185
+ * "which Loader" cannot drift between them. */
186
+ export function compositionLoader(ctx) {
187
+ const loader = compositionRoot(ctx).get('loader', false);
188
+ return loader !== undefined && typeof loader.locate === 'function' && typeof loader.resolve === 'function'
189
+ ? loader
190
+ : undefined;
191
+ }
184
192
  /** The package-root `dsh-plugin.json` of the entry that owns `fiber`, if any.
185
193
  * Both loader calls are fenced: `EntryTree.resolve` throws for nested ids
186
194
  * (`include:<group>:<row>`); an uninspectable entry is simply skipped. */
@@ -196,33 +204,67 @@ function manifestPathOf(loader, fiber) {
196
204
  const name = entry?.options?.name;
197
205
  if (typeof name !== 'string' || name === '')
198
206
  return undefined;
199
- const entryFile = resolveEntryFile(name, entry?.ctx?.baseUrl);
207
+ const entryFile = resolveEntryFile(loader, name, entry?.ctx?.baseUrl);
200
208
  return entryFile === undefined ? undefined : findManifest(entryFile);
201
209
  }
202
- /** The module file an entry `name` resolves to, following the same rules the
210
+ /** The module an entry `name` resolves to, following the same rules the
203
211
  * loader's own import uses (file URL, relative to `baseUrl`, bare
204
212
  * specifier relative to the profile). */
205
- function resolveEntryFile(name, baseUrl) {
213
+ function resolveEntryFile(loader, name, baseUrl) {
214
+ const url = resolveEntryUrl(loader, name, baseUrl);
215
+ if (url === undefined)
216
+ return undefined;
217
+ try {
218
+ return fileURLToPath(url);
219
+ }
220
+ catch {
221
+ return undefined;
222
+ }
223
+ }
224
+ /**
225
+ * The **URL** an entry `name` resolves to, through the exact resolver owned by
226
+ * the Loader that would execute it: its active conditions and hooks must select
227
+ * the same code and authority.
228
+ *
229
+ * `undefined` is a refusal to guess, not a "not found": a `cordis:` builtin has
230
+ * no module of its own, and a Loader without Node internals leaves the question
231
+ * open (one debug line, then out). Exported for the D-1 backend assembly, which
232
+ * resolves a *package* the same way rather than growing a second path resolver.
233
+ */
234
+ export function resolveEntryUrl(loader, name, baseUrl) {
206
235
  try {
207
- // Builtin rows (loader groups, timers) have no package directory.
208
236
  if (name.startsWith('cordis:'))
209
237
  return undefined;
210
- if (name.startsWith('file:'))
211
- return fileURLToPath(name);
212
- if (isAbsolute(name))
213
- return name;
214
- if (name.startsWith('.')) {
215
- return baseUrl === undefined || baseUrl === '' ? undefined : fileURLToPath(new URL(name, baseUrl));
238
+ const resolver = loader.internal;
239
+ if (resolver === undefined) {
240
+ logForDebugging('dsh-tui: admission skipped — the Loader ESM resolver is unavailable; refusing to guess component identity');
241
+ return undefined;
216
242
  }
217
- // Through the package's own resolution: `exports` need not list
218
- // `./package.json`, and a subpath (`pkg/sub`) lands on the same root.
219
- return findPackageJSON(name, requireBase(baseUrl));
243
+ const parent = moduleBase(baseUrl).href;
244
+ const resolved = resolver.version === 'v1'
245
+ ? resolver.resolveSync(name, parent, {})
246
+ : resolver.resolveSync(parent, { specifier: name, attributes: {} });
247
+ return resolved.url;
220
248
  }
221
249
  catch {
222
250
  return undefined;
223
251
  }
224
252
  }
225
- function requireBase(baseUrl) {
253
+ /**
254
+ * Import a module through the Loader's own door (`EntryTree.import`), so the
255
+ * namespace handed back is the one the Loader executed — conditions, hooks and
256
+ * module cache included. Falls back to importing the URL the resolver already
257
+ * returned (still the Loader's answer; no second resolver) for a loader shape
258
+ * that can resolve but not import.
259
+ */
260
+ export async function loadThroughLoader(loader, name, url, baseUrl) {
261
+ const internal = loader.internal;
262
+ if (internal?.import !== undefined) {
263
+ return await internal.import(name, moduleBase(baseUrl).href, {});
264
+ }
265
+ return await import(/* @vite-ignore */ url);
266
+ }
267
+ function moduleBase(baseUrl) {
226
268
  if (baseUrl === undefined || baseUrl === '')
227
269
  return pathToFileURL(join(process.cwd(), 'index.js'));
228
270
  try {
@@ -232,18 +274,21 @@ function requireBase(baseUrl) {
232
274
  return pathToFileURL(join(process.cwd(), 'index.js'));
233
275
  }
234
276
  }
235
- /** Walk up from the entry module to its package root. The walk stops at the
236
- * first `package.json`: a manifest lives at the package root, never deeper,
237
- * so DSH's own rows (a `package.json` one level up from their entry) cost
238
- * one lookup instead of a climb to the filesystem root. */
239
- function findManifest(from) {
277
+ /** Walk up from the entry module to its package root. A manifest counts only
278
+ * beside the `package.json` that establishes that root: a stray copy deeper
279
+ * in the tree (a build output directory, say) must not claim an outer
280
+ * package's code for its own identity. The walk stops at the first
281
+ * `package.json`, so DSH's own rows (a `package.json` one level up from
282
+ * their entry) cost one lookup instead of a climb to the filesystem root.
283
+ * Exported for the D-1 backend assembly, which reads a bundle's declaration
284
+ * through this same rule. */
285
+ export function findManifest(from) {
240
286
  let dir = dirname(resolvePath(from));
241
287
  for (let depth = 0; depth < 64; depth += 1) {
242
- const candidate = join(dir, 'dsh-plugin.json');
243
- if (existsSync(candidate))
244
- return candidate;
245
- if (existsSync(join(dir, 'package.json')))
246
- return undefined;
288
+ if (existsSync(join(dir, 'package.json'))) {
289
+ const candidate = join(dir, 'dsh-plugin.json');
290
+ return existsSync(candidate) ? candidate : undefined;
291
+ }
247
292
  const parent = dirname(dir);
248
293
  if (parent === dir)
249
294
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-view.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/agent-view.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAEnD,gEAAgE;AAChE,eAAO,MAAM,uBAAuB,EAAE,SAAS,eAAe,EAE7D,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAE3C;4DAC4D;AAC5D,eAAO,MAAM,qBAAqB,KAAK,CAAA;AAEvC;iEACiE;AACjE,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAcpE;AAED,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAE1E;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAA;IACjB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAA;IACnB;kEAC8D;IAC9D,OAAO,EAAE,MAAM,CAAA;IACf;yCACqC;IACrC,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAA;IACrD,KAAK,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,cAAc,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,aAAa,GAClB,aAAa,CAkDf;AAED,gEAAgE;AAChE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAanG;AAED;4DAC4D;AAC5D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUzF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,IAAI,EAAE,aAAa,EACnB,UAAU,EAAE,OAAO,GAClB,eAAe,CAMjB"}
1
+ {"version":3,"file":"agent-view.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/agent-view.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAGnD,gEAAgE;AAChE,eAAO,MAAM,uBAAuB,EAAE,SAAS,eAAe,EAE7D,CAAA;AAED,gEAAgE;AAChE,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAE3C;4DAC4D;AAC5D,eAAO,MAAM,qBAAqB,KAAK,CAAA;AAEvC;iEACiE;AACjE,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAcpE;AAED,2DAA2D;AAC3D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAE1E;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAA;IACjB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAA;IACnB;kEAC8D;IAC9D,OAAO,EAAE,MAAM,CAAA;IACf;yCACqC;IACrC,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAA;IACrD,KAAK,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,cAAc,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,aAAa,GAClB,aAAa,CAmDf;AAED,gEAAgE;AAChE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAanG;AAED;4DAC4D;AAC5D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUzF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,IAAI,EAAE,aAAa,EACnB,UAAU,EAAE,OAAO,GAClB,eAAe,CAMjB"}