@shepai/cli 1.162.0 → 1.163.0-pr505.35c41df

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 (419) hide show
  1. package/apis/json-schema/FabLayoutConfig.yaml +11 -0
  2. package/apis/json-schema/Settings.yaml +3 -0
  3. package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.d.ts +20 -0
  4. package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.d.ts.map +1 -1
  5. package/dist/packages/core/src/application/ports/output/services/index.d.ts +1 -1
  6. package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
  7. package/dist/packages/core/src/application/use-cases/repositories/list-github-organizations.use-case.d.ts +13 -0
  8. package/dist/packages/core/src/application/use-cases/repositories/list-github-organizations.use-case.d.ts.map +1 -0
  9. package/dist/packages/core/src/application/use-cases/repositories/list-github-organizations.use-case.js +35 -0
  10. package/dist/packages/core/src/domain/generated/output.d.ts +13 -0
  11. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  12. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  13. package/dist/packages/core/src/infrastructure/di/container.js +5 -0
  14. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +1 -0
  15. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  16. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +6 -0
  17. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/050-add-fab-position-swapped.d.ts +15 -0
  18. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/050-add-fab-position-swapped.d.ts.map +1 -0
  19. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/050-add-fab-position-swapped.js +20 -0
  20. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts +2 -1
  21. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts.map +1 -1
  22. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.js +20 -0
  23. package/dist/src/presentation/cli/commands/repo/add.command.d.ts.map +1 -1
  24. package/dist/src/presentation/cli/commands/repo/add.command.js +3 -1
  25. package/dist/src/presentation/tui/wizards/github-import.wizard.d.ts +5 -2
  26. package/dist/src/presentation/tui/wizards/github-import.wizard.d.ts.map +1 -1
  27. package/dist/src/presentation/tui/wizards/github-import.wizard.js +38 -6
  28. package/dist/src/presentation/web/app/actions/list-github-organizations.d.ts +6 -0
  29. package/dist/src/presentation/web/app/actions/list-github-organizations.d.ts.map +1 -0
  30. package/dist/src/presentation/web/app/actions/list-github-organizations.js +17 -0
  31. package/dist/src/presentation/web/app/actions/list-github-repositories.d.ts +1 -0
  32. package/dist/src/presentation/web/app/actions/list-github-repositories.d.ts.map +1 -1
  33. package/dist/src/presentation/web/app/features/feature-tree-page-client.d.ts +6 -0
  34. package/dist/src/presentation/web/app/features/feature-tree-page-client.d.ts.map +1 -0
  35. package/dist/src/presentation/web/app/features/feature-tree-page-client.js +13 -0
  36. package/dist/src/presentation/web/app/features/get-feature-tree-data.d.ts +3 -0
  37. package/dist/src/presentation/web/app/features/get-feature-tree-data.d.ts.map +1 -0
  38. package/dist/src/presentation/web/app/features/get-feature-tree-data.js +40 -0
  39. package/dist/src/presentation/web/app/features/page.d.ts +4 -0
  40. package/dist/src/presentation/web/app/features/page.d.ts.map +1 -0
  41. package/dist/src/presentation/web/app/features/page.js +9 -0
  42. package/dist/src/presentation/web/app/layout.d.ts.map +1 -1
  43. package/dist/src/presentation/web/app/layout.js +3 -1
  44. package/dist/src/presentation/web/components/common/github-import-dialog/github-repo-browser.d.ts +8 -1
  45. package/dist/src/presentation/web/components/common/github-import-dialog/github-repo-browser.d.ts.map +1 -1
  46. package/dist/src/presentation/web/components/common/github-import-dialog/github-repo-browser.js +37 -7
  47. package/dist/src/presentation/web/components/common/github-import-dialog/github-repo-browser.stories.d.ts +1 -0
  48. package/dist/src/presentation/web/components/common/github-import-dialog/github-repo-browser.stories.d.ts.map +1 -1
  49. package/dist/src/presentation/web/components/common/github-import-dialog/github-repo-browser.stories.js +35 -0
  50. package/dist/src/presentation/web/components/features/chat/ChatSheet.d.ts.map +1 -1
  51. package/dist/src/presentation/web/components/features/chat/ChatSheet.js +22 -2
  52. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  53. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +15 -1
  54. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.d.ts +28 -0
  55. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.d.ts.map +1 -0
  56. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.js +176 -0
  57. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.stories.d.ts +11 -0
  58. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.stories.d.ts.map +1 -0
  59. package/dist/src/presentation/web/components/features/feature-tree-table/feature-tree-table.stories.js +140 -0
  60. package/dist/src/presentation/web/components/features/feature-tree-table/index.d.ts +3 -0
  61. package/dist/src/presentation/web/components/features/feature-tree-table/index.d.ts.map +1 -0
  62. package/dist/src/presentation/web/components/features/feature-tree-table/index.js +1 -0
  63. package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
  64. package/dist/src/presentation/web/components/features/settings/settings-page-client.js +9 -2
  65. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  66. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +2 -2
  67. package/dist/src/presentation/web/hooks/fab-layout-context.d.ts +18 -0
  68. package/dist/src/presentation/web/hooks/fab-layout-context.d.ts.map +1 -0
  69. package/dist/src/presentation/web/hooks/fab-layout-context.js +19 -0
  70. package/dist/src/presentation/web/lib/fab-layout.d.ts +11 -0
  71. package/dist/src/presentation/web/lib/fab-layout.d.ts.map +1 -0
  72. package/dist/src/presentation/web/lib/fab-layout.js +21 -0
  73. package/dist/translations/ar/web.json +8 -0
  74. package/dist/translations/de/web.json +8 -0
  75. package/dist/translations/en/web.json +8 -0
  76. package/dist/translations/es/web.json +8 -0
  77. package/dist/translations/fr/web.json +8 -0
  78. package/dist/translations/he/web.json +8 -0
  79. package/dist/translations/pt/web.json +8 -0
  80. package/dist/translations/ru/web.json +8 -0
  81. package/dist/tsconfig.build.tsbuildinfo +1 -1
  82. package/package.json +1 -1
  83. package/web/.next/BUILD_ID +1 -1
  84. package/web/.next/app-path-routes-manifest.json +1 -0
  85. package/web/.next/build-manifest.json +5 -5
  86. package/web/.next/fallback-build-manifest.json +2 -2
  87. package/web/.next/prerender-manifest.json +3 -3
  88. package/web/.next/required-server-files.js +3 -3
  89. package/web/.next/required-server-files.json +3 -3
  90. package/web/.next/routes-manifest.json +6 -0
  91. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/build-manifest.json +3 -3
  92. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +71 -56
  93. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +3 -3
  94. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  95. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  96. package/web/.next/server/app/(dashboard)/@drawer/chat/page/build-manifest.json +3 -3
  97. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +67 -52
  98. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +3 -3
  99. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  100. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  101. package/web/.next/server/app/(dashboard)/@drawer/create/page/build-manifest.json +3 -3
  102. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +73 -58
  103. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +3 -3
  104. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  105. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  106. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/build-manifest.json +3 -3
  107. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +87 -72
  108. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +3 -3
  109. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  110. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  111. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/build-manifest.json +3 -3
  112. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +87 -72
  113. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +3 -3
  114. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  115. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  116. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/build-manifest.json +3 -3
  117. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +67 -52
  118. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +3 -3
  119. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  120. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  121. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/build-manifest.json +3 -3
  122. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +67 -52
  123. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +3 -3
  124. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  125. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  126. package/web/.next/server/app/(dashboard)/chat/page/build-manifest.json +3 -3
  127. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +67 -52
  128. package/web/.next/server/app/(dashboard)/chat/page.js +3 -3
  129. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  130. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  131. package/web/.next/server/app/(dashboard)/create/page/build-manifest.json +3 -3
  132. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +73 -58
  133. package/web/.next/server/app/(dashboard)/create/page.js +3 -3
  134. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  135. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  136. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/build-manifest.json +3 -3
  137. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +87 -72
  138. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +3 -3
  139. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  140. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  141. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/build-manifest.json +3 -3
  142. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +87 -72
  143. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +3 -3
  144. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  145. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  146. package/web/.next/server/app/(dashboard)/page/build-manifest.json +3 -3
  147. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +67 -52
  148. package/web/.next/server/app/(dashboard)/page.js +3 -3
  149. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  150. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  151. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/build-manifest.json +3 -3
  152. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +67 -52
  153. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +3 -3
  154. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  155. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  156. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/build-manifest.json +3 -3
  157. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +67 -52
  158. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +3 -3
  159. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  160. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  161. package/web/.next/server/app/_global-error/page/build-manifest.json +3 -3
  162. package/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  163. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  164. package/web/.next/server/app/_global-error.html +2 -2
  165. package/web/.next/server/app/_global-error.rsc +1 -1
  166. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  167. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  168. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  169. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  170. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  171. package/web/.next/server/app/_not-found/page/build-manifest.json +3 -3
  172. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +25 -10
  173. package/web/.next/server/app/_not-found/page.js +2 -2
  174. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  175. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  176. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  177. package/web/.next/server/app/api/attachments/upload-from-path/route.js +1 -1
  178. package/web/.next/server/app/api/attachments/upload-from-path/route.js.nft.json +1 -1
  179. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  180. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  181. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  182. package/web/.next/server/app/features/page/app-paths-manifest.json +3 -0
  183. package/web/.next/server/app/features/page/build-manifest.json +18 -0
  184. package/web/.next/server/app/features/page/next-font-manifest.json +6 -0
  185. package/web/.next/server/app/features/page/react-loadable-manifest.json +8 -0
  186. package/web/.next/server/app/features/page/server-reference-manifest.json +95 -0
  187. package/web/.next/server/app/features/page.js +18 -0
  188. package/web/.next/server/app/features/page.js.map +5 -0
  189. package/web/.next/server/app/features/page.js.nft.json +1 -0
  190. package/web/.next/server/app/features/page_client-reference-manifest.js +2 -0
  191. package/web/.next/server/app/settings/page/build-manifest.json +3 -3
  192. package/web/.next/server/app/settings/page/server-reference-manifest.json +31 -16
  193. package/web/.next/server/app/settings/page.js +3 -3
  194. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  195. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  196. package/web/.next/server/app/skills/page/build-manifest.json +3 -3
  197. package/web/.next/server/app/skills/page/server-reference-manifest.json +35 -20
  198. package/web/.next/server/app/skills/page.js +2 -2
  199. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  200. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  201. package/web/.next/server/app/tools/page/build-manifest.json +3 -3
  202. package/web/.next/server/app/tools/page/server-reference-manifest.json +35 -20
  203. package/web/.next/server/app/tools/page.js +2 -2
  204. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  205. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  206. package/web/.next/server/app/version/page/build-manifest.json +3 -3
  207. package/web/.next/server/app/version/page/server-reference-manifest.json +25 -10
  208. package/web/.next/server/app/version/page.js +2 -2
  209. package/web/.next/server/app/version/page.js.nft.json +1 -1
  210. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  211. package/web/.next/server/app-paths-manifest.json +1 -0
  212. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  213. package/web/.next/server/chunks/{[root-of-the-server]__ea653642._.js → [root-of-the-server]__a5879003._.js} +2 -2
  214. package/web/.next/server/chunks/{[root-of-the-server]__ea653642._.js.map → [root-of-the-server]__a5879003._.js.map} +1 -1
  215. package/web/.next/server/chunks/[root-of-the-server]__beda892a._.js.map +1 -1
  216. package/web/.next/server/chunks/[root-of-the-server]__cd67a84c._.js.map +1 -1
  217. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  218. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  219. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js +2 -2
  220. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_feature-drawer-client_tsx_e9755fc8._.js.map +1 -1
  221. package/web/.next/server/chunks/ssr/[root-of-the-server]__08c912ab._.js +3 -0
  222. package/web/.next/server/chunks/ssr/[root-of-the-server]__08c912ab._.js.map +1 -0
  223. package/web/.next/server/chunks/ssr/{[root-of-the-server]__b062b383._.js → [root-of-the-server]__0c5452c3._.js} +2 -2
  224. package/web/.next/server/chunks/ssr/[root-of-the-server]__0c5452c3._.js.map +1 -0
  225. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js +4 -0
  226. package/web/.next/server/chunks/ssr/[root-of-the-server]__1f389e5d._.js.map +1 -0
  227. package/web/.next/server/chunks/ssr/[root-of-the-server]__2b3d5020._.js +3 -0
  228. package/web/.next/server/chunks/ssr/[root-of-the-server]__2b3d5020._.js.map +1 -0
  229. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  230. package/web/.next/server/chunks/ssr/[root-of-the-server]__563e4faf._.js +4 -0
  231. package/web/.next/server/chunks/ssr/[root-of-the-server]__563e4faf._.js.map +1 -0
  232. package/web/.next/server/chunks/ssr/{[root-of-the-server]__dffa13c5._.js → [root-of-the-server]__69dd3217._.js} +2 -2
  233. package/web/.next/server/chunks/ssr/{[root-of-the-server]__dffa13c5._.js.map → [root-of-the-server]__69dd3217._.js.map} +1 -1
  234. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js +4 -0
  235. package/web/.next/server/chunks/ssr/[root-of-the-server]__6c7d3936._.js.map +1 -0
  236. package/web/.next/server/chunks/ssr/[root-of-the-server]__6eb2a2b0._.js +1 -1
  237. package/web/.next/server/chunks/ssr/[root-of-the-server]__7ffd3598._.js +4 -0
  238. package/web/.next/server/chunks/ssr/[root-of-the-server]__7ffd3598._.js.map +1 -0
  239. package/web/.next/server/chunks/ssr/[root-of-the-server]__821a11c1._.js +4 -0
  240. package/web/.next/server/chunks/ssr/[root-of-the-server]__821a11c1._.js.map +1 -0
  241. package/web/.next/server/chunks/ssr/{[root-of-the-server]__248ee887._.js → [root-of-the-server]__851f6adb._.js} +2 -2
  242. package/web/.next/server/chunks/ssr/[root-of-the-server]__851f6adb._.js.map +1 -0
  243. package/web/.next/server/chunks/ssr/[root-of-the-server]__98740ee4._.js +4 -0
  244. package/web/.next/server/chunks/ssr/[root-of-the-server]__98740ee4._.js.map +1 -0
  245. package/web/.next/server/chunks/ssr/[root-of-the-server]__b020c17d._.js +4 -0
  246. package/web/.next/server/chunks/ssr/[root-of-the-server]__b020c17d._.js.map +1 -0
  247. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js +4 -0
  248. package/web/.next/server/chunks/ssr/[root-of-the-server]__b7b96453._.js.map +1 -0
  249. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba9f9e11._.js +4 -0
  250. package/web/.next/server/chunks/ssr/[root-of-the-server]__ba9f9e11._.js.map +1 -0
  251. package/web/.next/server/chunks/ssr/[root-of-the-server]__e88da4ee._.js +4 -0
  252. package/web/.next/server/chunks/ssr/[root-of-the-server]__e88da4ee._.js.map +1 -0
  253. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  254. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  255. package/web/.next/server/chunks/ssr/{_9495d50b._.js → _0727935d._.js} +2 -2
  256. package/web/.next/server/chunks/ssr/{_9495d50b._.js.map → _0727935d._.js.map} +1 -1
  257. package/web/.next/server/chunks/ssr/_075fae20._.js +4 -0
  258. package/web/.next/server/chunks/ssr/_075fae20._.js.map +1 -0
  259. package/web/.next/server/chunks/ssr/_0dc06d07._.js.map +1 -1
  260. package/web/.next/server/chunks/ssr/_125c55af._.js +4 -0
  261. package/web/.next/server/chunks/ssr/_125c55af._.js.map +1 -0
  262. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  263. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  264. package/web/.next/server/chunks/ssr/{_bcaea66b._.js → _1879404a._.js} +2 -2
  265. package/web/.next/server/chunks/ssr/_1879404a._.js.map +1 -0
  266. package/web/.next/server/chunks/ssr/{_b9ba2473._.js → _1e08a336._.js} +2 -2
  267. package/web/.next/server/chunks/ssr/_1e08a336._.js.map +1 -0
  268. package/web/.next/server/chunks/ssr/{_73e1eb5f._.js → _20356a51._.js} +2 -2
  269. package/web/.next/server/chunks/ssr/{_73e1eb5f._.js.map → _20356a51._.js.map} +1 -1
  270. package/web/.next/server/chunks/ssr/_22e00a14._.js +4 -0
  271. package/web/.next/server/chunks/ssr/_22e00a14._.js.map +1 -0
  272. package/web/.next/server/chunks/ssr/_4a4709c5._.js +4 -0
  273. package/web/.next/server/chunks/ssr/_4a4709c5._.js.map +1 -0
  274. package/web/.next/server/chunks/ssr/_5119a3df._.js.map +1 -1
  275. package/web/.next/server/chunks/ssr/_560f2971._.js +3 -0
  276. package/web/.next/server/chunks/ssr/_560f2971._.js.map +1 -0
  277. package/web/.next/server/chunks/ssr/_56b9d60f._.js +1 -1
  278. package/web/.next/server/chunks/ssr/_56b9d60f._.js.map +1 -1
  279. package/web/.next/server/chunks/ssr/{_07635b7c._.js → _5cc74284._.js} +2 -2
  280. package/web/.next/server/chunks/ssr/{_07635b7c._.js.map → _5cc74284._.js.map} +1 -1
  281. package/web/.next/server/chunks/ssr/_628621c7._.js +4 -0
  282. package/web/.next/server/chunks/ssr/_628621c7._.js.map +1 -0
  283. package/web/.next/server/chunks/ssr/_68996e5b._.js +3 -0
  284. package/web/.next/server/chunks/ssr/_68996e5b._.js.map +1 -0
  285. package/web/.next/server/chunks/ssr/_8ea88281._.js +3 -0
  286. package/web/.next/server/chunks/ssr/_8ea88281._.js.map +1 -0
  287. package/web/.next/server/chunks/ssr/_9412b27f._.js +4 -0
  288. package/web/.next/server/chunks/ssr/_9412b27f._.js.map +1 -0
  289. package/web/.next/server/chunks/ssr/_a5a5901d._.js +4 -0
  290. package/web/.next/server/chunks/ssr/_a5a5901d._.js.map +1 -0
  291. package/web/.next/server/chunks/ssr/{_ac4a3873._.js → _ae8cf39a._.js} +2 -2
  292. package/web/.next/server/chunks/ssr/{_ac4a3873._.js.map → _ae8cf39a._.js.map} +1 -1
  293. package/web/.next/server/chunks/ssr/_c3f595c6._.js +4 -0
  294. package/web/.next/server/chunks/ssr/_c3f595c6._.js.map +1 -0
  295. package/web/.next/server/chunks/ssr/{_1c309165._.js → _ce97386b._.js} +2 -2
  296. package/web/.next/server/chunks/ssr/_ce97386b._.js.map +1 -0
  297. package/web/.next/server/chunks/ssr/_f1ba9be6._.js +6 -0
  298. package/web/.next/server/chunks/ssr/_f1ba9be6._.js.map +1 -0
  299. package/web/.next/server/chunks/ssr/_f33cd07e._.js +6 -0
  300. package/web/.next/server/chunks/ssr/_f33cd07e._.js.map +1 -0
  301. package/web/.next/server/chunks/ssr/_f535d854._.js +3 -0
  302. package/web/.next/server/chunks/ssr/_f535d854._.js.map +1 -0
  303. package/web/.next/server/chunks/ssr/_f79e241b._.js +3 -0
  304. package/web/.next/server/chunks/ssr/{_3bcda5d7._.js.map → _f79e241b._.js.map} +1 -1
  305. package/web/.next/server/chunks/ssr/_f8b45233._.js +4 -0
  306. package/web/.next/server/chunks/ssr/_f8b45233._.js.map +1 -0
  307. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  308. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  309. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  310. package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js +10 -0
  311. package/web/.next/server/chunks/ssr/src_presentation_web_app_features_feature-tree-page-client_tsx_34c5cbbf._.js.map +1 -0
  312. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js +1 -1
  313. package/web/.next/server/chunks/ssr/src_presentation_web_components_895e5bfa._.js.map +1 -1
  314. package/web/.next/server/chunks/ssr/src_presentation_web_components_common_page-header_index_ts_bdf4db0b._.js +3 -0
  315. package/web/.next/server/chunks/ssr/src_presentation_web_components_common_page-header_index_ts_bdf4db0b._.js.map +1 -0
  316. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  317. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  318. package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_select_tsx_45d6b8ae._.js +3 -0
  319. package/web/.next/server/chunks/ssr/src_presentation_web_components_ui_select_tsx_45d6b8ae._.js.map +1 -0
  320. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js +1 -1
  321. package/web/.next/server/chunks/ssr/translations_23dd5e7e._.js.map +1 -1
  322. package/web/.next/server/middleware-build-manifest.js +3 -3
  323. package/web/.next/server/pages/500.html +2 -2
  324. package/web/.next/server/server-reference-manifest.js +1 -1
  325. package/web/.next/server/server-reference-manifest.json +678 -495
  326. package/web/.next/static/chunks/20f7cc98a013b11c.js +1 -0
  327. package/web/.next/static/chunks/28ae5046faef6cec.js +1 -0
  328. package/web/.next/static/chunks/{d0613380bbaa9a8e.js → 36fc775163f18b69.js} +1 -1
  329. package/web/.next/static/chunks/399a4ab11438b3e3.js +7 -0
  330. package/web/.next/static/chunks/3a5e170cb1cd1e3d.css +1 -0
  331. package/web/.next/static/chunks/3e393d6a78b2ade4.js +1 -0
  332. package/web/.next/static/chunks/4cec255f2754e5ec.js +1 -0
  333. package/web/.next/static/chunks/4d13818d3eb8ef71.js +1 -0
  334. package/web/.next/static/chunks/52355f60ea8362fa.js +8 -0
  335. package/web/.next/static/chunks/5d4a8552d5b6a4a8.js +1 -0
  336. package/web/.next/static/chunks/802cc08a7ad04826.js +1 -0
  337. package/web/.next/static/chunks/83970faa05406450.js +3 -0
  338. package/web/.next/static/chunks/{a81350e847797ff8.js → 9094d63b7dce7929.js} +1 -1
  339. package/web/.next/static/chunks/{2770aabb38d76609.js → 92d2ff419c6808f1.js} +1 -1
  340. package/web/.next/static/chunks/{5281c5a2011132bc.js → 9b00d85b51431418.js} +2 -2
  341. package/web/.next/static/chunks/{192dd30a464572ef.js → a805fe4541d3ddab.js} +1 -1
  342. package/web/.next/static/chunks/bbd04e5805d9f654.js +5 -0
  343. package/web/.next/static/chunks/c3a67566f78b5bc3.js +1 -0
  344. package/web/.next/static/chunks/e779296e738a812b.css +1 -0
  345. package/web/.next/static/chunks/{1db4dfa35a1637ed.js → e854f587f29f8864.js} +1 -1
  346. package/web/.next/static/chunks/{7cd7aef397d53b94.js → f10cbed0a4fe0e76.js} +1 -1
  347. package/web/.next/static/chunks/f998b42b5cddafd6.js +1 -0
  348. package/web/.next/static/chunks/fce43a228cc9b455.js +1 -0
  349. package/web/.next/static/chunks/{turbopack-432ef324fc27240c.js → turbopack-62782e656a49f322.js} +1 -1
  350. package/web/package.json +2 -0
  351. package/web/.next/server/chunks/ssr/[root-of-the-server]__209c9597._.js +0 -4
  352. package/web/.next/server/chunks/ssr/[root-of-the-server]__209c9597._.js.map +0 -1
  353. package/web/.next/server/chunks/ssr/[root-of-the-server]__248ee887._.js.map +0 -1
  354. package/web/.next/server/chunks/ssr/[root-of-the-server]__27301e38._.js +0 -4
  355. package/web/.next/server/chunks/ssr/[root-of-the-server]__27301e38._.js.map +0 -1
  356. package/web/.next/server/chunks/ssr/[root-of-the-server]__56b70465._.js +0 -4
  357. package/web/.next/server/chunks/ssr/[root-of-the-server]__56b70465._.js.map +0 -1
  358. package/web/.next/server/chunks/ssr/[root-of-the-server]__6fecf886._.js +0 -4
  359. package/web/.next/server/chunks/ssr/[root-of-the-server]__6fecf886._.js.map +0 -1
  360. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b0aac03._.js +0 -4
  361. package/web/.next/server/chunks/ssr/[root-of-the-server]__8b0aac03._.js.map +0 -1
  362. package/web/.next/server/chunks/ssr/[root-of-the-server]__8d27866c._.js +0 -4
  363. package/web/.next/server/chunks/ssr/[root-of-the-server]__8d27866c._.js.map +0 -1
  364. package/web/.next/server/chunks/ssr/[root-of-the-server]__9f3504c7._.js +0 -4
  365. package/web/.next/server/chunks/ssr/[root-of-the-server]__9f3504c7._.js.map +0 -1
  366. package/web/.next/server/chunks/ssr/[root-of-the-server]__b062b383._.js.map +0 -1
  367. package/web/.next/server/chunks/ssr/[root-of-the-server]__bd6ed91a._.js +0 -4
  368. package/web/.next/server/chunks/ssr/[root-of-the-server]__bd6ed91a._.js.map +0 -1
  369. package/web/.next/server/chunks/ssr/[root-of-the-server]__c30f1f82._.js +0 -4
  370. package/web/.next/server/chunks/ssr/[root-of-the-server]__c30f1f82._.js.map +0 -1
  371. package/web/.next/server/chunks/ssr/[root-of-the-server]__ee0eaaf9._.js +0 -3
  372. package/web/.next/server/chunks/ssr/[root-of-the-server]__ee0eaaf9._.js.map +0 -1
  373. package/web/.next/server/chunks/ssr/_1c309165._.js.map +0 -1
  374. package/web/.next/server/chunks/ssr/_3a0b989f._.js +0 -6
  375. package/web/.next/server/chunks/ssr/_3a0b989f._.js.map +0 -1
  376. package/web/.next/server/chunks/ssr/_3bcda5d7._.js +0 -3
  377. package/web/.next/server/chunks/ssr/_5f69c13f._.js +0 -4
  378. package/web/.next/server/chunks/ssr/_5f69c13f._.js.map +0 -1
  379. package/web/.next/server/chunks/ssr/_7c5b97c6._.js +0 -4
  380. package/web/.next/server/chunks/ssr/_7c5b97c6._.js.map +0 -1
  381. package/web/.next/server/chunks/ssr/_82c57f10._.js +0 -4
  382. package/web/.next/server/chunks/ssr/_82c57f10._.js.map +0 -1
  383. package/web/.next/server/chunks/ssr/_9c5bd84a._.js +0 -3
  384. package/web/.next/server/chunks/ssr/_9c5bd84a._.js.map +0 -1
  385. package/web/.next/server/chunks/ssr/_a0e3f7e4._.js +0 -4
  386. package/web/.next/server/chunks/ssr/_a0e3f7e4._.js.map +0 -1
  387. package/web/.next/server/chunks/ssr/_b5fc318a._.js +0 -3
  388. package/web/.next/server/chunks/ssr/_b5fc318a._.js.map +0 -1
  389. package/web/.next/server/chunks/ssr/_b9ba2473._.js.map +0 -1
  390. package/web/.next/server/chunks/ssr/_bcaea66b._.js.map +0 -1
  391. package/web/.next/server/chunks/ssr/_ca0aa7f0._.js +0 -4
  392. package/web/.next/server/chunks/ssr/_ca0aa7f0._.js.map +0 -1
  393. package/web/.next/server/chunks/ssr/_cb5a021e._.js +0 -4
  394. package/web/.next/server/chunks/ssr/_cb5a021e._.js.map +0 -1
  395. package/web/.next/server/chunks/ssr/_d86175ae._.js +0 -4
  396. package/web/.next/server/chunks/ssr/_d86175ae._.js.map +0 -1
  397. package/web/.next/server/chunks/ssr/_d8bedf13._.js +0 -4
  398. package/web/.next/server/chunks/ssr/_d8bedf13._.js.map +0 -1
  399. package/web/.next/server/chunks/ssr/_d90b0a06._.js +0 -3
  400. package/web/.next/server/chunks/ssr/_d90b0a06._.js.map +0 -1
  401. package/web/.next/server/chunks/ssr/_fa7efce3._.js +0 -6
  402. package/web/.next/server/chunks/ssr/_fa7efce3._.js.map +0 -1
  403. package/web/.next/static/chunks/04b3e8b2c0b2a310.js +0 -3
  404. package/web/.next/static/chunks/1d980f961818ff68.js +0 -1
  405. package/web/.next/static/chunks/2c9404cf96b0a5a0.js +0 -1
  406. package/web/.next/static/chunks/3deefc76ea55047c.js +0 -1
  407. package/web/.next/static/chunks/40b6bcf1a2de4a0f.js +0 -1
  408. package/web/.next/static/chunks/4864ff06a738d58b.js +0 -1
  409. package/web/.next/static/chunks/63b4954715fc3423.js +0 -1
  410. package/web/.next/static/chunks/672e3da3ad26005b.js +0 -1
  411. package/web/.next/static/chunks/83928a921868a809.js +0 -1
  412. package/web/.next/static/chunks/86c476f04ff32e7b.css +0 -1
  413. package/web/.next/static/chunks/c7e793951b20a67f.js +0 -1
  414. package/web/.next/static/chunks/cb41e1da2ce3a710.js +0 -7
  415. package/web/.next/static/chunks/d2cbeefbc8967b16.js +0 -1
  416. package/web/.next/static/chunks/d6e702c209c413ce.js +0 -5
  417. /package/web/.next/static/{GXMtXdKTjklQ1IkrOohzE → Smr7Fl4Z08vMkbdUva14p}/_buildManifest.js +0 -0
  418. /package/web/.next/static/{GXMtXdKTjklQ1IkrOohzE → Smr7Fl4Z08vMkbdUva14p}/_clientMiddlewareManifest.json +0 -0
  419. /package/web/.next/static/{GXMtXdKTjklQ1IkrOohzE → Smr7Fl4Z08vMkbdUva14p}/_ssgManifest.js +0 -0
