create-principles-disciple 1.146.3 → 1.146.6

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 (311) hide show
  1. package/_release/product-identity.json +1 -1
  2. package/console/dist/web/assets/app.js +26 -26
  3. package/console/package.json +1 -1
  4. package/package.json +3 -3
  5. package/pd-cli/package.json +1 -1
  6. package/release-manager/package.json +3 -3
  7. package/console/dist/ui/App.d.ts +0 -1
  8. package/console/dist/ui/App.js +0 -172
  9. package/console/dist/ui/api.d.ts +0 -611
  10. package/console/dist/ui/api.js +0 -1094
  11. package/console/dist/ui/components/auth/login-form.d.ts +0 -4
  12. package/console/dist/ui/components/auth/login-form.js +0 -142
  13. package/console/dist/ui/components/auth/splash-screen.d.ts +0 -9
  14. package/console/dist/ui/components/auth/splash-screen.js +0 -22
  15. package/console/dist/ui/components/error-boundary.d.ts +0 -15
  16. package/console/dist/ui/components/error-boundary.js +0 -30
  17. package/console/dist/ui/components/focus/daily-thought-card.d.ts +0 -1
  18. package/console/dist/ui/components/focus/daily-thought-card.js +0 -41
  19. package/console/dist/ui/components/language-switcher.d.ts +0 -2
  20. package/console/dist/ui/components/language-switcher.js +0 -17
  21. package/console/dist/ui/components/layout/app-sidebar.d.ts +0 -27
  22. package/console/dist/ui/components/layout/app-sidebar.js +0 -128
  23. package/console/dist/ui/components/layout/page-loading.d.ts +0 -13
  24. package/console/dist/ui/components/layout/page-loading.js +0 -14
  25. package/console/dist/ui/components/layout/page-shell.d.ts +0 -12
  26. package/console/dist/ui/components/layout/page-shell.js +0 -11
  27. package/console/dist/ui/components/layout/section-title.d.ts +0 -10
  28. package/console/dist/ui/components/layout/section-title.js +0 -9
  29. package/console/dist/ui/components/notifications/NotificationProvider.d.ts +0 -14
  30. package/console/dist/ui/components/notifications/NotificationProvider.js +0 -136
  31. package/console/dist/ui/components/notifications/favicon-badge.d.ts +0 -3
  32. package/console/dist/ui/components/notifications/favicon-badge.js +0 -68
  33. package/console/dist/ui/components/notifications/notification-reducer.d.ts +0 -9
  34. package/console/dist/ui/components/notifications/notification-reducer.js +0 -9
  35. package/console/dist/ui/components/notifications/sound-storage.d.ts +0 -3
  36. package/console/dist/ui/components/notifications/sound-storage.js +0 -37
  37. package/console/dist/ui/components/notifications/useNotifications.d.ts +0 -1
  38. package/console/dist/ui/components/notifications/useNotifications.js +0 -9
  39. package/console/dist/ui/components/onboarding/CircuitDiagram.d.ts +0 -8
  40. package/console/dist/ui/components/onboarding/CircuitDiagram.js +0 -18
  41. package/console/dist/ui/components/onboarding/DemoResultView.d.ts +0 -22
  42. package/console/dist/ui/components/onboarding/DemoResultView.js +0 -33
  43. package/console/dist/ui/components/onboarding/SlashCommandsCard.d.ts +0 -16
  44. package/console/dist/ui/components/onboarding/SlashCommandsCard.js +0 -20
  45. package/console/dist/ui/components/onboarding/slashCommands.d.ts +0 -20
  46. package/console/dist/ui/components/onboarding/slashCommands.js +0 -22
  47. package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.d.ts +0 -6
  48. package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.js +0 -66
  49. package/console/dist/ui/components/theme-provider.d.ts +0 -14
  50. package/console/dist/ui/components/theme-provider.js +0 -40
  51. package/console/dist/ui/components/theme-toggle.d.ts +0 -2
  52. package/console/dist/ui/components/theme-toggle.js +0 -11
  53. package/console/dist/ui/components/ui/alert-dialog.d.ts +0 -20
  54. package/console/dist/ui/components/ui/alert-dialog.js +0 -26
  55. package/console/dist/ui/components/ui/badge.d.ts +0 -9
  56. package/console/dist/ui/components/ui/badge.js +0 -22
  57. package/console/dist/ui/components/ui/button.d.ts +0 -11
  58. package/console/dist/ui/components/ui/button.js +0 -34
  59. package/console/dist/ui/components/ui/card.d.ts +0 -8
  60. package/console/dist/ui/components/ui/card.js +0 -16
  61. package/console/dist/ui/components/ui/charts.d.ts +0 -51
  62. package/console/dist/ui/components/ui/charts.js +0 -72
  63. package/console/dist/ui/components/ui/dialog.d.ts +0 -19
  64. package/console/dist/ui/components/ui/dialog.js +0 -22
  65. package/console/dist/ui/components/ui/input.d.ts +0 -3
  66. package/console/dist/ui/components/ui/input.js +0 -8
  67. package/console/dist/ui/components/ui/markdown.d.ts +0 -24
  68. package/console/dist/ui/components/ui/markdown.js +0 -119
  69. package/console/dist/ui/components/ui/progress-bar.d.ts +0 -20
  70. package/console/dist/ui/components/ui/progress-bar.js +0 -38
  71. package/console/dist/ui/components/ui/select.d.ts +0 -13
  72. package/console/dist/ui/components/ui/select.js +0 -26
  73. package/console/dist/ui/components/ui/separator.d.ts +0 -3
  74. package/console/dist/ui/components/ui/separator.js +0 -6
  75. package/console/dist/ui/components/ui/sheet.d.ts +0 -25
  76. package/console/dist/ui/components/ui/sheet.js +0 -37
  77. package/console/dist/ui/components/ui/shiny-text.d.ts +0 -28
  78. package/console/dist/ui/components/ui/shiny-text.js +0 -46
  79. package/console/dist/ui/components/ui/skeleton.d.ts +0 -3
  80. package/console/dist/ui/components/ui/skeleton.js +0 -6
  81. package/console/dist/ui/components/ui/sonner.d.ts +0 -3
  82. package/console/dist/ui/components/ui/sonner.js +0 -13
  83. package/console/dist/ui/components/ui/tooltip.d.ts +0 -7
  84. package/console/dist/ui/components/ui/tooltip.js +0 -10
  85. package/console/dist/ui/data/daily-thoughts.d.ts +0 -15
  86. package/console/dist/ui/data/daily-thoughts.js +0 -164
  87. package/console/dist/ui/hooks/useNotificationSound.d.ts +0 -12
  88. package/console/dist/ui/hooks/useNotificationSound.js +0 -74
  89. package/console/dist/ui/i18n/en.json +0 -2399
  90. package/console/dist/ui/i18n/index.d.ts +0 -2
  91. package/console/dist/ui/i18n/index.js +0 -32
  92. package/console/dist/ui/i18n/zh-CN.json +0 -2399
  93. package/console/dist/ui/main.d.ts +0 -1
  94. package/console/dist/ui/main.js +0 -9
  95. package/console/dist/ui/pages/ReportProblemValidators.d.ts +0 -144
  96. package/console/dist/ui/pages/ReportProblemValidators.js +0 -418
  97. package/console/dist/ui/pages/activation/ActivationPage.d.ts +0 -1
  98. package/console/dist/ui/pages/activation/ActivationPage.js +0 -512
  99. package/console/dist/ui/pages/activation/ActivationValidators.d.ts +0 -20
  100. package/console/dist/ui/pages/activation/ActivationValidators.js +0 -160
  101. package/console/dist/ui/pages/control-center/AgentCard.d.ts +0 -31
  102. package/console/dist/ui/pages/control-center/AgentCard.js +0 -212
  103. package/console/dist/ui/pages/control-center/AgentGroup.d.ts +0 -26
  104. package/console/dist/ui/pages/control-center/AgentGroup.js +0 -38
  105. package/console/dist/ui/pages/control-center/ControlCenterPage.d.ts +0 -1
  106. package/console/dist/ui/pages/control-center/ControlCenterPage.js +0 -509
  107. package/console/dist/ui/pages/control-center/DesignGatePanel.d.ts +0 -1
  108. package/console/dist/ui/pages/control-center/DesignGatePanel.js +0 -137
  109. package/console/dist/ui/pages/control-center/RuntimeProfileManager.d.ts +0 -31
  110. package/console/dist/ui/pages/control-center/RuntimeProfileManager.js +0 -199
  111. package/console/dist/ui/pages/control-center/WorkflowDiagram.d.ts +0 -17
  112. package/console/dist/ui/pages/control-center/WorkflowDiagram.js +0 -55
  113. package/console/dist/ui/pages/debt/DebtPage.d.ts +0 -2
  114. package/console/dist/ui/pages/debt/DebtPage.js +0 -222
  115. package/console/dist/ui/pages/design-system/DesignSystemPage.d.ts +0 -2
  116. package/console/dist/ui/pages/design-system/DesignSystemPage.js +0 -30
  117. package/console/dist/ui/pages/examiner/ExaminerPage.d.ts +0 -15
  118. package/console/dist/ui/pages/examiner/ExaminerPage.js +0 -158
  119. package/console/dist/ui/pages/failed-tasks/FailedTasksPage.d.ts +0 -1
  120. package/console/dist/ui/pages/failed-tasks/FailedTasksPage.js +0 -421
  121. package/console/dist/ui/pages/focus/ApprovalSubjectReading.d.ts +0 -24
  122. package/console/dist/ui/pages/focus/ApprovalSubjectReading.js +0 -133
  123. package/console/dist/ui/pages/focus/FocusPage.d.ts +0 -123
  124. package/console/dist/ui/pages/focus/FocusPage.js +0 -567
  125. package/console/dist/ui/pages/focus/OwnerDecisionCard.d.ts +0 -9
  126. package/console/dist/ui/pages/focus/OwnerDecisionCard.js +0 -111
  127. package/console/dist/ui/pages/focus/OwnerWorkbench.d.ts +0 -19
  128. package/console/dist/ui/pages/focus/OwnerWorkbench.js +0 -75
  129. package/console/dist/ui/pages/focus/RuleCandidateBindingPanel.d.ts +0 -34
  130. package/console/dist/ui/pages/focus/RuleCandidateBindingPanel.js +0 -298
  131. package/console/dist/ui/pages/focus/focus-validation.d.ts +0 -40
  132. package/console/dist/ui/pages/focus/focus-validation.js +0 -211
  133. package/console/dist/ui/pages/intent/IntentOnboarding.d.ts +0 -67
  134. package/console/dist/ui/pages/intent/IntentOnboarding.js +0 -289
  135. package/console/dist/ui/pages/intent/IntentPage.d.ts +0 -1
  136. package/console/dist/ui/pages/intent/IntentPage.js +0 -252
  137. package/console/dist/ui/pages/pain/PainEvidenceValidators.d.ts +0 -59
  138. package/console/dist/ui/pages/pain/PainEvidenceValidators.js +0 -125
  139. package/console/dist/ui/pages/pain/PainPage.d.ts +0 -1
  140. package/console/dist/ui/pages/pain/PainPage.js +0 -420
  141. package/console/dist/ui/pages/pain/pain-card-helpers.d.ts +0 -175
  142. package/console/dist/ui/pages/pain/pain-card-helpers.js +0 -181
  143. package/console/dist/ui/pages/principles/CorePrinciplesPage.d.ts +0 -10
  144. package/console/dist/ui/pages/principles/CorePrinciplesPage.js +0 -59
  145. package/console/dist/ui/pages/principles/PrincipleDetailPage.d.ts +0 -60
  146. package/console/dist/ui/pages/principles/PrincipleDetailPage.js +0 -602
  147. package/console/dist/ui/pages/principles/PrinciplesPage.d.ts +0 -1
  148. package/console/dist/ui/pages/principles/PrinciplesPage.js +0 -327
  149. package/console/dist/ui/pages/principles/PrinciplesViewNav.d.ts +0 -8
  150. package/console/dist/ui/pages/principles/PrinciplesViewNav.js +0 -15
  151. package/console/dist/ui/pages/report-problem/ReportProblemPage.d.ts +0 -1
  152. package/console/dist/ui/pages/report-problem/ReportProblemPage.js +0 -467
  153. package/console/dist/ui/pages/settings/SettingsPage.d.ts +0 -4
  154. package/console/dist/ui/pages/settings/SettingsPage.js +0 -457
  155. package/console/dist/ui/pages/settings/UpdatePage.d.ts +0 -1
  156. package/console/dist/ui/pages/settings/UpdatePage.js +0 -215
  157. package/console/dist/ui/pages/welcome/WelcomePage.d.ts +0 -5
  158. package/console/dist/ui/pages/welcome/WelcomePage.js +0 -187
  159. package/console/dist/ui/utils/agent-metadata.d.ts +0 -71
  160. package/console/dist/ui/utils/agent-metadata.js +0 -284
  161. package/console/dist/ui/utils/approval-review.d.ts +0 -30
  162. package/console/dist/ui/utils/approval-review.js +0 -50
  163. package/console/dist/ui/utils/approval-warning-localization.d.ts +0 -34
  164. package/console/dist/ui/utils/approval-warning-localization.js +0 -148
  165. package/console/dist/ui/utils/attention-presentation.d.ts +0 -35
  166. package/console/dist/ui/utils/attention-presentation.js +0 -46
  167. package/console/dist/ui/utils/blocker-localization.d.ts +0 -23
  168. package/console/dist/ui/utils/blocker-localization.js +0 -36
  169. package/console/dist/ui/utils/control-center-helpers.d.ts +0 -79
  170. package/console/dist/ui/utils/control-center-helpers.js +0 -189
  171. package/console/dist/ui/utils/enum-labels.d.ts +0 -50
  172. package/console/dist/ui/utils/enum-labels.js +0 -171
  173. package/console/dist/ui/utils/format-date.d.ts +0 -11
  174. package/console/dist/ui/utils/format-date.js +0 -17
  175. package/console/dist/ui/utils/onboarding-state.d.ts +0 -25
  176. package/console/dist/ui/utils/onboarding-state.js +0 -77
  177. package/console/dist/ui/utils/reading-layout.d.ts +0 -20
  178. package/console/dist/ui/utils/reading-layout.js +0 -46
  179. package/console/dist/ui/utils/rule-binding-validators.d.ts +0 -13
  180. package/console/dist/ui/utils/rule-binding-validators.js +0 -188
  181. package/console/dist/ui/utils/runtime-mode.d.ts +0 -11
  182. package/console/dist/ui/utils/runtime-mode.js +0 -11
  183. package/console/dist/ui/utils/token-storage.d.ts +0 -22
  184. package/console/dist/ui/utils/token-storage.js +0 -47
  185. package/console/dist/ui/utils/validators.d.ts +0 -1178
  186. package/console/dist/ui/utils/validators.js +0 -3297
  187. package/release-manager/dist/bootstrap-entry.d.ts +0 -2
  188. package/release-manager/dist/bootstrap-entry.d.ts.map +0 -1
  189. package/release-manager/dist/bootstrap-entry.js.map +0 -1
  190. package/release-manager/dist/i18n.d.ts +0 -6
  191. package/release-manager/dist/i18n.d.ts.map +0 -1
  192. package/release-manager/dist/i18n.js.map +0 -1
  193. package/release-manager/dist/index.d.ts +0 -7
  194. package/release-manager/dist/index.d.ts.map +0 -1
  195. package/release-manager/dist/index.js +0 -656
  196. package/release-manager/dist/index.js.map +0 -1
  197. package/release-manager/dist/installer.d.ts +0 -629
  198. package/release-manager/dist/installer.d.ts.map +0 -1
  199. package/release-manager/dist/installer.js.map +0 -1
  200. package/release-manager/dist/installers/codex-host-installer.d.ts +0 -39
  201. package/release-manager/dist/installers/codex-host-installer.d.ts.map +0 -1
  202. package/release-manager/dist/installers/codex-host-installer.js.map +0 -1
  203. package/release-manager/dist/installers/index.d.ts +0 -51
  204. package/release-manager/dist/installers/index.d.ts.map +0 -1
  205. package/release-manager/dist/installers/index.js.map +0 -1
  206. package/release-manager/dist/installers/openclaw-host-installer.d.ts +0 -14
  207. package/release-manager/dist/installers/openclaw-host-installer.d.ts.map +0 -1
  208. package/release-manager/dist/installers/openclaw-host-installer.js.map +0 -1
  209. package/release-manager/dist/installers/workbuddy-host-installer.d.ts +0 -335
  210. package/release-manager/dist/installers/workbuddy-host-installer.d.ts.map +0 -1
  211. package/release-manager/dist/installers/workbuddy-host-installer.js.map +0 -1
  212. package/release-manager/dist/mvp-config.d.ts +0 -233
  213. package/release-manager/dist/mvp-config.d.ts.map +0 -1
  214. package/release-manager/dist/mvp-config.js.map +0 -1
  215. package/release-manager/dist/prompts.d.ts +0 -43
  216. package/release-manager/dist/prompts.d.ts.map +0 -1
  217. package/release-manager/dist/prompts.js +0 -268
  218. package/release-manager/dist/prompts.js.map +0 -1
  219. package/release-manager/dist/skill-language.d.ts +0 -32
  220. package/release-manager/dist/skill-language.d.ts.map +0 -1
  221. package/release-manager/dist/skill-language.js.map +0 -1
  222. package/release-manager/dist/uninstaller.d.ts +0 -68
  223. package/release-manager/dist/uninstaller.d.ts.map +0 -1
  224. package/release-manager/dist/uninstaller.js +0 -746
  225. package/release-manager/dist/uninstaller.js.map +0 -1
  226. package/release-manager/dist/update/apply-payload.d.ts +0 -143
  227. package/release-manager/dist/update/apply-payload.d.ts.map +0 -1
  228. package/release-manager/dist/update/apply-payload.js.map +0 -1
  229. package/release-manager/dist/update/atomic-file.d.ts +0 -35
  230. package/release-manager/dist/update/atomic-file.d.ts.map +0 -1
  231. package/release-manager/dist/update/atomic-file.js.map +0 -1
  232. package/release-manager/dist/update/bootstrap-executor.d.ts +0 -21
  233. package/release-manager/dist/update/bootstrap-executor.d.ts.map +0 -1
  234. package/release-manager/dist/update/bootstrap-executor.js.map +0 -1
  235. package/release-manager/dist/update/bootstrap-protocol.d.ts +0 -56
  236. package/release-manager/dist/update/bootstrap-protocol.d.ts.map +0 -1
  237. package/release-manager/dist/update/bootstrap-protocol.js.map +0 -1
  238. package/release-manager/dist/update/channel-metadata.d.ts +0 -28
  239. package/release-manager/dist/update/channel-metadata.d.ts.map +0 -1
  240. package/release-manager/dist/update/channel-metadata.js.map +0 -1
  241. package/release-manager/dist/update/channel-promotion.d.ts +0 -39
  242. package/release-manager/dist/update/channel-promotion.d.ts.map +0 -1
  243. package/release-manager/dist/update/channel-promotion.js +0 -55
  244. package/release-manager/dist/update/channel-promotion.js.map +0 -1
  245. package/release-manager/dist/update/console-surface.d.ts +0 -19
  246. package/release-manager/dist/update/console-surface.d.ts.map +0 -1
  247. package/release-manager/dist/update/console-surface.js.map +0 -1
  248. package/release-manager/dist/update/data-compatibility.d.ts +0 -35
  249. package/release-manager/dist/update/data-compatibility.d.ts.map +0 -1
  250. package/release-manager/dist/update/data-compatibility.js +0 -45
  251. package/release-manager/dist/update/data-compatibility.js.map +0 -1
  252. package/release-manager/dist/update/install-layout.d.ts +0 -105
  253. package/release-manager/dist/update/install-layout.d.ts.map +0 -1
  254. package/release-manager/dist/update/install-layout.js.map +0 -1
  255. package/release-manager/dist/update/product-identity.d.ts +0 -70
  256. package/release-manager/dist/update/product-identity.d.ts.map +0 -1
  257. package/release-manager/dist/update/product-identity.js.map +0 -1
  258. package/release-manager/dist/update/release-asset-manifest.d.ts +0 -31
  259. package/release-manager/dist/update/release-asset-manifest.d.ts.map +0 -1
  260. package/release-manager/dist/update/release-asset-manifest.js.map +0 -1
  261. package/release-manager/dist/update/release-identity.d.ts +0 -33
  262. package/release-manager/dist/update/release-identity.d.ts.map +0 -1
  263. package/release-manager/dist/update/release-identity.js.map +0 -1
  264. package/release-manager/dist/update/release-manager-authority.d.ts +0 -39
  265. package/release-manager/dist/update/release-manager-authority.d.ts.map +0 -1
  266. package/release-manager/dist/update/release-manager-authority.js.map +0 -1
  267. package/release-manager/dist/update/release-manager.d.ts +0 -156
  268. package/release-manager/dist/update/release-manager.d.ts.map +0 -1
  269. package/release-manager/dist/update/release-manager.js.map +0 -1
  270. package/release-manager/dist/update/release-metadata-publisher.d.ts +0 -199
  271. package/release-manager/dist/update/release-metadata-publisher.d.ts.map +0 -1
  272. package/release-manager/dist/update/release-metadata-publisher.js +0 -478
  273. package/release-manager/dist/update/release-metadata-publisher.js.map +0 -1
  274. package/release-manager/dist/update/release-metadata-source.d.ts +0 -85
  275. package/release-manager/dist/update/release-metadata-source.d.ts.map +0 -1
  276. package/release-manager/dist/update/release-metadata-source.js.map +0 -1
  277. package/release-manager/dist/update/release-metadata.d.ts +0 -60
  278. package/release-manager/dist/update/release-metadata.d.ts.map +0 -1
  279. package/release-manager/dist/update/release-metadata.js.map +0 -1
  280. package/release-manager/dist/update/release-policy.d.ts +0 -51
  281. package/release-manager/dist/update/release-policy.d.ts.map +0 -1
  282. package/release-manager/dist/update/release-policy.js.map +0 -1
  283. package/release-manager/dist/update/rollback-policy.d.ts +0 -56
  284. package/release-manager/dist/update/rollback-policy.d.ts.map +0 -1
  285. package/release-manager/dist/update/rollback-policy.js +0 -61
  286. package/release-manager/dist/update/rollback-policy.js.map +0 -1
  287. package/release-manager/dist/update/transaction-journal.d.ts +0 -212
  288. package/release-manager/dist/update/transaction-journal.d.ts.map +0 -1
  289. package/release-manager/dist/update/transaction-journal.js.map +0 -1
  290. package/release-manager/dist/update/trust-metadata.d.ts +0 -55
  291. package/release-manager/dist/update/trust-metadata.d.ts.map +0 -1
  292. package/release-manager/dist/update/trust-metadata.js.map +0 -1
  293. package/release-manager/dist/update/trust-root-provisioning.d.ts +0 -99
  294. package/release-manager/dist/update/trust-root-provisioning.d.ts.map +0 -1
  295. package/release-manager/dist/update/trust-root-provisioning.js.map +0 -1
  296. package/release-manager/dist/update/update-history.d.ts +0 -46
  297. package/release-manager/dist/update/update-history.d.ts.map +0 -1
  298. package/release-manager/dist/update/update-history.js +0 -123
  299. package/release-manager/dist/update/update-history.js.map +0 -1
  300. package/release-manager/dist/utils/config-file-io.d.ts +0 -34
  301. package/release-manager/dist/utils/config-file-io.d.ts.map +0 -1
  302. package/release-manager/dist/utils/config-file-io.js.map +0 -1
  303. package/release-manager/dist/utils/env.d.ts +0 -94
  304. package/release-manager/dist/utils/env.d.ts.map +0 -1
  305. package/release-manager/dist/utils/env.js.map +0 -1
  306. package/release-manager/dist/utils/logger.d.ts +0 -15
  307. package/release-manager/dist/utils/logger.d.ts.map +0 -1
  308. package/release-manager/dist/utils/logger.js.map +0 -1
  309. package/release-manager/dist/utils/workspace-divergence.d.ts +0 -36
  310. package/release-manager/dist/utils/workspace-divergence.d.ts.map +0 -1
  311. package/release-manager/dist/utils/workspace-divergence.js.map +0 -1