@@ -3,12 +3,15 @@
3
3
  *
4
4
  * Interactive TUI wizard that guides users through importing a GitHub repository.
5
5
  * Offers two paths: paste a GitHub URL or browse the user's repositories.
6
+ * Supports browsing repos from multiple organizations.
6
7
  * Returns the selected URL/nameWithOwner and optional destination override.
7
8
  */
8
9
  import { select, input } from '@inquirer/prompts';
9
10
  import { GitHubUrlParseError } from '../../../../packages/core/src/application/ports/output/services/github-repository-service.interface.js';
10
11
  import { getTuiI18n } from '../i18n.js';
11
12
  import { shepTheme } from '../themes/shep.theme.js';
13
+ /** Sentinel value representing the authenticated user's personal account */
14
+ const PERSONAL_OWNER = '__personal__';
12
15
  /**
13
16
  * Format a GitHub repo for display in the select list.
14
17
  * Shows name, visibility badge, and truncated description.
@@ -27,14 +30,15 @@ function formatRepoChoice(repo) {
27
30
  * Steps:
28
31
  * 1. Choose import method (URL input or browse repos)
29
32
  * 2a. If URL: prompt for URL, validate with parseGitHubUrl
30
- * 2b. If browse: fetch repos via listUseCase, display select list
33
+ * 2b. If browse: optionally select an org, then fetch repos via listUseCase, display select list
31
34
  * 3. Optionally prompt for destination directory override
32
35
  *
33
36
  * @param gitHubService - Service for URL validation
34
37
  * @param listUseCase - Use case for listing user repos
38
+ * @param listOrgsUseCase - Use case for listing user's organizations
35
39
  * @returns The selected import target and optional destination
36
40
  */
37
- export async function githubImportWizard(gitHubService, listUseCase) {
41
+ export async function githubImportWizard(gitHubService, listUseCase, listOrgsUseCase) {
38
42
  // Step 1: Choose import method
39
43
  const t = getTuiI18n().t;
40
44
  const method = await select({
@@ -58,7 +62,7 @@ export async function githubImportWizard(gitHubService, listUseCase) {
58
62
  url = await promptForUrl(gitHubService);
59
63
  }
60
64
  else {
61
- url = await promptForBrowse(listUseCase);
65
+ url = await promptForBrowse(listUseCase, listOrgsUseCase);
62
66
  }
63
67
  // Step 3: Optional destination override
64
68
  const dest = await promptForDestination();
@@ -97,11 +101,39 @@ async function promptForUrl(gitHubService) {
97
101
  }
98
102
  /**
99
103
  * Prompt the user to browse and select from their GitHub repositories.
100
- * Fetches repos via the list use case and displays them in a select prompt.
104
+ * If organizations are available, first prompts the user to select an owner.
101
105
  */
102
- async function promptForBrowse(listUseCase) {
103
- const repos = await listUseCase.execute({ limit: 30 });
106
+ async function promptForBrowse(listUseCase, listOrgsUseCase) {
104
107
  const t = getTuiI18n().t;
108
+ let owner;
109
+ // Try to load organizations for the owner selector
110
+ if (listOrgsUseCase) {
111
+ try {
112
+ const orgs = await listOrgsUseCase.execute();
113
+ if (orgs.length > 0) {
114
+ const ownerChoices = [
115
+ { name: 'My repositories', value: PERSONAL_OWNER },
116
+ ...orgs.map((org) => ({
117
+ name: org.login,
118
+ value: org.login,
119
+ description: org.description || undefined,
120
+ })),
121
+ ];
122
+ const selectedOwner = await select({
123
+ message: 'Select account',
124
+ choices: ownerChoices,
125
+ theme: shepTheme,
126
+ });
127
+ if (selectedOwner !== PERSONAL_OWNER) {
128
+ owner = selectedOwner;
129
+ }
130
+ }
131
+ }
132
+ catch {
133
+ // Org listing failure is non-critical — proceed with personal repos
134
+ }
135
+ }
136
+ const repos = await listUseCase.execute({ limit: 30, owner });
105
137
  if (repos.length === 0) {
106
138
  throw new Error(t('tui:wizards.githubImport.noRepos'));
107
139
  }
@@ -0,0 +1,6 @@
1
+ import type { GitHubOrganization } from '../../../../../packages/core/src/application/ports/output/services/github-repository-service.interface.js';
2
+ export declare function listGitHubOrganizations(): Promise<{
3
+ orgs?: GitHubOrganization[];
4
+ error?: string;
5
+ }>;
6
+ //# sourceMappingURL=list-github-organizations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-github-organizations.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/list-github-organizations.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oFAAoF,CAAC;AAG7H,wBAAsB,uBAAuB,IAAI,OAAO,CAAC;IACvD,IAAI,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAYD"}
@@ -0,0 +1,17 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ import { GitHubAuthError } from '../../../../../packages/core/src/application/ports/output/services/github-repository-service.interface.js';
4
+ export async function listGitHubOrganizations() {
5
+ try {
6
+ const useCase = resolve('ListGitHubOrganizationsUseCase');
7
+ const orgs = await useCase.execute();
8
+ return { orgs };
9
+ }
10
+ catch (error) {
11
+ if (error instanceof GitHubAuthError) {
12
+ return { error: 'GitHub CLI is not authenticated. Run `gh auth login` to sign in.' };
13
+ }
14
+ const message = error instanceof Error ? error.message : 'Failed to list organizations';
15
+ return { error: message };
16
+ }
17
+ }
@@ -2,6 +2,7 @@ import type { GitHubRepo } from '../../../../../packages/core/src/application/po
2
2
  interface ListGitHubRepositoriesInput {
3
3
  search?: string;
4
4
  limit?: number;
5
+ owner?: string;
5
6
  }
6
7
  export declare function listGitHubRepositories(input?: ListGitHubRepositoriesInput): Promise<{
7
8
  repos?: GitHubRepo[];
@@ -1 +1 @@
1
- {"version":3,"file":"list-github-repositories.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/list-github-repositories.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oFAAoF,CAAC;AAGrH,UAAU,2BAA2B;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,CAAC,EAAE,2BAA2B,GAClC,OAAO,CAAC;IAAE,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAYnD"}
1
+ {"version":3,"file":"list-github-repositories.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/list-github-repositories.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oFAAoF,CAAC;AAGrH,UAAU,2BAA2B;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,CAAC,EAAE,2BAA2B,GAClC,OAAO,CAAC;IAAE,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAYnD"}
@@ -0,0 +1,6 @@
1
+ import type { FeatureTreeRow } from '../../components/features/feature-tree-table/index.js';
2
+ export interface FeatureTreePageClientProps {
3
+ features: FeatureTreeRow[];
4
+ }
5
+ export declare function FeatureTreePageClient({ features }: FeatureTreePageClientProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=feature-tree-page-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-tree-page-client.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/features/feature-tree-page-client.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAG/E,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,EAAE,0BAA0B,2CAkB7E"}
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useRouter } from 'next/navigation';
4
+ import { useCallback } from 'react';
5
+ import { FeatureTreeTable } from '../../components/features/feature-tree-table/index.js';
6
+ import { PageHeader } from '../../components/common/page-header/index.js';
7
+ export function FeatureTreePageClient({ features }) {
8
+ const router = useRouter();
9
+ const handleFeatureClick = useCallback((featureId) => {
10
+ router.push(`/feature/${featureId}/overview`);
11
+ }, [router]);
12
+ return (_jsxs("div", { "data-testid": "feature-tree-page", className: "flex h-full flex-col gap-4", children: [_jsx(PageHeader, { title: "Features", description: "All features organized as a tree view" }), _jsx("div", { className: "min-h-0 flex-1", children: _jsx(FeatureTreeTable, { data: features, onFeatureClick: handleFeatureClick }) })] }));
13
+ }
@@ -0,0 +1,3 @@
1
+ import type { FeatureTreeRow } from '../../components/features/feature-tree-table/index.js';
2
+ export declare function getFeatureTreeData(): Promise<FeatureTreeRow[]>;
3
+ //# sourceMappingURL=get-feature-tree-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-feature-tree-data.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/features/get-feature-tree-data.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAwB/E,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAuBpE"}
@@ -0,0 +1,40 @@
1
+ import { resolve } from '../../lib/server-container.js';
2
+ import { SdlcLifecycle } from '../../../../../packages/core/src/domain/generated/output.js';
3
+ const LIFECYCLE_TO_STATUS = {
4
+ [SdlcLifecycle.Started]: 'pending',
5
+ [SdlcLifecycle.Analyze]: 'in-progress',
6
+ [SdlcLifecycle.Requirements]: 'action-needed',
7
+ [SdlcLifecycle.Research]: 'in-progress',
8
+ [SdlcLifecycle.Planning]: 'in-progress',
9
+ [SdlcLifecycle.Implementation]: 'in-progress',
10
+ [SdlcLifecycle.Review]: 'action-needed',
11
+ [SdlcLifecycle.Maintain]: 'done',
12
+ [SdlcLifecycle.Blocked]: 'blocked',
13
+ [SdlcLifecycle.Pending]: 'pending',
14
+ [SdlcLifecycle.Deleting]: 'blocked',
15
+ [SdlcLifecycle.AwaitingUpstream]: 'action-needed',
16
+ [SdlcLifecycle.Archived]: 'done',
17
+ };
18
+ function lifecycleToStatus(lifecycle) {
19
+ return LIFECYCLE_TO_STATUS[lifecycle] ?? 'pending';
20
+ }
21
+ export async function getFeatureTreeData() {
22
+ const listFeatures = resolve('ListFeaturesUseCase');
23
+ const listRepos = resolve('ListRepositoriesUseCase');
24
+ const [features, repositories] = await Promise.all([listFeatures.execute(), listRepos.execute()]);
25
+ const repoNameByPath = new Map();
26
+ for (const repo of repositories) {
27
+ repoNameByPath.set(repo.path, repo.name);
28
+ }
29
+ return features.map((feature) => ({
30
+ id: feature.id,
31
+ name: feature.name,
32
+ status: lifecycleToStatus(feature.lifecycle),
33
+ lifecycle: feature.lifecycle,
34
+ branch: feature.branch,
35
+ repositoryName: repoNameByPath.get(feature.repositoryPath) ??
36
+ feature.repositoryPath.split('/').pop() ??
37
+ feature.repositoryPath,
38
+ parentId: feature.parentId ?? undefined,
39
+ }));
40
+ }
@@ -0,0 +1,4 @@
1
+ /** Skip static pre-rendering since we need runtime DI container and server context. */
2
+ export declare const dynamic = "force-dynamic";
3
+ export default function FeaturesPage(): Promise<import("react/jsx-runtime").JSX.Element>;
4
+ //# sourceMappingURL=page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/features/page.tsx"],"names":[],"mappings":"AAGA,uFAAuF;AACvF,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,wBAA8B,YAAY,qDAQzC"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { FeatureTreePageClient } from './feature-tree-page-client.js';
3
+ import { getFeatureTreeData } from './get-feature-tree-data.js';
4
+ /** Skip static pre-rendering since we need runtime DI container and server context. */
5
+ export const dynamic = 'force-dynamic';
6
+ export default async function FeaturesPage() {
7
+ const features = await getFeatureTreeData();
8
+ return (_jsx("div", { className: "features-page-dotted-bg flex h-full flex-col p-6", children: _jsx(FeatureTreePageClient, { features: features }) }));
9
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/layout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAErC,OAAO,6BAA6B,CAAC;AACrC,OAAO,2CAA2C,CAAC;AACnD,OAAO,eAAe,CAAC;AASvB,sFAAsF;AACtF,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,eAAO,MAAM,QAAQ,EAAE,QAkBtB,CAAC;AAEF,wBAA8B,UAAU,CAAC,EACvC,QAAQ,GACT,EAAE,QAAQ,CAAC;IACV,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC,oDA2BD"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/layout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAErC,OAAO,6BAA6B,CAAC;AACrC,OAAO,2CAA2C,CAAC;AACnD,OAAO,eAAe,CAAC;AAWvB,sFAAsF;AACtF,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,eAAO,MAAM,QAAQ,EAAE,QAkBtB,CAAC;AAEF,wBAA8B,UAAU,CAAC,EACvC,QAAQ,GACT,EAAE,QAAQ,CAAC;IACV,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC,oDA6BD"}
@@ -6,7 +6,9 @@ import './globals.css';
6
6
  import { AppShell } from '../components/layouts/app-shell/index.js';
7
7
  import { Toaster } from '../components/ui/sonner.js';
8
8
  import { getFeatureFlags } from '../lib/feature-flags.js';
9
+ import { getFabLayout } from '../lib/fab-layout.js';
9
10
  import { FeatureFlagsProvider } from '../hooks/feature-flags-context.js';
11
+ import { FabLayoutProvider } from '../hooks/fab-layout-context.js';
10
12
  import { QueryProvider } from '../components/providers/query-provider.js';
11
13
  import { I18nProvider } from '../components/providers/i18n-provider.js';
12
14
  import { getLanguagePreference } from '../lib/language.js';
@@ -36,5 +38,5 @@ export default async function RootLayout({ children, }) {
36
38
  const { language, dir } = getLanguagePreference();
37
39
  return (_jsxs("html", { lang: language, dir: dir, suppressHydrationWarning: true, children: [_jsx("head", { children: _jsx("script", { dangerouslySetInnerHTML: {
38
40
  __html: `(function(){try{var d=document.documentElement,t=localStorage.getItem('shep-theme'),s=window.matchMedia('(prefers-color-scheme: dark)').matches;if(t==='dark'||(t==='system'&&s)||(!t&&s)){d.classList.add('dark')}}catch(e){}})();`,
39
- } }) }), _jsxs("body", { className: "min-h-screen antialiased", children: [_jsx(I18nProvider, { initialLanguage: language, children: _jsx(QueryProvider, { children: _jsx(FeatureFlagsProvider, { flags: getFeatureFlags(), children: _jsx(AppShell, { sidebarOpen: sidebarOpen, children: children }) }) }) }), _jsx(Toaster, { position: "bottom-center" })] })] }));
41
+ } }) }), _jsxs("body", { className: "min-h-screen antialiased", children: [_jsx(I18nProvider, { initialLanguage: language, children: _jsx(QueryProvider, { children: _jsx(FeatureFlagsProvider, { flags: getFeatureFlags(), children: _jsx(FabLayoutProvider, { layout: getFabLayout(), children: _jsx(AppShell, { sidebarOpen: sidebarOpen, children: children }) }) }) }) }), _jsx(Toaster, { position: "bottom-center" })] })] }));
40
42
  }