@@ -1,467 +0,0 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect, useCallback, useMemo } from "react";
3
- import { useSearchParams } from "react-router-dom";
4
- import { useTranslation } from "react-i18next";
5
- import { toast } from "sonner";
6
- import { PageShell } from "../../components/layout/page-shell.js";
7
- import { PageLoading } from "../../components/layout/page-loading.js";
8
- import { SectionTitle } from "../../components/layout/section-title.js";
9
- import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from "../../components/ui/dialog.js";
10
- import { createFeedbackReport, listFeedbackReports, getFeedbackReport, deleteFeedbackReport, fetchConfigSummary, fetchFeedbackChannels, submitFeedbackReport, markFeedbackReportSent, request, } from "../../api.js";
11
- import { enumLabel } from "../../utils/enum-labels.js";
12
- import { parseDraftRecord, parseDraftSummary, parseEnvelopeReport, getErrorMessage, buildFeedbackContextFromSearchParams, buildFeedbackDiagnostics, deriveFeedbackArea, } from "../ReportProblemValidators.js";
13
- const INITIAL_FORM = {
14
- type: "bug",
15
- title: "",
16
- description: "",
17
- stepsToReproduce: "",
18
- expectedBehavior: "",
19
- actualBehavior: "",
20
- frequency: undefined,
21
- blockingLevel: undefined,
22
- goal: "",
23
- stuckAt: "",
24
- job: "",
25
- currentWorkaround: "",
26
- sawWhat: "",
27
- whereSeen: "",
28
- submitting: false,
29
- };
30
- const FEEDBACK_TYPES = ["bug", "confusing", "privacy_concern", "feature_request", "other"];
31
- const VALID_FEEDBACK_TYPES = new Set(FEEDBACK_TYPES);
32
- const FREQUENCY_OPTIONS = ["always", "often", "sometimes", "once"];
33
- const BLOCKING_OPTIONS = ["blocked", "workaround", "minor"];
34
- const VALID_FREQUENCIES = new Set(FREQUENCY_OPTIONS);
35
- const VALID_BLOCKING = new Set(BLOCKING_OPTIONS);
36
- // 每类型对应的"补充细节"条件字段(spec §6)。标题与描述恒显;其余按 type 折叠。
37
- const PER_TYPE_DETAIL_FIELDS = {
38
- bug: ["stepsToReproduce", "expectedBehavior", "actualBehavior", "frequency", "blockingLevel"],
39
- confusing: ["goal", "stuckAt", "blockingLevel"],
40
- feature_request: ["job", "currentWorkaround"],
41
- privacy_concern: ["sawWhat", "whereSeen"],
42
- other: [],
43
- };
44
- // 文本类字段的 i18n 标签键(select 类频率/阻塞度单独处理)。
45
- const DETAIL_FIELD_LABEL = {
46
- stepsToReproduce: "pages.reportProblem.form.stepsLabel",
47
- expectedBehavior: "pages.reportProblem.form.expectedLabel",
48
- actualBehavior: "pages.reportProblem.form.actualLabel",
49
- goal: "pages.reportProblem.form.goalLabel",
50
- stuckAt: "pages.reportProblem.form.stuckAtLabel",
51
- job: "pages.reportProblem.form.jobLabel",
52
- currentWorkaround: "pages.reportProblem.form.currentWorkaroundLabel",
53
- sawWhat: "pages.reportProblem.form.sawWhatLabel",
54
- whereSeen: "pages.reportProblem.form.whereSeenLabel",
55
- };
56
- const CHANNEL_ORDER = ["ingest", "github", "email", "file"];
57
- // 类型默认值按来源推断(spec §6):failed-tasks / error 入口 → bug,通用入口 → other。
58
- function defaultTypeFromParams(searchParams) {
59
- const context = buildFeedbackContextFromSearchParams(searchParams);
60
- const area = deriveFeedbackArea(context);
61
- if (area === "failed_tasks" || area === "error")
62
- return "bug";
63
- return "other";
64
- }
65
- // ── Runtime validator for drafts list envelope (H section / ERR-001/005/009) ─
66
- function isRecord(value) {
67
- return typeof value === "object" && value !== null && !Array.isArray(value);
68
- }
69
- function validateDraftsList(raw) {
70
- if (!isRecord(raw)) {
71
- return { ok: false, reason: "Drafts list response is not an object" };
72
- }
73
- if (!Object.hasOwn(raw, "drafts")) {
74
- return { ok: false, reason: "Drafts list response missing 'drafts' field" };
75
- }
76
- if (!Array.isArray(raw.drafts)) {
77
- return { ok: false, reason: "Drafts list 'drafts' field is not an array" };
78
- }
79
- const result = [];
80
- for (const item of raw.drafts) {
81
- const parsed = parseDraftSummary(item);
82
- if (parsed !== null) {
83
- result.push(parsed);
84
- }
85
- }
86
- return { ok: true, drafts: result };
87
- }
88
- // ── Sub-components ────────────────────────────────────────────────────────────
89
- function NoAutoUploadBanner() {
90
- const { t } = useTranslation();
91
- return (_jsxs("div", { className: "flex items-center gap-2 px-4 py-3 bg-gov/8 border border-gov/20 rounded-[6px] mb-6", children: [_jsx("svg", { className: "shrink-0 w-4 h-4 text-gov", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" }) }), _jsx("span", { className: "text-ink text-sm font-medium", children: t("pages.reportProblem.noAutoUpload") })] }));
92
- }
93
- function PrivacySection({ draft }) {
94
- const { t } = useTranslation();
95
- if (draft === null) {
96
- return (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-privacy", children: [_jsx(SectionTitle, { id: "section-privacy", children: t("pages.reportProblem.privacy.title") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed", children: t("pages.reportProblem.privacy.submitFirst") }), _jsx(NoAutoUploadBanner, {})] }));
97
- }
98
- return (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-privacy", children: [_jsx(SectionTitle, { id: "section-privacy", children: t("pages.reportProblem.privacy.title") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-4", children: t("pages.reportProblem.privacy.description") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-4 space-y-4", children: [_jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("pages.reportProblem.privacy.included") }), draft.privacy.includedSections.length > 0 ? (_jsx("ul", { className: "space-y-1", children: draft.privacy.includedSections.map((section, i) => (_jsxs("li", { className: "flex items-center gap-2 text-ink-2 text-[13px]", children: [_jsx("span", { className: "text-green-600", "aria-hidden": "true", children: "\u2713" }), section] }, i))) })) : (_jsx("p", { className: "text-ink-4 text-[13px]", children: "\u2014" }))] }), _jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("pages.reportProblem.privacy.excluded") }), draft.privacy.excludedByDefault.length > 0 ? (_jsx("ul", { className: "space-y-1", children: draft.privacy.excludedByDefault.map((section, i) => (_jsxs("li", { className: "flex items-center gap-2 text-ink-2 text-[13px]", children: [_jsx("span", { className: "text-red-500", "aria-hidden": "true", children: "\u2717" }), section] }, i))) })) : (_jsx("p", { className: "text-ink-4 text-[13px]", children: "\u2014" }))] }), draft.privacy.redactionNotes.length > 0 && (_jsxs("div", { children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("pages.reportProblem.privacy.notes") }), _jsx("ul", { className: "space-y-1", children: draft.privacy.redactionNotes.map((note, i) => (_jsxs("li", { className: "text-ink-2 text-[13px]", children: ["\u2022 ", note] }, i))) })] }))] }), _jsx(NoAutoUploadBanner, {})] }));
99
- }
100
- function StatusBadge({ draft }) {
101
- const { t } = useTranslation();
102
- const submitted = draft.status === "submitted";
103
- return (_jsxs("span", { className: submitted
104
- ? "inline-flex items-center gap-1 px-2 py-[2px] rounded-[3px] text-[11px] font-medium border border-green-200 bg-green-50 text-green-700"
105
- : "inline-flex items-center gap-1 px-2 py-[2px] rounded-[3px] text-[11px] font-medium border border-line bg-surface text-ink-3", children: [_jsx("span", { className: submitted ? "w-1.5 h-1.5 rounded-full bg-green-500" : "w-1.5 h-1.5 rounded-full bg-ink-3", "aria-hidden": "true" }), submitted ? t("pages.reportProblem.draft.sentBadge") : t("pages.reportProblem.draft.draftBadge")] }));
106
- }
107
- function DraftCard({ draft, onCopyMarkdown, onCopyEmail, onOpenGithub, onOpenEmail, onDelete }) {
108
- const { t } = useTranslation();
109
- const [confirmDelete, setConfirmDelete] = useState(false);
110
- return (_jsxs("article", { className: "bg-panel border border-line rounded-[6px] p-4", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 mb-2", children: [_jsx("div", { className: "font-mono text-[11px] text-ink-3", children: t("pages.reportProblem.draft.savedAt", { id: draft.id, at: draft.createdAt }) }), _jsx(StatusBadge, { draft: draft })] }), _jsx("div", { className: "font-semibold text-ink mb-1", children: draft.title }), (draft.status === "submitted" || draft.trackingId || draft.submittedVia) && (_jsxs("div", { className: "text-ink-3 text-[12px] mb-2 space-y-0.5", children: [draft.submittedVia && (_jsxs("div", { children: ["via ", draft.submittedVia, draft.submittedAt ? ` · ${draft.submittedAt}` : ""] })), draft.trackingId && (_jsxs("div", { className: "font-mono", children: [t("pages.reportProblem.channel.receiptTrackingId"), ": ", draft.trackingId] })), draft.externalUrl && (_jsx("div", { children: _jsx("a", { href: draft.externalUrl, target: "_blank", rel: "noreferrer noopener", className: "text-gov underline hover:text-gov-2", children: t("pages.reportProblem.channel.openIssue") }) }))] })), _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx("button", { type: "button", onClick: onCopyMarkdown, className: "border border-line bg-surface text-ink rounded-[3px] px-[12px] py-[5px] text-[12px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.reportProblem.draft.copyMarkdown") }), _jsx("button", { type: "button", onClick: onCopyEmail, className: "border border-line bg-surface text-ink rounded-[3px] px-[12px] py-[5px] text-[12px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.reportProblem.draft.copyEmail") }), draft.outputs.githubIssueUrl && (_jsx("button", { type: "button", onClick: onOpenGithub, className: "border border-line bg-surface text-ink rounded-[3px] px-[12px] py-[5px] text-[12px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.reportProblem.draft.openGithub") })), draft.outputs.mailtoUrl && (_jsx("button", { type: "button", onClick: onOpenEmail, className: "border border-line bg-surface text-ink rounded-[3px] px-[12px] py-[5px] text-[12px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.reportProblem.draft.openEmail") })), !confirmDelete ? (_jsx("button", { type: "button", onClick: () => setConfirmDelete(true), className: "border border-red-200 text-red-600 rounded-[3px] px-[12px] py-[5px] text-[12px] hover:bg-red-50 transition-colors focus-visible:outline-2 focus-visible:outline-red-400 focus-visible:outline-offset-2", children: t("pages.reportProblem.draft.delete") })) : (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: onDelete, className: "border border-red-400 bg-red-600 text-white rounded-[3px] px-[12px] py-[5px] text-[12px] hover:bg-red-700 transition-colors focus-visible:outline-2 focus-visible:outline-red-400 focus-visible:outline-offset-2", children: [t("pages.reportProblem.draft.delete"), "?"] }), _jsx("button", { type: "button", onClick: () => setConfirmDelete(false), className: "border border-line bg-surface text-ink rounded-[3px] px-[12px] py-[5px] text-[12px] hover:border-line-2 transition-colors", children: "\u00D7" })] }))] })] }));
111
- }
112
- function SavedDraftsSection({ drafts, onLoad, onDelete }) {
113
- const { t } = useTranslation();
114
- return (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-saved", children: [_jsx(SectionTitle, { id: "section-saved", children: t("pages.reportProblem.saved.title") }), drafts.length === 0 ? (_jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed py-2", children: "\u2014" })) : (_jsx("div", { className: "space-y-3", children: drafts.map((draft) => (_jsxs("article", { className: "bg-panel border border-line rounded-[6px] px-4 py-3 flex items-center justify-between gap-4", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2 mb-1", children: [_jsxs("div", { className: "font-mono text-[11px] text-ink-3", children: [enumLabel('feedbackType', draft.type, t), " \u00B7 ", draft.createdAt] }), draft.status === "submitted" && (_jsx("span", { className: "inline-flex items-center gap-1 px-1.5 py-[1px] rounded-[2px] text-[10px] font-medium border border-green-200 bg-green-50 text-green-700", children: t("pages.reportProblem.draft.sentBadge") }))] }), _jsx("div", { className: "text-ink text-sm truncate", children: draft.title })] }), _jsxs("div", { className: "flex gap-2 shrink-0", children: [_jsx("button", { type: "button", onClick: () => onLoad(draft.id), className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.reportProblem.saved.load") }), _jsx("button", { type: "button", onClick: () => onDelete(draft.id), className: "border border-red-200 text-red-600 rounded-[3px] px-[10px] py-[6px] text-[12px] hover:bg-red-50 transition-colors focus-visible:outline-2 focus-visible:outline-red-400 focus-visible:outline-offset-2", children: t("pages.reportProblem.draft.delete") })] })] }, draft.id))) }))] }));
115
- }
116
- // ── Channel ladder (Slice 3, spec §4/§11) ─────────────────────────────────────
117
- function ChannelSubmitArea({ draft, channels, onSubmitIngest, onSubmitGithub, onOpenEmail, onExportFile, onMarkSent }) {
118
- const { t } = useTranslation();
119
- const byId = useMemo(() => {
120
- const m = new Map();
121
- for (const c of channels ?? [])
122
- m.set(c.id, c);
123
- return m;
124
- }, [channels]);
125
- const submitted = draft.status === "submitted";
126
- const renderChannelButton = (id) => {
127
- const status = byId.get(id);
128
- const available = status?.available ?? false;
129
- // email: 客户端动作,但依赖 maintainer_email 已配置(占位地址不可投递,
130
- // 探测不可用时禁用并内联显示原因 + nextAction,与 ingest/github 一致)。
131
- if (id === "email") {
132
- return (_jsxs("div", { className: "space-y-1", children: [_jsx("button", { type: "button", disabled: !available, onClick: onOpenEmail, className: available
133
- ? "w-full border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[8px] text-[13px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
134
- : "w-full border border-line bg-surface text-ink-4 rounded-[3px] px-[14px] py-[8px] text-[13px] cursor-not-allowed", children: t("pages.reportProblem.channel.email") }), !available && (status?.reason || status?.nextAction) && (_jsxs("p", { className: "text-[11px] text-ink-3 leading-snug", children: [t("pages.reportProblem.channel.disablingReason", { reason: status?.reason ?? "" }), status?.nextAction ? ` · ${status.nextAction}` : ""] })), !submitted && (_jsx("button", { type: "button", onClick: () => onMarkSent("email"), className: "text-[11px] text-ink-3 hover:text-gov underline underline-offset-2 text-left", children: t("pages.reportProblem.draft.markAsSent") }))] }, "email"));
135
- }
136
- if (id === "file") {
137
- return (_jsxs("div", { className: "space-y-1", children: [_jsx("button", { type: "button", onClick: onExportFile, className: "w-full border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[8px] text-[13px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.reportProblem.channel.file") }), !submitted && (_jsx("button", { type: "button", onClick: () => onMarkSent("file"), className: "text-[11px] text-ink-3 hover:text-gov underline underline-offset-2 text-left", children: t("pages.reportProblem.draft.markAsSent") }))] }, "file"));
138
- }
139
- // ingest / github: 服务端通道,需探测可用性(rc-9: 禁用显示原因 + nextAction)。
140
- const isIngest = id === "ingest";
141
- const label = isIngest ? t("pages.reportProblem.channel.ingest") : t("pages.reportProblem.channel.github");
142
- const onClick = isIngest ? onSubmitIngest : onSubmitGithub;
143
- return (_jsxs("div", { className: "space-y-1", children: [_jsx("button", { type: "button", disabled: !available, onClick: onClick, className: available
144
- ? "w-full border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[8px] text-[13px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2"
145
- : "w-full border border-line bg-surface text-ink-4 rounded-[3px] px-[14px] py-[8px] text-[13px] cursor-not-allowed", children: label }), !available && (status?.reason || status?.nextAction) && (_jsxs("p", { className: "text-[11px] text-ink-3 leading-snug", children: [t("pages.reportProblem.channel.disablingReason", { reason: status?.reason ?? "" }), status?.nextAction ? ` · ${status.nextAction}` : ""] }))] }, id));
146
- };
147
- return (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-channel", children: [_jsx(SectionTitle, { id: "section-channel", children: t("pages.reportProblem.channel.title") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-4", children: t("pages.reportProblem.channel.description") }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3", children: CHANNEL_ORDER.map(renderChannelButton) })] }));
148
- }
149
- function ConfirmSubmitDialog({ draft, channel, open, busy, onConfirm, onCancel }) {
150
- const { t } = useTranslation();
151
- return (_jsx(Dialog, { open: open, onOpenChange: (o) => { if (!o && !busy)
152
- onCancel(); }, children: _jsxs(DialogContent, { className: "sm:max-w-xl max-h-[85vh] overflow-hidden flex flex-col", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t("pages.reportProblem.channel.confirmTitle") }), _jsx(DialogDescription, { children: channel === "ingest"
153
- ? t("pages.reportProblem.channel.confirmDescription")
154
- : t("pages.reportProblem.channel.github") })] }), _jsxs("div", { className: "flex-1 min-h-0 overflow-auto space-y-2", children: [_jsx("div", { className: "font-mono text-[12px] text-ink-3", children: draft.title }), _jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("pages.reportProblem.channel.confirmBodyLabel") }), _jsx("pre", { className: "whitespace-pre-wrap text-ink-2 text-[13px] leading-relaxed bg-surface border border-line rounded-[3px] p-3 max-h-[320px] overflow-auto", children: draft.outputs.markdown })] }), _jsxs(DialogFooter, { children: [_jsx("button", { type: "button", onClick: onCancel, disabled: busy, className: "border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 disabled:opacity-50", children: t("pages.reportProblem.channel.confirmCancel") }), _jsx("button", { type: "button", onClick: onConfirm, disabled: busy, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 disabled:opacity-50 disabled:cursor-not-allowed", children: busy ? t("pages.reportProblem.form.submitting") : t("pages.reportProblem.channel.confirmSubmit") })] })] }) }));
155
- }
156
- export function ReportProblemPage() {
157
- const { t } = useTranslation();
158
- const [searchParams] = useSearchParams();
159
- const [form, setForm] = useState(() => ({
160
- ...INITIAL_FORM,
161
- type: defaultTypeFromParams(searchParams),
162
- }));
163
- const [drafts, setDrafts] = useState([]);
164
- const [currentDraft, setCurrentDraft] = useState(null);
165
- const [loadingState, setLoadingState] = useState("loading");
166
- const [loadError, setLoadError] = useState(null);
167
- const [showPreview, setShowPreview] = useState(false);
168
- const [showDetails, setShowDetails] = useState(false);
169
- // ── Channel ladder state (Slice 3) ──
170
- const [channels, setChannels] = useState(null);
171
- const [confirmCtx, setConfirmCtx] = useState(null);
172
- const [submittingChannel, setSubmittingChannel] = useState(false);
173
- const contextFromUrl = useMemo(() => buildFeedbackContextFromSearchParams(searchParams), [searchParams]);
174
- const areaFromUrl = useMemo(() => deriveFeedbackArea(contextFromUrl), [contextFromUrl]);
175
- // 类型切换时:有细节字段的类型自动展开"补充细节"。
176
- useEffect(() => {
177
- setShowDetails(PER_TYPE_DETAIL_FIELDS[form.type].length > 0);
178
- }, [form.type]);
179
- // ── Load drafts + channels on mount ─────────────────────────────────────
180
- const loadDrafts = useCallback(async () => {
181
- const result = await listFeedbackReports();
182
- if (!result.success) {
183
- setLoadError(result.error ?? "Failed to load drafts");
184
- setLoadingState("loaded");
185
- return;
186
- }
187
- const validated = validateDraftsList(result.data);
188
- if (!validated.ok) {
189
- setLoadError(validated.reason);
190
- setDrafts([]);
191
- setLoadingState("loaded");
192
- return;
193
- }
194
- setDrafts(validated.drafts);
195
- setLoadError(null);
196
- setLoadingState("loaded");
197
- }, []);
198
- const loadChannels = useCallback(async () => {
199
- const result = await fetchFeedbackChannels();
200
- if (!result.success || !result.data) {
201
- setChannels(null);
202
- return;
203
- }
204
- setChannels(result.data.channels);
205
- }, []);
206
- useEffect(() => {
207
- loadDrafts();
208
- loadChannels();
209
- }, [loadDrafts, loadChannels]);
210
- // ── Form handlers ────────────────────────────────────────────────────────
211
- const handleFieldChange = useCallback((field, value) => {
212
- setForm((prev) => ({ ...prev, [field]: value }));
213
- }, []);
214
- const buildInput = useCallback(() => {
215
- const base = {
216
- type: form.type,
217
- title: form.title.trim(),
218
- description: form.description.trim(),
219
- stepsToReproduce: form.stepsToReproduce.trim() || undefined,
220
- expectedBehavior: form.expectedBehavior.trim() || undefined,
221
- actualBehavior: form.actualBehavior.trim() || undefined,
222
- // 类型化新字段(全部可选,按 type 条件提交)
223
- goal: form.goal.trim() || undefined,
224
- stuckAt: form.stuckAt.trim() || undefined,
225
- job: form.job.trim() || undefined,
226
- currentWorkaround: form.currentWorkaround.trim() || undefined,
227
- sawWhat: form.sawWhat.trim() || undefined,
228
- whereSeen: form.whereSeen.trim() || undefined,
229
- frequency: form.frequency ?? undefined,
230
- blockingLevel: form.blockingLevel ?? undefined,
231
- ...(areaFromUrl ? { area: areaFromUrl } : {}),
232
- ...(contextFromUrl?.taskId ? { taskId: contextFromUrl.taskId } : {}),
233
- ...(contextFromUrl ? { context: contextFromUrl } : {}),
234
- };
235
- return base;
236
- }, [form, areaFromUrl, contextFromUrl]);
237
- const handleSubmit = useCallback(async (e) => {
238
- e.preventDefault();
239
- if (!form.title.trim() || !form.description.trim()) {
240
- toast.error(t("pages.reportProblem.errors.missingRequired"));
241
- return;
242
- }
243
- setForm((prev) => ({ ...prev, submitting: true }));
244
- try {
245
- const [configSettled, lifecycleSettled, healthSettled] = await Promise.allSettled([
246
- fetchConfigSummary(),
247
- request('/api/v1/lifecycle/state'),
248
- request('/api/health'),
249
- ]);
250
- const diagnostics = buildFeedbackDiagnostics(configSettled, lifecycleSettled, healthSettled);
251
- const result = await createFeedbackReport(buildInput(), diagnostics);
252
- if (!result.success) {
253
- toast.error(getErrorMessage(result, t("pages.reportProblem.errors.createFailed")));
254
- setForm((prev) => ({ ...prev, submitting: false }));
255
- return;
256
- }
257
- let parsed = parseEnvelopeReport(result.data);
258
- if (parsed === null && isRecord(result.data) && Object.hasOwn(result.data, "report")) {
259
- parsed = parseDraftRecord(result.data["report"]);
260
- }
261
- if (parsed === null) {
262
- toast.error(t("pages.reportProblem.errors.createFailed"));
263
- setForm((prev) => ({ ...prev, submitting: false }));
264
- return;
265
- }
266
- setCurrentDraft(parsed);
267
- toast.success(t("pages.reportProblem.toast.draftCreated"));
268
- setForm((prev) => ({
269
- ...INITIAL_FORM,
270
- type: prev.type,
271
- frequency: undefined,
272
- blockingLevel: undefined,
273
- submitting: false,
274
- }));
275
- setShowPreview(false);
276
- await loadDrafts();
277
- }
278
- catch {
279
- toast.error(t("pages.reportProblem.errors.createFailed"));
280
- }
281
- finally {
282
- setForm((prev) => ({ ...prev, submitting: false }));
283
- }
284
- }, [form, t, loadDrafts, buildInput]);
285
- // ── Draft actions ────────────────────────────────────────────────────────
286
- const handleLoadDraft = useCallback(async (id) => {
287
- const result = await getFeedbackReport(id);
288
- if (!result.success) {
289
- toast.error(t("pages.reportProblem.toast.loadFailed"));
290
- return;
291
- }
292
- const parsed = parseEnvelopeReport(result.data);
293
- if (parsed === null) {
294
- toast.error(t("pages.reportProblem.toast.loadFailed"));
295
- return;
296
- }
297
- setCurrentDraft(parsed);
298
- setForm({
299
- type: parsed.type,
300
- title: parsed.title,
301
- description: parsed.userText.description,
302
- stepsToReproduce: parsed.userText.stepsToReproduce ?? "",
303
- expectedBehavior: parsed.userText.expectedBehavior ?? "",
304
- actualBehavior: parsed.userText.actualBehavior ?? "",
305
- frequency: parsed.userText.frequency,
306
- blockingLevel: parsed.userText.blockingLevel,
307
- goal: parsed.userText.goal ?? "",
308
- stuckAt: parsed.userText.stuckAt ?? "",
309
- job: parsed.userText.job ?? "",
310
- currentWorkaround: parsed.userText.currentWorkaround ?? "",
311
- sawWhat: parsed.userText.sawWhat ?? "",
312
- whereSeen: parsed.userText.whereSeen ?? "",
313
- submitting: false,
314
- });
315
- }, [t]);
316
- const handleCopyMarkdown = useCallback(async (draft) => {
317
- try {
318
- if (!draft.outputs.markdown)
319
- return;
320
- await navigator.clipboard.writeText(draft.outputs.markdown);
321
- toast.success(t("pages.reportProblem.toast.markdownCopied"));
322
- }
323
- catch {
324
- toast.error(t("pages.reportProblem.toast.copyFailed"));
325
- }
326
- }, [t]);
327
- const handleCopyEmail = useCallback(async (draft) => {
328
- try {
329
- if (!draft.outputs.emailText)
330
- return;
331
- await navigator.clipboard.writeText(draft.outputs.emailText);
332
- toast.success(t("pages.reportProblem.toast.emailCopied"));
333
- }
334
- catch {
335
- toast.error(t("pages.reportProblem.toast.copyFailed"));
336
- }
337
- }, [t]);
338
- const handleOpenGithub = useCallback((draft) => {
339
- if (draft.outputs.githubIssueUrl) {
340
- window.open(draft.outputs.githubIssueUrl, "_blank");
341
- }
342
- }, []);
343
- const handleOpenEmail = useCallback((draft) => {
344
- if (draft.outputs.mailtoUrl) {
345
- window.open(draft.outputs.mailtoUrl, "_blank");
346
- }
347
- }, []);
348
- const handleExportFile = useCallback((draft) => {
349
- const blob = new Blob([draft.outputs.markdown], { type: "text/markdown;charset=utf-8" });
350
- const url = URL.createObjectURL(blob);
351
- const a = document.createElement("a");
352
- a.href = url;
353
- a.download = `PD-feedback-${draft.id}.md`;
354
- document.body.appendChild(a);
355
- a.click();
356
- a.remove();
357
- URL.revokeObjectURL(url);
358
- }, []);
359
- const refreshDraft = useCallback(async (id) => {
360
- const result = await getFeedbackReport(id);
361
- if (result.success) {
362
- const parsed = parseEnvelopeReport(result.data);
363
- if (parsed)
364
- setCurrentDraft(parsed);
365
- }
366
- }, []);
367
- const handleSubmitChannel = useCallback(async (channel) => {
368
- const draft = currentDraft;
369
- if (!draft)
370
- return;
371
- setSubmittingChannel(true);
372
- try {
373
- const result = await submitFeedbackReport(draft.id, channel);
374
- if (!result.success) {
375
- toast.error(getErrorMessage(result, t("pages.reportProblem.toast.submitFailed")));
376
- return;
377
- }
378
- await refreshDraft(draft.id);
379
- await loadDrafts();
380
- const data = result.data;
381
- if (data?.writeBackFailed) {
382
- toast.error(t("pages.reportProblem.channel.writeBackNote"));
383
- }
384
- else if (data?.alreadySubmitted) {
385
- toast.info(t("pages.reportProblem.channel.alreadySubmitted"));
386
- }
387
- else {
388
- toast.success(t("pages.reportProblem.toast.submitSucceeded", { trackingId: data?.trackingId ?? "" }));
389
- }
390
- }
391
- catch {
392
- toast.error(t("pages.reportProblem.toast.submitFailed"));
393
- }
394
- finally {
395
- setSubmittingChannel(false);
396
- setConfirmCtx(null);
397
- }
398
- }, [currentDraft, t, refreshDraft, loadDrafts]);
399
- const handleMarkSent = useCallback(async (via) => {
400
- const draft = currentDraft;
401
- if (!draft)
402
- return;
403
- const result = await markFeedbackReportSent(draft.id, via);
404
- if (!result.success) {
405
- toast.error(getErrorMessage(result, t("pages.reportProblem.toast.submitFailed")));
406
- return;
407
- }
408
- toast.success(t("pages.reportProblem.toast.markSentSucceeded"));
409
- await refreshDraft(draft.id);
410
- await loadDrafts();
411
- }, [currentDraft, t, refreshDraft, loadDrafts]);
412
- const handleDeleteDraft = useCallback(async (id) => {
413
- const result = await deleteFeedbackReport(id);
414
- if (!result.success) {
415
- toast.error(t("pages.reportProblem.toast.deleteFailed"));
416
- return;
417
- }
418
- toast.success(t("pages.reportProblem.toast.draftDeleted"));
419
- setDrafts((prev) => prev.filter((d) => d.id !== id));
420
- if (currentDraft?.id === id) {
421
- setCurrentDraft(null);
422
- }
423
- }, [t, currentDraft]);
424
- // ── Loading state ────────────────────────────────────────────────────────
425
- if (loadingState === "loading") {
426
- return (_jsx(PageShell, { children: _jsx(PageLoading, { cardCount: 3, label: t("common.loading") }) }));
427
- }
428
- // ── Error state (ERR-002: degradation with reason) ───────────────────────
429
- if (loadingState === "error") {
430
- return (_jsxs(PageShell, { children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.reportProblem.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.reportProblem.title") }), _jsxs("div", { className: "mt-6 p-4 bg-panel border border-line rounded-[6px] text-ink-2 text-sm", children: [_jsx("p", { children: t("pages.reportProblem.loadError") }), loadError && (_jsx("p", { className: "mt-2 text-ink-4 text-[13px] font-mono", children: loadError }))] })] }));
431
- }
432
- const detailFields = PER_TYPE_DETAIL_FIELDS[form.type];
433
- const renderDetailField = (key) => {
434
- if (key === "frequency") {
435
- const label = t("pages.reportProblem.form.frequencyLabel");
436
- return (_jsxs("div", { children: [_jsx("label", { htmlFor: "feedback-frequency", className: "block text-ink-2 text-[13px] mb-1.5", children: label }), _jsxs("select", { id: "feedback-frequency", value: form.frequency ?? "", onChange: (e) => {
437
- const v = e.target.value;
438
- if (v === "")
439
- handleFieldChange("frequency", undefined);
440
- else if (VALID_FREQUENCIES.has(v))
441
- handleFieldChange("frequency", v);
442
- }, className: "border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov", children: [_jsx("option", { value: "", children: t("pages.reportProblem.form.frequencyNotSet") }), FREQUENCY_OPTIONS.map((f) => (_jsx("option", { value: f, children: t(`pages.reportProblem.form.frequency${f.charAt(0).toUpperCase() + f.slice(1)}`) }, f)))] })] }, "frequency"));
443
- }
444
- if (key === "blockingLevel") {
445
- const label = t("pages.reportProblem.form.blockingLevelLabel");
446
- return (_jsxs("div", { children: [_jsx("label", { htmlFor: "feedback-blocking", className: "block text-ink-2 text-[13px] mb-1.5", children: label }), _jsxs("select", { id: "feedback-blocking", value: form.blockingLevel ?? "", onChange: (e) => {
447
- const v = e.target.value;
448
- if (v === "")
449
- handleFieldChange("blockingLevel", undefined);
450
- else if (VALID_BLOCKING.has(v))
451
- handleFieldChange("blockingLevel", v);
452
- }, className: "border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov", children: [_jsx("option", { value: "", children: t("pages.reportProblem.form.blockingLevelNotSet") }), BLOCKING_OPTIONS.map((b) => (_jsx("option", { value: b, children: t(`pages.reportProblem.form.blockingLevel${b.charAt(0).toUpperCase() + b.slice(1)}`) }, b)))] })] }, "blockingLevel"));
453
- }
454
- const value = form[key];
455
- const label = t(DETAIL_FIELD_LABEL[key] ?? "pages.reportProblem.form.descriptionLabel");
456
- return (_jsxs("div", { children: [_jsx("label", { htmlFor: `feedback-${key}`, className: "block text-ink-2 text-[13px] mb-1.5", children: label }), _jsx("textarea", { id: `feedback-${key}`, value: typeof value === "string" ? value : "", onChange: (e) => handleFieldChange(key, e.target.value), rows: key === "stepsToReproduce" ? 3 : 2, className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov resize-y" })] }, key));
457
- };
458
- // ── Loaded state ─────────────────────────────────────────────────────────
459
- return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.reportProblem.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.reportProblem.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.reportProblem.subtitle") }), _jsx(NoAutoUploadBanner, {}), _jsxs("section", { "aria-labelledby": "section-form", children: [_jsx(SectionTitle, { id: "section-form", children: t("pages.reportProblem.form.title") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-4", children: t("pages.reportProblem.form.description") }), _jsxs("form", { onSubmit: handleSubmit, className: "bg-panel border border-line rounded-[6px] p-5 space-y-4", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: "feedback-type", className: "block text-ink-2 text-[13px] mb-1.5", children: t("pages.reportProblem.form.type") }), _jsx("select", { id: "feedback-type", value: form.type, onChange: (e) => {
460
- const val = e.target.value;
461
- if (VALID_FEEDBACK_TYPES.has(val)) {
462
- setForm((prev) => ({ ...prev, type: val, frequency: undefined, blockingLevel: undefined }));
463
- }
464
- }, className: "border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov", children: FEEDBACK_TYPES.map((ft) => (_jsx("option", { value: ft, children: t(`pages.reportProblem.form.types.${ft}`) }, ft))) })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "feedback-title", className: "block text-ink-2 text-[13px] mb-1.5", children: t("pages.reportProblem.form.titleLabel") }), _jsx("input", { id: "feedback-title", type: "text", value: form.title, onChange: (e) => handleFieldChange("title", e.target.value), className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov" })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "feedback-description", className: "block text-ink-2 text-[13px] mb-1.5", children: t("pages.reportProblem.form.descriptionLabel") }), _jsx("textarea", { id: "feedback-description", value: form.description, onChange: (e) => handleFieldChange("description", e.target.value), rows: 4, className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov resize-y" })] }), detailFields.length > 0 && (_jsx("div", { children: _jsx("button", { type: "button", onClick: () => setShowDetails((prev) => !prev), className: "text-gov text-[13px] font-medium underline underline-offset-2 hover:text-gov-2 transition-colors", children: showDetails ? t("pages.reportProblem.form.detailsHide") : t("pages.reportProblem.form.detailsToggle") }) })), showDetails && (_jsx("div", { className: "space-y-4 border-t border-line pt-4", children: detailFields.map(renderDetailField) })), _jsxs("div", { className: "flex items-center gap-3 pt-2", children: [_jsx("button", { type: "submit", disabled: form.submitting, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: form.submitting ? t("pages.reportProblem.form.submitting") : t("pages.reportProblem.form.submit") }), currentDraft && (_jsx("button", { type: "button", onClick: () => setShowPreview((prev) => !prev), className: "border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: showPreview
465
- ? t("pages.reportProblem.form.hidePreview")
466
- : t("pages.reportProblem.form.showPreview") }))] })] }), showPreview && currentDraft && (_jsxs("div", { className: "mt-4 bg-panel border border-line rounded-[6px] p-4", children: [_jsx("h3", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-3", children: "Markdown" }), _jsx("pre", { className: "whitespace-pre-wrap text-ink-2 text-[13px] leading-relaxed bg-surface border border-line rounded-[3px] p-3 max-h-[400px] overflow-auto", children: currentDraft.outputs.markdown })] }))] }), _jsx(PrivacySection, { draft: currentDraft }), currentDraft && (_jsx(ChannelSubmitArea, { draft: currentDraft, channels: channels, onSubmitIngest: () => setConfirmCtx({ channel: "ingest" }), onSubmitGithub: () => setConfirmCtx({ channel: "github" }), onOpenEmail: () => handleOpenEmail(currentDraft), onExportFile: () => handleExportFile(currentDraft), onMarkSent: handleMarkSent })), currentDraft && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-current-draft", children: [_jsx(SectionTitle, { id: "section-current-draft", children: t("pages.reportProblem.draft.title") }), _jsx(DraftCard, { draft: currentDraft, onCopyMarkdown: () => handleCopyMarkdown(currentDraft), onCopyEmail: () => handleCopyEmail(currentDraft), onOpenGithub: () => handleOpenGithub(currentDraft), onOpenEmail: () => handleOpenEmail(currentDraft), onDelete: () => handleDeleteDraft(currentDraft.id) })] })), loadError && (_jsxs("div", { className: "mt-4 p-3 bg-panel border border-amber/20 rounded-[6px] text-ink-2 text-[13px]", children: [_jsx("p", { children: t("pages.reportProblem.loadError") }), _jsx("p", { className: "mt-1 text-ink-4 text-[12px] font-mono", children: loadError })] })), _jsx(SavedDraftsSection, { drafts: drafts, onLoad: handleLoadDraft, onDelete: handleDeleteDraft }), _jsx("footer", { className: "mt-12 pt-6 border-t border-line text-ink-3 text-[13px]", children: t("pages.reportProblem.privacy.guarantee") }), currentDraft && confirmCtx && (_jsx(ConfirmSubmitDialog, { draft: currentDraft, channel: confirmCtx.channel, open: true, busy: submittingChannel, onConfirm: () => handleSubmitChannel(confirmCtx.channel), onCancel: () => setConfirmCtx(null) }))] }) }));
467
- }
@@ -1,4 +0,0 @@
1
- import type { WorkspaceEntry } from "../../api.js";
2
- export declare function validateWorkspaceEntry(raw: unknown): WorkspaceEntry | null;
3
- export declare function validateWorkspaceArray(raw: unknown): WorkspaceEntry[] | null;
4
- export declare function SettingsPage(): import("react").JSX.Element;