@@ -1,4 +1,5 @@
1
1
  import type { GitHubRepo } from '../../../../../../packages/core/src/application/ports/output/services/github-repository-service.interface.js';
2
+ import type { GitHubOrganization } from '../../../../../../packages/core/src/application/ports/output/services/github-repository-service.interface.js';
2
3
  export interface GitHubRepoBrowserProps {
3
4
  onSelect: (nameWithOwner: string) => void;
4
5
  loading?: boolean;
@@ -6,10 +7,16 @@ export interface GitHubRepoBrowserProps {
6
7
  fetchRepos?: (input?: {
7
8
  search?: string;
8
9
  limit?: number;
10
+ owner?: string;
9
11
  }) => Promise<{
10
12
  repos?: GitHubRepo[];
11
13
  error?: string;
12
14
  }>;
15
+ /** Override the fetch function for testing/stories */
16
+ fetchOrgs?: () => Promise<{
17
+ orgs?: GitHubOrganization[];
18
+ error?: string;
19
+ }>;
13
20
  }
14
- export declare function GitHubRepoBrowser({ onSelect, loading: externalLoading, fetchRepos, }: GitHubRepoBrowserProps): import("react/jsx-runtime").JSX.Element;
21
+ export declare function GitHubRepoBrowser({ onSelect, loading: externalLoading, fetchRepos, fetchOrgs, }: GitHubRepoBrowserProps): import("react/jsx-runtime").JSX.Element;
15
22
  //# sourceMappingURL=github-repo-browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"github-repo-browser.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/github-import-dialog/github-repo-browser.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oFAAoF,CAAC;AAErH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,KAAK,OAAO,CAAC;QAAE,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD;AAED,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,OAAO,EAAE,eAAuB,EAChC,UAAmC,GACpC,EAAE,sBAAsB,2CAsIxB"}
1
+ {"version":3,"file":"github-repo-browser.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/github-import-dialog/github-repo-browser.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oFAAoF,CAAC;AACrH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oFAAoF,CAAC;AAK7H,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,KAAK,OAAO,CAAC;QAAE,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5E;AAED,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,OAAO,EAAE,eAAuB,EAChC,UAAmC,EACnC,SAAmC,GACpC,EAAE,sBAAsB,2CA+KxB"}
@@ -5,18 +5,44 @@ import { Lock, Globe, Loader2, Search, AlertCircle } from 'lucide-react';
5
5
  import { Input } from '../../ui/input.js';
6
6
  import { Badge } from '../../ui/badge.js';
7
7
  import { Skeleton } from '../../ui/skeleton.js';
8
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../ui/select.js';
8
9
  import { listGitHubRepositories } from '../../../app/actions/list-github-repositories.js';
9
- export function GitHubRepoBrowser({ onSelect, loading: externalLoading = false, fetchRepos = listGitHubRepositories, }) {
10
+ import { listGitHubOrganizations } from '../../../app/actions/list-github-organizations.js';
11
+ /** Sentinel value representing the authenticated user's personal account */
12
+ const PERSONAL_OWNER = '__personal__';
13
+ export function GitHubRepoBrowser({ onSelect, loading: externalLoading = false, fetchRepos = listGitHubRepositories, fetchOrgs = listGitHubOrganizations, }) {
10
14
  const [repos, setRepos] = useState([]);
15
+ const [orgs, setOrgs] = useState([]);
11
16
  const [fetching, setFetching] = useState(true);
12
17
  const [error, setError] = useState('');
13
18
  const [search, setSearch] = useState('');
19
+ const [selectedOwner, setSelectedOwner] = useState(PERSONAL_OWNER);
14
20
  const debounceRef = useRef(null);
15
- const fetchData = useCallback(async (searchTerm) => {
21
+ // Fetch organizations on mount
22
+ useEffect(() => {
23
+ async function loadOrgs() {
24
+ try {
25
+ const result = await fetchOrgs();
26
+ if (result.orgs) {
27
+ setOrgs(result.orgs);
28
+ }
29
+ }
30
+ catch {
31
+ // Org listing failure is non-critical — user can still browse personal repos
32
+ }
33
+ }
34
+ loadOrgs();
35
+ }, [fetchOrgs]);
36
+ const fetchData = useCallback(async (searchTerm, owner) => {
16
37
  setFetching(true);
17
38
  setError('');
18
39
  try {
19
- const result = await fetchRepos(searchTerm ? { search: searchTerm } : undefined);
40
+ const input = {};
41
+ if (searchTerm)
42
+ input.search = searchTerm;
43
+ if (owner && owner !== PERSONAL_OWNER)
44
+ input.owner = owner;
45
+ const result = await fetchRepos(Object.keys(input).length > 0 ? input : undefined);
20
46
  if (result.error) {
21
47
  setError(result.error);
22
48
  setRepos([]);
@@ -34,19 +60,23 @@ export function GitHubRepoBrowser({ onSelect, loading: externalLoading = false,
34
60
  }
35
61
  }, [fetchRepos]);
36
62
  useEffect(() => {
37
- fetchData();
38
- }, [fetchData]);
63
+ fetchData(search || undefined, selectedOwner);
64
+ }, [fetchData, selectedOwner]); // eslint-disable-line react-hooks/exhaustive-deps
39
65
  function handleSearchChange(value) {
40
66
  setSearch(value);
41
67
  if (debounceRef.current)
42
68
  clearTimeout(debounceRef.current);
43
69
  debounceRef.current = setTimeout(() => {
44
- fetchData(value || undefined);
70
+ fetchData(value || undefined, selectedOwner);
45
71
  }, 300);
46
72
  }
73
+ function handleOwnerChange(value) {
74
+ setSelectedOwner(value);
75
+ setSearch('');
76
+ }
47
77
  const disabled = externalLoading;
48
78
  if (error && !fetching) {
49
79
  return (_jsxs("div", { className: "flex flex-col items-center gap-2 py-8 text-center", "data-testid": "repo-browser-error", children: [_jsx(AlertCircle, { className: "text-destructive h-8 w-8" }), _jsx("p", { className: "text-destructive text-sm", children: error })] }));
50
80
  }
51
- return (_jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" }), _jsx(Input, { placeholder: "Search repositories...", value: search, onChange: (e) => handleSearchChange(e.target.value), className: "ps-9", disabled: disabled, "aria-label": "Search repositories" })] }), _jsx("div", { className: "max-h-64 overflow-x-hidden overflow-y-auto rounded-md border", role: "listbox", "aria-label": "GitHub repositories", children: fetching ? (_jsx("div", { className: "flex flex-col gap-2 p-3", "data-testid": "repo-browser-loading", children: Array.from({ length: 5 }).map((_, i) => (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Skeleton, { className: "h-4 w-48" }), _jsx(Skeleton, { className: "h-3 w-72" })] }, `skeleton-${String(i)}`))) })) : repos.length === 0 ? (_jsx("div", { className: "text-muted-foreground py-8 text-center text-sm", "data-testid": "repo-browser-empty", children: "No repositories found" })) : (repos.map((repo) => (_jsxs("button", { type: "button", role: "option", "aria-selected": false, className: "hover:bg-accent flex w-full items-start gap-2 border-b px-3 py-2.5 text-start last:border-b-0 disabled:opacity-50", onClick: () => onSelect(repo.nameWithOwner), disabled: disabled, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "truncate text-sm font-medium", children: repo.nameWithOwner }), _jsx(Badge, { variant: repo.isPrivate ? 'secondary' : 'outline', className: "shrink-0 text-xs", children: repo.isPrivate ? (_jsxs(_Fragment, { children: [_jsx(Lock, { className: "me-1 h-3 w-3" }), "Private"] })) : (_jsxs(_Fragment, { children: [_jsx(Globe, { className: "me-1 h-3 w-3" }), "Public"] })) })] }), repo.description ? (_jsx("p", { className: "text-muted-foreground mt-0.5 truncate text-xs", children: repo.description })) : null] }), disabled ? _jsx(Loader2, { className: "mt-0.5 h-4 w-4 shrink-0 animate-spin" }) : null] }, repo.nameWithOwner)))) })] }));
81
+ return (_jsxs("div", { className: "flex flex-col gap-3", children: [orgs.length > 0 ? (_jsxs(Select, { value: selectedOwner, onValueChange: handleOwnerChange, disabled: disabled, children: [_jsx(SelectTrigger, { "aria-label": "Select owner", children: _jsx(SelectValue, { placeholder: "Select owner" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: PERSONAL_OWNER, children: "My repositories" }), orgs.map((org) => (_jsx(SelectItem, { value: org.login, children: org.login }, org.login)))] })] })) : null, _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" }), _jsx(Input, { placeholder: "Search repositories...", value: search, onChange: (e) => handleSearchChange(e.target.value), className: "ps-9", disabled: disabled, "aria-label": "Search repositories" })] }), _jsx("div", { className: "max-h-64 overflow-x-hidden overflow-y-auto rounded-md border", role: "listbox", "aria-label": "GitHub repositories", children: fetching ? (_jsx("div", { className: "flex flex-col gap-2 p-3", "data-testid": "repo-browser-loading", children: Array.from({ length: 5 }).map((_, i) => (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Skeleton, { className: "h-4 w-48" }), _jsx(Skeleton, { className: "h-3 w-72" })] }, `skeleton-${String(i)}`))) })) : repos.length === 0 ? (_jsx("div", { className: "text-muted-foreground py-8 text-center text-sm", "data-testid": "repo-browser-empty", children: "No repositories found" })) : (repos.map((repo) => (_jsxs("button", { type: "button", role: "option", "aria-selected": false, className: "hover:bg-accent flex w-full items-start gap-2 border-b px-3 py-2.5 text-start last:border-b-0 disabled:opacity-50", onClick: () => onSelect(repo.nameWithOwner), disabled: disabled, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "truncate text-sm font-medium", children: repo.nameWithOwner }), _jsx(Badge, { variant: repo.isPrivate ? 'secondary' : 'outline', className: "shrink-0 text-xs", children: repo.isPrivate ? (_jsxs(_Fragment, { children: [_jsx(Lock, { className: "me-1 h-3 w-3" }), "Private"] })) : (_jsxs(_Fragment, { children: [_jsx(Globe, { className: "me-1 h-3 w-3" }), "Public"] })) })] }), repo.description ? (_jsx("p", { className: "text-muted-foreground mt-0.5 truncate text-xs", children: repo.description })) : null] }), disabled ? _jsx(Loader2, { className: "mt-0.5 h-4 w-4 shrink-0 animate-spin" }) : null] }, repo.nameWithOwner)))) })] }));
52
82
  }
@@ -4,6 +4,7 @@ declare const meta: Meta<typeof GitHubRepoBrowser>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof GitHubRepoBrowser>;
6
6
  export declare const Default: Story;
7
+ export declare const WithOrganizations: Story;
7
8
  export declare const Loading: Story;
8
9
  export declare const Empty: Story;
9
10
  export declare const Error: Story;
@@ -1 +1 @@
1
- {"version":3,"file":"github-repo-browser.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/github-import-dialog/github-repo-browser.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAyC1D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,iBAAiB,CAiBxC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEhD,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAInB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAOnB,CAAC"}
1
+ {"version":3,"file":"github-repo-browser.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/github-import-dialog/github-repo-browser.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAgE1D,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,iBAAiB,CAiBxC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEhD,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,KAU/B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAKnB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAQnB,CAAC"}
@@ -38,6 +38,26 @@ const mockRepos = [
38
38
  pushedAt: '2025-03-11T09:00:00Z',
39
39
  },
40
40
  ];
41
+ const mockOrgRepos = [
42
+ {
43
+ name: 'platform',
44
+ nameWithOwner: 'acme-corp/platform',
45
+ description: 'Core platform monorepo',
46
+ isPrivate: true,
47
+ pushedAt: '2025-03-15T10:00:00Z',
48
+ },
49
+ {
50
+ name: 'design-system',
51
+ nameWithOwner: 'acme-corp/design-system',
52
+ description: 'Shared design system components',
53
+ isPrivate: false,
54
+ pushedAt: '2025-03-14T08:00:00Z',
55
+ },
56
+ ];
57
+ const mockOrgs = [
58
+ { login: 'acme-corp', description: 'Acme Corporation' },
59
+ { login: 'open-source-collective', description: 'Open source projects' },
60
+ ];
41
61
  const meta = {
42
62
  title: 'Composed/GitHubRepoBrowser',
43
63
  component: GitHubRepoBrowser,
@@ -56,17 +76,31 @@ export default meta;
56
76
  export const Default = {
57
77
  args: {
58
78
  fetchRepos: () => Promise.resolve({ repos: mockRepos }),
79
+ fetchOrgs: () => Promise.resolve({ orgs: [] }),
80
+ },
81
+ };
82
+ export const WithOrganizations = {
83
+ args: {
84
+ fetchRepos: (input) => {
85
+ if (input?.owner === 'acme-corp') {
86
+ return Promise.resolve({ repos: mockOrgRepos });
87
+ }
88
+ return Promise.resolve({ repos: mockRepos });
89
+ },
90
+ fetchOrgs: () => Promise.resolve({ orgs: mockOrgs }),
59
91
  },
60
92
  };
61
93
  export const Loading = {
62
94
  args: {
63
95
  // eslint-disable-next-line @typescript-eslint/no-empty-function
64
96
  fetchRepos: () => new Promise(() => { }), // never resolves
97
+ fetchOrgs: () => Promise.resolve({ orgs: [] }),
65
98
  },
66
99
  };
67
100
  export const Empty = {
68
101
  args: {
69
102
  fetchRepos: () => Promise.resolve({ repos: [] }),
103
+ fetchOrgs: () => Promise.resolve({ orgs: [] }),
70
104
  },
71
105
  };
72
106
  export const Error = {
@@ -74,5 +108,6 @@ export const Error = {
74
108
  fetchRepos: () => Promise.resolve({
75
109
  error: 'GitHub CLI is not authenticated. Run `gh auth login` to sign in.',
76
110
  }),
111
+ fetchOrgs: () => Promise.resolve({ orgs: [] }),
77
112
  },
78
113
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ChatSheet.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatSheet.tsx"],"names":[],"mappings":"AAyDA,wBAAgB,eAAe,4CAkY9B"}
1
+ {"version":3,"file":"ChatSheet.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/chat/ChatSheet.tsx"],"names":[],"mappings":"AA2DA,wBAAgB,eAAe,4CAwY9B"}
@@ -8,6 +8,8 @@ import { Button } from '../../ui/button.js';
8
8
  import { ChatTab } from './ChatTab.js';
9
9
  import { ChatDotIndicator } from './ChatDotIndicator.js';
10
10
  import { useTurnStatus } from '../../../hooks/turn-statuses-provider.js';
11
+ import { useFabLayout } from '../../../hooks/fab-layout-context.js';
12
+ import { useSidebar } from '../../ui/sidebar.js';
11
13
  // ── Persistent global chat popup (draggable + resizable) ──────────────────
12
14
  const DEFAULT_W = 520;
13
15
  const DEFAULT_H_VH = 70; // percentage of viewport height
@@ -48,6 +50,8 @@ export function GlobalChatPopup() {
48
50
  const [hasOpened, setHasOpened] = useState(false);
49
51
  const [isMaximized, setIsMaximized] = useState(false);
50
52
  const globalChatTurnStatus = useTurnStatus('global');
53
+ const { swapPosition } = useFabLayout();
54
+ const { state: sidebarState } = useSidebar();
51
55
  // Position/size — initialized from localStorage
52
56
  // eslint-disable-next-line react/hook-use-state -- wrapped setters below
53
57
  const [pos, setPosRaw] = useState(() => loadPersistedState().pos);
@@ -229,7 +233,7 @@ export function GlobalChatPopup() {
229
233
  };
230
234
  return (_jsxs(_Fragment, { children: [hasOpened ? (_jsxs("div", { ref: panelRef, className: cn(isMaximized
231
235
  ? 'bg-background fixed inset-0 z-[60] flex flex-col overflow-hidden dark:bg-neutral-900'
232
- : cn(!pos && 'fixed end-8 bottom-24', 'z-[60] flex flex-col overflow-hidden rounded-lg', 'border-border/60 border dark:border-white/10', 'bg-background dark:bg-neutral-900', 'shadow-[0_8px_40px_-8px_rgba(0,0,0,0.2)] dark:shadow-[0_8px_40px_-8px_rgba(0,0,0,0.6)]'), 'transition-opacity duration-300 ease-out', isOpen ? 'pointer-events-auto opacity-100' : 'pointer-events-none opacity-0'), style: panelStyle, children: [!isMaximized ? (_jsx("div", { className: "h-[2px] shrink-0 bg-gradient-to-r from-transparent via-violet-500/50 to-transparent" })) : null, !isMaximized ? (_jsx("div", { onMouseDown: onResizeStart, className: "absolute end-0 top-0 z-10 h-4 w-4 cursor-ne-resize" })) : null, _jsxs("div", { onMouseDown: isMaximized ? undefined : onDragStart, className: cn('relative flex h-11 shrink-0 items-center gap-2.5 border-b border-black/[0.06] px-3.5 dark:border-white/[0.06]', !isMaximized && 'cursor-grab active:cursor-grabbing'), children: [_jsx("div", { className: "from-foreground/[0.02] to-foreground/[0.02] pointer-events-none absolute inset-0 bg-gradient-to-r via-transparent" }), !isMaximized ? (_jsx(GripVertical, { className: "text-foreground/15 relative h-3.5 w-3.5 shrink-0" })) : null, _jsx("div", { className: "relative flex h-5 w-5 items-center justify-center", children: _jsx(Bot, { className: "text-foreground/50 h-4 w-4" }) }), _jsxs("div", { className: "relative flex items-baseline gap-2", children: [_jsx("span", { className: "text-foreground/90 text-base font-bold tracking-tight", children: "Shep" }), _jsx("span", { className: "text-foreground/30 text-xs font-medium tracking-widest uppercase", children: "global" })] }), _jsxs("div", { className: "relative ms-auto flex items-center gap-0.5", children: [_jsx("button", { type: "button", onClick: toggleMaximize, className: "text-foreground/30 hover:text-foreground/60 rounded-md p-1 transition-colors", title: isMaximized ? 'Restore (⌘⇧M)' : 'Maximize (⌘⇧M)', children: isMaximized ? (_jsx(Minimize2, { className: "h-3.5 w-3.5" })) : (_jsx(Maximize2, { className: "h-3.5 w-3.5" })) }), _jsx("button", { type: "button", onClick: handleClose, className: "text-foreground/30 hover:text-foreground/60 rounded-md p-1 transition-colors", title: "Close (\u2318\u21E7K)", children: _jsx(X, { className: "h-3.5 w-3.5" }) })] })] }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: _jsx(ChatTab, { featureId: "global" }) }), !isMaximized ? (_jsx("div", { onMouseDown: (e) => {
236
+ : cn(!pos && (swapPosition ? 'fixed start-8 bottom-24' : 'fixed end-8 bottom-24'), 'z-[60] flex flex-col overflow-hidden rounded-lg', 'border-border/60 border dark:border-white/10', 'bg-background dark:bg-neutral-900', 'shadow-[0_8px_40px_-8px_rgba(0,0,0,0.2)] dark:shadow-[0_8px_40px_-8px_rgba(0,0,0,0.6)]'), 'transition-opacity duration-300 ease-out', isOpen ? 'pointer-events-auto opacity-100' : 'pointer-events-none opacity-0'), style: panelStyle, children: [!isMaximized ? (_jsx("div", { className: "h-[2px] shrink-0 bg-gradient-to-r from-transparent via-violet-500/50 to-transparent" })) : null, !isMaximized ? (_jsx("div", { onMouseDown: onResizeStart, className: "absolute end-0 top-0 z-10 h-4 w-4 cursor-ne-resize" })) : null, _jsxs("div", { onMouseDown: isMaximized ? undefined : onDragStart, className: cn('relative flex h-11 shrink-0 items-center gap-2.5 border-b border-black/[0.06] px-3.5 dark:border-white/[0.06]', !isMaximized && 'cursor-grab active:cursor-grabbing'), children: [_jsx("div", { className: "from-foreground/[0.02] to-foreground/[0.02] pointer-events-none absolute inset-0 bg-gradient-to-r via-transparent" }), !isMaximized ? (_jsx(GripVertical, { className: "text-foreground/15 relative h-3.5 w-3.5 shrink-0" })) : null, _jsx("div", { className: "relative flex h-5 w-5 items-center justify-center", children: _jsx(Bot, { className: "text-foreground/50 h-4 w-4" }) }), _jsxs("div", { className: "relative flex items-baseline gap-2", children: [_jsx("span", { className: "text-foreground/90 text-base font-bold tracking-tight", children: "Shep" }), _jsx("span", { className: "text-foreground/30 text-xs font-medium tracking-widest uppercase", children: "global" })] }), _jsxs("div", { className: "relative ms-auto flex items-center gap-0.5", children: [_jsx("button", { type: "button", onClick: toggleMaximize, className: "text-foreground/30 hover:text-foreground/60 rounded-md p-1 transition-colors", title: isMaximized ? 'Restore (⌘⇧M)' : 'Maximize (⌘⇧M)', children: isMaximized ? (_jsx(Minimize2, { className: "h-3.5 w-3.5" })) : (_jsx(Maximize2, { className: "h-3.5 w-3.5" })) }), _jsx("button", { type: "button", onClick: handleClose, className: "text-foreground/30 hover:text-foreground/60 rounded-md p-1 transition-colors", title: "Close (\u2318\u21E7K)", children: _jsx(X, { className: "h-3.5 w-3.5" }) })] })] }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: _jsx(ChatTab, { featureId: "global" }) }), !isMaximized ? (_jsx("div", { onMouseDown: (e) => {
233
237
  e.preventDefault();
234
238
  e.stopPropagation();
235
239
  const panel = panelRef.current;
@@ -255,7 +259,23 @@ export function GlobalChatPopup() {
255
259
  };
256
260
  document.addEventListener('mousemove', onMove);
257
261
  document.addEventListener('mouseup', onUp);
258
- }, className: "absolute end-0 bottom-0 z-10 h-4 w-4 cursor-se-resize" })) : null] })) : null, _jsxs("div", { className: cn('group/fab fixed end-8 bottom-6 z-30', isMaximized && 'hidden'), children: [_jsxs(Button, { size: "icon", onClick: toggle, className: cn('relative h-14 w-14 rounded-full shadow-lg', 'transition-all duration-200 hover:scale-105 hover:shadow-xl active:scale-95', isOpen
262
+ }, className: "absolute end-0 bottom-0 z-10 h-4 w-4 cursor-se-resize" })) : null] })) : null, _jsxs(ChatFabWrapper, { swapPosition: swapPosition, sidebarState: sidebarState, isMaximized: isMaximized, children: [_jsxs(Button, { size: "icon", onClick: toggle, className: cn('relative h-14 w-14 rounded-full shadow-lg', 'transition-all duration-200 hover:scale-105 hover:shadow-xl active:scale-95', isOpen
259
263
  ? 'bg-violet-600 text-white hover:bg-violet-500'
260
264
  : 'bg-violet-500 text-white hover:bg-violet-400 dark:bg-violet-500 dark:hover:bg-violet-400'), children: [_jsx(MessageSquare, { className: cn('absolute h-7 w-7 stroke-[2.5] transition-all duration-200', isOpen ? 'scale-0 rotate-90 opacity-0' : 'scale-100 rotate-0 opacity-100') }), _jsx(X, { className: cn('absolute h-6 w-6 stroke-[2.5] transition-all duration-200', isOpen ? 'scale-100 rotate-0 opacity-100' : 'scale-0 -rotate-90 opacity-0') }), !isOpen && _jsx(ChatDotIndicator, { status: globalChatTurnStatus, className: "end-0 top-0" })] }), _jsx("div", { className: "pointer-events-none absolute bottom-[calc(100%+8px)] left-1/2 -translate-x-1/2 translate-y-1 opacity-0 transition-all duration-200 group-hover/fab:translate-y-0 group-hover/fab:opacity-100", children: _jsxs("div", { className: "bg-foreground rounded-lg px-3 py-1.5 text-center shadow-lg", children: [_jsx("p", { className: "text-background text-xs font-medium whitespace-nowrap", children: t('chat.shepChat') }), _jsxs("p", { className: "text-background/50 mt-0.5 flex items-center justify-center gap-1 text-[10px]", children: [_jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "\u2318" }), _jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "\u21E7" }), _jsx("kbd", { className: "bg-background/15 rounded px-1 py-px font-mono", children: "K" })] })] }) })] })] }));
261
265
  }
266
+ /** Wrapper for the Chat FAB that handles position swapping. */
267
+ function ChatFabWrapper({ swapPosition, sidebarState, isMaximized, children, }) {
268
+ const { i18n } = useTranslation('web');
269
+ const isRtl = i18n.dir() === 'rtl';
270
+ if (!swapPosition) {
271
+ return (_jsx("div", { className: cn('group/fab fixed end-8 bottom-6 z-30', isMaximized && 'hidden'), children: children }));
272
+ }
273
+ // Swapped: chat FAB moves to start side, tracking sidebar width
274
+ const sidebarOffset = sidebarState === 'expanded'
275
+ ? 'calc(var(--sidebar-width) + 32px)'
276
+ : 'calc(var(--sidebar-width-icon) + 32px)';
277
+ const positionStyle = isRtl
278
+ ? { right: sidebarOffset, transition: 'right 200ms ease-in-out' }
279
+ : { left: sidebarOffset, transition: 'left 200ms ease-in-out' };
280
+ return (_jsx("div", { className: cn('group/fab fixed bottom-6 z-30', isMaximized && 'hidden'), style: positionStyle, children: children }));
281
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAIpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AA+B5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CA+czF"}
1
+ {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAIpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAgC5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CA+czF"}
@@ -16,6 +16,7 @@ import { useSoundAction } from '../../../hooks/use-sound-action.js';
16
16
  import { useDrawerCloseGuard } from '../../../hooks/drawer-close-guard.js';
17
17
  import { useViewportPersistence } from '../../../hooks/use-viewport-persistence.js';
18
18
  import { useSidebar } from '../../ui/sidebar.js';
19
+ import { useFabLayout } from '../../../hooks/fab-layout-context.js';
19
20
  import { ControlCenterEmptyState } from './control-center-empty-state.js';
20
21
  import { useControlCenterState } from './use-control-center-state.js';
21
22
  const AUTO_FOCUS_OPTIONS = {
@@ -353,11 +354,24 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
353
354
  const canvasToolbar = (_jsx(CanvasToolbar, { showArchived: showArchived, onToggleArchived: () => setShowArchived(!showArchived), onResetViewport: resetViewport }));
354
355
  return (_jsxs(_Fragment, { children: [_jsx(FeaturesCanvas, { nodes: showCanvas ? displayNodes : [], edges: showCanvas ? edges : [], selectedFeatureId: selectedFeatureId, selectedRepository: selectedRepository, defaultViewport: defaultViewport, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeClick: handleNodeClick, onPaneClick: handleClearDrawers, onMoveEnd: handleMoveEnd, toolbar: canvasToolbar, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: addRepoAndFocus }) }), showCanvas ? _jsx(CreateFab, { actions: fabActions }) : null] }));
355
356
  }
356
- /** (+) FAB that tracks sidebar width via CSS var + transition. */
357
+ /** (+) FAB that tracks sidebar width via CSS var + transition.
358
+ * When fabLayout.swapPosition is true, moves to the end side (right in LTR). */
357
359
  function CreateFab({ actions }) {
358
360
  const { state } = useSidebar();
359
361
  const { i18n } = useTranslation('web');
362
+ const { swapPosition } = useFabLayout();
360
363
  const isRtl = i18n.dir() === 'rtl';
364
+ // Default: start side (left in LTR), tracking sidebar width
365
+ // Swapped: end side (right in LTR), fixed 32px from edge
366
+ if (swapPosition) {
367
+ const positionStyle = isRtl
368
+ ? {
369
+ left: 'calc(var(--sidebar-width-icon) + 32px)',
370
+ transition: 'left 200ms ease-in-out',
371
+ }
372
+ : { right: '32px', transition: 'right 200ms ease-in-out' };
373
+ return (_jsx(FloatingActionButton, { actions: actions, className: "!fixed bottom-6", style: positionStyle }));
374
+ }
361
375
  // Sidebar expanded = var(--sidebar-width) = 16rem, collapsed = var(--sidebar-width-icon) = 3rem
362
376
  // Position just outside the sidebar edge with 16px gap
363
377
  const offset = state === 'expanded'
@@ -0,0 +1,28 @@
1
+ import type { FeatureStatus } from '../../common/feature-status-config.js';
2
+ import './feature-tree-table.css';
3
+ export interface FeatureTreeRow {
4
+ id: string;
5
+ name: string;
6
+ status: FeatureStatus;
7
+ lifecycle: string;
8
+ branch: string;
9
+ repositoryName: string;
10
+ parentId?: string;
11
+ /** Child rows for tree hierarchy */
12
+ _children?: FeatureTreeRow[];
13
+ /** Whether this row is a repository group header */
14
+ _isRepoGroup?: boolean;
15
+ }
16
+ export interface FeatureTreeTableProps {
17
+ data: FeatureTreeRow[];
18
+ className?: string;
19
+ onFeatureClick?: (featureId: string) => void;
20
+ }
21
+ /**
22
+ * Build tree-structured data grouped by repository.
23
+ * Each repository becomes a parent node with its features as children.
24
+ * Features that have parent-child relationships are nested within their repository group.
25
+ */
26
+ export declare function buildTreeData(flatData: FeatureTreeRow[]): FeatureTreeRow[];
27
+ export declare function FeatureTreeTable({ data, className, onFeatureClick }: FeatureTreeTableProps): import("react/jsx-runtime").JSX.Element;
28
+ //# sourceMappingURL=feature-tree-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-tree-table.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/feature-tree-table/feature-tree-table.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC/E,OAAO,0BAA0B,CAAC;AAElC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,oDAAoD;IACpD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAyED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CA4D1E;AAED,wBAAgB,gBAAgB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE,qBAAqB,2CAiD1F"}