@aitne/dashboard 0.1.4 → 0.1.7

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 (751) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +5 -1
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/cache/.tsbuildinfo +1 -1
  5. package/.next/diagnostics/route-bundle-stats.json +450 -356
  6. package/.next/fallback-build-manifest.json +3 -3
  7. package/.next/prerender-manifest.json +96 -0
  8. package/.next/routes-manifest.json +24 -0
  9. package/.next/server/app/_global-error.html +1 -1
  10. package/.next/server/app/_global-error.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/server/app/_not-found.html +1 -1
  19. package/.next/server/app/_not-found.rsc +15 -15
  20. package/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  21. package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  22. package/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  23. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  24. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  25. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  26. package/.next/server/app/activity/page.js.nft.json +1 -1
  27. package/.next/server/app/activity/page_client-reference-manifest.js +1 -1
  28. package/.next/server/app/activity.html +1 -1
  29. package/.next/server/app/activity.rsc +19 -19
  30. package/.next/server/app/activity.segments/_full.segment.rsc +19 -19
  31. package/.next/server/app/activity.segments/_head.segment.rsc +4 -4
  32. package/.next/server/app/activity.segments/_index.segment.rsc +10 -10
  33. package/.next/server/app/activity.segments/_tree.segment.rsc +2 -2
  34. package/.next/server/app/activity.segments/activity/__PAGE__.segment.rsc +4 -4
  35. package/.next/server/app/activity.segments/activity.segment.rsc +4 -4
  36. package/.next/server/app/analytics/page.js.nft.json +1 -1
  37. package/.next/server/app/analytics/page_client-reference-manifest.js +1 -1
  38. package/.next/server/app/analytics.html +1 -1
  39. package/.next/server/app/analytics.rsc +19 -19
  40. package/.next/server/app/analytics.segments/_full.segment.rsc +19 -19
  41. package/.next/server/app/analytics.segments/_head.segment.rsc +4 -4
  42. package/.next/server/app/analytics.segments/_index.segment.rsc +10 -10
  43. package/.next/server/app/analytics.segments/_tree.segment.rsc +2 -2
  44. package/.next/server/app/analytics.segments/analytics/__PAGE__.segment.rsc +4 -4
  45. package/.next/server/app/analytics.segments/analytics.segment.rsc +4 -4
  46. package/.next/server/app/api/[...path]/route.js +1 -1
  47. package/.next/server/app/api/[...path]/route.js.nft.json +1 -1
  48. package/.next/server/app/chat/page.js.nft.json +1 -1
  49. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  50. package/.next/server/app/chat.html +1 -1
  51. package/.next/server/app/chat.rsc +17 -17
  52. package/.next/server/app/chat.segments/_full.segment.rsc +17 -17
  53. package/.next/server/app/chat.segments/_head.segment.rsc +4 -4
  54. package/.next/server/app/chat.segments/_index.segment.rsc +10 -10
  55. package/.next/server/app/chat.segments/_tree.segment.rsc +2 -2
  56. package/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +4 -4
  57. package/.next/server/app/chat.segments/chat.segment.rsc +3 -3
  58. package/.next/server/app/connections/calendar/page.js.nft.json +1 -1
  59. package/.next/server/app/connections/calendar/page_client-reference-manifest.js +1 -1
  60. package/.next/server/app/connections/calendar.html +1 -1
  61. package/.next/server/app/connections/calendar.rsc +18 -18
  62. package/.next/server/app/connections/calendar.segments/_full.segment.rsc +18 -18
  63. package/.next/server/app/connections/calendar.segments/_head.segment.rsc +4 -4
  64. package/.next/server/app/connections/calendar.segments/_index.segment.rsc +10 -10
  65. package/.next/server/app/connections/calendar.segments/_tree.segment.rsc +2 -2
  66. package/.next/server/app/connections/calendar.segments/connections/calendar/__PAGE__.segment.rsc +4 -4
  67. package/.next/server/app/connections/calendar.segments/connections/calendar.segment.rsc +3 -3
  68. package/.next/server/app/connections/calendar.segments/connections.segment.rsc +4 -4
  69. package/.next/server/app/connections/journal/page.js.nft.json +1 -1
  70. package/.next/server/app/connections/journal/page_client-reference-manifest.js +1 -1
  71. package/.next/server/app/connections/journal.html +1 -1
  72. package/.next/server/app/connections/journal.rsc +16 -16
  73. package/.next/server/app/connections/journal.segments/_full.segment.rsc +16 -16
  74. package/.next/server/app/connections/journal.segments/_head.segment.rsc +4 -4
  75. package/.next/server/app/connections/journal.segments/_index.segment.rsc +10 -10
  76. package/.next/server/app/connections/journal.segments/_tree.segment.rsc +2 -2
  77. package/.next/server/app/connections/journal.segments/connections/journal/__PAGE__.segment.rsc +2 -2
  78. package/.next/server/app/connections/journal.segments/connections/journal.segment.rsc +3 -3
  79. package/.next/server/app/connections/journal.segments/connections.segment.rsc +4 -4
  80. package/.next/server/app/connections/knowledge/page.js.nft.json +1 -1
  81. package/.next/server/app/connections/knowledge/page_client-reference-manifest.js +1 -1
  82. package/.next/server/app/connections/knowledge.html +1 -1
  83. package/.next/server/app/connections/knowledge.rsc +18 -18
  84. package/.next/server/app/connections/knowledge.segments/_full.segment.rsc +18 -18
  85. package/.next/server/app/connections/knowledge.segments/_head.segment.rsc +4 -4
  86. package/.next/server/app/connections/knowledge.segments/_index.segment.rsc +10 -10
  87. package/.next/server/app/connections/knowledge.segments/_tree.segment.rsc +2 -2
  88. package/.next/server/app/connections/knowledge.segments/connections/knowledge/__PAGE__.segment.rsc +4 -4
  89. package/.next/server/app/connections/knowledge.segments/connections/knowledge.segment.rsc +3 -3
  90. package/.next/server/app/connections/knowledge.segments/connections.segment.rsc +4 -4
  91. package/.next/server/app/connections/mail/page.js.nft.json +1 -1
  92. package/.next/server/app/connections/mail/page_client-reference-manifest.js +1 -1
  93. package/.next/server/app/connections/mail.html +1 -1
  94. package/.next/server/app/connections/mail.rsc +18 -18
  95. package/.next/server/app/connections/mail.segments/_full.segment.rsc +18 -18
  96. package/.next/server/app/connections/mail.segments/_head.segment.rsc +4 -4
  97. package/.next/server/app/connections/mail.segments/_index.segment.rsc +10 -10
  98. package/.next/server/app/connections/mail.segments/_tree.segment.rsc +2 -2
  99. package/.next/server/app/connections/mail.segments/connections/mail/__PAGE__.segment.rsc +4 -4
  100. package/.next/server/app/connections/mail.segments/connections/mail.segment.rsc +3 -3
  101. package/.next/server/app/connections/mail.segments/connections.segment.rsc +4 -4
  102. package/.next/server/app/connections/mcp/page.js.nft.json +1 -1
  103. package/.next/server/app/connections/mcp/page_client-reference-manifest.js +1 -1
  104. package/.next/server/app/connections/mcp.html +1 -1
  105. package/.next/server/app/connections/mcp.rsc +18 -18
  106. package/.next/server/app/connections/mcp.segments/_full.segment.rsc +18 -18
  107. package/.next/server/app/connections/mcp.segments/_head.segment.rsc +4 -4
  108. package/.next/server/app/connections/mcp.segments/_index.segment.rsc +10 -10
  109. package/.next/server/app/connections/mcp.segments/_tree.segment.rsc +2 -2
  110. package/.next/server/app/connections/mcp.segments/connections/mcp/__PAGE__.segment.rsc +4 -4
  111. package/.next/server/app/connections/mcp.segments/connections/mcp.segment.rsc +3 -3
  112. package/.next/server/app/connections/mcp.segments/connections.segment.rsc +4 -4
  113. package/.next/server/app/connections/messaging/page.js.nft.json +1 -1
  114. package/.next/server/app/connections/messaging/page_client-reference-manifest.js +1 -1
  115. package/.next/server/app/connections/messaging.html +1 -1
  116. package/.next/server/app/connections/messaging.rsc +18 -18
  117. package/.next/server/app/connections/messaging.segments/_full.segment.rsc +18 -18
  118. package/.next/server/app/connections/messaging.segments/_head.segment.rsc +4 -4
  119. package/.next/server/app/connections/messaging.segments/_index.segment.rsc +10 -10
  120. package/.next/server/app/connections/messaging.segments/_tree.segment.rsc +2 -2
  121. package/.next/server/app/connections/messaging.segments/connections/messaging/__PAGE__.segment.rsc +4 -4
  122. package/.next/server/app/connections/messaging.segments/connections/messaging.segment.rsc +3 -3
  123. package/.next/server/app/connections/messaging.segments/connections.segment.rsc +4 -4
  124. package/.next/server/app/connections/page.js.nft.json +1 -1
  125. package/.next/server/app/connections/page_client-reference-manifest.js +1 -1
  126. package/.next/server/app/connections/repositories/page.js.nft.json +1 -1
  127. package/.next/server/app/connections/repositories/page_client-reference-manifest.js +1 -1
  128. package/.next/server/app/connections/repositories.html +1 -1
  129. package/.next/server/app/connections/repositories.rsc +18 -18
  130. package/.next/server/app/connections/repositories.segments/_full.segment.rsc +18 -18
  131. package/.next/server/app/connections/repositories.segments/_head.segment.rsc +4 -4
  132. package/.next/server/app/connections/repositories.segments/_index.segment.rsc +10 -10
  133. package/.next/server/app/connections/repositories.segments/_tree.segment.rsc +2 -2
  134. package/.next/server/app/connections/repositories.segments/connections/repositories/__PAGE__.segment.rsc +4 -4
  135. package/.next/server/app/connections/repositories.segments/connections/repositories.segment.rsc +3 -3
  136. package/.next/server/app/connections/repositories.segments/connections.segment.rsc +4 -4
  137. package/.next/server/app/connections/routines/page.js.nft.json +1 -1
  138. package/.next/server/app/connections/routines/page_client-reference-manifest.js +1 -1
  139. package/.next/server/app/connections/routines.html +1 -1
  140. package/.next/server/app/connections/routines.rsc +16 -16
  141. package/.next/server/app/connections/routines.segments/_full.segment.rsc +16 -16
  142. package/.next/server/app/connections/routines.segments/_head.segment.rsc +4 -4
  143. package/.next/server/app/connections/routines.segments/_index.segment.rsc +10 -10
  144. package/.next/server/app/connections/routines.segments/_tree.segment.rsc +2 -2
  145. package/.next/server/app/connections/routines.segments/connections/routines/__PAGE__.segment.rsc +2 -2
  146. package/.next/server/app/connections/routines.segments/connections/routines.segment.rsc +3 -3
  147. package/.next/server/app/connections/routines.segments/connections.segment.rsc +4 -4
  148. package/.next/server/app/connections.html +1 -1
  149. package/.next/server/app/connections.rsc +16 -16
  150. package/.next/server/app/connections.segments/_full.segment.rsc +16 -16
  151. package/.next/server/app/connections.segments/_head.segment.rsc +4 -4
  152. package/.next/server/app/connections.segments/_index.segment.rsc +10 -10
  153. package/.next/server/app/connections.segments/_tree.segment.rsc +2 -2
  154. package/.next/server/app/connections.segments/connections/__PAGE__.segment.rsc +2 -2
  155. package/.next/server/app/connections.segments/connections.segment.rsc +4 -4
  156. package/.next/server/app/conversations/[id]/page.js.nft.json +1 -1
  157. package/.next/server/app/conversations/[id]/page_client-reference-manifest.js +1 -1
  158. package/.next/server/app/conversations/page.js.nft.json +1 -1
  159. package/.next/server/app/conversations/page_client-reference-manifest.js +1 -1
  160. package/.next/server/app/conversations.html +1 -1
  161. package/.next/server/app/conversations.rsc +15 -15
  162. package/.next/server/app/conversations.segments/_full.segment.rsc +15 -15
  163. package/.next/server/app/conversations.segments/_head.segment.rsc +4 -4
  164. package/.next/server/app/conversations.segments/_index.segment.rsc +10 -10
  165. package/.next/server/app/conversations.segments/_tree.segment.rsc +2 -2
  166. package/.next/server/app/conversations.segments/conversations/__PAGE__.segment.rsc +2 -2
  167. package/.next/server/app/conversations.segments/conversations.segment.rsc +3 -3
  168. package/.next/server/app/docs/[[...slug]]/page.js.nft.json +1 -1
  169. package/.next/server/app/docs/[[...slug]]/page_client-reference-manifest.js +1 -1
  170. package/.next/server/app/finance/page.js.nft.json +1 -1
  171. package/.next/server/app/finance/page_client-reference-manifest.js +1 -1
  172. package/.next/server/app/finance.html +1 -1
  173. package/.next/server/app/finance.rsc +17 -17
  174. package/.next/server/app/finance.segments/_full.segment.rsc +17 -17
  175. package/.next/server/app/finance.segments/_head.segment.rsc +4 -4
  176. package/.next/server/app/finance.segments/_index.segment.rsc +10 -10
  177. package/.next/server/app/finance.segments/_tree.segment.rsc +2 -2
  178. package/.next/server/app/finance.segments/finance/__PAGE__.segment.rsc +4 -4
  179. package/.next/server/app/finance.segments/finance.segment.rsc +3 -3
  180. package/.next/server/app/git/page.js.nft.json +1 -1
  181. package/.next/server/app/git/page_client-reference-manifest.js +1 -1
  182. package/.next/server/app/git.html +1 -1
  183. package/.next/server/app/git.rsc +17 -17
  184. package/.next/server/app/git.segments/_full.segment.rsc +17 -17
  185. package/.next/server/app/git.segments/_head.segment.rsc +4 -4
  186. package/.next/server/app/git.segments/_index.segment.rsc +10 -10
  187. package/.next/server/app/git.segments/_tree.segment.rsc +2 -2
  188. package/.next/server/app/git.segments/git/__PAGE__.segment.rsc +4 -4
  189. package/.next/server/app/git.segments/git.segment.rsc +3 -3
  190. package/.next/server/app/health/page.js.nft.json +1 -1
  191. package/.next/server/app/health/page_client-reference-manifest.js +1 -1
  192. package/.next/server/app/health.html +1 -1
  193. package/.next/server/app/health.rsc +17 -17
  194. package/.next/server/app/health.segments/_full.segment.rsc +17 -17
  195. package/.next/server/app/health.segments/_head.segment.rsc +4 -4
  196. package/.next/server/app/health.segments/_index.segment.rsc +10 -10
  197. package/.next/server/app/health.segments/_tree.segment.rsc +2 -2
  198. package/.next/server/app/health.segments/health/__PAGE__.segment.rsc +4 -4
  199. package/.next/server/app/health.segments/health.segment.rsc +3 -3
  200. package/.next/server/app/index.html +1 -1
  201. package/.next/server/app/index.rsc +17 -17
  202. package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  203. package/.next/server/app/index.segments/_full.segment.rsc +17 -17
  204. package/.next/server/app/index.segments/_head.segment.rsc +4 -4
  205. package/.next/server/app/index.segments/_index.segment.rsc +10 -10
  206. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  207. package/.next/server/app/knowledge/page.js.nft.json +1 -1
  208. package/.next/server/app/knowledge/page_client-reference-manifest.js +1 -1
  209. package/.next/server/app/knowledge.html +1 -1
  210. package/.next/server/app/knowledge.rsc +18 -18
  211. package/.next/server/app/knowledge.segments/_full.segment.rsc +18 -18
  212. package/.next/server/app/knowledge.segments/_head.segment.rsc +4 -4
  213. package/.next/server/app/knowledge.segments/_index.segment.rsc +10 -10
  214. package/.next/server/app/knowledge.segments/_tree.segment.rsc +2 -2
  215. package/.next/server/app/knowledge.segments/knowledge/__PAGE__.segment.rsc +4 -4
  216. package/.next/server/app/knowledge.segments/knowledge.segment.rsc +4 -4
  217. package/.next/server/app/page.js.nft.json +1 -1
  218. package/.next/server/app/page_client-reference-manifest.js +1 -1
  219. package/.next/server/app/reading/page.js.nft.json +1 -1
  220. package/.next/server/app/reading/page_client-reference-manifest.js +1 -1
  221. package/.next/server/app/reading.html +1 -1
  222. package/.next/server/app/reading.rsc +17 -17
  223. package/.next/server/app/reading.segments/_full.segment.rsc +17 -17
  224. package/.next/server/app/reading.segments/_head.segment.rsc +4 -4
  225. package/.next/server/app/reading.segments/_index.segment.rsc +10 -10
  226. package/.next/server/app/reading.segments/_tree.segment.rsc +2 -2
  227. package/.next/server/app/reading.segments/reading/__PAGE__.segment.rsc +4 -4
  228. package/.next/server/app/reading.segments/reading.segment.rsc +3 -3
  229. package/.next/server/app/schedule/page.js.nft.json +1 -1
  230. package/.next/server/app/schedule/page_client-reference-manifest.js +1 -1
  231. package/.next/server/app/schedule.html +1 -1
  232. package/.next/server/app/schedule.rsc +17 -17
  233. package/.next/server/app/schedule.segments/_full.segment.rsc +17 -17
  234. package/.next/server/app/schedule.segments/_head.segment.rsc +4 -4
  235. package/.next/server/app/schedule.segments/_index.segment.rsc +10 -10
  236. package/.next/server/app/schedule.segments/_tree.segment.rsc +2 -2
  237. package/.next/server/app/schedule.segments/schedule/__PAGE__.segment.rsc +4 -4
  238. package/.next/server/app/schedule.segments/schedule.segment.rsc +3 -3
  239. package/.next/server/app/settings/advanced/page.js.nft.json +1 -1
  240. package/.next/server/app/settings/advanced/page_client-reference-manifest.js +1 -1
  241. package/.next/server/app/settings/advanced.html +1 -1
  242. package/.next/server/app/settings/advanced.rsc +18 -18
  243. package/.next/server/app/settings/advanced.segments/_full.segment.rsc +18 -18
  244. package/.next/server/app/settings/advanced.segments/_head.segment.rsc +4 -4
  245. package/.next/server/app/settings/advanced.segments/_index.segment.rsc +10 -10
  246. package/.next/server/app/settings/advanced.segments/_tree.segment.rsc +2 -2
  247. package/.next/server/app/settings/advanced.segments/settings/advanced/__PAGE__.segment.rsc +4 -4
  248. package/.next/server/app/settings/advanced.segments/settings/advanced.segment.rsc +3 -3
  249. package/.next/server/app/settings/advanced.segments/settings.segment.rsc +4 -4
  250. package/.next/server/app/settings/backends/page.js.nft.json +1 -1
  251. package/.next/server/app/settings/backends/page_client-reference-manifest.js +1 -1
  252. package/.next/server/app/settings/backends.html +1 -1
  253. package/.next/server/app/settings/backends.rsc +16 -16
  254. package/.next/server/app/settings/backends.segments/_full.segment.rsc +16 -16
  255. package/.next/server/app/settings/backends.segments/_head.segment.rsc +4 -4
  256. package/.next/server/app/settings/backends.segments/_index.segment.rsc +10 -10
  257. package/.next/server/app/settings/backends.segments/_tree.segment.rsc +2 -2
  258. package/.next/server/app/settings/backends.segments/settings/backends/__PAGE__.segment.rsc +2 -2
  259. package/.next/server/app/settings/backends.segments/settings/backends.segment.rsc +3 -3
  260. package/.next/server/app/settings/backends.segments/settings.segment.rsc +4 -4
  261. package/.next/server/app/settings/commands/page.js.nft.json +1 -1
  262. package/.next/server/app/settings/commands/page_client-reference-manifest.js +1 -1
  263. package/.next/server/app/settings/commands.html +1 -1
  264. package/.next/server/app/settings/commands.rsc +18 -18
  265. package/.next/server/app/settings/commands.segments/_full.segment.rsc +18 -18
  266. package/.next/server/app/settings/commands.segments/_head.segment.rsc +4 -4
  267. package/.next/server/app/settings/commands.segments/_index.segment.rsc +10 -10
  268. package/.next/server/app/settings/commands.segments/_tree.segment.rsc +2 -2
  269. package/.next/server/app/settings/commands.segments/settings/commands/__PAGE__.segment.rsc +4 -4
  270. package/.next/server/app/settings/commands.segments/settings/commands.segment.rsc +3 -3
  271. package/.next/server/app/settings/commands.segments/settings.segment.rsc +4 -4
  272. package/.next/server/app/settings/connections/page.js.nft.json +1 -1
  273. package/.next/server/app/settings/connections/page_client-reference-manifest.js +1 -1
  274. package/.next/server/app/settings/connections.html +1 -1
  275. package/.next/server/app/settings/connections.rsc +16 -16
  276. package/.next/server/app/settings/connections.segments/_full.segment.rsc +16 -16
  277. package/.next/server/app/settings/connections.segments/_head.segment.rsc +4 -4
  278. package/.next/server/app/settings/connections.segments/_index.segment.rsc +10 -10
  279. package/.next/server/app/settings/connections.segments/_tree.segment.rsc +2 -2
  280. package/.next/server/app/settings/connections.segments/settings/connections/__PAGE__.segment.rsc +2 -2
  281. package/.next/server/app/settings/connections.segments/settings/connections.segment.rsc +3 -3
  282. package/.next/server/app/settings/connections.segments/settings.segment.rsc +4 -4
  283. package/.next/server/app/settings/journal/page.js.nft.json +1 -1
  284. package/.next/server/app/settings/journal/page_client-reference-manifest.js +1 -1
  285. package/.next/server/app/settings/journal.html +1 -1
  286. package/.next/server/app/settings/journal.rsc +18 -18
  287. package/.next/server/app/settings/journal.segments/_full.segment.rsc +18 -18
  288. package/.next/server/app/settings/journal.segments/_head.segment.rsc +4 -4
  289. package/.next/server/app/settings/journal.segments/_index.segment.rsc +10 -10
  290. package/.next/server/app/settings/journal.segments/_tree.segment.rsc +2 -2
  291. package/.next/server/app/settings/journal.segments/settings/journal/__PAGE__.segment.rsc +4 -4
  292. package/.next/server/app/settings/journal.segments/settings/journal.segment.rsc +3 -3
  293. package/.next/server/app/settings/journal.segments/settings.segment.rsc +4 -4
  294. package/.next/server/app/settings/management/page.js.nft.json +1 -1
  295. package/.next/server/app/settings/management/page_client-reference-manifest.js +1 -1
  296. package/.next/server/app/settings/management.html +1 -1
  297. package/.next/server/app/settings/management.rsc +18 -18
  298. package/.next/server/app/settings/management.segments/_full.segment.rsc +18 -18
  299. package/.next/server/app/settings/management.segments/_head.segment.rsc +4 -4
  300. package/.next/server/app/settings/management.segments/_index.segment.rsc +10 -10
  301. package/.next/server/app/settings/management.segments/_tree.segment.rsc +2 -2
  302. package/.next/server/app/settings/management.segments/settings/management/__PAGE__.segment.rsc +4 -4
  303. package/.next/server/app/settings/management.segments/settings/management.segment.rsc +3 -3
  304. package/.next/server/app/settings/management.segments/settings.segment.rsc +4 -4
  305. package/.next/server/app/settings/messaging/page.js.nft.json +1 -1
  306. package/.next/server/app/settings/messaging/page_client-reference-manifest.js +1 -1
  307. package/.next/server/app/settings/messaging.html +1 -1
  308. package/.next/server/app/settings/messaging.rsc +16 -16
  309. package/.next/server/app/settings/messaging.segments/_full.segment.rsc +16 -16
  310. package/.next/server/app/settings/messaging.segments/_head.segment.rsc +4 -4
  311. package/.next/server/app/settings/messaging.segments/_index.segment.rsc +10 -10
  312. package/.next/server/app/settings/messaging.segments/_tree.segment.rsc +2 -2
  313. package/.next/server/app/settings/messaging.segments/settings/messaging/__PAGE__.segment.rsc +2 -2
  314. package/.next/server/app/settings/messaging.segments/settings/messaging.segment.rsc +3 -3
  315. package/.next/server/app/settings/messaging.segments/settings.segment.rsc +4 -4
  316. package/.next/server/app/settings/models/page.js.nft.json +1 -1
  317. package/.next/server/app/settings/models/page_client-reference-manifest.js +1 -1
  318. package/.next/server/app/settings/models.html +1 -1
  319. package/.next/server/app/settings/models.rsc +18 -18
  320. package/.next/server/app/settings/models.segments/_full.segment.rsc +18 -18
  321. package/.next/server/app/settings/models.segments/_head.segment.rsc +4 -4
  322. package/.next/server/app/settings/models.segments/_index.segment.rsc +10 -10
  323. package/.next/server/app/settings/models.segments/_tree.segment.rsc +2 -2
  324. package/.next/server/app/settings/models.segments/settings/models/__PAGE__.segment.rsc +4 -4
  325. package/.next/server/app/settings/models.segments/settings/models.segment.rsc +3 -3
  326. package/.next/server/app/settings/models.segments/settings.segment.rsc +4 -4
  327. package/.next/server/app/settings/page.js.nft.json +1 -1
  328. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  329. package/.next/server/app/settings/processes/page.js.nft.json +1 -1
  330. package/.next/server/app/settings/processes/page_client-reference-manifest.js +1 -1
  331. package/.next/server/app/settings/processes.html +1 -1
  332. package/.next/server/app/settings/processes.rsc +16 -16
  333. package/.next/server/app/settings/processes.segments/_full.segment.rsc +16 -16
  334. package/.next/server/app/settings/processes.segments/_head.segment.rsc +4 -4
  335. package/.next/server/app/settings/processes.segments/_index.segment.rsc +10 -10
  336. package/.next/server/app/settings/processes.segments/_tree.segment.rsc +2 -2
  337. package/.next/server/app/settings/processes.segments/settings/processes/__PAGE__.segment.rsc +2 -2
  338. package/.next/server/app/settings/processes.segments/settings/processes.segment.rsc +3 -3
  339. package/.next/server/app/settings/processes.segments/settings.segment.rsc +4 -4
  340. package/.next/server/app/settings/routines/page.js.nft.json +1 -1
  341. package/.next/server/app/settings/routines/page_client-reference-manifest.js +1 -1
  342. package/.next/server/app/settings/routines.html +1 -1
  343. package/.next/server/app/settings/routines.rsc +18 -18
  344. package/.next/server/app/settings/routines.segments/_full.segment.rsc +18 -18
  345. package/.next/server/app/settings/routines.segments/_head.segment.rsc +4 -4
  346. package/.next/server/app/settings/routines.segments/_index.segment.rsc +10 -10
  347. package/.next/server/app/settings/routines.segments/_tree.segment.rsc +2 -2
  348. package/.next/server/app/settings/routines.segments/settings/routines/__PAGE__.segment.rsc +4 -4
  349. package/.next/server/app/settings/routines.segments/settings/routines.segment.rsc +3 -3
  350. package/.next/server/app/settings/routines.segments/settings.segment.rsc +4 -4
  351. package/.next/server/app/settings/schedule/page.js.nft.json +1 -1
  352. package/.next/server/app/settings/schedule/page_client-reference-manifest.js +1 -1
  353. package/.next/server/app/settings/schedule.html +1 -1
  354. package/.next/server/app/settings/schedule.rsc +18 -18
  355. package/.next/server/app/settings/schedule.segments/_full.segment.rsc +18 -18
  356. package/.next/server/app/settings/schedule.segments/_head.segment.rsc +4 -4
  357. package/.next/server/app/settings/schedule.segments/_index.segment.rsc +10 -10
  358. package/.next/server/app/settings/schedule.segments/_tree.segment.rsc +2 -2
  359. package/.next/server/app/settings/schedule.segments/settings/schedule/__PAGE__.segment.rsc +4 -4
  360. package/.next/server/app/settings/schedule.segments/settings/schedule.segment.rsc +3 -3
  361. package/.next/server/app/settings/schedule.segments/settings.segment.rsc +4 -4
  362. package/.next/server/app/settings/self-learning/page.js.nft.json +1 -1
  363. package/.next/server/app/settings/self-learning/page_client-reference-manifest.js +1 -1
  364. package/.next/server/app/settings/self-learning.html +1 -1
  365. package/.next/server/app/settings/self-learning.rsc +18 -18
  366. package/.next/server/app/settings/self-learning.segments/_full.segment.rsc +18 -18
  367. package/.next/server/app/settings/self-learning.segments/_head.segment.rsc +4 -4
  368. package/.next/server/app/settings/self-learning.segments/_index.segment.rsc +10 -10
  369. package/.next/server/app/settings/self-learning.segments/_tree.segment.rsc +2 -2
  370. package/.next/server/app/settings/self-learning.segments/settings/self-learning/__PAGE__.segment.rsc +4 -4
  371. package/.next/server/app/settings/self-learning.segments/settings/self-learning.segment.rsc +3 -3
  372. package/.next/server/app/settings/self-learning.segments/settings.segment.rsc +4 -4
  373. package/.next/server/app/settings/wiki/page/app-paths-manifest.json +3 -0
  374. package/.next/server/app/settings/wiki/page/build-manifest.json +18 -0
  375. package/.next/server/app/settings/wiki/page/next-font-manifest.json +6 -0
  376. package/.next/server/app/settings/wiki/page/react-loadable-manifest.json +8 -0
  377. package/.next/server/app/settings/wiki/page/server-reference-manifest.json +4 -0
  378. package/.next/server/app/settings/wiki/page.js +16 -0
  379. package/.next/server/app/settings/wiki/page.js.map +5 -0
  380. package/.next/server/app/settings/wiki/page.js.nft.json +1 -0
  381. package/.next/server/app/settings/wiki/page_client-reference-manifest.js +3 -0
  382. package/.next/server/app/settings/wiki/timeline/page/app-paths-manifest.json +3 -0
  383. package/.next/server/app/settings/wiki/timeline/page/build-manifest.json +18 -0
  384. package/.next/server/app/settings/wiki/timeline/page/next-font-manifest.json +6 -0
  385. package/.next/server/app/settings/wiki/timeline/page/react-loadable-manifest.json +8 -0
  386. package/.next/server/app/settings/wiki/timeline/page/server-reference-manifest.json +4 -0
  387. package/.next/server/app/settings/wiki/timeline/page.js +17 -0
  388. package/.next/server/app/settings/wiki/timeline/page.js.map +5 -0
  389. package/.next/server/app/settings/wiki/timeline/page.js.nft.json +1 -0
  390. package/.next/server/app/settings/wiki/timeline/page_client-reference-manifest.js +3 -0
  391. package/.next/server/app/settings/wiki/timeline.html +1 -0
  392. package/.next/server/app/settings/wiki/timeline.meta +17 -0
  393. package/.next/server/app/settings/wiki/timeline.rsc +24 -0
  394. package/.next/server/app/settings/wiki/timeline.segments/_full.segment.rsc +24 -0
  395. package/.next/server/app/settings/wiki/timeline.segments/_head.segment.rsc +6 -0
  396. package/.next/server/app/settings/wiki/timeline.segments/_index.segment.rsc +11 -0
  397. package/.next/server/app/settings/wiki/timeline.segments/_tree.segment.rsc +2 -0
  398. package/.next/server/app/settings/wiki/timeline.segments/settings/wiki/timeline/__PAGE__.segment.rsc +6 -0
  399. package/.next/server/app/settings/wiki/timeline.segments/settings/wiki/timeline.segment.rsc +5 -0
  400. package/.next/server/app/settings/wiki/timeline.segments/settings/wiki.segment.rsc +5 -0
  401. package/.next/server/app/settings/wiki/timeline.segments/settings.segment.rsc +5 -0
  402. package/.next/server/app/settings/wiki.html +1 -0
  403. package/.next/server/app/settings/wiki.meta +16 -0
  404. package/.next/server/app/settings/wiki.rsc +27 -0
  405. package/.next/server/app/settings/wiki.segments/_full.segment.rsc +27 -0
  406. package/.next/server/app/settings/wiki.segments/_head.segment.rsc +6 -0
  407. package/.next/server/app/settings/wiki.segments/_index.segment.rsc +11 -0
  408. package/.next/server/app/settings/wiki.segments/_tree.segment.rsc +2 -0
  409. package/.next/server/app/settings/wiki.segments/settings/wiki/__PAGE__.segment.rsc +9 -0
  410. package/.next/server/app/settings/wiki.segments/settings/wiki.segment.rsc +5 -0
  411. package/.next/server/app/settings/wiki.segments/settings.segment.rsc +5 -0
  412. package/.next/server/app/settings.html +1 -1
  413. package/.next/server/app/settings.rsc +18 -18
  414. package/.next/server/app/settings.segments/_full.segment.rsc +18 -18
  415. package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
  416. package/.next/server/app/settings.segments/_index.segment.rsc +10 -10
  417. package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  418. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
  419. package/.next/server/app/settings.segments/settings.segment.rsc +4 -4
  420. package/.next/server/app/setup/page.js.nft.json +1 -1
  421. package/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  422. package/.next/server/app/setup.html +1 -1
  423. package/.next/server/app/setup.rsc +17 -17
  424. package/.next/server/app/setup.segments/_full.segment.rsc +17 -17
  425. package/.next/server/app/setup.segments/_head.segment.rsc +4 -4
  426. package/.next/server/app/setup.segments/_index.segment.rsc +10 -10
  427. package/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  428. package/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +4 -4
  429. package/.next/server/app/setup.segments/setup.segment.rsc +3 -3
  430. package/.next/server/app/trip/page.js.nft.json +1 -1
  431. package/.next/server/app/trip/page_client-reference-manifest.js +1 -1
  432. package/.next/server/app/trip.html +1 -1
  433. package/.next/server/app/trip.rsc +17 -17
  434. package/.next/server/app/trip.segments/_full.segment.rsc +17 -17
  435. package/.next/server/app/trip.segments/_head.segment.rsc +4 -4
  436. package/.next/server/app/trip.segments/_index.segment.rsc +10 -10
  437. package/.next/server/app/trip.segments/_tree.segment.rsc +2 -2
  438. package/.next/server/app/trip.segments/trip/__PAGE__.segment.rsc +4 -4
  439. package/.next/server/app/trip.segments/trip.segment.rsc +3 -3
  440. package/.next/server/app/wiki/page/app-paths-manifest.json +3 -0
  441. package/.next/server/app/wiki/page/build-manifest.json +18 -0
  442. package/.next/server/app/wiki/page/next-font-manifest.json +6 -0
  443. package/.next/server/app/wiki/page/react-loadable-manifest.json +8 -0
  444. package/.next/server/app/wiki/page/server-reference-manifest.json +4 -0
  445. package/.next/server/app/wiki/page.js +15 -0
  446. package/.next/server/app/wiki/page.js.map +5 -0
  447. package/.next/server/app/wiki/page.js.nft.json +1 -0
  448. package/.next/server/app/wiki/page_client-reference-manifest.js +3 -0
  449. package/.next/server/app/wiki/timeline/page/app-paths-manifest.json +3 -0
  450. package/.next/server/app/wiki/timeline/page/build-manifest.json +18 -0
  451. package/.next/server/app/wiki/timeline/page/next-font-manifest.json +6 -0
  452. package/.next/server/app/wiki/timeline/page/react-loadable-manifest.json +8 -0
  453. package/.next/server/app/wiki/timeline/page/server-reference-manifest.json +4 -0
  454. package/.next/server/app/wiki/timeline/page.js +15 -0
  455. package/.next/server/app/wiki/timeline/page.js.map +5 -0
  456. package/.next/server/app/wiki/timeline/page.js.nft.json +1 -0
  457. package/.next/server/app/wiki/timeline/page_client-reference-manifest.js +3 -0
  458. package/.next/server/app/wiki/timeline.html +1 -0
  459. package/.next/server/app/wiki/timeline.meta +16 -0
  460. package/.next/server/app/wiki/timeline.rsc +26 -0
  461. package/.next/server/app/wiki/timeline.segments/_full.segment.rsc +26 -0
  462. package/.next/server/app/wiki/timeline.segments/_head.segment.rsc +6 -0
  463. package/.next/server/app/wiki/timeline.segments/_index.segment.rsc +11 -0
  464. package/.next/server/app/wiki/timeline.segments/_tree.segment.rsc +2 -0
  465. package/.next/server/app/wiki/timeline.segments/wiki/timeline/__PAGE__.segment.rsc +9 -0
  466. package/.next/server/app/wiki/timeline.segments/wiki/timeline.segment.rsc +5 -0
  467. package/.next/server/app/wiki/timeline.segments/wiki.segment.rsc +5 -0
  468. package/.next/server/app/wiki.html +1 -0
  469. package/.next/server/app/wiki.meta +15 -0
  470. package/.next/server/app/wiki.rsc +26 -0
  471. package/.next/server/app/wiki.segments/_full.segment.rsc +26 -0
  472. package/.next/server/app/wiki.segments/_head.segment.rsc +6 -0
  473. package/.next/server/app/wiki.segments/_index.segment.rsc +11 -0
  474. package/.next/server/app/wiki.segments/_tree.segment.rsc +2 -0
  475. package/.next/server/app/wiki.segments/wiki/__PAGE__.segment.rsc +9 -0
  476. package/.next/server/app/wiki.segments/wiki.segment.rsc +5 -0
  477. package/.next/server/app-paths-manifest.json +5 -1
  478. package/.next/server/chunks/0z~i_next_dist_esm_build_templates_app-route_0o_o_hp.js +1 -1
  479. package/.next/server/chunks/0z~i_next_dist_esm_build_templates_app-route_0o_o_hp.js.map +1 -1
  480. package/.next/server/chunks/{[root-of-the-server]__00gp8gz._.js → [root-of-the-server]__01knfi.._.js} +1 -1
  481. package/.next/server/chunks/{[root-of-the-server]__0-0wgko._.js → [root-of-the-server]__08_s4yo._.js} +2 -2
  482. package/.next/server/chunks/ssr/0juq_dashboard__next-internal_server_app_settings_wiki_timeline_page_actions_0czqn6z.js +3 -0
  483. package/.next/server/chunks/ssr/0juq_dashboard__next-internal_server_app_settings_wiki_timeline_page_actions_0czqn6z.js.map +1 -0
  484. package/.next/server/chunks/ssr/0mzu_lucide-react_dist_esm_icons_zap_115-27i.js +3 -0
  485. package/.next/server/chunks/ssr/0mzu_lucide-react_dist_esm_icons_zap_115-27i.js.map +1 -0
  486. package/.next/server/chunks/ssr/0z~i_next_dist_esm_build_templates_app-page_0k3x-na.js +4 -0
  487. package/.next/server/chunks/ssr/0z~i_next_dist_esm_build_templates_app-page_0k3x-na.js.map +1 -0
  488. package/.next/server/chunks/ssr/0z~i_next_dist_esm_build_templates_app-page_0km22.v.js +4 -0
  489. package/.next/server/chunks/ssr/0z~i_next_dist_esm_build_templates_app-page_0km22.v.js.map +1 -0
  490. package/.next/server/chunks/ssr/0z~i_next_dist_esm_build_templates_app-page_0vui1gx.js +4 -0
  491. package/.next/server/chunks/ssr/0z~i_next_dist_esm_build_templates_app-page_0vui1gx.js.map +1 -0
  492. package/.next/server/chunks/ssr/0z~i_next_dist_esm_build_templates_app-page_11h319t.js +4 -0
  493. package/.next/server/chunks/ssr/0z~i_next_dist_esm_build_templates_app-page_11h319t.js.map +1 -0
  494. package/.next/server/chunks/ssr/[root-of-the-server]__007ymqm._.js +3 -0
  495. package/.next/server/chunks/ssr/[root-of-the-server]__007ymqm._.js.map +1 -0
  496. package/.next/server/chunks/ssr/[root-of-the-server]__00vjce2._.js +3 -0
  497. package/.next/server/chunks/ssr/[root-of-the-server]__00vjce2._.js.map +1 -0
  498. package/.next/server/chunks/ssr/[root-of-the-server]__07pkvm3._.js +3 -0
  499. package/.next/server/chunks/ssr/[root-of-the-server]__07pkvm3._.js.map +1 -0
  500. package/.next/server/chunks/ssr/[root-of-the-server]__0dfuz7_._.js +3 -0
  501. package/.next/server/chunks/ssr/[root-of-the-server]__0dfuz7_._.js.map +1 -0
  502. package/.next/server/chunks/ssr/[root-of-the-server]__117dw_l._.js +3 -0
  503. package/.next/server/chunks/ssr/[root-of-the-server]__117dw_l._.js.map +1 -0
  504. package/.next/server/chunks/ssr/_0-3uzu1._.js +3 -0
  505. package/.next/server/chunks/ssr/_0-3uzu1._.js.map +1 -0
  506. package/.next/server/chunks/ssr/_0-6jgyg._.js +3 -0
  507. package/.next/server/chunks/ssr/_0-6jgyg._.js.map +1 -0
  508. package/.next/server/chunks/ssr/_0-fv_sr._.js +1 -1
  509. package/.next/server/chunks/ssr/_0-fv_sr._.js.map +1 -1
  510. package/.next/server/chunks/ssr/_0.7pki~._.js +3 -0
  511. package/.next/server/chunks/ssr/_0.7pki~._.js.map +1 -0
  512. package/.next/server/chunks/ssr/_02s86rg._.js +3 -0
  513. package/.next/server/chunks/ssr/_02s86rg._.js.map +1 -0
  514. package/.next/server/chunks/ssr/_03bq.de._.js +3 -0
  515. package/.next/server/chunks/ssr/_03bq.de._.js.map +1 -0
  516. package/.next/server/chunks/ssr/_03u6ja0._.js +3 -0
  517. package/.next/server/chunks/ssr/_03u6ja0._.js.map +1 -0
  518. package/.next/server/chunks/ssr/_04-.z69._.js +3 -0
  519. package/.next/server/chunks/ssr/_04-.z69._.js.map +1 -0
  520. package/.next/server/chunks/ssr/_05rlac0._.js +3 -0
  521. package/.next/server/chunks/ssr/_05rlac0._.js.map +1 -0
  522. package/.next/server/chunks/ssr/_05xysbw._.js +3 -0
  523. package/.next/server/chunks/ssr/_05xysbw._.js.map +1 -0
  524. package/.next/server/chunks/ssr/_09e_66m._.js +3 -0
  525. package/.next/server/chunks/ssr/_09e_66m._.js.map +1 -0
  526. package/.next/server/chunks/ssr/_0_bnan9._.js +3 -0
  527. package/.next/server/chunks/ssr/_0_bnan9._.js.map +1 -0
  528. package/.next/server/chunks/ssr/_0b00io4._.js +3 -0
  529. package/.next/server/chunks/ssr/_0b00io4._.js.map +1 -0
  530. package/.next/server/chunks/ssr/_0es_2i2._.js +3 -0
  531. package/.next/server/chunks/ssr/_0es_2i2._.js.map +1 -0
  532. package/.next/server/chunks/ssr/_0g7_r5i._.js +3 -0
  533. package/.next/server/chunks/ssr/_0g7_r5i._.js.map +1 -0
  534. package/.next/server/chunks/ssr/_0hojxqy._.js +1 -1
  535. package/.next/server/chunks/ssr/_0hojxqy._.js.map +1 -1
  536. package/.next/server/chunks/ssr/_0ifb9jm._.js +3 -0
  537. package/.next/server/chunks/ssr/_0ifb9jm._.js.map +1 -0
  538. package/.next/server/chunks/ssr/_0jl_-u5._.js +3 -0
  539. package/.next/server/chunks/ssr/_0jl_-u5._.js.map +1 -0
  540. package/.next/server/chunks/ssr/_0lfuvjg._.js +3 -0
  541. package/.next/server/chunks/ssr/_0lfuvjg._.js.map +1 -0
  542. package/.next/server/chunks/ssr/{_0jm~wn-._.js → _0mp7n5i._.js} +2 -2
  543. package/.next/server/chunks/ssr/{_0jm~wn-._.js.map → _0mp7n5i._.js.map} +1 -1
  544. package/.next/server/chunks/ssr/_0powsoh._.js +3 -0
  545. package/.next/server/chunks/ssr/_0powsoh._.js.map +1 -0
  546. package/.next/server/chunks/ssr/_0q34y9l._.js +3 -0
  547. package/.next/server/chunks/ssr/_0q34y9l._.js.map +1 -0
  548. package/.next/server/chunks/ssr/_0q4rpi-._.js +5 -0
  549. package/.next/server/chunks/ssr/_0q4rpi-._.js.map +1 -0
  550. package/.next/server/chunks/ssr/_0rc-7d4._.js +3 -0
  551. package/.next/server/chunks/ssr/_0rc-7d4._.js.map +1 -0
  552. package/.next/server/chunks/ssr/_0tjsh16._.js +3 -0
  553. package/.next/server/chunks/ssr/_0tjsh16._.js.map +1 -0
  554. package/.next/server/chunks/ssr/_0tl98en._.js +1 -1
  555. package/.next/server/chunks/ssr/_0tl98en._.js.map +1 -1
  556. package/.next/server/chunks/ssr/{_0._ysx3._.js → _0v_6ros._.js} +2 -2
  557. package/.next/server/chunks/ssr/_0v_6ros._.js.map +1 -0
  558. package/.next/server/chunks/ssr/_0vncjim._.js +3 -0
  559. package/.next/server/chunks/ssr/_0vncjim._.js.map +1 -0
  560. package/.next/server/chunks/ssr/_0vx-jgf._.js +3 -0
  561. package/.next/server/chunks/ssr/_0vx-jgf._.js.map +1 -0
  562. package/.next/server/chunks/ssr/_0w1ez1p._.js +3 -0
  563. package/.next/server/chunks/ssr/_0w1ez1p._.js.map +1 -0
  564. package/.next/server/chunks/ssr/_0yl49yk._.js +3 -0
  565. package/.next/server/chunks/ssr/_0yl49yk._.js.map +1 -0
  566. package/.next/server/chunks/ssr/_0z1ah9x._.js +1 -1
  567. package/.next/server/chunks/ssr/_0z1ah9x._.js.map +1 -1
  568. package/.next/server/chunks/ssr/_0z9ikwn._.js +3 -0
  569. package/.next/server/chunks/ssr/_0z9ikwn._.js.map +1 -0
  570. package/.next/server/chunks/ssr/_0z_cp12._.js +3 -0
  571. package/.next/server/chunks/ssr/_0z_cp12._.js.map +1 -0
  572. package/.next/server/chunks/ssr/_10hvwg5._.js +3 -0
  573. package/.next/server/chunks/ssr/_10hvwg5._.js.map +1 -0
  574. package/.next/server/chunks/ssr/packages_dashboard__next-internal_server_app_settings_wiki_page_actions_12d~w9l.js +3 -0
  575. package/.next/server/chunks/ssr/packages_dashboard__next-internal_server_app_settings_wiki_page_actions_12d~w9l.js.map +1 -0
  576. package/.next/server/chunks/ssr/packages_dashboard__next-internal_server_app_wiki_page_actions_026bi.d.js +3 -0
  577. package/.next/server/chunks/ssr/packages_dashboard__next-internal_server_app_wiki_page_actions_026bi.d.js.map +1 -0
  578. package/.next/server/chunks/ssr/packages_dashboard__next-internal_server_app_wiki_timeline_page_actions_06jb4gg.js +3 -0
  579. package/.next/server/chunks/ssr/packages_dashboard__next-internal_server_app_wiki_timeline_page_actions_06jb4gg.js.map +1 -0
  580. package/.next/server/chunks/ssr/packages_dashboard_src_0bx940s._.js +3 -0
  581. package/.next/server/chunks/ssr/packages_dashboard_src_0bx940s._.js.map +1 -0
  582. package/.next/server/chunks/ssr/packages_dashboard_src_0fo7nqq._.js +3 -0
  583. package/.next/server/chunks/ssr/packages_dashboard_src_0fo7nqq._.js.map +1 -0
  584. package/.next/server/chunks/ssr/packages_dashboard_src_0uxs9-.._.js +1 -1
  585. package/.next/server/chunks/ssr/packages_dashboard_src_0uxs9-.._.js.map +1 -1
  586. package/.next/server/chunks/ssr/packages_dashboard_src_app_activity_page_tsx_08yep46._.js +1 -1
  587. package/.next/server/chunks/ssr/packages_dashboard_src_app_activity_page_tsx_08yep46._.js.map +1 -1
  588. package/.next/server/chunks/ssr/packages_dashboard_src_app_connections_repositories_page_tsx_08y6paq._.js +1 -1
  589. package/.next/server/chunks/ssr/packages_dashboard_src_app_connections_repositories_page_tsx_08y6paq._.js.map +1 -1
  590. package/.next/server/chunks/ssr/packages_dashboard_src_app_git_page_tsx_0ah19-6._.js +1 -1
  591. package/.next/server/chunks/ssr/packages_dashboard_src_app_git_page_tsx_0ah19-6._.js.map +1 -1
  592. package/.next/server/chunks/ssr/packages_dashboard_src_app_schedule_page_tsx_0znc404._.js +1 -1
  593. package/.next/server/chunks/ssr/packages_dashboard_src_app_schedule_page_tsx_0znc404._.js.map +1 -1
  594. package/.next/server/chunks/ssr/packages_dashboard_src_app_settings_models_page_tsx_0djsx88._.js +1 -1
  595. package/.next/server/chunks/ssr/packages_dashboard_src_app_settings_models_page_tsx_0djsx88._.js.map +1 -1
  596. package/.next/server/chunks/ssr/packages_dashboard_src_app_settings_schedule_page_tsx_0b8zr2l._.js +1 -1
  597. package/.next/server/chunks/ssr/packages_dashboard_src_app_settings_schedule_page_tsx_0b8zr2l._.js.map +1 -1
  598. package/.next/server/chunks/ssr/packages_dashboard_src_app_settings_wiki_page_tsx_0..1tkb._.js +3 -0
  599. package/.next/server/chunks/ssr/packages_dashboard_src_app_settings_wiki_page_tsx_0..1tkb._.js.map +1 -0
  600. package/.next/server/chunks/ssr/packages_dashboard_src_app_setup_page_tsx_06k3via._.js +1 -1
  601. package/.next/server/chunks/ssr/packages_dashboard_src_app_setup_page_tsx_06k3via._.js.map +1 -1
  602. package/.next/server/chunks/ssr/packages_dashboard_src_components_connections_slack-card_tsx_0mahejj._.js +1 -1
  603. package/.next/server/chunks/ssr/packages_dashboard_src_components_connections_slack-card_tsx_0mahejj._.js.map +1 -1
  604. package/.next/server/chunks/ssr/packages_dashboard_src_components_settings_backend-settings_tsx_0i-tp_u._.js +3 -0
  605. package/.next/server/chunks/ssr/packages_dashboard_src_components_settings_backend-settings_tsx_0i-tp_u._.js.map +1 -0
  606. package/.next/server/chunks/ssr/packages_shared_dist_index_0kuvow-.js +1 -1
  607. package/.next/server/chunks/ssr/packages_shared_dist_index_0kuvow-.js.map +1 -1
  608. package/.next/server/middleware/middleware-manifest.json +1 -1
  609. package/.next/server/middleware-build-manifest.js +3 -3
  610. package/.next/server/middleware-manifest.json +1 -1
  611. package/.next/server/pages/404.html +1 -1
  612. package/.next/server/pages/500.html +1 -1
  613. package/.next/static/chunks/01yix41q.0970.js +1 -0
  614. package/.next/static/chunks/02qjylw4yp63l.js +1 -0
  615. package/.next/static/chunks/06y2ddf5x9x_4.js +1 -0
  616. package/.next/static/chunks/{0ztl~44vjnpe1.js → 08ie9t4zn6n4-.js} +1 -1
  617. package/.next/static/chunks/091khs5zza4_4.js +1 -0
  618. package/.next/static/chunks/{0~_56pt8wsmeo.js → 0abhg-m1-acdb.js} +1 -1
  619. package/.next/static/chunks/0ae.1upy09t--.js +1 -0
  620. package/.next/static/chunks/0bvcd~k.vfro8.js +1 -0
  621. package/.next/static/chunks/{0g6.0r0i-wyeg.js → 0eqm47_oikj36.js} +1 -1
  622. package/.next/static/chunks/0fqugh~hv4my1.js +1 -0
  623. package/.next/static/chunks/0has04tc4mrik.js +1 -0
  624. package/.next/static/chunks/0huynm-qbj26k.js +1 -0
  625. package/.next/static/chunks/0ibq4zul6305p.js +1 -0
  626. package/.next/static/chunks/0jm_e6e6n~rdn.js +1 -0
  627. package/.next/static/chunks/0k0.4cksmybb2.js +1 -0
  628. package/.next/static/chunks/0l07yrtw3fxp5.js +1 -0
  629. package/.next/static/chunks/0nhqu-sq045x7.js +1 -0
  630. package/.next/static/chunks/0op3oc-if6n5-.js +3 -0
  631. package/.next/static/chunks/0p34n6.st3s~1.js +1 -0
  632. package/.next/static/chunks/0r8nosw42e2m9.js +1 -0
  633. package/.next/static/chunks/0shx3_mxukfhr.js +1 -0
  634. package/.next/static/chunks/0thm~t5g5adz1.js +1 -0
  635. package/.next/static/chunks/0thyr1cngc-j..css +1 -0
  636. package/.next/static/chunks/0ttdb_354lh4t.js +1 -0
  637. package/.next/static/chunks/0v..ut2v38yep.js +1 -0
  638. package/.next/static/chunks/{17npklzvg8-~3.js → 0vhj0k-zy6jhh.js} +1 -1
  639. package/.next/static/chunks/0wdx410~0~gmn.js +1 -0
  640. package/.next/static/chunks/0y3ptqa0bbi-h.js +1 -0
  641. package/.next/static/chunks/{0zbxi2grjtx.c.js → 0zx_~u_zxg_7e.js} +1 -1
  642. package/.next/static/chunks/{0f3kjzb~5zhc~.js → 10pq~97vgkzro.js} +1 -1
  643. package/.next/static/chunks/11hlk6.h1of0y.js +1 -0
  644. package/.next/static/chunks/13w_6v~nprp8j.js +11 -0
  645. package/.next/static/chunks/14-kkni6ecqaw.js +1 -0
  646. package/.next/static/chunks/{148a9fv~bo0gq.js → 1555iv~_t.1lp.js} +1 -1
  647. package/.next/static/chunks/{04bbme2th8s1_.js → 15ec5~pa1pv_z.js} +1 -1
  648. package/.next/static/chunks/15vc-857cdedi.js +1 -0
  649. package/.next/static/chunks/16zgco6hwlr-n.js +1 -0
  650. package/.next/trace +2 -2
  651. package/.next/trace-build +1 -1
  652. package/.next/types/routes.d.ts +5 -1
  653. package/.next/types/validator.ts +36 -0
  654. package/package.json +2 -2
  655. package/.next/server/chunks/ssr/[root-of-the-server]__02idks~._.js +0 -3
  656. package/.next/server/chunks/ssr/[root-of-the-server]__02idks~._.js.map +0 -1
  657. package/.next/server/chunks/ssr/_0-8__9s._.js +0 -3
  658. package/.next/server/chunks/ssr/_0-8__9s._.js.map +0 -1
  659. package/.next/server/chunks/ssr/_0._ysx3._.js.map +0 -1
  660. package/.next/server/chunks/ssr/_0.h-tj4._.js +0 -3
  661. package/.next/server/chunks/ssr/_0.h-tj4._.js.map +0 -1
  662. package/.next/server/chunks/ssr/_02g4o18._.js +0 -3
  663. package/.next/server/chunks/ssr/_02g4o18._.js.map +0 -1
  664. package/.next/server/chunks/ssr/_0463dg_._.js +0 -3
  665. package/.next/server/chunks/ssr/_0463dg_._.js.map +0 -1
  666. package/.next/server/chunks/ssr/_04a42pa._.js +0 -3
  667. package/.next/server/chunks/ssr/_04a42pa._.js.map +0 -1
  668. package/.next/server/chunks/ssr/_04kt9.8._.js +0 -3
  669. package/.next/server/chunks/ssr/_04kt9.8._.js.map +0 -1
  670. package/.next/server/chunks/ssr/_052zlig._.js +0 -3
  671. package/.next/server/chunks/ssr/_052zlig._.js.map +0 -1
  672. package/.next/server/chunks/ssr/_060itkv._.js +0 -3
  673. package/.next/server/chunks/ssr/_060itkv._.js.map +0 -1
  674. package/.next/server/chunks/ssr/_07p0n9g._.js +0 -3
  675. package/.next/server/chunks/ssr/_07p0n9g._.js.map +0 -1
  676. package/.next/server/chunks/ssr/_08mbdt1._.js +0 -3
  677. package/.next/server/chunks/ssr/_08mbdt1._.js.map +0 -1
  678. package/.next/server/chunks/ssr/_08r_qwd._.js +0 -3
  679. package/.next/server/chunks/ssr/_08r_qwd._.js.map +0 -1
  680. package/.next/server/chunks/ssr/_08xk3kp._.js +0 -3
  681. package/.next/server/chunks/ssr/_08xk3kp._.js.map +0 -1
  682. package/.next/server/chunks/ssr/_0938p.1._.js +0 -3
  683. package/.next/server/chunks/ssr/_0938p.1._.js.map +0 -1
  684. package/.next/server/chunks/ssr/_0afdsbz._.js +0 -3
  685. package/.next/server/chunks/ssr/_0afdsbz._.js.map +0 -1
  686. package/.next/server/chunks/ssr/_0ff5qav._.js +0 -3
  687. package/.next/server/chunks/ssr/_0ff5qav._.js.map +0 -1
  688. package/.next/server/chunks/ssr/_0gp8d.p._.js +0 -3
  689. package/.next/server/chunks/ssr/_0gp8d.p._.js.map +0 -1
  690. package/.next/server/chunks/ssr/_0k2j6-t._.js +0 -3
  691. package/.next/server/chunks/ssr/_0k2j6-t._.js.map +0 -1
  692. package/.next/server/chunks/ssr/_0mix09j._.js +0 -3
  693. package/.next/server/chunks/ssr/_0mix09j._.js.map +0 -1
  694. package/.next/server/chunks/ssr/_0mk7dqt._.js +0 -3
  695. package/.next/server/chunks/ssr/_0mk7dqt._.js.map +0 -1
  696. package/.next/server/chunks/ssr/_0n168uk._.js +0 -3
  697. package/.next/server/chunks/ssr/_0n168uk._.js.map +0 -1
  698. package/.next/server/chunks/ssr/_0nwg6lo._.js +0 -3
  699. package/.next/server/chunks/ssr/_0nwg6lo._.js.map +0 -1
  700. package/.next/server/chunks/ssr/_0pwd-nz._.js +0 -3
  701. package/.next/server/chunks/ssr/_0pwd-nz._.js.map +0 -1
  702. package/.next/server/chunks/ssr/_0rspzax._.js +0 -3
  703. package/.next/server/chunks/ssr/_0rspzax._.js.map +0 -1
  704. package/.next/server/chunks/ssr/_0t-2u_i._.js +0 -3
  705. package/.next/server/chunks/ssr/_0t-2u_i._.js.map +0 -1
  706. package/.next/server/chunks/ssr/_0vn5_62._.js +0 -5
  707. package/.next/server/chunks/ssr/_0vn5_62._.js.map +0 -1
  708. package/.next/server/chunks/ssr/_0yiz~s5._.js +0 -3
  709. package/.next/server/chunks/ssr/_0yiz~s5._.js.map +0 -1
  710. package/.next/server/chunks/ssr/_0~4ta0s._.js +0 -3
  711. package/.next/server/chunks/ssr/_0~4ta0s._.js.map +0 -1
  712. package/.next/server/chunks/ssr/_0~5r_8s._.js +0 -3
  713. package/.next/server/chunks/ssr/_0~5r_8s._.js.map +0 -1
  714. package/.next/server/chunks/ssr/_115_o9h._.js +0 -3
  715. package/.next/server/chunks/ssr/_115_o9h._.js.map +0 -1
  716. package/.next/server/chunks/ssr/_13mk_9n._.js +0 -3
  717. package/.next/server/chunks/ssr/_13mk_9n._.js.map +0 -1
  718. package/.next/server/chunks/ssr/packages_dashboard_src_07.4ogy._.js +0 -3
  719. package/.next/server/chunks/ssr/packages_dashboard_src_07.4ogy._.js.map +0 -1
  720. package/.next/static/chunks/00p2fat~wl7uz.js +0 -1
  721. package/.next/static/chunks/07aksg8x5r0d9.js +0 -1
  722. package/.next/static/chunks/082cjr-p4ubw7.js +0 -1
  723. package/.next/static/chunks/09hewwcw-ts34.js +0 -1
  724. package/.next/static/chunks/09j~fmfefj03i.js +0 -1
  725. package/.next/static/chunks/0adfy5uyh_8c8.js +0 -1
  726. package/.next/static/chunks/0agoryx~xvt31.js +0 -1
  727. package/.next/static/chunks/0aoci_z-c0ele.css +0 -1
  728. package/.next/static/chunks/0atsym5j2dgzw.js +0 -1
  729. package/.next/static/chunks/0b3tta7tnnbur.js +0 -1
  730. package/.next/static/chunks/0d02.lqlwe9a_.js +0 -1
  731. package/.next/static/chunks/0eqyosc.qae5n.js +0 -1
  732. package/.next/static/chunks/0kkrrex6qm68-.js +0 -1
  733. package/.next/static/chunks/0lfxqap3b6sar.js +0 -11
  734. package/.next/static/chunks/0ord2b6oqi.3g.js +0 -1
  735. package/.next/static/chunks/0rh-ee9ky1ybq.js +0 -1
  736. package/.next/static/chunks/0t5v~o90gn66f.js +0 -1
  737. package/.next/static/chunks/0vaymprggmdwi.js +0 -3
  738. package/.next/static/chunks/0x2vder5-rzy3.js +0 -1
  739. package/.next/static/chunks/0yk64vsbmwqd8.js +0 -1
  740. package/.next/static/chunks/0yvzj34_7s6kb.js +0 -1
  741. package/.next/static/chunks/104za._t2qmr8.js +0 -1
  742. package/.next/static/chunks/13pe2-ed6nel..js +0 -1
  743. package/.next/static/chunks/13zn61okwjlyn.js +0 -1
  744. package/.next/static/chunks/153hm0-366-at.js +0 -1
  745. package/.next/static/chunks/16k3_-6f7kx97.js +0 -1
  746. package/.next/static/chunks/18904zqns5ncn.js +0 -1
  747. /package/.next/server/chunks/{[root-of-the-server]__00gp8gz._.js.map → [root-of-the-server]__01knfi.._.js.map} +0 -0
  748. /package/.next/server/chunks/{[root-of-the-server]__0-0wgko._.js.map → [root-of-the-server]__08_s4yo._.js.map} +0 -0
  749. /package/.next/static/{CDXVH-99b-ZdHz0Rd9pr_ → lsV2FU1YUtwJPmeiim7tk}/_buildManifest.js +0 -0
  750. /package/.next/static/{CDXVH-99b-ZdHz0Rd9pr_ → lsV2FU1YUtwJPmeiim7tk}/_clientMiddlewareManifest.js +0 -0
  751. /package/.next/static/{CDXVH-99b-ZdHz0Rd9pr_ → lsV2FU1YUtwJPmeiim7tk}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../packages/dashboard/src/app/setup/page.tsx","../../../../../../packages/dashboard/src/components/setup/wizard-step-frame.tsx","../../../../../../packages/dashboard/src/components/setup/basics-step.tsx","../../../../../../packages/dashboard/src/components/setup/vault-step.logic.ts","../../../../../../packages/dashboard/src/components/setup/vault-step.tsx","../../../../../../packages/dashboard/src/components/setup/backends-step.tsx","../../../../../../packages/dashboard/src/components/setup/mail-step.tsx","../../../../../../packages/dashboard/src/components/setup/calendar-step.tsx","../../../../../../packages/dashboard/src/components/setup/note-step.tsx","../../../../../../packages/dashboard/src/components/setup/messaging-step.tsx","../../../../../../packages/dashboard/src/components/setup/conversation-step.tsx","../../../../../../packages/dashboard/src/components/setup/setup-complete.tsx","../../../../../../node_modules/.pnpm/lucide-react%400.468.0_react%4019.2.4/node_modules/lucide-react/src/icons/skip-forward.ts","../../../../../../packages/dashboard/src/components/setup/basics-step.logic.ts","../../../../../../packages/dashboard/src/lib/setup-storage.ts","../../../../../../packages/dashboard/src/components/setup/note-step.logic.ts","../../../../../../packages/dashboard/src/components/setup/wizard-steps.logic.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState, Suspense } from \"react\";\nimport { useSearchParams } from \"next/navigation\";\nimport { DEFAULT_AGENT_DISPLAY_NAME } from \"@aitne/shared\";\nimport { BasicsStep } from \"@/components/setup/basics-step\";\nimport { VaultStep } from \"@/components/setup/vault-step\";\nimport { BackendsStep } from \"@/components/setup/backends-step\";\nimport { MailStep } from \"@/components/setup/mail-step\";\nimport { CalendarStep } from \"@/components/setup/calendar-step\";\nimport { NoteStep } from \"@/components/setup/note-step\";\nimport { MessagingStep } from \"@/components/setup/messaging-step\";\nimport { ConversationStep } from \"@/components/setup/conversation-step\";\nimport { SetupComplete } from \"@/components/setup/setup-complete\";\nimport {\n BASE_INITIAL_STEPS,\n STEP_LABELS,\n deriveVaultMode,\n filterInitialSteps,\n type SetupStep,\n} from \"@/components/setup/wizard-steps.logic\";\nimport { useConfig } from \"@/lib/hooks/use-config\";\nimport { cn } from \"@/lib/utils\";\nimport { readWizardState, writeWizardState, clearWizardState } from \"@/lib/setup-storage\";\n\nfunction SetupPageInner() {\n const searchParams = useSearchParams();\n const mode = searchParams.get(\"mode\") === \"update\" ? \"update\" : \"initial\";\n const { data: config } = useConfig();\n\n // Wizard state is persisted in sessionStorage so a page reload mid-setup\n // restores progress. Update mode short-circuits to the rules step (the\n // chat-driven Customize Rules screen) — SETUP-FLOW-REDESIGN-PLAN §6.5.\n const [step, setStep] = useState<SetupStep>(() =>\n mode === \"update\"\n ? \"rules\"\n : ((readWizardState().step as SetupStep | undefined) ?? \"basics\"),\n );\n const [agentDisplayName, setAgentDisplayName] = useState(() =>\n mode === \"update\"\n ? DEFAULT_AGENT_DISPLAY_NAME\n : (readWizardState().agentDisplayName ?? \"\"),\n );\n\n const [modeOverride, setModeOverride] = useState<\n \"plain\" | \"obsidian\" | null\n >(() => (mode === \"initial\" ? readWizardState().modeOverride ?? null : null));\n const pendingVaultMode = deriveVaultMode(modeOverride, config?.vaultMode);\n const onPendingVaultModeChange = (next: \"plain\" | \"obsidian\") => {\n setModeOverride(next);\n };\n\n // SETUP-FLOW-REDESIGN-PLAN §5.2 — the chosen primary-vault path is held\n // here (not committed) until the user enters the Customize Rules step.\n // Hydrated from sessionStorage only; we don't seed from\n // `config.primaryVaultPath` because (a) initial-mode runs start from a\n // plain default so there's nothing useful to seed, and (b) the\n // DirectoryPickerField in VaultStep already passes\n // `config.primaryVaultPath` as the picker's `defaultPath`, so a user\n // re-doing setup over a prior install sees the previous folder in the\n // native picker without us setting state inside an effect.\n const [pendingVaultPath, setPendingVaultPath] = useState<string>(\n () =>\n mode === \"initial\"\n ? (readWizardState().pendingVaultPath ?? \"\")\n : \"\",\n );\n\n // Persist wizard state on every change so reload restores progress.\n useEffect(() => {\n if (mode === \"update\") return;\n writeWizardState({\n step,\n agentDisplayName,\n modeOverride,\n pendingVaultPath: pendingVaultPath || null,\n });\n }, [mode, step, agentDisplayName, modeOverride, pendingVaultPath]);\n\n // Reaching `complete` means rules were saved successfully — clear all\n // persisted setup state so any future setup re-entry starts clean.\n useEffect(() => {\n if (step === \"complete\") {\n clearWizardState();\n }\n }, [step]);\n\n // Reset scroll position whenever the step changes — without this, a tall\n // previous step (e.g. Backends) leaves scrollTop mid-page and the next\n // step (e.g. Mail) renders mid-page instead of from the top.\n const scrollRef = useRef<HTMLDivElement | null>(null);\n useEffect(() => {\n scrollRef.current?.scrollTo(0, 0);\n }, [step]);\n\n // SETUP-FLOW-REDESIGN-PLAN §6.5 — `filterInitialSteps` is identity in\n // v1 (no conditional sub-steps); kept as a function so future\n // conditional gating has an obvious home.\n const INITIAL_STEPS = useMemo<SetupStep[]>(\n () => filterInitialSteps(),\n [],\n );\n\n const next = () => {\n const idx = INITIAL_STEPS.indexOf(step);\n if (idx < INITIAL_STEPS.length - 1) {\n setStep(INITIAL_STEPS[idx + 1]);\n }\n };\n\n const currentIdx = INITIAL_STEPS.indexOf(step);\n\n // Update mode opens directly on `rules` with no prior step to return\n // to. On initial runs every step except basics/complete gets a Back\n // button.\n const canGoBack =\n mode === \"initial\" && currentIdx > 0 && step !== \"complete\";\n const prev = canGoBack\n ? () => setStep(INITIAL_STEPS[currentIdx - 1])\n : undefined;\n\n return (\n <div className=\"flex h-full flex-col\">\n {mode === \"initial\" &&\n step !== \"complete\" && (\n <div className=\"flex items-center justify-center gap-1 border-b border-border bg-muted/30 px-4 py-3\">\n {INITIAL_STEPS.filter((s) => s !== \"complete\").map((s, i) => {\n const stepIdx = INITIAL_STEPS.indexOf(s);\n const isActive = s === step;\n const isDone = stepIdx < currentIdx;\n\n return (\n <div key={s} className=\"flex items-center gap-1\">\n {i > 0 && (\n <div\n className={cn(\n \"h-px w-6\",\n isDone ? \"bg-primary\" : \"bg-border\",\n )}\n />\n )}\n <div\n className={cn(\n \"flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium transition-colors\",\n isActive\n ? \"bg-primary text-primary-foreground\"\n : isDone\n ? \"bg-primary/10 text-primary\"\n : \"text-muted-foreground\",\n )}\n >\n <span\n className={cn(\n \"flex h-5 w-5 items-center justify-center rounded-full text-[10px]\",\n isActive\n ? \"bg-primary-foreground/20\"\n : isDone\n ? \"bg-primary/20\"\n : \"bg-muted\",\n )}\n >\n {isDone ? \"✓\" : i + 1}\n </span>\n {STEP_LABELS[s]}\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Step content */}\n <div ref={scrollRef} className=\"flex-1 overflow-y-auto\">\n {step === \"basics\" && (\n <BasicsStep\n agentDisplayName={agentDisplayName}\n onAgentDisplayNameChange={setAgentDisplayName}\n onNext={next}\n />\n )}\n {step === \"vault\" && (\n <VaultStep\n onNext={next}\n onBack={prev}\n pendingVaultMode={pendingVaultMode}\n onPendingVaultModeChange={onPendingVaultModeChange}\n pendingVaultPath={pendingVaultPath}\n onPendingVaultPathChange={setPendingVaultPath}\n />\n )}\n {step === \"backend\" && <BackendsStep onNext={next} onBack={prev} />}\n {step === \"mail\" && <MailStep onNext={next} onBack={prev} />}\n {step === \"calendar\" && <CalendarStep onNext={next} onBack={prev} />}\n {step === \"note\" && <NoteStep onNext={next} onBack={prev} />}\n {step === \"messaging\" && <MessagingStep onNext={next} onBack={prev} />}\n {step === \"rules\" && (\n <ConversationStep\n mode={mode}\n agentDisplayName={agentDisplayName}\n onComplete={() => setStep(\"complete\")}\n onBack={prev}\n pendingVaultMode={pendingVaultMode}\n pendingVaultPath={pendingVaultPath}\n />\n )}\n {step === \"complete\" && (\n <SetupComplete\n mode={mode}\n agentDisplayName={agentDisplayName || DEFAULT_AGENT_DISPLAY_NAME}\n />\n )}\n </div>\n </div>\n );\n}\n\nexport default function SetupPage() {\n return (\n <Suspense>\n <SetupPageInner />\n </Suspense>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { ArrowLeft, ArrowRight, SkipForward } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface WizardStepFrameProps {\n /** Step heading. */\n title: string;\n /** Short description shown below the heading. */\n description?: string;\n /** The settings component(s) rendered inside the frame. */\n children: ReactNode;\n /** Called when the user advances to the next step. */\n onNext: () => void;\n /** Called when the user goes back to the previous step. Omit to hide the back button. */\n onBack?: () => void;\n /** Label for the skip button. Omit to hide skip entirely. */\n skipLabel?: string;\n /** Label for the next button. Defaults to \"Next\". */\n nextLabel?: string;\n /** Disable the next button (e.g. while a required action hasn't completed). */\n nextDisabled?: boolean;\n /** Hide both navigation buttons (for steps that manage their own flow). */\n hideNav?: boolean;\n /** Override the default max-w-lg container width (e.g. \"max-w-3xl\"). */\n maxWidth?: string;\n}\n\n/**\n * Consistent wizard chrome for setup steps that wrap settings components.\n *\n * Provides: centred title + description, content slot, skip / next buttons.\n * The progress stepper is owned by the parent page — not duplicated here.\n */\nexport function WizardStepFrame({\n title,\n description,\n children,\n onNext,\n onBack,\n skipLabel = \"Set Up Later\",\n nextLabel = \"Next\",\n nextDisabled = false,\n hideNav = false,\n maxWidth,\n}: WizardStepFrameProps) {\n return (\n <div className={`mx-auto ${maxWidth ?? \"max-w-lg\"} space-y-6 py-8`}>\n <div className=\"space-y-2 text-center\">\n <h2 className=\"text-xl font-semibold\">{title}</h2>\n {description && (\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n )}\n </div>\n\n {children}\n\n {!hideNav && (\n <div className=\"flex justify-between pt-4\">\n <div className=\"flex gap-2\">\n {onBack ? (\n <Button\n variant=\"ghost\"\n onClick={onBack}\n className=\"gap-2 text-muted-foreground\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </Button>\n ) : null}\n {skipLabel ? (\n <Button\n variant=\"ghost\"\n onClick={onNext}\n className=\"gap-2 text-muted-foreground\"\n >\n <SkipForward className=\"h-4 w-4\" />\n {skipLabel}\n </Button>\n ) : null}\n {!onBack && !skipLabel ? <div /> : null}\n </div>\n <Button\n onClick={onNext}\n className=\"gap-2\"\n disabled={nextDisabled}\n >\n {nextLabel}\n <ArrowRight className=\"h-4 w-4\" />\n </Button>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { ArrowLeft, ArrowRight, Loader2 } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { api, ApiError } from \"@/lib/api-client\";\nimport { useConfig } from \"@/lib/hooks/use-config\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport {\n AGENT_DISPLAY_NAME_MAX_LENGTH,\n SUPPORTED_LANGUAGES,\n buildBasicsPatchBody,\n canContinue,\n hydrateLanguageSelection,\n isCustomLanguageInvalid,\n resolveLanguage,\n} from \"./basics-step.logic\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * SETUP-FLOW-REDESIGN-PLAN §5.1 — Basics step.\n *\n * Replaces Welcome + the language portion of the legacy Vault step.\n * Two atomic fields persisted on Continue via `PATCH /api/config`:\n * - `agentDisplayName`\n * - `primaryLanguage`\n */\n\ninterface BasicsStepProps {\n agentDisplayName: string;\n onAgentDisplayNameChange: (value: string) => void;\n onNext: () => void;\n}\n\nexport function BasicsStep({\n agentDisplayName,\n onAgentDisplayNameChange,\n onNext,\n}: BasicsStepProps) {\n const { data: config } = useConfig();\n const queryClient = useQueryClient();\n const [primaryLanguage, setPrimaryLanguage] = useState(\"en\");\n const [customLanguage, setCustomLanguage] = useState(\"\");\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const hydratedRef = useRef(false);\n\n // Hydrate once from server state so back-nav restores the user's prior\n // pick. Subsequent config refetches (SSE) must not overwrite an edit\n // in progress — same pattern the legacy vault-step uses.\n useEffect(() => {\n if (hydratedRef.current || !config) return;\n hydratedRef.current = true;\n const hydrated = hydrateLanguageSelection(config.primaryLanguage);\n setPrimaryLanguage(hydrated.primary);\n setCustomLanguage(hydrated.custom);\n if (\n typeof config.agentDisplayName === \"string\"\n && config.agentDisplayName.length > 0\n && agentDisplayName.length === 0\n ) {\n onAgentDisplayNameChange(config.agentDisplayName);\n }\n }, [config, agentDisplayName, onAgentDisplayNameChange]);\n\n const resolvedLanguage = resolveLanguage(primaryLanguage, customLanguage);\n const customInvalid = isCustomLanguageInvalid(primaryLanguage, customLanguage);\n const ready = canContinue({ agentDisplayName, resolvedLanguage, saving });\n\n const handleContinue = async () => {\n if (!ready) return;\n setSaving(true);\n setError(null);\n try {\n await api.patch(\n \"/config\",\n buildBasicsPatchBody({ agentDisplayName, resolvedLanguage }),\n );\n await queryClient.invalidateQueries({ queryKey: [\"config\"] });\n onNext();\n } catch (err) {\n if (err instanceof ApiError) {\n const body = err.body as { message?: string } | null;\n setError(body?.message ?? err.message ?? \"Failed to save basics\");\n } else {\n setError(err instanceof Error ? err.message : \"Failed to save basics\");\n }\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <WizardStepFrame\n title=\"Basics\"\n description=\"Tell your agent what to call itself and which language to think in.\"\n onNext={onNext}\n hideNav\n >\n <div className=\"w-full max-w-sm mx-auto space-y-6 rounded-xl border border-border bg-card p-5 text-left\">\n <div className=\"space-y-2\">\n <label\n htmlFor=\"agent-name\"\n className=\"text-sm font-medium text-foreground\"\n >\n Agent name\n </label>\n <p className=\"text-xs text-muted-foreground\">\n Shown in the dashboard and prepended to outbound messages.\n </p>\n <Input\n id=\"agent-name\"\n value={agentDisplayName}\n onChange={(e) => onAgentDisplayNameChange(e.target.value)}\n placeholder=\"Aitne\"\n maxLength={AGENT_DISPLAY_NAME_MAX_LENGTH}\n />\n </div>\n\n <div className=\"space-y-2 border-t border-border pt-4\">\n <label className=\"text-sm font-medium text-foreground\">\n Primary language\n </label>\n <p className=\"text-xs text-muted-foreground\">\n Controls user-facing prose (profile, daily journal, weekly /\n monthly reviews). System files stay in English.\n </p>\n <Select value={primaryLanguage} onValueChange={setPrimaryLanguage}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SUPPORTED_LANGUAGES.map((lang) => (\n <SelectItem key={lang.tag} value={lang.tag}>\n {lang.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {primaryLanguage === \"__custom__\" && (\n <Input\n value={customLanguage}\n onChange={(e) => setCustomLanguage(e.target.value)}\n placeholder=\"e.g. zh-Hans\"\n className=\"mt-2\"\n />\n )}\n {customInvalid && (\n <p className=\"text-xs text-destructive\">\n Use a BCP-47 tag like <code>en-US</code> or <code>zh-Hans</code>.\n </p>\n )}\n </div>\n </div>\n\n {error && (\n <p className=\"text-sm text-red-600 dark:text-red-400 text-center\">\n {error}\n </p>\n )}\n\n <div className=\"flex justify-center gap-3 pt-4\">\n <Button\n size=\"lg\"\n onClick={handleContinue}\n disabled={!ready}\n className=\"gap-2\"\n >\n {saving ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Saving…\n </>\n ) : (\n <>\n Continue\n <ArrowRight className=\"h-4 w-4\" />\n </>\n )}\n </Button>\n </div>\n </WizardStepFrame>\n );\n}\n\n// Re-export for callers that still want the import surface.\nexport { ArrowLeft };\n","/**\n * SETUP-FLOW-REDESIGN-PLAN §5.2 — vault step pure logic.\n *\n * Replaces the language-aware logic that used to live here. The Basics\n * step now owns language; this module owns the vault-mode + primary-path\n * decisions. The component is a thin shell around these helpers.\n *\n * Validation against the daemon's `validatePrimaryVaultPath` is the\n * server-side source of truth (see `daemon/src/config.ts`); this module\n * keeps a slim client-side mirror so the user gets immediate feedback\n * before the round-trip.\n */\n\nimport {\n isClientAbsolutePath,\n isClientPathInsideOrEqual,\n} from \"@/lib/path-client\";\n\nexport type VaultMode = \"plain\" | \"obsidian\";\n\nexport type VaultPathIssue =\n | \"empty\"\n | \"not_absolute\"\n | \"overlaps_data_dir\";\n\nexport interface ValidatePrimaryVaultPathInput {\n path: string;\n dataDir: string;\n}\n\n/**\n * Pre-flight client-side path check. Mirrors the prefix rules in\n * `daemon/src/config.ts:validatePrimaryVaultPath` — the daemon\n * re-runs the full validation server-side, so this is just an\n * immediate-feedback layer (no system-path denials, no parent-existence\n * check; those need fs access).\n */\nexport function validatePrimaryVaultPathClient(\n input: ValidatePrimaryVaultPathInput,\n): VaultPathIssue | null {\n const trimmed = input.path.trim();\n if (trimmed.length === 0) return \"empty\";\n if (!isClientAbsolutePath(trimmed)) {\n return \"not_absolute\";\n }\n if (input.dataDir.length > 0) {\n if (isClientPathInsideOrEqual(input.dataDir, trimmed)) {\n return \"overlaps_data_dir\";\n }\n }\n return null;\n}\n\nexport function vaultPathIssueMessage(issue: VaultPathIssue): string {\n switch (issue) {\n case \"empty\":\n return \"Pick a directory for the agent's primary vault.\";\n case \"not_absolute\":\n return \"Use an absolute path (for example `/Users/me/Vault`, `~/Vault`, or `C:\\\\Vault`).\";\n case \"overlaps_data_dir\":\n return \"Path overlaps the agent's data directory; choose a separate location.\";\n }\n}\n\n/**\n * True when the user picked \"plain\" while the daemon is still in\n * `obsidian` mode — the one case where VaultStep must call\n * `/setup/migrate-context` to walk the daemon back out of obsidian.\n */\nexport function shouldRollbackToPlain(\n pendingMode: VaultMode,\n currentMode: VaultMode | null | undefined,\n): boolean {\n return pendingMode === \"plain\" && currentMode === \"obsidian\";\n}\n\n/**\n * Continue-button enablement. Plain mode never blocks on path; obsidian\n * mode requires a valid (or at least non-empty) path. `saving` blocks\n * both branches.\n */\nexport function canContinue(input: {\n vaultMode: VaultMode;\n pathIssue: VaultPathIssue | null;\n saving: boolean;\n}): boolean {\n if (input.saving) return false;\n if (input.vaultMode === \"plain\") return true;\n return input.pathIssue === null;\n}\n\n/**\n * Build the `POST /api/setup/migrate-context` body. Plain mode does not\n * carry a path; obsidian mode trims the user input.\n */\nexport type VaultMigrationBody =\n | { targetVaultMode: \"plain\"; conflictPolicy: \"abort\" }\n | {\n targetVaultMode: \"obsidian\";\n targetVaultPath: string;\n conflictPolicy: \"abort\";\n };\n\nexport function buildVaultMigrationBody(input: {\n vaultMode: VaultMode;\n primaryVaultPath: string;\n}): VaultMigrationBody {\n if (input.vaultMode === \"plain\") {\n return { targetVaultMode: \"plain\", conflictPolicy: \"abort\" };\n }\n return {\n targetVaultMode: \"obsidian\",\n targetVaultPath: input.primaryVaultPath.trim(),\n conflictPolicy: \"abort\",\n };\n}\n\n/**\n * Inputs to the deferred-migration decision used by `ConversationStep`.\n * `currentMode` / `currentPath` come from `/api/config`; `pendingMode` /\n * `pendingPath` come from wizard state populated on the Vault step.\n */\nexport interface VaultMigrationDecisionInput {\n pendingMode: VaultMode;\n pendingPath: string;\n currentMode: VaultMode;\n currentPath: string | null;\n}\n\nexport type VaultMigrationDecision =\n | { kind: \"no_migration_needed\" }\n | { kind: \"migrate\"; mode: VaultMode; path: string };\n\n/**\n * Decide whether the deferred vault migration should run on entry to the\n * Customize Rules step, given the user's pending picks and the daemon's\n * current config. Pure — exists so the test suite can pin down the\n * branches that previously lived inside an `IIFE` in a `useEffect`.\n *\n * Rules:\n * - plain & current plain → no-op.\n * - plain & current obsidian → migrate (rollback to plain).\n * - obsidian & empty path → no-op (defensive; Vault step blocks this).\n * - obsidian & current plain → migrate.\n * - obsidian & path differs → migrate (re-target).\n * - obsidian & path matches → no-op.\n *\n * Path comparison is by exact string after trimming the pending value;\n * the daemon's `validateMigrationTargetPath` resolves `~`/relatives, so\n * we never compare against an unresolved server path.\n */\nexport function decideVaultMigration(\n input: VaultMigrationDecisionInput,\n): VaultMigrationDecision {\n if (input.pendingMode === \"plain\") {\n if (input.currentMode === \"obsidian\") {\n return { kind: \"migrate\", mode: \"plain\", path: \"\" };\n }\n return { kind: \"no_migration_needed\" };\n }\n const pendingPathTrimmed = input.pendingPath.trim();\n if (pendingPathTrimmed.length === 0) {\n return { kind: \"no_migration_needed\" };\n }\n if (input.currentMode !== \"obsidian\") {\n return { kind: \"migrate\", mode: \"obsidian\", path: pendingPathTrimmed };\n }\n if (input.currentPath !== pendingPathTrimmed) {\n return { kind: \"migrate\", mode: \"obsidian\", path: pendingPathTrimmed };\n }\n return { kind: \"no_migration_needed\" };\n}\n","\"use client\";\n\nimport { ArrowLeft, FolderSymlink } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { DirectoryPickerField } from \"@/components/directory-picker-field\";\nimport { useConfig } from \"@/lib/hooks/use-config\";\nimport { cn } from \"@/lib/utils\";\nimport {\n canContinue,\n validatePrimaryVaultPathClient,\n vaultPathIssueMessage,\n type VaultMode,\n type VaultPathIssue,\n} from \"./vault-step.logic\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * SETUP-FLOW-REDESIGN-PLAN §5.2 — vault step.\n *\n * The user picks vault mode + path here, but the actual\n * `/setup/migrate-context` call is deferred to the Customize Rules step\n * (see `conversation-step.tsx`). Holding off on file creation lets the\n * user Back-navigate from any later step and re-pick the same directory\n * without seeing it already populated with agent skeleton files.\n */\n\ninterface VaultStepProps {\n onNext: () => void;\n onBack?: () => void;\n pendingVaultMode: VaultMode;\n onPendingVaultModeChange: (mode: VaultMode) => void;\n pendingVaultPath: string;\n onPendingVaultPathChange: (path: string) => void;\n}\n\nexport function VaultStep({\n onNext,\n onBack,\n pendingVaultMode,\n onPendingVaultModeChange,\n pendingVaultPath,\n onPendingVaultPathChange,\n}: VaultStepProps) {\n const { data: config } = useConfig();\n\n const dataDir = config?.contextDir ?? \"\";\n const pathIssue: VaultPathIssue | null = pendingVaultMode === \"obsidian\"\n ? validatePrimaryVaultPathClient({ path: pendingVaultPath, dataDir })\n : null;\n const ready = canContinue({\n vaultMode: pendingVaultMode,\n pathIssue,\n saving: false,\n });\n\n return (\n <WizardStepFrame\n title=\"Vault\"\n description=\"Where should your agent store its memory? Obsidian users can pick an existing vault.\"\n onNext={onNext}\n hideNav\n >\n <div className=\"w-full max-w-xl mx-auto space-y-5 rounded-xl border border-border bg-card p-5 text-left\">\n <div className=\"grid grid-cols-1 gap-2\">\n {([\"plain\", \"obsidian\"] as const).map((mode) => (\n <button\n key={mode}\n type=\"button\"\n onClick={() => onPendingVaultModeChange(mode)}\n className={cn(\n \"rounded-md border px-3 py-2 text-left text-sm transition-colors\",\n pendingVaultMode === mode\n ? \"border-primary bg-primary/10 text-foreground\"\n : \"border-border bg-background text-muted-foreground hover:border-primary/50\",\n )}\n >\n <span className=\"block font-medium\">\n {mode === \"plain\"\n ? \"Plain markdown\"\n : \"Obsidian\"}\n </span>\n <span className=\"block text-xs text-muted-foreground\">\n {mode === \"plain\"\n ? \"Stored at ~/.personal-agent/context. Only this app reads + writes.\"\n : \"Use an existing Obsidian vault as the agent's working directory.\"}\n </span>\n </button>\n ))}\n </div>\n\n {pendingVaultMode === \"obsidian\" && (\n <div className=\"space-y-2 border-t border-border pt-4\">\n <label\n htmlFor=\"primary-vault-path\"\n className=\"text-sm font-medium text-foreground\"\n >\n Vault path\n </label>\n <p className=\"text-xs text-muted-foreground\">\n Pick an existing folder. Cloud-sync directories (iCloud,\n Dropbox, OneDrive, Google Drive) work; local SSDs are faster.\n The folder stays untouched until you reach the final step.\n </p>\n <DirectoryPickerField\n id=\"primary-vault-path\"\n value={pendingVaultPath}\n onChange={onPendingVaultPathChange}\n title=\"Choose primary vault directory\"\n placeholder=\"Choose a folder for the primary vault\"\n defaultPath={config?.primaryVaultPath || undefined}\n />\n {pathIssue && pathIssue !== \"empty\" && (\n <p className=\"text-xs text-destructive\">\n {vaultPathIssueMessage(pathIssue)}\n </p>\n )}\n </div>\n )}\n </div>\n\n <div className=\"flex justify-center gap-3 pt-4\">\n {onBack && (\n <Button variant=\"ghost\" onClick={onBack} className=\"gap-2\">\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </Button>\n )}\n <Button\n size=\"lg\"\n onClick={onNext}\n disabled={!ready}\n className=\"gap-2\"\n >\n <FolderSymlink className=\"h-4 w-4\" />\n Continue\n </Button>\n </div>\n </WizardStepFrame>\n );\n}\n","\"use client\";\n\nimport {\n AlertTriangle,\n ArrowLeft,\n ArrowRight,\n ChevronDown,\n Loader2,\n ShieldCheck,\n Unlock,\n} from \"lucide-react\";\nimport { useCallback, useState } from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport type { BackendId } from \"@aitne/shared\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { api, ApiError } from \"@/lib/api-client\";\nimport {\n BACKEND_PROVIDER_LABELS,\n BACKEND_PROVIDER_SHORT,\n} from \"@/lib/backend-ui\";\nimport { cn } from \"@/lib/utils\";\nimport { useBackends } from \"@/lib/hooks/use-backends\";\nimport { BackendApiKeyPanel } from \"@/components/settings/backend-api-key-panel\";\nimport { BackendCard } from \"@/components/settings/backend-card\";\nimport { isContinueEligible } from \"@/components/settings/backend-card.logic\";\nimport { SubscriptionAuthWarning } from \"@/components/settings/subscription-auth-warning\";\nimport {\n buildSetupModePayload,\n EMPTY_OVERRIDES,\n hasDivergentOverride,\n type ExecutionModeUi,\n type PerBackendOverrides,\n} from \"@/components/settings/execution-mode.logic\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * Wizard step for the backend selection. Subscription-plan registration\n * has been removed — Aitne is designed to run on provider API keys\n * (`ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `GEMINI_API_KEY`), so the\n * daemon does not ask the operator which Claude/Codex/Gemini tier they\n * hold. `process_backend_config` is seeded with fixed defaults (Sonnet\n * for main agent surfaces, Haiku for delegated/simple polling). The\n * user picks the main backend, authenticates it via the per-backend\n * API-key panel (or, as a fallback, signs in to the local CLI), and\n * non-main backends can be configured later from /settings/models.\n *\n * On Continue, this step calls `PUT /api/backends/main` with the\n * chosen backend, which seeds default `process_backend_config` rows\n * for that backend on a fresh install.\n */\n\nconst BACKENDS: readonly BackendId[] = [\"claude\", \"codex\", \"gemini\"];\n\ninterface BackendsStepProps {\n onNext: () => void;\n onBack?: () => void;\n}\n\ninterface InstallCheckEntry {\n status: \"idle\" | \"checking\" | \"ok\" | \"error\";\n error?: string | null;\n version?: string | null;\n}\n\nexport function BackendsStep({ onNext, onBack }: BackendsStepProps) {\n const { data: backendsData, refetch: refetchBackends } = useBackends();\n const queryClient = useQueryClient();\n\n const [mainBackend, setMainBackend] = useState<BackendId | null>(\"claude\");\n const [topMode, setTopMode] = useState<ExecutionModeUi>(\"safe\");\n const [overrides, setOverrides] = useState<PerBackendOverrides>(EMPTY_OVERRIDES);\n const [advancedOpen, setAdvancedOpen] = useState(false);\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n // INTEGRATION_NATIVE_MODE_DESIGN.md §11.4 — when the wizard is re-run\n // after the operator has provisioned native rows (uncommon but possible),\n // changing the main backend cascades non-matching native rows to\n // `disabled`. Surface the cascade inline so the user finds out here\n // rather than discovering silently-disabled rows on /connections.\n const [cascadeNotice, setCascadeNotice] = useState<string | null>(null);\n const [installCheck, setInstallCheck] = useState<\n Record<BackendId, InstallCheckEntry>\n >({\n claude: { status: \"idle\" },\n codex: { status: \"idle\" },\n gemini: { status: \"idle\" },\n });\n\n const pickMain = useCallback((backendId: BackendId) => {\n setMainBackend(backendId);\n }, []);\n\n const verifyInstall = useCallback(\n async (backendId: BackendId) => {\n setInstallCheck((prev) => ({\n ...prev,\n [backendId]: { status: \"checking\" },\n }));\n try {\n const res = await api.post<{\n ok: boolean;\n cliInstalled: boolean;\n cliCommand: string;\n exitCode: number | null;\n version: string | null;\n stdout: string;\n stderr: string;\n timedOut: boolean;\n }>(`/backends/${backendId}/verify-install`);\n await refetchBackends();\n if (res.ok) {\n setInstallCheck((prev) => ({\n ...prev,\n [backendId]: { status: \"ok\", version: res.version },\n }));\n } else {\n const reason = !res.cliInstalled\n ? `${res.cliCommand} not found on PATH`\n : res.timedOut\n ? `${res.cliCommand} --version timed out`\n : (res.stderr.trim() || res.stdout.trim() || \"CLI failed to run\");\n setInstallCheck((prev) => ({\n ...prev,\n [backendId]: { status: \"error\", error: reason },\n }));\n }\n } catch (err) {\n setInstallCheck((prev) => ({\n ...prev,\n [backendId]: {\n status: \"error\",\n error: err instanceof Error ? err.message : \"Verify install failed\",\n },\n }));\n }\n },\n [refetchBackends],\n );\n\n const canContinue = isContinueEligible({ mainBackend });\n\n async function applyAndNext(): Promise<void> {\n if (!mainBackend) return;\n // INTEGRATION_NATIVE_MODE_DESIGN.md §11.4 — second click after a\n // cascade notice: the user has now acknowledged the cascade. Skip\n // re-PUTting `/backends/main` (the change already landed on the\n // first click) and proceed to the next wizard step.\n if (cascadeNotice !== null) {\n setCascadeNotice(null);\n onNext();\n return;\n }\n setSaving(true);\n setSaveError(null);\n try {\n // INTEGRATION_NATIVE_MODE_DESIGN.md §11.4 — capture `nativeUnbound`\n // from the response so the wizard can warn the user inline. Mirrors\n // the settings page toast (`backends-section.tsx`) so re-running the\n // wizard after configuring native rows doesn't silently drop them.\n const res = await api.put<{\n status?: string;\n nativeUnbound?: Array<{ key: string; priorNativeBackend: string }>;\n }>(\"/backends/main\", { backendId: mainBackend });\n // /backends/main flips `backends.enabled = 1` server-side and\n // re-seeds process_backend_config rows for the new backend.\n // Invalidate the backends query so the next step (GoogleModeStep)\n // reads the post-apply state.\n // INTEGRATION_NATIVE_MODE_DESIGN.md §11.4 — the same call cascades\n // any native rows whose `nativeBackend` no longer matches. The\n // wizard's first launch never has native rows (defaults all\n // `disabled`/`direct`), but a re-run of the wizard with an\n // operator-provisioned native row would; surface the cascade\n // through the same invalidation chain the settings page uses so\n // /connections renders the §11.5 banner consistently.\n await queryClient.invalidateQueries({ queryKey: [\"backends\"] });\n await queryClient.invalidateQueries({ queryKey: [\"integrations\"] });\n await queryClient.invalidateQueries({ queryKey: [\"health\"] });\n await queryClient.invalidateQueries({\n queryKey: [\"agent-actions\", \"native_unbound\"],\n });\n\n const modePayload = buildSetupModePayload(topMode, overrides);\n if (modePayload) {\n await api.post(\"/setup/mode\", modePayload);\n await queryClient.invalidateQueries({ queryKey: [\"config\"] });\n }\n\n // Defer the cascade-confirmation gate to *after* the mode payload\n // POST so a failure in `/setup/mode` doesn't strand the user with\n // a half-applied state. If cascade fired, hold here; the user\n // acknowledges, then clicks Next again — the early-return at the\n // top of this function advances without a redundant PUT.\n const unbound = res?.nativeUnbound ?? [];\n if (unbound.length > 0) {\n const keys = unbound.map((u) => u.key).join(\", \");\n setCascadeNotice(\n `${unbound.length} native integration${unbound.length === 1 ? \"\" : \"s\"} (${keys}) ` +\n `were bound to a different backend and are now disabled. ` +\n `Re-configure them on /settings/integrations after the wizard completes.`,\n );\n setSaving(false);\n return;\n }\n } catch (err) {\n setSaveError(\n err instanceof ApiError\n ? err.message\n : err instanceof Error\n ? err.message\n : \"Failed to apply default presets\",\n );\n setSaving(false);\n return;\n }\n onNext();\n }\n\n return (\n <WizardStepFrame\n title=\"AI Backend\"\n description=\"Pick the main backend, install its CLI, and (optionally) save a provider API key. You can skip the key setup and configure it later from Settings → Backends.\"\n onNext={onNext}\n hideNav\n maxWidth=\"max-w-4xl\"\n >\n <SubscriptionAuthWarning />\n\n <div className=\"space-y-4\">\n {BACKENDS.map((backendId) => {\n const row = backendsData?.backends.find((b) => b.id === backendId);\n return (\n <div key={backendId} className=\"space-y-2\">\n <BackendCard\n backendId={backendId}\n mode=\"wizard\"\n isMain={mainBackend === backendId}\n authStatus={row?.authStatus ?? \"unknown\"}\n authStatusDetail={row?.authDetail ?? null}\n authFirstExpiredAt={row?.authFirstExpiredAt ?? null}\n authLastSuccessAt={row?.authLastSuccessAt ?? null}\n authNotificationCount={row?.authNotificationCount ?? 0}\n cliInstalled={row?.cliInstalled ?? true}\n enabled={row?.enabled ?? true}\n webSearchEnabled={row?.webSearchEnabled ?? false}\n webSearchSupported={row?.webSearchSupported ?? false}\n permissionMode={null}\n installCheck={installCheck[backendId]}\n onCliInstalled={() => {\n void refetchBackends();\n }}\n onVerifyInstall={() => {\n void verifyInstall(backendId);\n }}\n />\n <BackendApiKeyPanel backendId={backendId} />\n </div>\n );\n })}\n\n {/* Main backend radio */}\n <div className=\"rounded-lg border border-border bg-muted/30 p-4\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n Main backend\n </h3>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n The main backend runs every configurable process by default.\n </p>\n <div className=\"mt-3 flex flex-wrap gap-3\">\n {BACKENDS.map((backendId) => {\n const isActive = mainBackend === backendId;\n return (\n <label\n key={backendId}\n className={`flex flex-1 min-w-[180px] items-start gap-2 rounded-md border px-3 py-2 text-sm transition-colors ${\n isActive\n ? \"border-primary bg-primary/10\"\n : \"border-border hover:border-foreground/30\"\n }`}\n >\n <input\n type=\"radio\"\n name=\"main-backend\"\n className=\"mt-1\"\n checked={isActive}\n onChange={() => pickMain(backendId)}\n />\n <span className=\"font-medium\">\n {BACKEND_PROVIDER_SHORT[backendId]}\n </span>\n </label>\n );\n })}\n </div>\n </div>\n </div>\n\n <ExecutionModeSection\n topMode={topMode}\n overrides={overrides}\n advancedOpen={advancedOpen}\n onTopModeChange={setTopMode}\n onOverridesChange={setOverrides}\n onAdvancedOpenChange={setAdvancedOpen}\n />\n\n {saveError && (\n <p className=\"text-sm text-destructive text-center\">{saveError}</p>\n )}\n {cascadeNotice && (\n <p\n className=\"rounded-md border border-amber-300/60 bg-amber-50/60 px-3 py-2 text-xs text-amber-900 dark:border-amber-700/50 dark:bg-amber-950/30 dark:text-amber-100\"\n role=\"status\"\n >\n {cascadeNotice}\n </p>\n )}\n\n <div className=\"flex items-center justify-between gap-3 pt-2\">\n {onBack ? (\n <Button variant=\"ghost\" onClick={onBack} className=\"gap-2\">\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </Button>\n ) : (\n <div />\n )}\n <Button\n onClick={() => void applyAndNext()}\n disabled={!canContinue || saving}\n >\n {saving ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Applying defaults…\n </>\n ) : cascadeNotice ? (\n <>\n Acknowledge &amp; continue <ArrowRight className=\"ml-2 h-4 w-4\" />\n </>\n ) : (\n <>\n Next <ArrowRight className=\"ml-2 h-4 w-4\" />\n </>\n )}\n </Button>\n </div>\n </WizardStepFrame>\n );\n}\n\ninterface ExecutionModeSectionProps {\n topMode: ExecutionModeUi;\n overrides: PerBackendOverrides;\n advancedOpen: boolean;\n onTopModeChange: (mode: ExecutionModeUi) => void;\n onOverridesChange: (\n next: PerBackendOverrides | ((prev: PerBackendOverrides) => PerBackendOverrides),\n ) => void;\n onAdvancedOpenChange: (open: boolean) => void;\n}\n\nfunction ExecutionModeSection({\n topMode,\n overrides,\n advancedOpen,\n onTopModeChange,\n onOverridesChange,\n onAdvancedOpenChange,\n}: ExecutionModeSectionProps) {\n const divergent = hasDivergentOverride(topMode, overrides);\n return (\n <div className=\"rounded-lg border border-border bg-muted/30 p-4 space-y-3\">\n <div>\n <h3 className=\"text-sm font-semibold text-foreground\">\n Execution permissions\n </h3>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n Pick how freely the agent may run shell, file, and tool commands.\n Dangerous operations — recursive deletes, privilege escalation, and\n secret-file reads — remain blocked in both modes.\n </p>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <ModeCard\n icon={<ShieldCheck className=\"h-4 w-4\" />}\n title=\"Safe\"\n badge=\"Recommended\"\n selected={topMode === \"safe\"}\n onSelect={() => onTopModeChange(\"safe\")}\n >\n Strict permission checks, asks for confirmation before\n side-effectful actions.\n </ModeCard>\n <ModeCard\n icon={<Unlock className=\"h-4 w-4\" />}\n title=\"Allow\"\n selected={topMode === \"allow\"}\n onSelect={() => onTopModeChange(\"allow\")}\n >\n Runs with the skills, plugins, and MCP servers installed in your\n CLI harness.\n </ModeCard>\n </div>\n\n <Collapsible open={advancedOpen} onOpenChange={onAdvancedOpenChange}>\n <CollapsibleTrigger asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between rounded-md border border-border bg-background px-3 py-2 text-left text-xs text-muted-foreground hover:bg-muted/40\"\n >\n <span className=\"flex items-center gap-2\">\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 transition-transform\",\n advancedOpen && \"rotate-180\",\n )}\n />\n Per-backend overrides\n {divergent && (\n <span className=\"rounded bg-amber-500/15 px-1.5 py-0.5 text-[10px] font-medium text-amber-700 dark:text-amber-300\">\n mixed\n </span>\n )}\n </span>\n <span className=\"text-[11px]\">\n {advancedOpen ? \"Hide\" : \"Show\"}\n </span>\n </button>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"mt-2 space-y-2 rounded-md border border-border bg-background p-3\">\n {([\"claude\", \"codex\", \"gemini\"] as const).map((backend) => (\n <BackendOverrideRow\n key={backend}\n backend={backend}\n topMode={topMode}\n override={overrides[backend]}\n onChange={(next) =>\n onOverridesChange((prev) => ({ ...prev, [backend]: next }))\n }\n />\n ))}\n </CollapsibleContent>\n </Collapsible>\n </div>\n );\n}\n\ninterface ModeCardProps {\n icon: React.ReactNode;\n title: string;\n badge?: string;\n selected: boolean;\n onSelect: () => void;\n children: React.ReactNode;\n}\n\nfunction ModeCard({\n icon,\n title,\n badge,\n selected,\n onSelect,\n children,\n}: ModeCardProps) {\n return (\n <button\n type=\"button\"\n onClick={onSelect}\n className={cn(\n \"block w-full rounded-md border p-3 text-left transition-colors\",\n selected\n ? \"border-primary bg-primary/10 shadow-sm\"\n : \"border-border bg-background hover:border-foreground/30\",\n )}\n >\n <div className=\"flex items-center gap-2 text-sm font-semibold text-foreground\">\n {icon}\n {title}\n {badge && (\n <span className=\"rounded bg-primary/15 px-1.5 py-0.5 text-[10px] font-medium text-primary\">\n {badge}\n </span>\n )}\n </div>\n <p className=\"mt-1 text-xs text-muted-foreground\">{children}</p>\n </button>\n );\n}\n\ninterface BackendOverrideRowProps {\n backend: BackendId;\n topMode: ExecutionModeUi;\n override: ExecutionModeUi | null;\n onChange: (next: ExecutionModeUi | null) => void;\n}\n\nfunction BackendOverrideRow({\n backend,\n topMode,\n override,\n onChange,\n}: BackendOverrideRowProps) {\n const effective = override ?? topMode;\n const showCodexAllowWarning = backend === \"codex\" && effective === \"allow\";\n return (\n <div className=\"rounded-md border border-border/60 px-3 py-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"text-sm\">\n <div className=\"font-medium text-foreground\">\n {BACKEND_PROVIDER_LABELS[backend]}\n <span className=\"ml-1 text-xs text-muted-foreground\">\n ({BACKEND_PROVIDER_SHORT[backend]})\n </span>\n </div>\n <div className=\"text-[11px] text-muted-foreground\">\n runs as: {effective}\n </div>\n </div>\n <div className=\"flex items-center gap-1 text-xs\">\n <OverrideChip\n active={override === null}\n label=\"Follow\"\n onClick={() => onChange(null)}\n />\n <OverrideChip\n active={override === \"safe\"}\n label=\"Safe\"\n onClick={() => onChange(\"safe\")}\n />\n <OverrideChip\n active={override === \"allow\"}\n label=\"Allow\"\n onClick={() => onChange(\"allow\")}\n />\n </div>\n </div>\n {showCodexAllowWarning && (\n <p className=\"mt-2 flex items-start gap-1.5 text-[11px] text-amber-700 dark:text-amber-300\">\n <AlertTriangle className=\"mt-0.5 h-3 w-3 shrink-0\" />\n <span>\n Codex Allow runs sandbox-off; the daemon&apos;s absolute-block\n layer cannot intercept destructive shell commands for Codex.\n </span>\n </p>\n )}\n </div>\n );\n}\n\nfunction OverrideChip({\n active,\n label,\n onClick,\n}: {\n active: boolean;\n label: string;\n onClick: () => void;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"rounded-md border px-2 py-1 transition-colors\",\n active\n ? \"border-primary bg-primary/10 text-foreground\"\n : \"border-border text-muted-foreground hover:border-foreground/30\",\n )}\n >\n {label}\n </button>\n );\n}\n","\"use client\";\n\nimport { GmailCard } from \"@/components/mail/gmail-card\";\nimport { OutlookCard } from \"@/components/mail/outlook-card\";\nimport { ImapCard } from \"@/components/mail/imap-card\";\nimport { GoogleCard } from \"@/components/connections/google-card\";\nimport { IntegrationCard } from \"@/components/connections/integration-card\";\nimport { useHealth } from \"@/lib/hooks/use-health\";\nimport {\n useMailAccounts,\n useMailProviders,\n} from \"@/components/mail/use-mail-data\";\nimport type { MailAccount, MailProviderKind } from \"@/components/mail/types\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * SETUP-FLOW-REDESIGN-PLAN §5.4 — Mail step.\n *\n * Each provider stacks the registry-driven `IntegrationCard` (mode\n * toggle + delegated/native backend picker) on top of the auth card\n * (GmailCard / OutlookCard) so the wizard exposes the same decisions\n * as `/connections/mail`. Outlook's descriptor declares the full mode\n * tuple (`direct` / `delegated` / `native` / `disabled`) with\n * `userManagedConnector: true`, so the IntegrationCard renders a\n * \"register an Outlook MCP on the chosen backend\" notice for both\n * delegated and native — INTEGRATION_NATIVE_MODE_DESIGN.md §5.3\n * (2026-05 amendment). IMAP has no delegated/native path (no\n * integration key in the registry); the IMAP cards stay auth-only.\n *\n * Direct-mode Gmail needs a Google OAuth credential. The wizard\n * embeds the same `GoogleCard` used on `/connections/calendar` here\n * so the user can complete OAuth without navigating out of an\n * incomplete wizard. The card is suppressed when Gmail is not in\n * direct mode (no credentials needed for delegated / native / disabled).\n */\ninterface MailStepProps {\n onNext: () => void;\n onBack?: () => void;\n}\n\nexport function MailStep({ onNext, onBack }: MailStepProps) {\n const accountsQuery = useMailAccounts();\n const providersQuery = useMailProviders();\n const health = useHealth();\n\n const accounts = accountsQuery.data?.accounts ?? [];\n const enabledKinds = providersQuery.data?.enabledKinds ?? [];\n const grouped = groupByKind(accounts);\n\n // Only show the GoogleCard when Gmail's mode requires OAuth (direct).\n // In delegated mode, auth lives in the backend's connector store, not\n // the daemon keychain; in disabled mode there is no auth to configure.\n const gmailMode = health.data?.integrationModes?.gmail?.mode ?? \"disabled\";\n const showGoogleAuth = gmailMode === \"direct\";\n\n return (\n <WizardStepFrame\n title=\"Mail\"\n description=\"Hook up the mail accounts your agent should watch. Skip any you don't use — you can configure them later from Settings → Mail.\"\n onNext={onNext}\n onBack={onBack}\n skipLabel=\"Skip\"\n maxWidth=\"max-w-2xl\"\n >\n <IntegrationCard\n integrationKey=\"gmail\"\n gmailAccountCount={grouped.gmail.length}\n />\n <GmailCard\n accounts={grouped.gmail}\n enabledKinds={enabledKinds}\n hideExternalGoogleLink\n />\n {showGoogleAuth && <GoogleCard />}\n <IntegrationCard integrationKey=\"outlook_mail\" />\n <OutlookCard accounts={grouped.outlook} enabledKinds={enabledKinds} />\n <ImapCard\n kind=\"yahoo\"\n accounts={grouped.yahoo}\n enabledKinds={enabledKinds}\n />\n <ImapCard\n kind=\"icloud\"\n accounts={grouped.icloud}\n enabledKinds={enabledKinds}\n />\n </WizardStepFrame>\n );\n}\n\nfunction groupByKind(\n accounts: MailAccount[],\n): Record<MailProviderKind, MailAccount[]> {\n const out: Record<MailProviderKind, MailAccount[]> = {\n gmail: [],\n outlook: [],\n yahoo: [],\n icloud: [],\n };\n for (const a of accounts) out[a.kind].push(a);\n return out;\n}\n","\"use client\";\n\nimport { ArrowRight } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { GoogleCard } from \"@/components/connections/google-card\";\nimport { IntegrationCard } from \"@/components/connections/integration-card\";\nimport { useHealth } from \"@/lib/hooks/use-health\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * SETUP-FLOW-REDESIGN-PLAN §5.5 — Calendar wizard step.\n *\n * Renders the registry-driven `IntegrationCard` for Google Calendar and\n * Outlook Calendar back-to-back. Mode toggles + per-mode disclosures\n * (OAuth, calendar-id picker) are owned by `IntegrationCard`; this\n * component is just the page chrome, the cards, and the nav buttons.\n *\n * Skip is first-class: Calendar is optional input. Continue advances\n * unconditionally — soft-warning state is surfaced inside each card.\n *\n * When Google Calendar is in direct mode the wizard renders the same\n * `GoogleCard` used on `/connections/calendar` so OAuth completes\n * inside the wizard rather than navigating the user out.\n */\ninterface CalendarStepProps {\n onNext: () => void;\n onBack?: () => void;\n}\n\nexport function CalendarStep({ onNext, onBack }: CalendarStepProps) {\n const health = useHealth();\n const calendarMode =\n health.data?.integrationModes?.google_calendar?.mode ?? \"disabled\";\n const showGoogleAuth = calendarMode === \"direct\";\n\n return (\n <WizardStepFrame\n title=\"Calendar\"\n description=\"Pick the calendars your agent should follow. Skip if you don't use one.\"\n onNext={onNext}\n onBack={onBack}\n skipLabel=\"Skip\"\n nextLabel=\"Continue\"\n >\n <div className=\"w-full max-w-2xl mx-auto space-y-4\">\n <IntegrationCard integrationKey=\"google_calendar\" />\n {showGoogleAuth && <GoogleCard />}\n <IntegrationCard integrationKey=\"outlook_calendar\" />\n <p className=\"text-xs text-muted-foreground text-center\">\n Outlook Calendar shares OAuth with Outlook Mail — if you connect Mail\n first, Calendar reads succeed without a second consent screen.\n Apple Calendar can be configured later under Settings → Connections.\n </p>\n </div>\n </WizardStepFrame>\n );\n}\n\n// Re-export for symmetry with other step files.\nexport { ArrowRight, Button };\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { ArrowLeft, FolderSymlink, Loader2 } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { DirectoryPickerField } from \"@/components/directory-picker-field\";\nimport { IntegrationCard } from \"@/components/connections/integration-card\";\nimport { api, ApiError } from \"@/lib/api-client\";\nimport { useConfig } from \"@/lib/hooks/use-config\";\nimport {\n DEFAULT_NOTE_STEP_FIELDS,\n buildNotePatchBody,\n canContinue,\n notePathIssueMessage,\n validateExternalVaultPathClient,\n type NotePathIssue,\n} from \"./note-step.logic\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * SETUP-FLOW-REDESIGN-PLAN §5.6 — Note step.\n *\n * Two sections side-by-side: Notion (existing IntegrationCard) and the\n * user's external Obsidian vault (new — `externalObsidianVaultPath` +\n * `externalObsidianWatch`). The Note Sources section in\n * `<dataDir>/integrations.md` re-renders as soon as the daemon's\n * `applyConfigUpdates` hook fires (see SETUP-FLOW-REDESIGN-PLAN §6.2).\n */\n\ninterface NoteStepProps {\n onNext: () => void;\n onBack?: () => void;\n}\n\nexport function NoteStep({ onNext, onBack }: NoteStepProps) {\n const { data: config } = useConfig();\n const queryClient = useQueryClient();\n const [path, setPath] = useState<string>(\n DEFAULT_NOTE_STEP_FIELDS.externalObsidianVaultPath,\n );\n const [watch, setWatch] = useState<boolean>(\n DEFAULT_NOTE_STEP_FIELDS.externalObsidianWatch,\n );\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const hydratedRef = useRef(false);\n\n // Hydrate once from server state. The daemon serialises\n // `externalObsidianWatch` as boolean (default true); a `null` /\n // missing value resolves to `true` so existing installs keep\n // watching by default.\n useEffect(() => {\n if (hydratedRef.current || !config) return;\n hydratedRef.current = true;\n if (\n typeof config.externalObsidianVaultPath === \"string\"\n && config.externalObsidianVaultPath.length > 0\n ) {\n setPath(config.externalObsidianVaultPath);\n }\n if (typeof config.externalObsidianWatch === \"boolean\") {\n setWatch(config.externalObsidianWatch);\n }\n }, [config]);\n\n const pathIssue: NotePathIssue | null = path.trim().length === 0\n ? null\n : validateExternalVaultPathClient({\n path,\n dataDir: config?.contextDir ?? \"\",\n primaryVaultPath: config?.primaryVaultPath ?? null,\n });\n\n const ready = canContinue({ pathIssue, saving });\n\n const handleSave = async () => {\n if (!ready) return;\n setSaving(true);\n setError(null);\n try {\n await api.patch(\n \"/config\",\n buildNotePatchBody({\n externalObsidianVaultPath: path,\n externalObsidianWatch: watch,\n }),\n );\n await queryClient.invalidateQueries({ queryKey: [\"config\"] });\n onNext();\n } catch (err) {\n if (err instanceof ApiError) {\n const body = err.body as { message?: string } | null;\n setError(body?.message ?? err.message ?? \"Failed to save Note settings\");\n } else {\n setError(err instanceof Error ? err.message : \"Failed to save Note settings\");\n }\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <WizardStepFrame\n title=\"Note\"\n description=\"Where do you keep your own notes? Skip if you don't use either.\"\n onNext={onNext}\n hideNav\n >\n <div className=\"w-full max-w-2xl mx-auto space-y-6\">\n {/* Notion card — registry-driven; mode toggle + direct API key body. */}\n <IntegrationCard integrationKey=\"notion\" />\n\n <div className=\"rounded-xl border border-border bg-card p-5 text-left space-y-4\">\n <div>\n <h3 className=\"text-sm font-semibold text-foreground\">\n Obsidian (your personal vault)\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n This is separate from the agent&rsquo;s working vault — point us\n at the vault YOU use for your own notes. The agent reads + appends\n there via the Obsidian skill.\n </p>\n </div>\n\n <DirectoryPickerField\n id=\"external-obsidian-vault-path\"\n value={path}\n onChange={setPath}\n title=\"Choose your personal Obsidian vault\"\n placeholder=\"Skip if you don't use Obsidian\"\n disabled={saving}\n />\n {pathIssue && pathIssue !== \"empty\" && (\n <p className=\"text-xs text-destructive\">\n {notePathIssueMessage(pathIssue)}\n </p>\n )}\n\n <label className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <input\n type=\"checkbox\"\n checked={watch}\n onChange={(e) => setWatch(e.currentTarget.checked)}\n className=\"h-4 w-4 rounded border-border text-primary focus:ring-primary\"\n />\n Watch this vault for changes (default ON)\n </label>\n <p className=\"text-[11px] text-muted-foreground\">\n Disabling watching keeps the path readable through the Obsidian\n skill but stops the file-change observer — useful for very large\n vaults that produce noisy events.\n </p>\n </div>\n\n {error && (\n <p className=\"text-sm text-red-600 dark:text-red-400 text-center\">\n {error}\n </p>\n )}\n </div>\n\n <div className=\"flex justify-center gap-3 pt-4\">\n {onBack && (\n <Button variant=\"ghost\" onClick={onBack} className=\"gap-2\">\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </Button>\n )}\n <Button variant=\"ghost\" onClick={onNext}>\n Skip\n </Button>\n <Button\n size=\"lg\"\n onClick={handleSave}\n disabled={!ready}\n className=\"gap-2\"\n >\n {saving ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Saving…\n </>\n ) : (\n <>\n <FolderSymlink className=\"h-4 w-4\" />\n Continue\n </>\n )}\n </Button>\n </div>\n </WizardStepFrame>\n );\n}\n","\"use client\";\n\nimport { SlackCard } from \"@/components/connections/slack-card\";\nimport { TelegramCard } from \"@/components/connections/telegram-card\";\nimport { DiscordCard } from \"@/components/connections/discord-card\";\nimport { WhatsAppCard } from \"@/components/connections/whatsapp-card\";\nimport { DestinationSelector } from \"@/components/connections/destination-selector\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\ninterface MessagingStepProps {\n onNext: () => void;\n onBack?: () => void;\n}\n\nexport function MessagingStep({ onNext, onBack }: MessagingStepProps) {\n return (\n <WizardStepFrame\n title=\"Messaging Channels\"\n description=\"Connect the apps you use to communicate with your agent. You can set up any combination — configure only the ones you need.\"\n onNext={onNext}\n onBack={onBack}\n skipLabel=\"Skip\"\n maxWidth=\"max-w-2xl\"\n >\n <div className=\"space-y-4\">\n <SlackCard />\n <TelegramCard />\n <DiscordCard />\n <WhatsAppCard />\n <DestinationSelector />\n </div>\n </WizardStepFrame>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState, useCallback, useMemo } from \"react\";\nimport {\n DEFAULT_AGENT_DISPLAY_NAME,\n normalizeAgentDisplayName,\n} from \"@aitne/shared\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useChat, fetchSessionMessages } from \"@/lib/hooks/use-chat\";\nimport { useConfig } from \"@/lib/hooks/use-config\";\nimport { api, ApiError } from \"@/lib/api-client\";\nimport { MessageBubble } from \"@/components/chat/message-bubble\";\nimport { ToolProgress } from \"@/components/chat/tool-progress\";\nimport { ChatInput } from \"@/components/chat/chat-input\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport { Button } from \"@/components/ui/button\";\nimport { Alert } from \"@/components/ui/alert\";\nimport { Pencil, Save, ArrowLeft, Loader2 } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n CharacterEditor,\n isCharacterOverCap,\n} from \"@/components/settings/character-editor\";\nimport type { ChatMessage } from \"@/lib/hooks/use-chat\";\nimport type {\n MigrationErrorBody,\n MigrationOkResponse,\n} from \"@/lib/api-types\";\nimport {\n readWizardState,\n writeWizardState,\n clearWizardState,\n} from \"@/lib/setup-storage\";\nimport {\n buildVaultMigrationBody,\n decideVaultMigration,\n type VaultMode,\n} from \"./vault-step.logic\";\n\n// ── Types ──\n\ninterface ConversationStepProps {\n mode: \"initial\" | \"update\";\n agentDisplayName?: string;\n onComplete: () => void;\n /**\n * SETUP-FLOW-REDESIGN-PLAN §5.8 — Back button shown above the agent\n * conversation. The legacy Phase 1 (tool selections) is gone, so the\n * step mounts directly into the chat panel.\n */\n onBack?: () => void;\n /**\n * SETUP-FLOW-REDESIGN-PLAN §5.2 — the user's pending vault choice from\n * the Vault step. Holding these here (rather than committing on the\n * vault step) lets the user Back-navigate freely; the actual\n * `/setup/migrate-context` runs on mount of this step so files only\n * appear at the chosen path once setup is essentially done. Omitted in\n * `update` mode (no vault decision is being made).\n */\n pendingVaultMode?: VaultMode;\n pendingVaultPath?: string;\n}\n\n// ── Helpers ──\n\nfunction extractRulesBlock(content: string): string | null {\n const match = content.match(/```management-rules\\n([\\s\\S]*?)```/);\n return match ? match[1].trim() : null;\n}\n\nfunction extractCharacterBlock(content: string): string | null {\n const match = content.match(/```character\\n([\\s\\S]*?)```/);\n return match ? match[1].trim() : null;\n}\n\n// Staged code blocks are rendered in the preview cards below. Replace them in\n// the chat bubble so the same content isn't shown twice.\nfunction stripStagedBlocksForDisplay(content: string): string {\n return content\n .replace(/```management-rules\\n[\\s\\S]*?```/g, \"_(management rules preview shown below ↓)_\")\n .replace(/```character\\n[\\s\\S]*?```/g, \"_(character preview shown below ↓)_\")\n .trim();\n}\n\nfunction extractChoices(content: string): string[] {\n const choices: string[] = [];\n for (const line of content.split(\"\\n\")) {\n const match = line.match(/^- \\*\\*(.+?)\\*\\*/);\n if (match) choices.push(match[1]);\n }\n return choices.length >= 2 && choices.length <= 8 ? choices : [];\n}\n\n// ── Component ──\n\nexport function ConversationStep({\n mode,\n agentDisplayName,\n onComplete,\n onBack,\n pendingVaultMode,\n pendingVaultPath,\n}: ConversationStepProps) {\n const { data: config } = useConfig();\n\n // SETUP-FLOW-REDESIGN-PLAN §5.8 — the legacy two-phase split is\n // gone; the step mounts directly into the chat panel. Persisted\n // wizard state (sessionStorage) still tracks `setupSessionId` for\n // reload-survival, but `phase` and `selections` are no longer\n // written or consumed here.\n\n // ── Chat state ──\n const {\n messages,\n restoredMessages,\n setRestoredMessages,\n streaming,\n toolProgress,\n sessionInfo,\n sendMessage,\n } = useChat({ disableHistory: true });\n const displayMessages = useMemo(\n () => [...restoredMessages, ...messages],\n [restoredMessages, messages],\n );\n const queryClient = useQueryClient();\n const scrollRef = useRef<HTMLDivElement>(null);\n const startedRef = useRef(false);\n // Synchronous in-flight latch for the vault migration. State-based\n // checks (`if (migrating) return;`) don't dedupe under React 18\n // StrictMode (the dev double-invoke sees the same pre-setState value\n // and both invocations pass the gate). A ref flips synchronously on\n // the first run and blocks the second.\n const migrationInFlightRef = useRef(false);\n\n const [rulesContent, setRulesContent] = useState<string | null>(null);\n const [editing, setEditing] = useState(false);\n const [editBuffer, setEditBuffer] = useState(\"\");\n const [saving, setSaving] = useState(false);\n const [waitingForReply, setWaitingForReply] = useState(false);\n const [startError, setStartError] = useState<string | null>(null);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [startAttempt, setStartAttempt] = useState(0);\n\n // SETUP-FLOW-REDESIGN-PLAN §5.2 — vault migration runs HERE (not on\n // the Vault step), so the user's chosen folder stays untouched until\n // they commit by reaching this final step. `migrationReady` gates the\n // `/setup/start` effect below; in update mode (no vault decision) it\n // is true from the first render. `migrationAttempt` lets the user\n // retry after a transient failure (e.g. iCloud eviction) without\n // forcing them to back-nav.\n const [migrationReady, setMigrationReady] = useState<boolean>(\n mode === \"update\",\n );\n const [migrating, setMigrating] = useState<boolean>(false);\n const [migrationError, setMigrationError] = useState<\n MigrationErrorBody | null\n >(null);\n const [migrationAttempt, setMigrationAttempt] = useState(0);\n // Character is staged via a ```character``` code block from the agent. The\n // draft is what the user sees in the inline editor — seeded from the agent's\n // block, manually editable, committed to /api/config on Save & Finish.\n // `characterInitialized` tracks whether we've seeded the draft from either\n // the agent block or the current config, so user edits don't get clobbered\n // by a later block the agent emits during revisions.\n const [characterDraft, setCharacterDraft] = useState<string>(\"\");\n const [characterInitialized, setCharacterInitialized] = useState(false);\n const [characterUserEdited, setCharacterUserEdited] = useState(false);\n const effectiveAgentDisplayName =\n mode === \"initial\"\n ? normalizeAgentDisplayName(agentDisplayName)\n : config?.agentDisplayName ?? DEFAULT_AGENT_DISPLAY_NAME;\n\n // Reset waitingForReply on new assistant / error message\n useEffect(() => {\n if (displayMessages.length === 0) return;\n const lastMsg = displayMessages[displayMessages.length - 1];\n if (lastMsg.role === \"assistant\" || lastMsg.role === \"error\") {\n setWaitingForReply(false);\n }\n }, [displayMessages]);\n\n // Safety timeout\n useEffect(() => {\n if (!waitingForReply) return;\n const timer = setTimeout(() => setWaitingForReply(false), 120_000);\n return () => clearTimeout(timer);\n }, [waitingForReply]);\n\n const isProcessing = waitingForReply || streaming;\n\n // Auto-scroll\n useEffect(() => {\n const el = scrollRef.current;\n if (el) el.scrollTop = el.scrollHeight;\n }, [displayMessages.length, toolProgress]);\n\n // SETUP-FLOW-REDESIGN-PLAN §5.2 — commit the user's vault choice now,\n // not earlier. The Vault step writes its picks into wizard state; this\n // effect calls `/setup/migrate-context` only when the daemon's current\n // config differs from those picks, then flips `migrationReady` so the\n // `/setup/start` effect below can run. A failed migration leaves\n // `migrationReady` false; the user sees a Retry / Back path instead of\n // a half-bound chat session.\n //\n // Known limitation: if the user reaches rules once (a dashboard_chat\n // session was created by `/setup/start`), back-navigates to Vault,\n // changes the path, then forwards back to rules, the daemon's\n // active-session guard inside `/setup/migrate-context` will respond\n // with 409 `sessions_active`. We surface the daemon's message via the\n // error UI; the user must close the tab to drop the session and\n // restart, or the daemon must restart (which sweeps stale chat\n // sessions). Resolving this cleanly would require a `/setup/abandon`\n // endpoint and is out of scope for the deferred-migration change.\n useEffect(() => {\n if (mode !== \"initial\") return;\n if (migrationReady) return;\n if (migrationInFlightRef.current) return;\n // Sticky-error guard: once a migration attempt errors, the effect\n // would otherwise re-fire (because `migrating` just flipped false)\n // and hammer the daemon in a loop. The user must click Retry, which\n // clears `migrationError` and increments `migrationAttempt`.\n if (migrationError) return;\n if (!config) return;\n\n const decision = decideVaultMigration({\n pendingMode: pendingVaultMode ?? \"plain\",\n pendingPath: pendingVaultPath ?? \"\",\n currentMode: config.vaultMode === \"obsidian\" ? \"obsidian\" : \"plain\",\n currentPath: config.primaryVaultPath ?? null,\n });\n\n if (decision.kind === \"no_migration_needed\") {\n setMigrationReady(true);\n return;\n }\n\n // Latch BEFORE any setState so a StrictMode double-invoke or rapid\n // dep re-fire is dropped at the synchronous gate above.\n migrationInFlightRef.current = true;\n setMigrating(true);\n setMigrationError(null);\n api\n .post<MigrationOkResponse>(\n \"/setup/migrate-context\",\n buildVaultMigrationBody({\n vaultMode: decision.mode,\n primaryVaultPath: decision.path,\n }),\n )\n .then(async () => {\n await queryClient.invalidateQueries({ queryKey: [\"config\"] });\n await queryClient.invalidateQueries({ queryKey: [\"health\"] });\n setMigrationReady(true);\n })\n .catch((err) => {\n if (err instanceof ApiError) {\n setMigrationError((err.body ?? {}) as MigrationErrorBody);\n } else {\n setMigrationError({\n error: \"internal_error\",\n message:\n err instanceof Error ? err.message : \"Unexpected error.\",\n });\n }\n })\n .finally(() => {\n migrationInFlightRef.current = false;\n setMigrating(false);\n });\n }, [\n mode,\n migrationReady,\n migrationError,\n config,\n pendingVaultMode,\n pendingVaultPath,\n queryClient,\n migrationAttempt,\n ]);\n\n // Start agent conversation when entering phase 2.\n //\n // Resume path: if a previous run persisted a `setupSessionId` AND the SSE\n // server bound the same id (it auto-adopts the still-`active`\n // dashboard_chat session via `findActiveDashboardSessionId`), skip\n // /setup/start and just refetch history. The daemon-startup sweep in\n // `index.ts` closes leftover dashboard_chat sessions on restart, so a\n // mismatched `sessionInfo.sessionId` after restart correctly falls\n // through to a fresh /setup/start instead of resuming a stale agent\n // state with no `currentSetupMode` server-side.\n useEffect(() => {\n if (startedRef.current || !sessionInfo?.channelId) return;\n // SETUP-FLOW-REDESIGN-PLAN §5.2 — block until vault migration\n // commits. In update mode `migrationReady` is true from the first\n // render so this is a no-op.\n if (!migrationReady) return;\n\n // Resume only when the persisted session id was created under THIS\n // mode — otherwise an `initial` setupSessionId left in storage from\n // an abandoned run would wrongly skip the fresh /setup/start the\n // current `update` flow needs.\n const persistedNow = readWizardState();\n const modeMatches = persistedNow.setupSessionMode === mode;\n const resumedSessionId =\n modeMatches\n && typeof persistedNow.setupSessionId === \"number\"\n && persistedNow.setupSessionId > 0\n && sessionInfo.sessionId === persistedNow.setupSessionId\n ? persistedNow.setupSessionId\n : null;\n\n if (resumedSessionId !== null) {\n startedRef.current = true;\n fetchSessionMessages(resumedSessionId)\n .then((restored) => {\n setRestoredMessages(restored);\n })\n .catch((err) => {\n // History fetch failed — the conversation is still resumable\n // through the live SSE stream, so don't surface a fatal error.\n console.warn(\"[setup] failed to refetch resumed session history\", err);\n });\n return;\n }\n\n startedRef.current = true;\n setStartError(null);\n setWaitingForReply(true);\n\n // SETUP-FLOW-REDESIGN-PLAN §5.8 — `/setup/start` no longer takes\n // `selections`. The agent derives the Source-of-Truth table from\n // the integrations registry (steps 4–6 already configured those)\n // and asks the user only about rows it could not infer.\n api\n .post(\"/setup/start\", {\n channelId: sessionInfo.channelId,\n mode,\n ...(mode === \"initial\"\n ? { agentDisplayName: effectiveAgentDisplayName }\n : {}),\n })\n .catch((err) => {\n startedRef.current = false;\n const msg = err instanceof Error ? err.message : \"Failed to start setup\";\n setStartError(msg);\n setWaitingForReply(false);\n });\n }, [\n sessionInfo?.channelId,\n sessionInfo?.sessionId,\n mode,\n effectiveAgentDisplayName,\n startAttempt,\n migrationReady,\n setRestoredMessages,\n ]);\n\n // Persist the in-flight setup session id once the dispatcher binds it.\n // On reload the resume effect above can verify it against the SSE-\n // adopted session and skip /setup/start. Tagging with the current\n // mode lets the resume effect reject a match that came from a\n // different mode's abandoned run.\n useEffect(() => {\n if (typeof sessionInfo?.sessionId !== \"number\") return;\n writeWizardState({\n setupSessionId: sessionInfo.sessionId,\n setupSessionMode: mode,\n });\n }, [mode, sessionInfo?.sessionId]);\n\n // Detect rules + character blocks in assistant messages. Walks back from\n // the most recent message so a later revision turn overrides an earlier\n // draft. `rulesContent` is load-bearing — the Save & Finish card only\n // shows once rules are staged. Character is optional: if the agent never\n // emits a block we fall back to the current `/api/config.character` value.\n useEffect(() => {\n if (streaming) return;\n for (let i = displayMessages.length - 1; i >= 0; i--) {\n const msg = displayMessages[i];\n if (msg.role !== \"assistant\") continue;\n const rules = extractRulesBlock(msg.content);\n if (rules) {\n setRulesContent(rules);\n if (!editing) setEditBuffer(rules);\n }\n const character = extractCharacterBlock(msg.content);\n if (character !== null && !characterUserEdited) {\n setCharacterDraft(character);\n setCharacterInitialized(true);\n }\n if (rules || character !== null) break;\n }\n }, [displayMessages, streaming, editing, characterUserEdited]);\n\n // Seed the character draft from /api/config the first time the rules\n // preview appears, so the editor is never empty for an update-mode run\n // where the agent didn't emit a ```character``` block. Only runs once —\n // later agent revisions re-seed via the block-detector above, and explicit\n // user edits flip `characterUserEdited` which both branches respect.\n useEffect(() => {\n if (!rulesContent || characterInitialized) return;\n setCharacterDraft(config?.character ?? \"\");\n setCharacterInitialized(true);\n }, [rulesContent, characterInitialized, config?.character]);\n\n const handleSave = useCallback(async () => {\n const content = editing ? editBuffer : rulesContent;\n if (!content) return;\n const trimmedCharacter = characterDraft.trim();\n if (isCharacterOverCap(trimmedCharacter)) {\n setSaveError(\"Character exceeds the 1000-character cap.\");\n return;\n }\n setSaving(true);\n setSaveError(null);\n try {\n // PATCH character first. If this fails, rules haven't been saved yet,\n // so the user can retry cleanly without the wizard advancing on half\n // a write. We only fire the PATCH when the draft actually differs from\n // the current config — avoids an inert write-lock row for no-op edits.\n const currentCharacter = config?.character ?? \"\";\n if (characterInitialized && trimmedCharacter !== currentCharacter) {\n await api.patch(\"/config\", { character: trimmedCharacter });\n }\n await api.post(\"/setup/save-rules\", {\n content,\n ...(mode === \"initial\"\n ? { agentDisplayName: effectiveAgentDisplayName }\n : {}),\n ...(typeof sessionInfo?.sessionId === \"number\"\n ? { sessionId: sessionInfo.sessionId }\n : {}),\n });\n // Optimistically set cache so Overview doesn't redirect back to /setup\n // (invalidateQueries only marks stale — the old needsSetup:true would be\n // returned immediately on next mount, triggering a redirect loop)\n queryClient.setQueryData([\"setup-status\"], {\n needsSetup: false,\n completedAt: new Date().toISOString(),\n });\n queryClient.invalidateQueries({ queryKey: [\"config\"] });\n queryClient.invalidateQueries({ queryKey: [\"health\"] });\n // Setup is committed — drop all persisted wizard state so a future\n // re-entry (re-setup or update mode) starts clean instead of\n // restoring stale step / selections / setupSessionId.\n clearWizardState();\n onComplete();\n } catch (err) {\n setSaveError(err instanceof Error ? err.message : \"Failed to save rules\");\n } finally {\n setSaving(false);\n }\n }, [\n editing,\n editBuffer,\n rulesContent,\n characterDraft,\n characterInitialized,\n config?.character,\n queryClient,\n onComplete,\n mode,\n effectiveAgentDisplayName,\n sessionInfo?.sessionId,\n ]);\n\n const handleChoiceClick = useCallback(\n (choice: string) => {\n sendMessage(choice);\n setWaitingForReply(true);\n },\n [sendMessage],\n );\n\n const handleSendMessage = useCallback(\n (content: string) => {\n sendMessage(content);\n setWaitingForReply(true);\n },\n [sendMessage],\n );\n\n const lastAssistantMsg = [...displayMessages].reverse().find((m) => m.role === \"assistant\");\n const choices = lastAssistantMsg && !isProcessing ? extractChoices(lastAssistantMsg.content) : [];\n\n // SETUP-FLOW-REDESIGN-PLAN §5.8 — Phase 1 (tool selections) is removed.\n // The Source-of-Truth table is derived inside the agent conversation\n // from the integrations registry; the wizard mounts directly into the\n // chat panel.\n\n // ══════════════════════════════════════════\n // Phase 2: Agent Conversation (Claude Code)\n // ══════════════════════════════════════════\n return (\n <div className=\"mx-auto flex h-full w-full max-w-4xl flex-col\">\n <div className=\"space-y-1 px-4 pt-4 text-center\">\n <h2 className=\"text-xl font-semibold\">\n {mode === \"initial\" ? \"Customize Your Rules\" : \"Update Management Rules\"}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {mode === \"initial\"\n ? \"Answer a few more questions and the agent will generate your management rules.\"\n : \"Review the current rules and let us know what you'd like to change.\"}\n </p>\n </div>\n\n {migrating && (\n <Alert className=\"mx-4 mt-4 rounded-lg px-4 py-3 text-sm\">\n <div className=\"flex items-center gap-3\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Setting up your vault…</span>\n </div>\n </Alert>\n )}\n\n {migrationError && !migrating && (\n <Alert variant=\"error\" className=\"mx-4 mt-4 rounded-lg px-4 py-3 text-sm\">\n <div className=\"flex items-start justify-between gap-3 w-full\">\n <div>\n <p className=\"font-medium\">Could not set up your vault</p>\n <p className=\"mt-0.5\">{migrationError.message}</p>\n </div>\n <div className=\"flex shrink-0 gap-2\">\n {onBack && (\n <Button size=\"sm\" variant=\"ghost\" onClick={onBack}>\n Back\n </Button>\n )}\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n setMigrationError(null);\n setMigrationAttempt((prev) => prev + 1);\n }}\n >\n Retry\n </Button>\n </div>\n </div>\n </Alert>\n )}\n\n {startError && (\n <Alert variant=\"error\" className=\"mx-4 mt-4 rounded-lg px-4 py-3 text-sm\">\n <div className=\"flex items-center justify-between gap-3 w-full\">\n <span>{startError}</span>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setStartAttempt((prev) => prev + 1)}\n >\n Retry\n </Button>\n </div>\n </Alert>\n )}\n\n <ScrollArea ref={scrollRef} className=\"flex-1 px-4 py-4\">\n <div className=\"space-y-4\">\n {displayMessages.map((msg: ChatMessage) => (\n <MessageBubble\n key={msg.id}\n message={\n msg.role === \"assistant\"\n ? { ...msg, content: stripStagedBlocksForDisplay(msg.content) }\n : msg\n }\n assistantLabel={effectiveAgentDisplayName}\n />\n ))}\n <ToolProgress items={toolProgress} />\n {isProcessing && (\n <div className=\"flex justify-start\">\n <span className=\"inline-block h-5 w-1 animate-pulse rounded-full bg-foreground\" />\n </div>\n )}\n {displayMessages.length === 0\n && !isProcessing\n && !startError\n && !migrating\n && !migrationError && (\n <div className=\"flex flex-col items-center justify-center py-16 text-muted-foreground\">\n <p className=\"text-sm\">Preparing setup...</p>\n </div>\n )}\n </div>\n </ScrollArea>\n\n {choices.length > 0 && !rulesContent && (\n <div className=\"flex flex-wrap gap-2 border-t border-border bg-muted/30 px-4 py-3\">\n {choices.map((choice) => (\n <Button\n key={choice}\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleChoiceClick(choice)}\n disabled={isProcessing}\n className=\"text-xs\"\n >\n {choice}\n </Button>\n ))}\n </div>\n )}\n\n {rulesContent && (\n <div className=\"border-t border-border bg-muted/30 px-4 py-4 space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-sm font-medium\">Management Rules Preview</h3>\n <div className=\"flex gap-2\">\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n if (editing) setEditBuffer(rulesContent);\n setEditing(!editing);\n }}\n className=\"gap-1 text-xs\"\n >\n <Pencil className=\"h-3 w-3\" />\n {editing ? \"Cancel\" : \"Edit\"}\n </Button>\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={saving || isCharacterOverCap(characterDraft)}\n className=\"gap-1\"\n >\n {saving ? (\n \"Saving...\"\n ) : (\n <>\n <Save className=\"h-3.5 w-3.5\" />\n Save & Finish\n </>\n )}\n </Button>\n </div>\n </div>\n\n {saveError && <Alert variant=\"error\">{saveError}</Alert>}\n\n {editing ? (\n <textarea\n value={editBuffer}\n onChange={(e) => setEditBuffer(e.target.value)}\n className=\"w-full rounded-md border border-input bg-background p-3 font-mono text-xs leading-relaxed focus:outline-none focus:ring-2 focus:ring-ring\"\n rows={16}\n />\n ) : (\n <pre className=\"max-h-96 overflow-auto rounded-md border border-border bg-background p-3 text-xs leading-relaxed\">\n {rulesContent}\n </pre>\n )}\n\n <div className=\"space-y-2 border-t border-border/60 pt-4\">\n <div>\n <h3 className=\"text-sm font-medium\">Character</h3>\n <p className=\"text-xs text-muted-foreground\">\n How the agent should talk to you — tone, language, formality.\n Applies across every session and backend. Leave blank to skip.\n </p>\n </div>\n <CharacterEditor\n value={characterDraft}\n onChange={(next) => {\n setCharacterDraft(next);\n setCharacterUserEdited(true);\n if (!characterInitialized) setCharacterInitialized(true);\n }}\n disabled={saving}\n rows={4}\n />\n </div>\n </div>\n )}\n\n {!saving && (\n <ChatInput\n onSend={handleSendMessage}\n disabled={isProcessing || displayMessages.length === 0}\n />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useRouter } from \"next/navigation\";\nimport { CheckCircle2, ArrowRight, FileText } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface SetupCompleteProps {\n mode: \"initial\" | \"update\";\n agentDisplayName: string;\n}\n\nexport function SetupComplete({ mode, agentDisplayName }: SetupCompleteProps) {\n const router = useRouter();\n\n return (\n <div className=\"flex flex-col items-center justify-center gap-8 py-16 text-center\">\n <div className=\"rounded-full bg-emerald-100 p-6 dark:bg-emerald-950\">\n <CheckCircle2 className=\"h-12 w-12 text-emerald-600 dark:text-emerald-400\" />\n </div>\n\n <div className=\"max-w-md space-y-3\">\n <h1 className=\"text-2xl font-bold text-foreground\">\n {mode === \"initial\" ? \"Setup Complete\" : \"Rules Updated\"}\n </h1>\n <p className=\"text-muted-foreground\">\n {mode === \"initial\"\n ? `${agentDisplayName} is ready to manage your schedule and tasks.`\n : \"Management Rules have been updated. Changes take effect immediately.\"}\n </p>\n </div>\n\n <div className=\"flex gap-3\">\n <Button\n variant=\"outline\"\n onClick={() => router.push(\"/memory\")}\n className=\"gap-2\"\n >\n <FileText className=\"h-4 w-4\" />\n View Management Rules\n </Button>\n <Button\n onClick={() => router.push(\"/\")}\n className=\"gap-2\"\n >\n Go to Overview\n <ArrowRight className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n","import createLucideIcon from '../createLucideIcon';\n\n/**\n * @component @name SkipForward\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cG9seWdvbiBwb2ludHM9IjUgNCAxNSAxMiA1IDIwIDUgNCIgLz4KICA8bGluZSB4MT0iMTkiIHgyPSIxOSIgeTE9IjUiIHkyPSIxOSIgLz4KPC9zdmc+Cg==) - https://lucide.dev/icons/skip-forward\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst SkipForward = createLucideIcon('SkipForward', [\n ['polygon', { points: '5 4 15 12 5 20 5 4', key: '16p6eg' }],\n ['line', { x1: '19', x2: '19', y1: '5', y2: '19', key: 'futhcm' }],\n]);\n\nexport default SkipForward;\n","/**\n * SETUP-FLOW-REDESIGN-PLAN §5.1 — pure decision logic for the Basics\n * step. Tests live in the `.test.ts` sibling. The component is a thin\n * shell around these helpers.\n *\n * Replaces the former Welcome step + the language portion of the old\n * Vault step. Two atomic fields persisted on Continue:\n *\n * - `agentDisplayName` — trim, length 1–40, no leading/trailing\n * whitespace.\n * - `language` — BCP-47 tag (e.g. `en-US`, `zh-Hans`); validated\n * against the same regex used by the legacy vault-step logic so\n * dashboards that already saved a custom tag round-trip cleanly.\n */\n\nexport const LANGUAGE_TAG_RE = /^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})?$/;\n\n/** UI-visible upper bound — keeps Slack/WhatsApp prefixes readable. */\nexport const AGENT_DISPLAY_NAME_MAX_LENGTH = 40;\n\nexport interface BasicsStepFields {\n agentDisplayName: string;\n language: string;\n /** Optional second-input value for the \"Other (BCP-47…)\" custom case. */\n customLanguage?: string;\n}\n\nexport const SUPPORTED_LANGUAGES: ReadonlyArray<{\n tag: string;\n label: string;\n}> = [\n { tag: \"en\", label: \"English\" },\n { tag: \"ja\", label: \"日本語 (Japanese)\" },\n { tag: \"zh\", label: \"中文 (Chinese)\" },\n { tag: \"es\", label: \"Español (Spanish)\" },\n { tag: \"fr\", label: \"Français (French)\" },\n { tag: \"de\", label: \"Deutsch (German)\" },\n { tag: \"pt\", label: \"Português (Portuguese)\" },\n { tag: \"ko\", label: \"한국어 (Korean)\" },\n { tag: \"__custom__\", label: \"Other (enter BCP-47 tag…)\" },\n];\n\nconst SUPPORTED_TAG_SET: ReadonlySet<string> = new Set(\n SUPPORTED_LANGUAGES.filter((l) => l.tag !== \"__custom__\").map((l) => l.tag),\n);\n\n/**\n * Resolve the language tag the form will POST. Mirrors the legacy\n * vault-step helper — `__custom__` falls through to the user-entered\n * BCP-47 tag, anything else is the dropdown value verbatim.\n */\nexport function resolveLanguage(\n primarySelection: string,\n customRaw: string,\n): string {\n return primarySelection === \"__custom__\"\n ? customRaw.trim()\n : primarySelection;\n}\n\nexport function isCustomLanguageInvalid(\n primarySelection: string,\n customRaw: string,\n): boolean {\n if (primarySelection !== \"__custom__\") return false;\n const trimmed = customRaw.trim();\n if (trimmed.length === 0) return false;\n return !LANGUAGE_TAG_RE.test(trimmed);\n}\n\n/**\n * True when the form is ready to POST. Blocks while a save is in flight\n * and when either field fails validation.\n */\nexport function canContinue(input: {\n agentDisplayName: string;\n resolvedLanguage: string;\n saving: boolean;\n}): boolean {\n if (input.saving) return false;\n const trimmed = input.agentDisplayName.trim();\n if (trimmed.length === 0) return false;\n if (trimmed.length > AGENT_DISPLAY_NAME_MAX_LENGTH) return false;\n if (input.resolvedLanguage.length === 0) return false;\n if (!LANGUAGE_TAG_RE.test(input.resolvedLanguage)) return false;\n return true;\n}\n\n/**\n * Build the `PATCH /api/config` body. Fields are emitted only when\n * non-empty so the API short-circuits no-op writes.\n */\nexport interface BasicsPatchBody {\n agentDisplayName: string;\n primaryLanguage: string;\n}\n\nexport function buildBasicsPatchBody(input: {\n agentDisplayName: string;\n resolvedLanguage: string;\n}): BasicsPatchBody {\n return {\n agentDisplayName: input.agentDisplayName.trim(),\n primaryLanguage: input.resolvedLanguage,\n };\n}\n\n/**\n * When hydrating from `config`, resolve a stored tag back into the\n * `(dropdown value, custom input)` pair the form expects. Unknown tags\n * land in `__custom__` so the user sees their previous choice intact.\n */\nexport function hydrateLanguageSelection(\n storedTag: string | null | undefined,\n): { primary: string; custom: string } {\n if (typeof storedTag !== \"string\" || storedTag.length === 0) {\n return { primary: \"en\", custom: \"\" };\n }\n if (SUPPORTED_TAG_SET.has(storedTag)) {\n return { primary: storedTag, custom: \"\" };\n }\n return { primary: \"__custom__\", custom: storedTag };\n}\n","\"use client\";\n\n/**\n * Wizard state persistence for `/setup`. Without this, a page reload mid-\n * setup drops the user back to `welcome` (initial mode) and a re-entry to\n * the conversation step calls `/setup/start` again, restarting the agent\n * conversation from scratch and forcing the user to redo every answer.\n *\n * Daemon-side: a startup sweep in `index.ts` closes any leftover active\n * `dashboard_chat` sessions, so a stored `setupSessionId` whose row was\n * orphaned by a daemon restart will fail the active-status check and the\n * conversation step falls through to a fresh start.\n *\n * Storage is `sessionStorage` so the state lives for the duration of the\n * tab — closing the tab discards it, which matches the user's mental\n * model of \"I left setup half-done in this tab.\"\n */\n\nimport type { IntegrationKey, IntegrationMode } from \"@aitne/shared\";\nimport type { SetupStep } from \"@/components/setup/wizard-steps.logic\";\n\nconst STORAGE_KEY = \"pa-setup-wizard-state\";\n\nexport interface PersistedWizardState {\n step?: SetupStep;\n agentDisplayName?: string;\n modeOverride?: \"plain\" | \"obsidian\" | null;\n /**\n * SETUP-FLOW-REDESIGN-PLAN §5.2 — the user's chosen primary-vault path,\n * persisted but NOT yet committed to the daemon. The actual\n * `/setup/migrate-context` call runs on entry to the Customize Rules\n * step (see `conversation-step.tsx`); deferring file creation lets the\n * user freely Back-navigate and re-pick the same directory without\n * the picker showing it as already populated.\n */\n pendingVaultPath?: string | null;\n integrationModeDraft?: Partial<Record<IntegrationKey, IntegrationMode>>;\n /**\n * Per-radio optionId pick for the Google-mode step (e.g.\n * `delegated:codex`, `direct`, `disabled`). Without this, a remount of\n * `GoogleModeStep` (Back navigation, reload while on the step) would\n * re-seed `defaultOptionId` and propagate the default through\n * `onDraftChange`, overwriting any prior user pick — and a subsequent\n * Continue would PATCH the daemon back to that default.\n */\n googleModeSelections?: Partial<Record<IntegrationKey, string>>;\n /** Same protection for the Notion single-radio step. */\n notionModeSelection?: string;\n /**\n * SETUP-FLOW-REDESIGN-PLAN §5.8 — the legacy `phase` / `selections`\n * fields are gone (Phase 1 tool selections were deleted). Kept as\n * loose-typed leftovers in this interface so a stale sessionStorage\n * entry from before the redesign deserializes cleanly via the\n * `readWizardState` JSON.parse path; new writers never set them.\n */\n phase?: \"selections\" | \"conversation\";\n selections?: {\n schedule: string | null;\n tasks: string | null;\n notes: string | null;\n projects: string | null;\n };\n /** DB id of the in-flight setup conversation. Written when /setup/start\n * resolves; checked on remount to decide between resume and fresh start. */\n setupSessionId?: number;\n /** Mode the persisted `setupSessionId` was created under. Resume must\n * reject a session id from a different mode (e.g. an initial-mode id\n * left in storage when the user later opens `?mode=update`) — a match\n * there would skip the fresh `/setup/start` the update flow needs. */\n setupSessionMode?: \"initial\" | \"update\";\n}\n\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\";\n}\n\nexport function readWizardState(): PersistedWizardState {\n if (!isBrowser()) return {};\n try {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\") return {};\n return parsed as PersistedWizardState;\n } catch {\n return {};\n }\n}\n\nexport function writeWizardState(patch: PersistedWizardState): void {\n if (!isBrowser()) return;\n try {\n const current = readWizardState();\n const merged = { ...current, ...patch };\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(merged));\n } catch {\n /* quota exceeded or sessionStorage disabled — ignore */\n }\n}\n\nexport function clearWizardState(): void {\n if (!isBrowser()) return;\n try {\n sessionStorage.removeItem(STORAGE_KEY);\n } catch {\n /* ignore */\n }\n}\n","/**\n * SETUP-FLOW-REDESIGN-PLAN §5.6 — Note step pure logic.\n *\n * The Note step writes to **two** systems:\n * 1. Notion — via `PATCH /api/integrations/notion`. Mode + (in direct\n * mode) API key + DB mappings, all owned by the existing\n * `IntegrationCard` + `NotionDirectSettingsBody` components.\n * 2. External Obsidian vault — `externalObsidianVaultPath` +\n * `externalObsidianWatch` via `PATCH /api/config`. Validation:\n * path must be absolute, must not overlap `dataDir`, must not\n * overlap the primary vault. The daemon's `validateExternalObsidianVaultPath`\n * is the source of truth; we mirror its prefix checks client-side\n * so the user gets an immediate signal without a round-trip.\n */\n\nimport {\n isClientAbsolutePath,\n isClientPathInsideOrEqual,\n} from \"@/lib/path-client\";\n\nexport interface NoteStepFields {\n externalObsidianVaultPath: string;\n externalObsidianWatch: boolean;\n}\n\nexport const DEFAULT_NOTE_STEP_FIELDS: NoteStepFields = {\n externalObsidianVaultPath: \"\",\n externalObsidianWatch: true,\n};\n\n/**\n * Pre-flight client-side path check. Mirrors the prefix rules in\n * `daemon/src/config.ts:validateExternalObsidianVaultPath` — the\n * daemon re-runs the full validation server-side, so this is just an\n * immediate-feedback layer.\n */\nexport type NotePathIssue =\n | \"empty\"\n | \"not_absolute\"\n | \"overlaps_data_dir\"\n | \"overlaps_primary_vault\";\n\nexport interface ValidateExternalVaultPathInput {\n path: string;\n dataDir: string;\n primaryVaultPath: string | null;\n}\n\nexport function validateExternalVaultPathClient(\n input: ValidateExternalVaultPathInput,\n): NotePathIssue | null {\n const trimmed = input.path.trim();\n if (trimmed.length === 0) return \"empty\";\n if (!isClientAbsolutePath(trimmed)) {\n return \"not_absolute\";\n }\n // Prefix-match against the data-dir; do a normalised strip so trailing\n // slashes don't confuse the check. The daemon does a stat-based realpath\n // resolution; here we approximate with raw prefix match. False\n // positives (a sibling that *starts with* dataDir) are rare and the\n // server re-runs the real validation.\n if (\n input.dataDir.length > 0\n && isClientPathInsideOrEqual(input.dataDir, trimmed)\n ) {\n return \"overlaps_data_dir\";\n }\n if (\n input.primaryVaultPath\n && isClientPathInsideOrEqual(input.primaryVaultPath, trimmed)\n ) {\n return \"overlaps_primary_vault\";\n }\n return null;\n}\n\n/** Human-readable inline error messages keyed off `NotePathIssue`. */\nexport function notePathIssueMessage(issue: NotePathIssue): string {\n switch (issue) {\n case \"empty\":\n return \"Pick a path or leave the field blank to skip.\";\n case \"not_absolute\":\n return \"Use an absolute path (for example `/Users/me/Vault`, `~/Vault`, or `C:\\\\Vault`).\";\n case \"overlaps_data_dir\":\n return \"Path overlaps the agent's data directory; choose a separate location.\";\n case \"overlaps_primary_vault\":\n return \"Path overlaps the agent's primary vault; choose a separate location.\";\n }\n}\n\n/**\n * Continue-button enablement. Empty path is **allowed** — the user is\n * skipping the external-vault opt-in; in that case the field is just\n * not persisted. A non-empty path with a validation issue blocks.\n */\nexport function canContinue(input: {\n pathIssue: NotePathIssue | null;\n saving: boolean;\n}): boolean {\n if (input.saving) return false;\n if (input.pathIssue === null) return true;\n // Empty is the implicit-skip path — allow.\n return input.pathIssue === \"empty\";\n}\n\n/**\n * Build the `PATCH /api/config` body for the Note step. Path is\n * trimmed; an empty path resolves to `null` so the daemon clears the\n * field (lets the user un-pair an Obsidian vault from the wizard).\n */\nexport interface NotePatchBody {\n externalObsidianVaultPath: string | null;\n externalObsidianWatch: boolean;\n}\n\nexport function buildNotePatchBody(\n fields: NoteStepFields,\n): NotePatchBody {\n const trimmed = fields.externalObsidianVaultPath.trim();\n return {\n externalObsidianVaultPath: trimmed.length === 0 ? null : trimmed,\n externalObsidianWatch: fields.externalObsidianWatch,\n };\n}\n","/**\n * SETUP-FLOW-REDESIGN-PLAN §6.5 — flow controller for the redesigned\n * setup wizard. The list collapses from 13 steps to 7 collection steps\n * + a terminal `complete`:\n *\n * 1. Basics (display name + language) — required\n * 2. Vault (mode + primary path inline) — required\n * 3. AI Backend (main backend selection) — required\n * 4. Mail (Gmail + Outlook + IMAP) — skippable\n * 5. Calendar (Google + Outlook) — skippable\n * 6. Note (Notion + external Obsidian vault) — skippable\n * 7. Messaging (Slack/Telegram/Discord/WhatsApp) — skippable\n * 8. Customize Rules (chat-driven; no tools form) — required\n * 9. Complete — terminal\n *\n * Repositories are not registered during setup — users add them\n * post-setup from Settings → Connections → Repositories. Conditional\n * sub-steps are gone: every former mode-then-credentials pair is now\n * inline inside the parent step, so `filterInitialSteps` collapses to\n * identity. The wizard list returned matches the `BASE_INITIAL_STEPS`\n * order; `app/setup/page.tsx` switches on the id to mount the right\n * component.\n */\n\nexport type SetupStep =\n | \"basics\"\n | \"vault\"\n | \"backend\"\n | \"mail\"\n | \"calendar\"\n | \"note\"\n | \"messaging\"\n | \"rules\"\n | \"complete\";\n\nexport const BASE_INITIAL_STEPS: readonly SetupStep[] = [\n \"basics\",\n \"vault\",\n \"backend\",\n \"mail\",\n \"calendar\",\n \"note\",\n \"messaging\",\n \"rules\",\n \"complete\",\n];\n\n/**\n * The required steps — the wizard cannot finish without each of these\n * having been visited at least once. (`complete` is the terminal screen\n * and is included in the set so the type system can read it as\n * required-by-existence.) Skip buttons are hidden on these steps; every\n * other step exposes Skip.\n */\nexport const REQUIRED_STEPS: ReadonlySet<SetupStep> = new Set<SetupStep>([\n \"basics\",\n \"vault\",\n \"backend\",\n \"rules\",\n \"complete\",\n]);\n\n/**\n * Human-readable labels for the stepper. Single source of truth so the\n * page header and the per-step `WizardStepFrame` titles cannot drift.\n */\nexport const STEP_LABELS: Record<SetupStep, string> = {\n basics: \"Basics\",\n vault: \"Vault\",\n backend: \"AI Backend\",\n mail: \"Mail\",\n calendar: \"Calendar\",\n note: \"Note\",\n messaging: \"Messaging\",\n rules: \"Rules\",\n complete: \"Done\",\n};\n\n/**\n * Derived vault mode for the wizard. `modeOverride` is non-null only\n * when the user explicitly toggled the choice in VaultStep; in that\n * case their click wins over whatever the daemon currently has\n * persisted. Otherwise we mirror `config.vaultMode`, defaulting to\n * \"plain\" when config is still loading (so the initial render does\n * not flicker the inline path field in and out).\n */\nexport function deriveVaultMode(\n modeOverride: \"plain\" | \"obsidian\" | null,\n configVaultMode: \"plain\" | \"obsidian\" | null | undefined,\n): \"plain\" | \"obsidian\" {\n if (modeOverride !== null) return modeOverride;\n return configVaultMode === \"obsidian\" ? \"obsidian\" : \"plain\";\n}\n\n/**\n * Identity in v1 — every former conditional sub-step (`google`,\n * `obsidian`, `notion`) is now an inline disclosure in its parent\n * step, so the list never shrinks from `BASE_INITIAL_STEPS`.\n *\n * Kept as a separate function so `app/setup/page.tsx` doesn't need a\n * conditional import path during the redesign cutover, and so future\n * conditional gating (e.g. enterprise-only steps) has an obvious home.\n */\nexport function filterInitialSteps(\n baseSteps: readonly SetupStep[] = BASE_INITIAL_STEPS,\n): SetupStep[] {\n return [...baseSteps];\n}\n\n/** True for steps the Skip button should render. */\nexport function isSkippable(step: SetupStep): boolean {\n return !REQUIRED_STEPS.has(step);\n}\n"],"names":["LANGUAGE_TAG_RE","AGENT_DISPLAY_NAME_MAX_LENGTH","SUPPORTED_LANGUAGES","tag","label","SUPPORTED_TAG_SET","map","Set","l","filter","primarySelection","resolveLanguage","trimmed","customRaw","trim","isCustomLanguageInvalid","input","length","test","canContinue","saving","agentDisplayName","resolvedLanguage","custom","has","buildBasicsPatchBody","primaryLanguage","primary","hydrateLanguageSelection","storedTag"],"mappings":"wDAEA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,OAAA,IAAA,EAAA,EAAA,CAAA,CAAA,OEDA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,MACA,EAAA,EAAA,CAAA,CAAA,OAOA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OWAO,IAAMA,EAAkB,qCAYlBE,EAGR,CACH,CAAEC,IAAK,KAAMC,MAAO,SAAU,EAC9B,CAAED,IAAK,KAAMC,MAAO,gBAAiB,EACrC,CAAED,IAAK,KAAMC,MAAO,cAAe,EACnC,CAAED,IAAK,KAAMC,MAAO,mBAAoB,EACxC,CAAED,IAAK,KAAMC,MAAO,mBAAoB,EACxC,CAAED,IAAK,KAAMC,MAAO,kBAAmB,EACvC,CAAED,IAAK,KAAMC,MAAO,wBAAyB,EAC7C,CAAED,IAAK,KAAMC,MAAO,cAAe,EACnC,CAAED,IAAK,aAAcC,MAAO,2BAA4B,EACzD,CAEKC,EAAyC,IAAIE,IACjDL,EAAoBO,MAAM,CAAC,AAACD,GAAgB,eAAVA,EAAEL,GAAG,EAAmBG,GAAG,CAAC,AAACE,GAAMA,EAAEL,GAAG,GD9BtE,CAAA,CAAA,CAAA,CAAA,CAAA,AAAc,CAAd,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAc,OAAA,EAAiB,aAAe,CAAA,CAAA,AAClD,CAAC,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAW,CAAA,CAAA,AAAE,OAAQ,CAAsB,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,AAAK,QAAA,CAAU,CAAA,CAAA,AAC3D,CAAC,CAAA,CAAA,CAAA,IAAQ,CAAE,CAAA,CAAA,CAAI,CAAM,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,AAAI,CAAM,CAAA,GAAA,EAAA,CAAI,IAAK,CAAA,CAAA,CAAI,CAAA,CAAA,CAAA,CAAM,CAAA,CAAA,GAAK,QAAA,CAAU,CAAA,CAClE,EXmBM,SAAS,EAAgB,OAC9B,CAAK,aACL,CAAW,UACX,CAAQ,QACR,CAAM,QACN,CAAM,WACN,EAAY,cAAc,WAC1B,EAAY,MAAM,cAClBA,EAAe,EAAK,SACpB,GAAU,CAAK,UACf,CAAQ,CACa,EACrB,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAW,CAAC,QAAQ,EAAE,GAAY,WAAW,eAAe,CAAC,WAChE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,kCACb,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,iCAAyB,IACtC,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCAAiC,OAIjD,EAEA,CAAC,GACA,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAIO,UAAU,sCACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,uBACZ,EACC,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,MAAM,CAAA,CACL,QAAQ,QACR,QAAS,EACT,UAAU,wCAEV,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,SAAS,CAAA,CAAC,UAAU,YAAY,UAGjC,KACH,EACCE,CAAAA,EAAAA,EAAAA,IAAAA,EAAC,EAAA,MAAM,CAAA,CACL,QAAQ,QACR,QAAS,EACT,UAAU,wCAEV,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAY,UAAU,YACtB,KAED,KACH,AAAC,GAAW,EAAsB,KAAvB,AAAa,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAA,MAE5B,CAAA,EAAA,EAAA,IAAA,EAACA,EAAAA,MAAM,CAAA,CACL,QAAS,EACT,UAAU,QACV,SAAU,YAET,EACD,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,UAAU,CAAA,CAAC,UAAU,oBAMlC,CCrDO,SAAS,EAAW,CACzB,kBAAgB,0BAChB,CAAwB,QACxB,CAAM,CACU,EAChB,GAAM,CAAE,KAAM,CAAM,CAAE,CAAG,CAAA,EAAA,EAAA,SAAA,AAAS,IAC5B,EAAc,CAAA,EAAA,EAAA,cAAc,AAAd,IACd,CAAC,EAAiB,EAAmB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,MACjD,CAAC,EAAgB,EAAkB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,IAC/C,CAAC,EAAQ,EAAU,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAC/B,CAAC,EAAO,EAAS,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MAC5C,EAAc,CAAA,EAAA,EAAA,MAAA,AAAM,GAAC,GAK3B,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,WACR,GAAI,EAAY,OAAO,EAAI,CAAC,EAAQ,MACpC,GAAY,OAAO,CAAG,GACtB,IAAM,EWsDR,AAAyB,SXtDN,CWsDf,OAFJiB,AAEWA,EXtDiC,EAAOnB,KWoDf,UXpD8B,GWsDR,GAAG,CAAxBmB,EAAUZ,MAAM,CAC5C,CAAEU,QAAS,KAAMJ,OAAQ,EAAG,EAEjClB,EAAkBmB,GAAG,CAACK,GACjB,CAAEF,QAASE,AADkB,EACPN,OAAQ,EAAG,EAEnC,CAAEI,QAAS,aAAcJ,OAAQM,CAAU,EX3DhD,EAAmB,EAASf,OAAO,EACnC,EAAkB,EAAS,MAAM,EAE/B,AAAmC,iBAA5B,EAAO,gBAAgB,EAC3B,EAAO,gBAAgB,CAAC,MAAM,CAAG,GACL,GAC/B,CADG,EAAiB,MAAM,EAE1B,EAAyB,EAAO,gBAAgB,CAEpD,EAAG,CAAC,EAAQ,EAAkB,EAAyB,EAEvD,IAAM,EWlBCJ,AAAqB,eXkBa,EAAiB,AWjBtDG,AXiBqB,EWjBXC,IAAI,KACdJ,AXiBE,EWdD,AXciB,SWdRK,AACdL,CAAwB,CACxBG,CAAiB,EAEjB,GAAIH,AAAqB,iBAAc,OAAO,EAC9C,IAAME,EAAUC,EAAUC,IAAI,UAC9B,AAAuB,GAAG,CAAtBF,EAAQK,IAAqB,EAAf,EACX,CAACjB,EAAgBkB,IAAI,CAACN,EAC/B,EXMgD,EAAiBI,GACzD,EWDD,AXCS,SWDYA,AAAZG,CAIf,EACC,GAAIH,EAAMI,MAAM,CAAE,OAAO,EACzB,IAAMR,EAAUI,EAAMK,gBAAgB,CAACP,IAAI,UACpB,GAAG,CAAtBF,EAAQK,IAAqB,EAAf,IACdL,EAAQK,MAAM,CAhEyB,EAgEtBhB,GAA+B,AACd,GAAG,CAArCe,EAAMM,CADiD,GACX,YAAtB,CAACL,MAAM,GAC7B,CAACjB,EAAgBkB,IAAI,CAACF,EAAMM,gBAAgB,CAElD,EXX4B,AWSyB,OAAO,WXT9B,mBAAkB,SAAkB,CAAO,GAEjE,EAAiB,UACrB,GAAK,CAAD,EACJ,GAAU,CADEN,EAEZ,EAAS,MACT,GAAI,KWgB6BA,CXf/B,IWkBL,GXlBW,EAAA,GAAG,CAAC,KAAK,CACb,UWkBC,CXjBD,AWkBJK,iBAAkBL,GXlBO,kBAAE,mBAAkB,CAAiB,GWkBtCK,gBAAgB,CAACP,IAAI,GAC7CY,gBAAiBV,EAAMM,gBAAgB,AACzC,GXlBI,MAAM,EAAY,iBAAiBJ,CAAC,CAAE,SAAU,CAAC,SAAS,AAAC,GAC3D,GACF,CAAE,MAAO,EAAK,CACZ,GAAI,aAAe,EAAA,QAAQ,CAAE,CAC3B,IAAM,EAAO,EAAI,IAAI,CACrB,EAAS,GAAM,SAAW,EAAI,OAAO,EAAI,wBAC3C,MACE,CADK,CACI,aAAe,MAAQ,EAAI,OAAO,CAAG,wBAElD,QAAU,CACR,GAAU,EACZ,EACF,EAEA,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,CACC,MAAM,SACN,YAAYJ,sEACZ,OAAQ,EACR,OAAO,CAAA,CAAA,YAEP,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oGACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sBACb,CAAA,EAAA,EAAA,GAAA,EAAC,QAAA,CACC,QAAQ,aACR,UAAU,+CACX,eAGD,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCAAgC,+DAG7C,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,KAAK,CAAA,CACJ,GAAG,aACH,MAAO,EACP,SAAU,AAAC,GAAM,EAAyB,EAAE,MAAM,CAAC,KAAK,EACxD,YAAY,QACZ,WAAW,OAIf,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,kDACb,CAAA,EAAA,EAAA,GAAA,EAAC,QAAA,CAAM,UAAU,+CAAsC,qBAGvD,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCAAgC,iHAI7C,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,MAAM,CAAA,CAAC,MAAO,EAAiB,cAAe,YAC7C,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,aAAa,CAAA,UACZ,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CAAA,KAEd,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,aAAa,CAAA,UACX,EAAoB,GAAG,CAAC,AAAC,GACxB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,UAAU,CAAA,CAAgB,MAAO,EAAK,GAAG,UACvC,EAAK,KAAK,EADI,EAAK,GAAG,QAMV,eAApB,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,KAAK,CAAA,CACJ,MAAO,EACP,SAAU,AAAC,GAAM,EAAkB,EAAE,MAAM,CAAC,KAAK,EACjD,YAAY,eACZ,UAAU,SAGb,GACC,CAAA,EAAA,EAAA,IAAA,EAAC,IAAA,CAAE,UAAU,qCAA2B,yBAChB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UAAK,UAAY,OAAI,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UAAK,YAAc,aAMvE,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,8DACV,IAIL,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,0CACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CACL,KAAK,KACL,QAAS,EACT,SAAU,CAAC,EACX,UAAU,iBAET,EACC,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,OAAO,CAAA,CAAC,UAAU,yBAAyB,aAI9C,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WAAE,WAEA,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,UAAU,CAAA,CAAC,UAAU,qBAOpC,CE7LA,IAAA,EAAA,EAAA,CAAA,CAAA,OAEA,EAAA,EAAA,CAAA,CAAA,OAEA,EAAA,EAAA,CAAA,CAAA,ODOA,EAAA,EAAA,CAAA,CAAA,OCsBO,SAAS,EAAU,QACxB,CAAM,CACN,QAAM,CACN,kBAAgB,0BAChB,CAAwB,kBACxB,CAAgB,0BAChB,CAAwBV,CACT,UACf,MAAM,CAAE,KAAM,CAAM,CAAE,CAAG,CAAA,EAAA,EAAA,SAAA,AAAS,IAE5B,EAAU,GAAQA,YAAc,GAChC,EAAwD,aAArB,AACrC,EDNmBA,GAAG,CAAtB,CADE,EAAU,CAFhB,ECSmC,CAAE,EDTD,GCSO,EAAkB,SAAQ,GDP/C,IAAI,CAAC,IAAI,IACnBD,MAAM,CAAe,QAC5B,CAAA,EAAA,EAAA,oBAAA,AAAoB,EAAC,GAGtB,EAAM,KAH0B,EAGnB,CAAC,MAAM,CAAG,GAAG,AACxB,CAAA,EAAA,EAAA,yBAAA,AAAyB,EAAC,EAAM,OAAO,CAAE,GACpC,OAD8C,aAIlD,KAPE,eCKL,KACE,EDqCN,CAAI,CALsB,EChCAD,CACxB,CADY,CDoCfU,QCnCc,EACX,YACA,QAAQ,CACVT,GDiCU,MAAM,EAAE,CACM,MADC,GACQ,CAA7B,EAAMF,IAA8B,KAArB,EACQ,OAApB,EAAMe,SAAS,ECjCtB,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,CACC,MAAM,QACN,YAAY,uFACZ,OAAQ,EACR,OAAO,CAAA,CAAA,YAEP,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oGACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,kCACZ,CAAE,QAAS,WAAW,CAAW,GAAG,CAAC,AAAC,GACrC,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CAEC,KAAK,SACL,QAAS,IAAM,EAAyB,GACxC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,kEACA,IAAqB,EACjB,+CACA,uFAGN,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,6BACb,AAAS,YACN,iBACA,aAEN,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,+CACJ,UAAT,EACG,qEACA,uEAlBD,MAwBW,aAArB,GACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,kDACb,CAAA,EAAA,EAAA,GAAA,EAAC,QAAA,CACC,QAAQ,qBACR,UAAU,+CACX,eAGD,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCAAgC,sLAK7C,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,oBAAoB,CAAA,CACnB,GAAG,qBACH,MAAO,EACP,SAAU,EACV,MAAMQ,iCACN,YAAY,wCACZ,YAAa,GAAQ,kBAAoB,SAE1C,GAA2B,UAAd,GACZ,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,oCD3DpB,AC4DU,SD5DD,AAAsBhB,CAAqB,EACzDA,OAAQ,GACN,IAAK,QACH,MAAO,iDACT,KAAK,eACH,MAAO,kFACT,KAAK,oBACH,MAAO,uEACX,CACF,ECmDuC,WAOjC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,2CACZ,GACC,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,MAAM,CAAA,CAAC,QAAQ,QAAQ,QAAS,EAAQ,UAAU,kBACjD,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,SAAS,CAAA,CAAC,UAAU,YAAY,UAIrC,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,MAAM,CAAA,CACL,KAAK,KACL,QAAS,EACT,SAAU,CAAC,EACX,UAAU,kBAEV,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,aAAa,CAAA,CAAC,UAAU,YAAY,mBAM/C,CCzIA,IAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA,OAaA,EAAA,EAAA,CAAA,CAAA,OAMA,EAAA,EAAA,CAAA,CAAA,OAKA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OAyBA,IAAM,EAAiC,CAAC,SAAU,QAAS,SAAS,CAa7D,SAAS,EAAa,QAAE,CAAM,QAAE,CAAM,CAAqB,EAChE,GAAM,CAAE,KAAM,CAAY,CAAE,QAAS,CAAe,CAAE,CAAG,CAAA,EAAA,EAAA,WAAA,AAAW,IAC9D,EAAc,CAAA,EAAA,EAAA,cAAA,AAAc,IAE5B,CAAC,EAAa,EAAe,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAmBQ,UAC3D,CAAC,EAAS,EAAW,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAkBF,QAClD,CAAC,EAAW,EAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAsB,EAAA,eAAe,EACzE,CAAC,EAAc,EAAgB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAC3C,CAAC,EAAQ,EAAU,CAAGd,CAAAA,EAAAA,EAAAA,QAAAA,AAAQ,GAAC,GAC/B,CAAC,EAAW,EAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MAMpD,CAAC,EAAe,EAAiB,CAAG,CAAA,EAAA,EAAA,QAAQ,AAAR,EAAwB,MAC5D,CAAC,EAAc,EAAgB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAE9C,CACA,OAAQ,CAAE,OAAQ,MAAO,EACzB,MAAO,CAAE,OAAQ,MAAO,EACxB,OAAQ,CAAE,OAAQ,MAAO,CAC3B,GAEM,EAAW,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,AAAC,IAC5B,EAAe,EACjB,EAAG,EAAE,EAEC,EAAgB,CAAA,EAAA,EAAA,WAAA,AAAW,EAC/B,MAAO,IACL,EAAgB,AAAC,GAAU,EACzB,EADwB,CACrB,CAAI,CACP,CAAC,EAAU,CAAE,CAAE,OAAQ,UAAW,EACpCK,CAAC,EACD,GAAI,CACF,IAAM,EAAM,MAAM,EAAA,GAAG,CAAC,IAAI,CASvB,CAAC,UAAU,EAAE,EAAU,eAAe,CAAC,EAE1C,GADA,MAAM,IACF,EAAI,EAAE,CACR,CADU,CACM,AAAC,IAAU,CACzB,EADwB,CACrB,CAAI,CACP,CAAC,EAAU,CAAE,CAAE,OAAQ,KAAM,QAAS,EAAI,OAAO,AAAC,EACpD,CAAC,MACI,CACL,IAAM,EAAS,AAAC,EAAI,YAAY,CAE5B,EAAI,QAAQ,CACV,CAAA,EAAG,EAAI,UAAU,CAAC,oBAAoB,CAAC,CACtC,EAAI,MAAM,CAAC,IAAI,IAAM,EAAI,MAAM,CAAC,IAAI,IAAM,oBAH7C,CAAA,EAAG,EAAI,UAAU,CAAC,kBAAkB,CAAC,CAIzC,EAAgB,AAAC,IAAU,CACzB,EADwB,CACrB,CAAI,CACP,CAAC,EAAU,CAAE,CAAE,OAAQ,QAAS,MAAO,CAAO,EAChD,CAAC,CACH,CACF,CAAE,MAAO,EAAK,CACZ,EAAgB,AAAC,IAAU,CACzB,EADwB,CACrB,CAAI,CACP,CAAC,EAAU,CAAE,CACX,OAAQ,QACR,MAAO,aAAe,MAAQ,EAAI,OAAO,CAAG,uBAC9C,EACF,CAAC,CACH,CACF,EACA,CAAC,EAAgB,EAGb,EAAc,CAAA,EAAA,EAAA,kBAAA,AAAkB,EAAC,aAAE,CAAY,GAErD,eAAe,IACb,GAAK,CAAD,EAKJ,GAAsB,OALJ,AAKd,EAAwB,CAC1B,EAAiB,MACjB,IACA,MACF,CACA,GAAU,GACV,EAAa,MACb,GAAI,CAKF,IAAM,EAAM,MAAM,EAAA,GAAG,CAAC,GAAG,CAGtB,iBAAkB,CAAE,UAAW,CAAY,EAY9C,OAAM,EAAY,iBAAiB,CAAC,CAAE,SAAU,CAAC,WAAW,AAAC,GAC7D,MAAM,EAAY,iBAAiB,CAAC,CAAE,SAAU,CAAC,eAAgB,AAAD,GAChE,MAAM,EAAY,iBAAiB,CAAC,CAAE,SAAU,CAAC,SAAS,AAAC,GAC3D,MAAM,EAAY,iBAAiB,CAAC,CAClC,SAAU,CAAC,gBAAiB,iBAAiB,AAC/C,GAEA,IAAM,EAAc,CAAA,EAAA,EAAA,qBAAA,AAAqB,EAAC,EAAS,GAC/C,IACF,MAAM,EAAA,CADS,EACN,CAAC,IAAI,CAAC,cAAe,GAC9B,MAAM,EAAY,iBAAiB,CAAC,CAAE,SAAU,CAAC,SAAU,AAAD,IAQ5D,IAAM,EAAU,GAAK,eAAiB,EAAE,CACxC,GAAI,EAAQ,MAAM,CAAG,EAAG,CACtB,IAAM,EAAO,EAAQ,GAAG,CAAC,AAAC,GAAM,EAAE,GAAG,EAAE,IAAI,CAAC,MAC5C,EACE,CAAA,EAAG,EAAQ,MAAM,CAAC,mBAAmB,EAAqB,IAAnB,EAAQ,MAAM,CAAS,GAAK,IAAI,EAAE,EAAE,EAAK,iIAAE,CAAC,EAIrF,CAHE,CAAC,CAGO,GACV,MACF,CACF,CAAE,MAAO,EAAK,CACZ,EACE,aAAe,EAAA,QAAQ,EAEnB,CADA,IAAI,GATmD,CAAC,GAC1D,AAQa,CACI,AAThB,MAUG,EAAI,OAAO,CACX,mCAER,GAAU,GACV,MACF,CACA,IACF,CAEA,EAnBgF,CAAC,GAoB/E,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,CACC,MAAM,aACN,YAAY,gKACZ,OAAQ,EACR,OAAO,CAAA,CAAA,EACP,SAAS,sBAET,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,uBAAuB,CAAA,CAAA,GAExB,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sBACZ,EAAS,GAAG,CAAC,AAAC,IACb,IAAM,EAAM,GAAc,SAAS,KAAK,AAAC,GAAM,EAAE,EAAE,GAAK,GACxD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAoB,UAAU,sBAC7B,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CACV,UAAW,EACX,KAAK,SACL,OAAQ,IAAgB,EACxB,WAAY,GAAK,YAAc,UAC/B,iBAAkB,GAAK,YAAc,KACrC,mBAAoB,GAAK,oBAAsB,KAC/C,kBAAmB,GAAK,mBAAqB,KAC7C,sBAAuB,GAAK,uBAAyB,EACrD,aAAc,GAAK,eAAgB,EACnC,QAAS,GAAK,UAAW,EACzB,iBAAkB,GAAK,mBAAoB,EAC3C,mBAAoB,GAAK,qBAAsB,EAC/C,eAAgB,KAChB,aAAc,CAAY,CAAC,EAAU,CACrC,eAAgB,KACT,GACP,EACA,gBAAiB,KACV,EAAc,EACrB,IAEF,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,kBAAkB,CAAA,CAAC,UAAW,MAvBvB,EA0Bd,GAGA,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,4DACb,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,iDAAwC,iBAGtD,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,8CAAqC,iEAGlD,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,qCACZ,EAAS,GAAG,CAAC,AAAC,IACb,IAAM,EAAW,IAAgB,EACjC,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,QAAA,CAEC,UAAW,CAAC,kGAAkG,EAC5G,EACI,+BACA,2CAAA,CACJ,WAEF,CAAA,EAAA,EAAA,GAAA,EAAC,QAAA,CACC,KAAK,QACL,KAAK,eACL,UAAU,OACV,QAAS,EACT,SAAU,IAAM,EAAS,KAE3B,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,uBACb,EAAA,sBAAsB,CAAC,EAAU,KAf/B,EAmBX,WAKN,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,QAAS,EACT,UAAW,EACX,aAAc,EACd,gBAAiB,EACjB,kBAAmB,EACnB,qBAAsB,IAGvB,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,gDAAwC,IAEtD,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CACC,UAAU,0JACV,KAAK,kBAEJ,IAIL,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yDACZ,EACC,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,MAAM,CAAA,CAAC,QAAQ,QAAQ,QAAS,EAAQ,UAAU,kBACjD,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,SAAS,CAAA,CAAC,UAAU,YAAY,UAInC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAA,GAEH,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CACL,QAAS,IAAM,KAAK,IACpB,SAAU,CAAC,GAAe,WAEzB,EACC,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,OAAO,CAAA,CAAC,UAAU,8BAA8B,wBAGjD,EACF,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WAAE,0BAC2B,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,UAAU,CAAA,CAAC,UAAU,oBAGnD,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WAAE,QACK,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,UAAU,CAAA,CAAC,UAAU,2BAOzC,CAaA,SAAS,EAAqB,SAC5B,CAAO,WACP,CAAS,cACT,CAAY,iBACZ,CAAe,CACf,mBAAiB,sBACjB,CAAoB,CACM,EAC1B,IAAM,EAAY,CAAA,EAAA,EAAA,oBAAA,AAAoB,EAAC,EAAS,GAChD,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sEACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,WACC,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,iDAAwC,0BAGtD,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,8CAAqC,+LAOpD,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sCACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,KAAM,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CAAC,UAAU,YAC7B,MAAM,OACN,MAAM,cACN,SAAsB,SAAZ,EACV,SAAU,IAAM,EAAgB,iBACjC,mFAID,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,KAAM,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CAAC,UAAU,YACxB,MAAM,QACN,SAAsB,UAAZ,EACV,SAAU,IAAM,EAAgB,kBACjC,qFAMH,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,WAAW,CAAA,CAAC,KAAM,EAAc,aAAc,YAC7C,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,kBAAkB,CAAA,CAAC,OAAO,CAAA,CAAA,WACzB,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,UAAU,uKAEV,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,oCACd,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CACV,UAAW,CAAA,EAAA,EAAA,EAAE,AAAF,EACT,mCACA,GAAgB,gBAElB,wBAED,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,4GAAmG,aAKvH,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,uBACb,EAAe,OAAS,cAI/B,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,kBAAkB,CAAA,CAAC,UAAU,4EAC1B,CAAC,SAAU,QAAS,SAAS,CAAW,GAAG,CAAC,AAAC,GAC7C,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAEC,QAAS,EACT,QAAS,EACT,SAAU,CAAS,CAAC,EAAQ,CAC5B,SAAU,AAAC,GACT,EAAmB,AAAD,GAAW,EAAE,EAAH,CAAM,CAAI,CAAE,CAAC,EAAQ,CAAE,EAAK,CAAC,GALtD,WAanB,CAWA,SAAS,EAAS,MAChB,CAAI,OACJ,CAAK,CACL,OAAK,UACL,CAAQ,UACR,CAAQ,UACR,CAAQ,CACM,EACd,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,EACT,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,iEACA,EACI,yCACA,oEAGN,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,0EACZ,EACA,EACA,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,oFACb,OAIP,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,8CAAsC,MAGzD,CASA,SAAS,EAAmB,SAC1B,CAAO,SACP,CAAO,UACP,CAAQ,UACR,CAAQ,CACgB,EACxB,IAAM,EAAY,GAAY,EAE9B,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,yDACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oDACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oBACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,wCACZ,EAAA,uBAAuB,CAAC,EAAQ,CACjC,CAAA,EAAA,EAAA,IAAA,EAAC,OAAA,CAAK,UAAU,+CAAqC,IACjD,EAAA,sBAAsB,CAAC,EAAQ,CAAC,UAGtC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8CAAoC,YACvC,QAGd,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,4CACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,OAAqB,OAAb,EACR,MAAM,SACN,QAAS,IAAM,EAAS,QAE1B,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,OAAqB,SAAb,EACR,MAAM,OACN,QAAS,IAAM,EAAS,UAE1B,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,OAAQ,AAAa,YACrB,MAAM,QACN,QAAS,IAAM,EAAS,iBA7BQ,AAiCrC,UAjCyB,GAAqC,UAAd,GAkC/C,CAAA,EAAA,EAAA,IAAA,EAAC,IAAA,CAAE,UAAU,yFACX,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,aAAa,CAAA,CAAC,UAAU,4BACzB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UAAK,gIAQhB,CAEA,SAAS,EAAa,QACpB,CAAM,OACN,CAAK,SACL,CAAO,CAKR,EACC,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,SAAA,CACC,KAAK,SACL,QAAS,EACT,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,gDACA,EACI,+CACA,2EAGL,GAGP,CChkBA,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,MACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,MAgCO,SAAS,EAAS,QAAE,CAAM,CAAE,QAAM,CAAiB,EACxD,IAAM,EAAgB,CAAA,EAAA,EAAA,eAAA,AAAe,IAC/B,EAAiB,CAAA,EAAA,EAAA,gBAAA,AAAgB,IACjC,EAAS,CAAA,EAAA,EAAA,SAAA,AAAS,IAElB,EAAW,EAAc,IAAI,EAAE,UAAY,EAAE,CAC7C,EAAe,EAAe,IAAI,EAAE,cAAgB,EAAE,CACtD,EAAU,AA2ClB,SAAS,AACP,CAAuB,EAEvB,IAAM,EAA+C,CACnD,MAAO,EAAE,CACT,QAAS,EAAE,CACX,MAAO,EAAE,CACT,OAAQ,EAAE,AACZ,EACA,IAAK,IAAM,KAAK,EAAU,CAAG,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,GAC3C,OAAO,CACT,EAtD8B,GAKtB,EAAY,EAAO,IAAI,EAAE,kBAAkB,OAAO,MAAQ,WAGhE,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,CACC,MAAM,OACN,YAAY,iIACZ,OAAQ,EACR,OAAQ,EACR,UAAU,OACV,SAAS,sBAET,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,eAAe,CAAA,CACdW,eAAe,QACf,kBAAmB,EAAQhB,KAAK,CAAC,MAAM,GAEzC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,SAAS,CAAA,CACR,SAAU,EAAQ,KAAK,CACvB,aAAc,EACd,sBAAsB,CAAA,CAAA,IAEvB,AApBgC,WAAd,GAoBA,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,UAAU,CAAA,CAAA,GAC9B,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,eAAe,CAAA,CAAC,eAAe,iBAChC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,WAAW,CAAA,CAAC,SAAU,EAAQ,OAAO,CAAE,aAAc,IACtD,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,QAAQ,CAAA,CACP,KAAK,QACL,SAAU,EAAQ,KAAK,CACvB,aAAc,IAEhB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,QAAQ,CAAA,CACP,KAAK,SACL,SAAU,EAAQ,MAAM,CACxB,aAAc,MAItB,CC3DO,SAAS,EAAa,QAAE,CAAM,QAAE,CAAMG,CAAqB,EAChE,IAAM,EAAS,CAAA,EAAA,EAAA,SAAA,AAAS,IAClB,EACJ,EAAO,IAAI,EAAE,kBAAkB,iBAAiB,MAAQ,WAG1D,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,MAAM,WACN,YAAY,0EACZ,OAAQ,EACR,OAAQ,EACR,UAAU,OACV,UAAU,oBAEVG,CAAAA,EAAAA,EAAAA,IAAAA,EAAC,MAAA,CAAIE,UAAU,+CACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,eAAe,CAAA,CAAC,eAAe,oBAC/B,AAbiC,WAAjB,GAaE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,UAAU,CAAA,CAAA,GAC9B,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,eAAe,CAAA,CAAC,eAAe,qBAChC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,qDAA4C,kNAQjE,CCrBO,SAAS,EAAS,QAAE,CAAM,QAAE,CAAM,CAAiBL,MOcxD,EA8C0B,EP3D1B,COaqCK,EAiDtC,CA/CO,EPfA,CAAE,KAAM,CAAM,CAAE,CAAG,CAAA,EAAA,EAAA,SAAA,AAAS,IAC5B,EAAc,CAAA,EAAA,EAAA,cAAA,AAAc,IAC5B,CAAC,EAAM,EAAQ,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EOZL,APazB,IAEI,CAAC,EAAO,EAAS,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAFP,AAGzB,AOfqB,IPiBjBD,CAAC,EAAQ,EAAU,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EALgB,AAGzB,CAEU,GAC/B,CAAC,EAAO,EAAS,CAAG,CAAA,EAAA,EAAA,MAHsB,EAGtB,AAAQ,EAAgB,MAC5C,EAAc,CAAA,EAAA,EAAA,MAAA,AAAM,GAAC,GAM3B,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,MACJ,EAAY,OAAOG,EAAK,EAAD,EAC3B,EAAY,EADwB,KACjB,EAAG,EAEwB,UAA5C,OAAO,EAAO,yBAAyB,EACpC,EAAO,yBAAyB,CAAC,MAAM,CAAG,GAC7C,AACA,EAAQ,EAAO,yBAAyB,EAEtC,AAAwC,WAAW,OAA5C,EAAO,qBAAqB,EACrC,EAAS,EAAO,qBAAqB,EAEzC,EAAG,CAAC,EAAO,EAEX,IAAM,EAAyD,IAAvB,EAAK,IAAI,GAAG,MAAM,CACtD,KOfA,AAAmB,EPgBnB,COhBsB,IADV,GPiBoB,MAC9B,EACA,QAASM,GAAQ,YAAc,GAC/B,iBAAkB,GAAQ,kBAAoB,IAChD,GOrBkB,IAAI,CAAC,IAAI,IACnB,MAAM,CAAe,QAC5B,CAAA,EAAA,EAAA,oBAAA,AAAoB,EAAC,GASxB,EAAM,KAT4B,EASrB,CAAC,MAAM,CAAG,GACpB,CAAA,EAAA,EAAA,yBAAA,AAAyB,EAAC,EAAM,OAAO,CAAE,GAErC,OADP,aAIA,EAAM,gBAAgB,EACnB,CAAA,EAAA,EAAA,yBAAA,AAAyB,EAAC,EAAM,gBAAgB,CAAE,GAE9C,OADP,kBAGK,KAnBE,ePoBH,EOyBN,CAAI,GPzBsB,EAAZ,SAAc,EAAW,QAAO,GOyBpC,MAAM,EAAE,CACM,MADC,AACK,CAA1B,EAAM,IAA2B,KAAlB,EAEZ,AAAoB,YAAd,SAAS,EP1BhB,EAAa,UACjB,GAAK,CAAD,EACJ,GAAU,CADE,EAEZ,EAAS,MACT,GAAI,KOoCN,MAAsB,CPnClB,OAAM,EAAA,GAAG,CAAC,KAAK,CACb,WOoCA,APnCA,EOmCU,GPnCS,CACjB,0BAA2B,EAC3B,sBAAuB,CACzB,GOgCiB,yBAAyB,CAAC,IAAI,GAC9C,CACL,0BAA8C,IAAnB,EAAQ,MAAM,CAAS,KAAO,EACzD,sBAAuB,EAAO,qBAAqB,AACrD,IPlCI,MAAM,EAAY,iBAAiB,CAAC,CAAE,SAAU,CAAC,SAAS,AAAC,GAC3D,GACF,CAAE,MAAO,EAAK,CACZ,GAAI,aAAe,EAAA,QAAQ,CAAE,CAC3B,IAAM,EAAO,EAAI,IAAI,CACrB,EAAS,GAAM,SAAW,EAAI,OAAO,EAAI,+BAC3C,MACE,CADK,CACI,aAAe,MAAQ,EAAI,OAAO,CAAG,+BAElDF,QAAU,CACR,GAAU,EACZ,EACF,EAEA,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,CACC,MAAM,OACN,YAAY,kEACZ,OAAQ,EACR,OAAO,CAAA,CAAA,YAEP,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,+CAEb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,eAAe,CAAA,CAAC,eAAe,WAEhC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,4EACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,WACC,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,iDAAwC,mCAGtD,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCAAgC,mKAO/C,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,oBAAoB,CAAA,CACnB,GAAG,+BACH,MAAO,EACP,SAAU,EACV,MAAM,sCACN,YAAY,iCACZ,SAAU,IAEX,GAAa,AAAc,aAC1B,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,oCACV,AO1DR,SAA8B,AAArB,CAAyC,EACvD,OAAQ,GACN,IAAK,QACH,MAAO,+CACT,KAAK,eACH,MAAO,kFACT,KAAK,oBACH,MAAO,uEACT,KAAK,yBACH,MAAO,sEACX,CACF,EP+CoC,KAI1B,CAAA,EAAA,EAAA,IAAA,EAAC,QAAA,CAAM,UAAU,kEACf,CAAA,EAAA,EAAA,GAAA,EAAC,QAAA,CACC,KAAK,WACL,QAAS,EACT,SAAU,AAAC,GAAM,EAAS,EAAE,aAAa,CAAC,OAAO,EACjD,UAAU,kEACV,+CAGJ,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,6CAAoC,0KAOlD,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,8DACV,OAKP,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,2CACZ,GACC,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,MAAM,CAAA,CAAC,QAAQ,QAAQ,QAAS,EAAQ,UAAU,kBACjD,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,SAAS,CAAA,CAAC,UAAU,YAAY,UAIrC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CAAC,QAAQ,QAAQ,QAAS,WAAQ,SAGzC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CACL,KAAK,KACL,QAAS,EACT,SAAU,CAAC,EACX,UAAU,iBAET,EACC,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,OAAO,CAAA,CAAC,UAAU,yBAAyB,aAI9C,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,aAAa,CAAA,CAAC,UAAU,YAAY,qBAQnD,CC/LA,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,MACA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,OAQO,SAAS,GAAc,QAAE,CAAM,QAAE,CAAM,CAAsB,EAClE,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,MAAM,qBACN,YAAY,8HACZ,OAAQ,EACR,OAAQ,EACR,UAAU,OACV,SAAS,qBAET,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sBACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,SAAS,CAAA,CAAA,GACV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CAAA,GACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,WAAW,CAAA,CAAA,GACZ,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CAAA,GACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,mBAAmB,CAAA,CAAA,OAI5B,CCzBA,IAAA,GAAA,EAAA,CAAA,CAAA,KAGA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,MAEA,GAAA,EAAA,CAAA,CAAA,OACA,GAAA,EAAA,CAAA,CAAA,MAAA,GAAA,EAAA,CAAA,CAAA,OAEA,GAAA,EAAA,CAAA,CAAA,MIsEO,SAAS,GAAiB,CAA2B,EAS5D,CAEO,SAAS,KAOhB,CJZO,SAAS,GAAiB,MAC/BO,CAAI,kBACJ,CAAgB,YAChB,CAAU,QACV,CAAM,kBACNC,CAAgB,kBAChB,CAAgB,CACM,EACtB,GAAM,CAAE,KAAM,CAAM,CAAE,CAAG,CAAA,EAAA,EAAA,SAAS,AAAT,IASnB,UACJ,CAAQ,kBACR,CAAgB,qBAChB,CAAmB,WACnB,CAAS,cACT,CAAY,aACZ,CAAW,aACX,CAAW,CACZ,CAAG,CAAA,EAAA,GAAA,OAAA,AAAO,EAAC,CAAE,gBAAgB,CAAK,GAC7B,EAAkB,CAAA,EAAA,EAAA,OAAA,AAAO,EAC7B,IAAM,IAAI,KAAqB,EAAS,CACxC,CAAC,EAAkB,EAAS,EAExB,EAAc,CAAA,EAAA,EAAA,cAAA,AAAc,IAC5B,EAAY,CAAA,EAAA,EAAA,MAAA,AAAM,EAAiB,MACnC,EAAa,CAAA,EAAA,EAAA,MAAA,AAAM,EAAC,IAMpB,EAAuB,CAAA,EAAA,EAAA,MAAA,AAAM,GAAC,GAE9B,CAAC,EAAc,EAAgB,CAAG,CAAA,EAAA,EAAA,QAAQ,AAAR,EAAwB,MAC1D,CAAC,EAAS,EAAW,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACjC,CAAC,EAAY,EAAc,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,IACvC,CAAC,EAAQ,EAAU,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,IAC/B,CAAC,EAAiB,EAAmB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GACjD,CAAC,EAAY,EAAc,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MACtD,CAAC,EAAW,EAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAgB,MACpD,CAAC,EAAc,EAAgB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,GAS3C,CAAC,EAAgB,EAAkB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EACzC,WAAT,GAEI,CAAC,EAAW,EAAa,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAU,IAC9C,CAAC,EAAgB,EAAkB,CAAG,CAAA,EAAA,EAAA,QAAQ,AAAR,EAE1C,MACI,CAAC,EAAkB,EAAoB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,GAOnD,CAAC,EAAgB,EAAkB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAS,IACvD,CAAC,EAAsB,GAAwB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,GAAC,GAC3D,CAAC,GAAqB,GAAuB,CAAG,CAAA,EAAA,EAAA,QAAQ,AAAR,GAAS,GACzD,GACK,YAAT,EACI,CAAA,EAAA,EAAA,yBAAA,AAAyB,EAAC,GAC1B,GAAQ,kBAAoB,EAAA,0BAA0B,CAG5D,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,GAA+B,IAA3B,EAAgB,MAAM,CAAQ,OAClC,IAAM,EAAU,CAAe,CAAC,EAAgB,MAAM,CAAG,EAAE,EACtC,cAAjB,EAAQ,IAAI,EAAqC,AAAjB,YAAQ,IAAS,AAAL,GAAc,AAC5D,EAAmB,GAEvB,EAAG,CAAC,EAAgB,EAGpB,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,GAAI,CAAC,EAAiB,OACtB,IAAM,EAAQ,WAAW,IAAM,GAAmB,GAAQ,MAC1D,MAAO,IAAM,aAAa,EAC5B,EAAG,CAAC,EAAgB,EAEpB,IAAM,GAAe,GAAmB,EAGxC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,IAAM,EAAK,EAAU,OAAO,CACxB,IAAI,EAAG,SAAS,CAAG,EAAG,YAAA,AAAY,CACxC,EAAG,CAAC,EAAgB,MAAM,CAAE,EAAa,EAmBzC,CAAA,EAAA,EAAA,SAAS,AAAT,EAAU,WACR,GAAa,YAAT,GACA,GACA,EAAqB,OAAO,EAAE,AAK9B,EANgB,CAOhB,CAAC,EARmB,MAQX,CAEb,GAHoB,CAGd,EAAW,AP1Ed,SAAS,AACd,CAAkC,EAElC,GAA0B,SAAS,CAA/B,EAAM,WAAW,OACnB,AAA0B,YAAY,CAAlC,EAAM,WAAW,CACZ,CAAE,KAAM,UAAW,KAAM,QAAS,KAAM,EAAG,EAE7C,CAAE,KAAM,qBAAsB,EAEvC,IAAM,EAAqB,EAAM,WAAW,CAAC,IAAI,UACf,AAAlC,GAAqC,CAAjC,EAAmB,MAAM,CACpB,CAAE,KAAM,qBAAsB,EAEb,YAAY,CAAlC,EAAM,WAAW,EAGjB,EAAM,WAAW,GAAK,EAFjB,CAAE,KAAM,UAAW,EAEkB,GAFZ,WAAY,KAAM,CAAmB,EAKhE,CAAE,KAAM,qBAAsB,CACvC,EOsD0C,CACpC,YAAa,GAAoB,QACjC,YAAa,GAAoB,GACjC,YAAkC,aAArB,EAAO,SAAS,CAAkB,WAAa,QAC5D,YAAa,EAAO,gBAAgB,EAAI,IAC1C,EAEA,CAAsB,uBAAuB,CAAzC,EAAS,IAAI,CACf,GAAkB,IAMpB,EAAqB,OAAO,CAAG,GAC/B,GAAa,GACb,EAAkB,MAClB,EAAA,GAAG,CACA,IAAI,CACH,yBPzIN,AAAwB,CO0IlB,QP1I2B,CAA7B,CAJkC,EO8IR,CACtB,EP5IT,QO4IoB,EAAS,IAAI,CACxB,iBAAkB,EAAS,IAC7B,AADiC,GP5I7BD,SAAS,CACV,CAAE,gBAAiB,QAAS,eAAgB,OAAQ,EAEtD,CACL,gBAAiB,WACjB,gBAAiB,EAAM,gBAAgB,CAAC,IAAI,GAC5C,eAAgB,OAClB,GOwIK,IAAI,CAAC,UACJ,MAAM,EAAY,iBAAiB,CAAC,CAAE,SAAU,CAAC,SAAS,AAAC,GAC3D,MAAM,EAAY,iBAAiB,CAAC,CAAE,SAAU,CAAC,SAAS,AAAC,GAC3D,GAAkB,EACpB,GACC,KAAK,CAAC,AAAC,IACF,aAAe,EAAA,QAAQ,CACzB,CAD2B,CACR,EAAI,IAAI,EAAI,CAAC,GAEhC,EAAkB,CAChB,MAAO,iBACP,QACE,aAAe,MAAQ,EAAI,OAAO,CAAG,mBACzC,EAEJ,GACC,OAAO,CAAC,KACP,EAAqB,OAAO,EAAG,EAC/B,GAAa,EACf,GACJ,EAAG,CACD,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACD,EAYD,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,GAAI,EAAW,OAAO,EAAI,CAAC,GAAa,WAIpC,CAAC,EAJ8C,OAUnD,IAAM,GANe,EAQf,EADc,AAElB,EAF+B,MADZ,UAC4B,GAAK,GAGV,UAAvC,OAAO,EAAa,cAAc,EAClC,EAAa,cAAc,CAAG,GAC9B,EAAY,SAAS,GAAK,EAAa,cAAc,CACpD,EAAa,cAAc,CAC3B,KAEN,GAAyB,OAArB,EAA2B,CAC7B,EAAW,OAAO,EAAG,EACrB,CAAA,EAAA,GAAA,oBAAoB,AAApB,EAAqB,GAClB,IAAI,CAAC,AAAC,IACL,EAAoB,EACtB,GACC,KAAK,CAAC,AAAC,IAGN,QAAQ,IAAI,CAAC,oDAAqD,EACpE,GACF,MACF,CAEA,EAAW,OAAO,CAAG,GACrB,EAAc,MACd,GAAmB,GAMnB,EAAA,GAAG,CACA,IAAI,CAAC,eAAgB,CACpB,UAAW,EAAY,SAAS,MAChC,EACA,GAAa,YAAT,EACA,CAAE,iBAAkB,EAA0B,EAC9C,CAAC,CAAC,AACR,GACC,KAAK,CAAC,AAAC,IACN,EAAW,OAAO,EAAG,EAErB,EADY,YACE,CADa,MAAQ,EAAI,OAAO,CAAG,yBAEjD,GAAmB,EACrB,EACJ,EAAG,CACD,GAAa,UACb,GAAa,UACb,EACA,GACA,EACA,EACA,EACD,EAOD,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KAC8B,UAAU,AAA5C,OAAO,GAAa,WACxB,GAAiB,CACf,eAAgB,EAAY,SAAS,CACrC,iBAAkB,CACpB,EACF,EAAG,CAAC,EAAM,GAAa,UAAU,EAOjC,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACR,IAAI,EACJ,IAAK,IAAI,CADM,CACF,EAAgB,MAAM,CAAG,EAAG,GAAK,EAAG,IAAK,CACpD,IAAM,EAAM,CAAe,CAAC,EAAE,CAC9B,GAAI,AAAa,gBAAT,IAAI,CAAkB,SAC9B,IAAM,EA5TZ,AA4ToB,SA5TX,AAAkB,CAAe,EACxC,IAAMT,EAAQK,EAAQ,KAAK,CAAC,sCAC5B,OAAO,EAAQ,CAAK,CAAC,EAAE,CAAC,IAAI,GAAK,IACnC,EAyTsC,EAAI,OAAO,EACvC,IACF,EAAgB,CADP,EAEL,AAAC,GAAS,EAAc,IAE9B,IAAM,EAAY,AA5TxB,SAAS,AAAsB,CAAe,EAC5C,IAAM,EAAQ,EAAQ,KAAK,CAAC,+BAC5B,OAAO,EAAQ,CAAK,CAAC,EAAE,CAAC,IAAI,GAAK,IACnC,EAyT8C,EAAI,OAAO,EAKnD,GAJkB,OAAd,CAAsB,EAAC,KACzB,EAAkB,GAClB,IAAwB,IAEtB,GAAS,AAAc,AAJqB,SAIf,KACnC,CACF,EAAG,CAAC,EAAiB,EAAW,EAAS,GAAoB,EAO7D,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACH,IAAgB,IACrB,EAAkB,GAAQ,WAAa,EADI,EAE3C,IAAwB,GAC1B,EAAG,CAAC,EAAc,EAAsB,GAAQ,UAAU,EAE1D,IAAM,GAAa,CAAA,EAAA,EAAA,WAAA,AAAW,EAAC,UAC7B,IAAM,EAAU,EAAU,EAAa,EACvC,GAAI,CAAC,EAAS,OACd,IAAM,EAAmB,EAAe,IAAI,GAC5C,GAAI,CAAA,EAAA,GAAA,kBAAA,AAAkB,EAAC,GAAmB,YACxC,EAAa,6CAGf,GAAU,GACV,EAAa,MACb,GAAI,CAKF,IAAM,EAAmB,GAAQ,WAAa,GAC1C,GAAwB,IAAqB,GAC/C,MAAM,EAAA,GAAG,CAAC,GADuD,EAClD,CAAC,UAAW,CAAE,UAAW,CAAiB,GAE3D,MAAM,EAAA,GAAG,CAAC,IAAI,CAAC,oBAAqB,SAClC,EACA,GAAI,AAAS,cACT,CAAE,iBAAkB,EAA0B,EAC9C,CAAC,CAAC,CACN,GAAsC,UAAlC,OAAO,GAAa,UACpB,CAAE,UAAW,EAAY,SAAS,AAAC,EACnC,CAAC,CAAC,AACR,GAIA,EAAY,YAAY,CAAC,CAAC,eAAe,CAAE,CACzC,YAAY,EACZ,YAAa,IAAI,OAAO,WAAW,EACrC,GACA,EAAY,iBAAiB,CAAC,CAAE,SAAU,CAAC,SAAS,AAAC,GACrD,EAAY,iBAAiB,CAAC,CAAE,SAAU,CAAC,SAAS,AAAC,GAIrD,KACA,GACF,CAAE,MAAO,EAAK,CACZ,EAAa,aAAe,MAAQ,EAAI,OAAO,CAAG,uBACpD,QAAU,CACR,GAAU,EACZ,CACF,EAAG,CACD,EACA,EACA,EACA,EACA,EACA,GAAQ,UACR,EACA,EACA,EACA,GACA,GAAa,UACd,EAEK,GAAoB,CAAA,EAAA,EAAA,WAAA,AAAW,EACnC,AAAC,IACC,EAAY,GACZ,GAAmB,EACrB,EACA,CAAC,EAAY,EAGT,GAAoB,CAAA,EAAA,EAAA,WAAA,AAAW,EACnC,AAAC,IACC,EAAY,GACZ,EAAmB,GACrB,EACA,CAAC,EAAY,EAGT,GAAmB,IAAI,EAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,AAAC,GAAiB,cAAX,EAAE,IAAI,EACpE,GAAU,IAAoB,CAAC,GAhZvC,AAgZsD,SAhZ7C,AAAe,CAAe,EACrC,IAAM,EAAoB,EAAE,CAC5B,IAAK,IAAM,KAAQ,EAAQ,KAAK,CAAC,MAAO,CACtC,IAAM,EAAQ,EAAK,KAAK,CAAC,oBACrB,GAAO,EAAQ,IAAI,CAAC,CAAK,CAAC,EAAE,CAClC,CACA,OAAO,EAAQ,MAAM,EAAI,GAAK,EAAQ,MAAM,EAAI,EAAI,EAAU,EAAE,AAClE,EAyYqE,GAAiB,OAAO,EAAI,EAAE,CAUjG,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,0DACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,4CACb,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,iCACF,YAAT,EAAqB,uBAAyB,4BAEjD,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCACD,YAAT,EACG,iFACA,2EAIP,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,UAAU,kDACf,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,oCACb,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,OAAO,CAAA,CAAC,UAAU,yBACnB,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UAAK,gCAKX,GAAkB,CAAC,GAClB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,QAAQ,QAAQ,UAAU,kDAC/B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,0DACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,WACC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,uBAAc,gCAC3B,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,kBAAU,EAAe,OAAO,MAE/C,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,gCACZ,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CAAC,KAAK,KAAK,QAAQ,QAAQ,QAAS,WAAQ,SAIrD,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CACL,KAAK,KACL,QAAQ,UACR,QAAS,KACP,EAAkB,MAClB,EAAoB,AAAC,GAAS,EAAO,EACvC,WACD,kBAQR,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,QAAQ,QAAQ,UAAU,kDAC/B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,2DACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,UAAM,IACP,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CACL,KAAK,KACL,QAAQ,UACR,QAAS,IAAM,EAAgB,AAAC,GAAS,EAAO,YACjD,eAOP,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,UAAU,CAAA,CAAC,IAAK,EAAW,UAAU,4BACpC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,sBACZ,EAAgB,GAAG,CAAC,AAAC,GACpB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,aAAa,CAAA,CAEZ,QACe,cAAb,EAAI,IAAI,CACJ,CAAE,GAAG,CAAG,CAAE,QAxerB,AAwe0D,CAA5B,CAAgC,OAAO,CAvezE,OAAO,CAAC,oCAAqC,8CAC7C,OAAO,CAAC,6BAA8B,uCACtC,IAAI,EAqeuE,EAC5D,EAEN,eAAgB,IANX,EAAI,EAAE,GASf,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CAAC,MAAO,IACpB,IACC,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,8BACb,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CAAK,UAAU,oEAGQ,IAA3B,EAAgB,MAAM,EAClB,CAAC,IACD,CAAC,GACD,CAAC,GACD,CAAC,GACJ,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,iFACb,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,mBAAU,8BAM9B,GAAQ,MAAM,CAAG,GAAK,CAAC,GACtB,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,6EACZ,GAAQ,GAAG,CAAC,AAAC,GACZ,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CAEL,KAAK,KACL,QAAQ,UACR,QAAS,IAAM,GAAkB,GACjC,SAAU,GACV,UAAU,mBAET,GAPI,MAaZ,GACC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,mEACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8CACb,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,+BAAsB,6BACpC,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,uBACb,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,MAAM,CAAA,CACL,KAAK,KACL,QAAQ,QACR,QAAS,KACH,GAAS,EAAc,GAC3B,EAAW,CAAC,EACd,EACA,UAAU,0BAEV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,MAAM,CAAA,CAAC,UAAU,YACjB,EAAU,SAAW,UAExB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,MAAM,CAAA,CACL,KAAK,KACL,QAAS,GACT,SAAU,GAAU,CAAA,EAAA,GAAA,kBAAA,AAAkB,EAAC,GACvC,UAAU,iBAET,EACC,YAEA,CAAA,EAAA,EAAA,IAAA,EAAA,EAAA,QAAA,CAAA,WACE,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,IAAI,CAAA,CAAC,UAAU,gBAAgB,2BAQzC,GAAa,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,KAAK,CAAA,CAAC,QAAQ,iBAAS,IAErC,EACC,CAAA,EAAA,EAAA,GAAA,EAAC,WAAA,CACC,MAAO,EACP,SAAU,AAAC,GAAM,EAAc,EAAE,MAAM,CAAC,KAAK,EAC7C,UAAU,4IACV,KAAM,KAGR,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,4GACZ,IAIL,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,qDACb,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,WACC,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,+BAAsB,cACpC,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,yCAAgC,oIAK/C,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,eAAe,CAAA,CACd,MAAO,EACP,SAAW,AAAD,IACR,EAAkB,GAClB,IAAuB,GACnB,AAAC,GAAsB,GAAwB,GACrD,EACA,SAAU,EACV,KAAM,UAMb,CAAC,GACA,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,SAAS,CAAA,CACR,OAAQ,GACR,SAAU,IAA2C,IAA3B,EAAgB,MAAM,KAK1D,CC5qBA,IAAA,GAAA,EAAA,CAAA,CAAA,OAAA,GAAA,EAAA,CAAA,CAAA,OAQO,SAAS,GAAc,MAAE,CAAI,kBAAE,CAAgB,CAAsB,EAC1E,IAAM,EAAS,CAAA,EAAA,EAAA,SAAA,AAAS,IAExB,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,8EACb,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,+DACb,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,YAAY,CAAA,CAAC,UAAU,uDAG1B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,+BACb,CAAA,EAAA,EAAA,GAAA,EAAC,KAAA,CAAG,UAAU,8CACF,YAAT,EAAqB,iBAAmB,kBAE3C,CAAA,EAAA,EAAA,GAAA,EAAC,IAAA,CAAE,UAAU,iCACV,AAAS,cACN,CAAA,EAAG,EAAiB,4CAA4C,CAAC,CACjE,4EAIR,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,uBACb,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,MAAM,CAAA,CACL,QAAQ,UACR,QAAS,IAAM,EAAO,IAAI,CAAC,WAC3B,UAAU,kBAEV,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,QAAQ,CAAA,CAAC,UAAU,YAAY,2BAGlC,CAAA,EAAA,EAAA,IAAA,EAAC,EAAA,MAAM,CAAA,CACL,QAAS,IAAM,EAAO,IAAI,CAAC,KAC3B,UAAU,kBACX,iBAEC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,UAAU,CAAA,CAAC,UAAU,oBAKhC,CKfO,IAAM,GAA2C,CACtD,SACA,QACA,UACA,OACA,WACA,OACA,YACAT,QACA,WACD,CAqBY,GAAyC,CACpD,OAAQ,SACR,MAAO,QACP,QAAS,aACT,KAAM,OACN,SAAU,WACV,KAAM,OACN,UAAW,YACX,MAAO,QACP,SAAU,MACZ,EhBnDA,SAAS,SgB+DP,EhB7DA,IAAM,EAAoC,OgB6Dc,IhB9DnC,AACR,CADQ,EAAA,EAAA,eAAe,AAAf,IACK,GAAG,CAAC,QAAuB,SAAW,UAC1D,CAAE,KAAM,CAAM,CAAE,CAAG,CAAA,EAAA,EAAA,SAAS,AAAT,IAKnBH,CAAC,EAAM,EAAQ,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAY,IAC1C,AAAS,aACL,QACC,UAAqD,QAAlCC,EAEpB,CAAC,CAFuB,CAEL,EAAoB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,IAC9C,WAAT,EACI,EAAA,0BAA0B,CACzB,OcoCmB,GdpCmB,IAGvC,CAAC,EAAc,CAHI,CAGY,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,CAHP,CAKvC,IAAgBI,YAAT,EAAqB,UAAkC,KAAO,GAAvB,GAC1C,KAAiD,GAAQ,CADH,SgB4CvC,AAAjB,AAAJ,ChB3CyB,KgB2CE,GhB3Cc,EgB4Cd,EADO,WAC3B,EAAiC,WAAa,ShB9B/C,CAAC,EAAkB,EAAoB,CAAG,CAAA,EAAA,EAAA,QAAA,AAAQ,EACtD,IACE,AAAS,cACJ,CcagB,SdbsB,GACvC,IAIR,CAAA,AAL2B,EAK3B,EAAA,SAAA,AAAS,EAAC,CALiC,IAM5B,UAAU,CAAnB,GACJ,GAAiB,MACf,mBACA,eACA,EACA,iBAAkB,GAAoB,IACxC,EACF,EAAG,CAAC,EAAM,EAAM,EAAkB,EAAc,EAAiB,EAIjE,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,KACK,YAAY,CAArB,GACF,IAEJ,EAAG,CAAC,EAAK,EAKT,IAAM,EAAY,CAAA,EAAA,EAAA,MAAA,AAAMa,EAAwBlB,MAChD,CAAA,EAAA,EAAA,SAAA,AAASmB,EAAC,KACR,EAAU,OAAO,EAAE,SAAS,EAAG,EACjC,EAAG,CAAC,EAAK,EAKT,IAAM,EAAgB,CAAA,EAAA,EAAA,OAAA,AAAO,EAC3B,IAAM,CgBIH,SAAS,AACd,EAAkC,EAAkB,EAEpD,MAAO,IAAI,EAAU,CACvB,IhBPI,EAAE,EAGE,EAAO,KACX,IAAM,EAAM,EAAc,OAAO,CAAC,EAC9B,GAAM,EAAc,MAAM,CAAG,GAAG,AAClC,EAAQ,CAAa,CAAC,EAAM,EAAE,CAElC,EAEM,EAAa,EAAc,OAAO,CAAC,GAOnC,EADK,AACE,YADX,GAAsB,EAAa,GAAc,aAAT,EAEtC,IAAM,EAAQ,CAAa,CAAC,EAAa,EAAE,OAC3C,EAEJ,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,UAAU,iCACH,YAAT,GACU,aAAT,GACE,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CAAI,UAAU,+FACZ,EAAc,MAAM,CAAC,AAAC,GAAY,aAAN,GAAkB,GAAG,CAAC,CAAC,EAAG,KACrD,IAAM,EAAU,EAAc,OAAO,CAAC,GAChC,EAAW,IAAM,EACjB,EAAS,EAAU,EAEzB,MACE,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAY,UAAU,oCACpB,EAAI,GACH,CAAA,EAAA,EAAA,GAAA,EAAC,MAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,WACA,EAAS,aAAe,eAI9B,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,yFACA,EACI,qCACA,EACE,6BACA,mCAGR,CAAA,EAAA,EAAA,GAAA,EAAC,OAAA,CACC,UAAW,CAAA,EAAA,EAAA,EAAA,AAAE,EACX,oEACA,EACI,2BACA,EACE,gBACA,qBAGP,EAAS,IAAM,EAAI,IAErB,EAAW,CAAC,EAAE,MA/BT,EAmCd,KAKN,CAAA,EAAA,EAAA,IAAA,EAAC,MAAA,CAAI,IAAK,EAAW,UAAU,mCACnB,WAAT,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,iBAAkB,EAClB,yBAA0B,EAC1B,OAAQ,IAGF,UAAT,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CACC,OAAQ,EACR,OAAQ,EACR,iBAAkB,EAClB,yBAzIuB,AAAC,CAyIE,GAxIlC,EAAgB,EAClB,EAwIU,iBAAkB,EAClB,yBAA0B,IAG7B,AAAS,eAAa,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAa,OAAQ,EAAM,OAAQ,IACjD,SAAT,GAAmB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAS,OAAQ,EAAM,OAAQ,IAC1C,aAAT,GAAuB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAa,OAAQ,EAAM,OAAQ,IAClD,SAAT,GAAmB,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,CAAS,OAAQ,EAAM,OAAQ,IAC1C,cAAT,GAAwB,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAc,OAAQ,EAAM,OAAQ,IAC7D,AAAS,aACR,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,EACN,iBAAkB,EAClB,WAAY,IAAM,EAAQ,YAC1B,OAAQ,EACR,iBAAkB,EAClB,iBAAkB,IAGZ,aAAT,GACC,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CACC,KAAM,EACN,iBAAkB,GAAoB,EAAA,0BAA0B,QAM5E,kBAEe,SAAS,EACtB,MACE,CAAA,EAAA,EAAA,GAAA,EAAC,EAAA,QAAQ,CAAA,UACP,CAAA,EAAA,EAAA,GAAA,EAAC,GAAA,CAAA,IAGP","ignoreList":[12]}
1
+ {"version":3,"sources":["../../../../../../packages/dashboard/src/app/setup/page.tsx","../../../../../../packages/dashboard/src/components/setup/wizard-step-frame.tsx","../../../../../../packages/dashboard/src/components/setup/basics-step.tsx","../../../../../../packages/dashboard/src/components/setup/vault-step.logic.ts","../../../../../../packages/dashboard/src/components/setup/vault-step.tsx","../../../../../../packages/dashboard/src/components/setup/backends-step.tsx","../../../../../../packages/dashboard/src/components/setup/mail-step.tsx","../../../../../../packages/dashboard/src/components/setup/calendar-step.tsx","../../../../../../packages/dashboard/src/components/setup/note-step.tsx","../../../../../../packages/dashboard/src/components/setup/messaging-step.tsx","../../../../../../packages/dashboard/src/components/setup/conversation-step.tsx","../../../../../../packages/dashboard/src/components/setup/setup-complete.tsx","../../../../../../node_modules/.pnpm/lucide-react%400.468.0_react%4019.2.4/node_modules/lucide-react/src/icons/skip-forward.ts","../../../../../../packages/dashboard/src/components/setup/basics-step.logic.ts","../../../../../../packages/dashboard/src/lib/setup-storage.ts","../../../../../../packages/dashboard/src/components/setup/note-step.logic.ts","../../../../../../packages/dashboard/src/components/setup/wizard-steps.logic.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useRef, useState, Suspense } from \"react\";\nimport { useSearchParams } from \"next/navigation\";\nimport { DEFAULT_AGENT_DISPLAY_NAME } from \"@aitne/shared\";\nimport { BasicsStep } from \"@/components/setup/basics-step\";\nimport { VaultStep } from \"@/components/setup/vault-step\";\nimport { BackendsStep } from \"@/components/setup/backends-step\";\nimport { MailStep } from \"@/components/setup/mail-step\";\nimport { CalendarStep } from \"@/components/setup/calendar-step\";\nimport { NoteStep } from \"@/components/setup/note-step\";\nimport { MessagingStep } from \"@/components/setup/messaging-step\";\nimport { ConversationStep } from \"@/components/setup/conversation-step\";\nimport { SetupComplete } from \"@/components/setup/setup-complete\";\nimport {\n BASE_INITIAL_STEPS,\n STEP_LABELS,\n deriveVaultMode,\n filterInitialSteps,\n type SetupStep,\n} from \"@/components/setup/wizard-steps.logic\";\nimport { useConfig } from \"@/lib/hooks/use-config\";\nimport { cn } from \"@/lib/utils\";\nimport { readWizardState, writeWizardState, clearWizardState } from \"@/lib/setup-storage\";\n\nfunction SetupPageInner() {\n const searchParams = useSearchParams();\n const mode = searchParams.get(\"mode\") === \"update\" ? \"update\" : \"initial\";\n const { data: config } = useConfig();\n\n // Wizard state is persisted in sessionStorage so a page reload mid-setup\n // restores progress. Update mode short-circuits to the rules step (the\n // chat-driven Customize Rules screen) — SETUP-FLOW-REDESIGN-PLAN §6.5.\n const [step, setStep] = useState<SetupStep>(() =>\n mode === \"update\"\n ? \"rules\"\n : ((readWizardState().step as SetupStep | undefined) ?? \"basics\"),\n );\n const [agentDisplayName, setAgentDisplayName] = useState(() =>\n mode === \"update\"\n ? DEFAULT_AGENT_DISPLAY_NAME\n : (readWizardState().agentDisplayName ?? \"\"),\n );\n\n const [modeOverride, setModeOverride] = useState<\n \"plain\" | \"obsidian\" | null\n >(() => (mode === \"initial\" ? readWizardState().modeOverride ?? null : null));\n const pendingVaultMode = deriveVaultMode(modeOverride, config?.vaultMode);\n const onPendingVaultModeChange = (next: \"plain\" | \"obsidian\") => {\n setModeOverride(next);\n };\n\n // SETUP-FLOW-REDESIGN-PLAN §5.2 — the chosen primary-vault path is held\n // here (not committed) until the user enters the Customize Rules step.\n // Hydrated from sessionStorage only; we don't seed from\n // `config.primaryVaultPath` because (a) initial-mode runs start from a\n // plain default so there's nothing useful to seed, and (b) the\n // DirectoryPickerField in VaultStep already passes\n // `config.primaryVaultPath` as the picker's `defaultPath`, so a user\n // re-doing setup over a prior install sees the previous folder in the\n // native picker without us setting state inside an effect.\n const [pendingVaultPath, setPendingVaultPath] = useState<string>(\n () =>\n mode === \"initial\"\n ? (readWizardState().pendingVaultPath ?? \"\")\n : \"\",\n );\n\n // Persist wizard state on every change so reload restores progress.\n useEffect(() => {\n if (mode === \"update\") return;\n writeWizardState({\n step,\n agentDisplayName,\n modeOverride,\n pendingVaultPath: pendingVaultPath || null,\n });\n }, [mode, step, agentDisplayName, modeOverride, pendingVaultPath]);\n\n // Reaching `complete` means rules were saved successfully — clear all\n // persisted setup state so any future setup re-entry starts clean.\n useEffect(() => {\n if (step === \"complete\") {\n clearWizardState();\n }\n }, [step]);\n\n // Reset scroll position whenever the step changes — without this, a tall\n // previous step (e.g. Backends) leaves scrollTop mid-page and the next\n // step (e.g. Mail) renders mid-page instead of from the top.\n const scrollRef = useRef<HTMLDivElement | null>(null);\n useEffect(() => {\n scrollRef.current?.scrollTo(0, 0);\n }, [step]);\n\n // SETUP-FLOW-REDESIGN-PLAN §6.5 — `filterInitialSteps` is identity in\n // v1 (no conditional sub-steps); kept as a function so future\n // conditional gating has an obvious home.\n const INITIAL_STEPS = useMemo<SetupStep[]>(\n () => filterInitialSteps(),\n [],\n );\n\n const next = () => {\n const idx = INITIAL_STEPS.indexOf(step);\n if (idx < INITIAL_STEPS.length - 1) {\n setStep(INITIAL_STEPS[idx + 1]);\n }\n };\n\n const currentIdx = INITIAL_STEPS.indexOf(step);\n\n // Update mode opens directly on `rules` with no prior step to return\n // to. On initial runs every step except basics/complete gets a Back\n // button.\n const canGoBack =\n mode === \"initial\" && currentIdx > 0 && step !== \"complete\";\n const prev = canGoBack\n ? () => setStep(INITIAL_STEPS[currentIdx - 1])\n : undefined;\n\n return (\n <div className=\"flex h-full flex-col\">\n {mode === \"initial\" &&\n step !== \"complete\" && (\n <div className=\"flex items-center justify-center gap-1 border-b border-border bg-muted/30 px-4 py-3\">\n {INITIAL_STEPS.filter((s) => s !== \"complete\").map((s, i) => {\n const stepIdx = INITIAL_STEPS.indexOf(s);\n const isActive = s === step;\n const isDone = stepIdx < currentIdx;\n\n return (\n <div key={s} className=\"flex items-center gap-1\">\n {i > 0 && (\n <div\n className={cn(\n \"h-px w-6\",\n isDone ? \"bg-primary\" : \"bg-border\",\n )}\n />\n )}\n <div\n className={cn(\n \"flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium transition-colors\",\n isActive\n ? \"bg-primary text-primary-foreground\"\n : isDone\n ? \"bg-primary/10 text-primary\"\n : \"text-muted-foreground\",\n )}\n >\n <span\n className={cn(\n \"flex h-5 w-5 items-center justify-center rounded-full text-[10px]\",\n isActive\n ? \"bg-primary-foreground/20\"\n : isDone\n ? \"bg-primary/20\"\n : \"bg-muted\",\n )}\n >\n {isDone ? \"✓\" : i + 1}\n </span>\n {STEP_LABELS[s]}\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Step content */}\n <div ref={scrollRef} className=\"flex-1 overflow-y-auto\">\n {step === \"basics\" && (\n <BasicsStep\n agentDisplayName={agentDisplayName}\n onAgentDisplayNameChange={setAgentDisplayName}\n onNext={next}\n />\n )}\n {step === \"vault\" && (\n <VaultStep\n onNext={next}\n onBack={prev}\n pendingVaultMode={pendingVaultMode}\n onPendingVaultModeChange={onPendingVaultModeChange}\n pendingVaultPath={pendingVaultPath}\n onPendingVaultPathChange={setPendingVaultPath}\n />\n )}\n {step === \"backend\" && <BackendsStep onNext={next} onBack={prev} />}\n {step === \"mail\" && <MailStep onNext={next} onBack={prev} />}\n {step === \"calendar\" && <CalendarStep onNext={next} onBack={prev} />}\n {step === \"note\" && <NoteStep onNext={next} onBack={prev} />}\n {step === \"messaging\" && <MessagingStep onNext={next} onBack={prev} />}\n {step === \"rules\" && (\n <ConversationStep\n mode={mode}\n agentDisplayName={agentDisplayName}\n onComplete={() => setStep(\"complete\")}\n onBack={prev}\n pendingVaultMode={pendingVaultMode}\n pendingVaultPath={pendingVaultPath}\n />\n )}\n {step === \"complete\" && (\n <SetupComplete\n mode={mode}\n agentDisplayName={agentDisplayName || DEFAULT_AGENT_DISPLAY_NAME}\n />\n )}\n </div>\n </div>\n );\n}\n\nexport default function SetupPage() {\n return (\n <Suspense>\n <SetupPageInner />\n </Suspense>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { ArrowLeft, ArrowRight, SkipForward } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface WizardStepFrameProps {\n /** Step heading. */\n title: string;\n /** Short description shown below the heading. */\n description?: string;\n /** The settings component(s) rendered inside the frame. */\n children: ReactNode;\n /** Called when the user advances to the next step. */\n onNext: () => void;\n /** Called when the user goes back to the previous step. Omit to hide the back button. */\n onBack?: () => void;\n /** Label for the skip button. Omit to hide skip entirely. */\n skipLabel?: string;\n /** Label for the next button. Defaults to \"Next\". */\n nextLabel?: string;\n /** Disable the next button (e.g. while a required action hasn't completed). */\n nextDisabled?: boolean;\n /** Hide both navigation buttons (for steps that manage their own flow). */\n hideNav?: boolean;\n /** Override the default max-w-lg container width (e.g. \"max-w-3xl\"). */\n maxWidth?: string;\n}\n\n/**\n * Consistent wizard chrome for setup steps that wrap settings components.\n *\n * Provides: centred title + description, content slot, skip / next buttons.\n * The progress stepper is owned by the parent page — not duplicated here.\n */\nexport function WizardStepFrame({\n title,\n description,\n children,\n onNext,\n onBack,\n skipLabel = \"Set Up Later\",\n nextLabel = \"Next\",\n nextDisabled = false,\n hideNav = false,\n maxWidth,\n}: WizardStepFrameProps) {\n return (\n <div className={`mx-auto ${maxWidth ?? \"max-w-lg\"} space-y-6 py-8`}>\n <div className=\"space-y-2 text-center\">\n <h2 className=\"text-xl font-semibold\">{title}</h2>\n {description && (\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n )}\n </div>\n\n {children}\n\n {!hideNav && (\n <div className=\"flex justify-between pt-4\">\n <div className=\"flex gap-2\">\n {onBack ? (\n <Button\n variant=\"ghost\"\n onClick={onBack}\n className=\"gap-2 text-muted-foreground\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </Button>\n ) : null}\n {skipLabel ? (\n <Button\n variant=\"ghost\"\n onClick={onNext}\n className=\"gap-2 text-muted-foreground\"\n >\n <SkipForward className=\"h-4 w-4\" />\n {skipLabel}\n </Button>\n ) : null}\n {!onBack && !skipLabel ? <div /> : null}\n </div>\n <Button\n onClick={onNext}\n className=\"gap-2\"\n disabled={nextDisabled}\n >\n {nextLabel}\n <ArrowRight className=\"h-4 w-4\" />\n </Button>\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { ArrowLeft, ArrowRight, Loader2 } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { api, ApiError } from \"@/lib/api-client\";\nimport { useConfig } from \"@/lib/hooks/use-config\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport {\n AGENT_DISPLAY_NAME_MAX_LENGTH,\n SUPPORTED_LANGUAGES,\n buildBasicsPatchBody,\n canContinue,\n hydrateLanguageSelection,\n isCustomLanguageInvalid,\n resolveLanguage,\n} from \"./basics-step.logic\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * SETUP-FLOW-REDESIGN-PLAN §5.1 — Basics step.\n *\n * Replaces Welcome + the language portion of the legacy Vault step.\n * Two atomic fields persisted on Continue via `PATCH /api/config`:\n * - `agentDisplayName`\n * - `primaryLanguage`\n */\n\ninterface BasicsStepProps {\n agentDisplayName: string;\n onAgentDisplayNameChange: (value: string) => void;\n onNext: () => void;\n}\n\nexport function BasicsStep({\n agentDisplayName,\n onAgentDisplayNameChange,\n onNext,\n}: BasicsStepProps) {\n const { data: config } = useConfig();\n const queryClient = useQueryClient();\n const [primaryLanguage, setPrimaryLanguage] = useState(\"en\");\n const [customLanguage, setCustomLanguage] = useState(\"\");\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const hydratedRef = useRef(false);\n\n // Hydrate once from server state so back-nav restores the user's prior\n // pick. Subsequent config refetches (SSE) must not overwrite an edit\n // in progress — same pattern the legacy vault-step uses.\n useEffect(() => {\n if (hydratedRef.current || !config) return;\n hydratedRef.current = true;\n const hydrated = hydrateLanguageSelection(config.primaryLanguage);\n setPrimaryLanguage(hydrated.primary);\n setCustomLanguage(hydrated.custom);\n if (\n typeof config.agentDisplayName === \"string\"\n && config.agentDisplayName.length > 0\n && agentDisplayName.length === 0\n ) {\n onAgentDisplayNameChange(config.agentDisplayName);\n }\n }, [config, agentDisplayName, onAgentDisplayNameChange]);\n\n const resolvedLanguage = resolveLanguage(primaryLanguage, customLanguage);\n const customInvalid = isCustomLanguageInvalid(primaryLanguage, customLanguage);\n const ready = canContinue({ agentDisplayName, resolvedLanguage, saving });\n\n const handleContinue = async () => {\n if (!ready) return;\n setSaving(true);\n setError(null);\n try {\n await api.patch(\n \"/config\",\n buildBasicsPatchBody({ agentDisplayName, resolvedLanguage }),\n );\n await queryClient.invalidateQueries({ queryKey: [\"config\"] });\n onNext();\n } catch (err) {\n if (err instanceof ApiError) {\n const body = err.body as { message?: string } | null;\n setError(body?.message ?? err.message ?? \"Failed to save basics\");\n } else {\n setError(err instanceof Error ? err.message : \"Failed to save basics\");\n }\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <WizardStepFrame\n title=\"Basics\"\n description=\"Tell your agent what to call itself and which language to think in.\"\n onNext={onNext}\n hideNav\n >\n <div className=\"w-full max-w-sm mx-auto space-y-6 rounded-xl border border-border bg-card p-5 text-left\">\n <div className=\"space-y-2\">\n <label\n htmlFor=\"agent-name\"\n className=\"text-sm font-medium text-foreground\"\n >\n Agent name\n </label>\n <p className=\"text-xs text-muted-foreground\">\n Shown in the dashboard and prepended to outbound messages.\n </p>\n <Input\n id=\"agent-name\"\n value={agentDisplayName}\n onChange={(e) => onAgentDisplayNameChange(e.target.value)}\n placeholder=\"Aitne\"\n maxLength={AGENT_DISPLAY_NAME_MAX_LENGTH}\n />\n </div>\n\n <div className=\"space-y-2 border-t border-border pt-4\">\n <label className=\"text-sm font-medium text-foreground\">\n Primary language\n </label>\n <p className=\"text-xs text-muted-foreground\">\n Controls user-facing prose (profile, daily journal, weekly /\n monthly reviews). System files stay in English.\n </p>\n <Select value={primaryLanguage} onValueChange={setPrimaryLanguage}>\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SUPPORTED_LANGUAGES.map((lang) => (\n <SelectItem key={lang.tag} value={lang.tag}>\n {lang.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {primaryLanguage === \"__custom__\" && (\n <Input\n value={customLanguage}\n onChange={(e) => setCustomLanguage(e.target.value)}\n placeholder=\"e.g. zh-Hans\"\n className=\"mt-2\"\n />\n )}\n {customInvalid && (\n <p className=\"text-xs text-destructive\">\n Use a BCP-47 tag like <code>en-US</code> or <code>zh-Hans</code>.\n </p>\n )}\n </div>\n </div>\n\n {error && (\n <p className=\"text-sm text-red-600 dark:text-red-400 text-center\">\n {error}\n </p>\n )}\n\n <div className=\"flex justify-center gap-3 pt-4\">\n <Button\n size=\"lg\"\n onClick={handleContinue}\n disabled={!ready}\n className=\"gap-2\"\n >\n {saving ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Saving…\n </>\n ) : (\n <>\n Continue\n <ArrowRight className=\"h-4 w-4\" />\n </>\n )}\n </Button>\n </div>\n </WizardStepFrame>\n );\n}\n\n// Re-export for callers that still want the import surface.\nexport { ArrowLeft };\n","/**\n * SETUP-FLOW-REDESIGN-PLAN §5.2 — vault step pure logic.\n *\n * Replaces the language-aware logic that used to live here. The Basics\n * step now owns language; this module owns the vault-mode + primary-path\n * decisions. The component is a thin shell around these helpers.\n *\n * Validation against the daemon's `validatePrimaryVaultPath` is the\n * server-side source of truth (see `daemon/src/config.ts`); this module\n * keeps a slim client-side mirror so the user gets immediate feedback\n * before the round-trip.\n */\n\nimport {\n isClientAbsolutePath,\n isClientPathInsideOrEqual,\n} from \"@/lib/path-client\";\n\nexport type VaultMode = \"plain\" | \"obsidian\";\n\nexport type VaultPathIssue =\n | \"empty\"\n | \"not_absolute\"\n | \"overlaps_data_dir\";\n\nexport interface ValidatePrimaryVaultPathInput {\n path: string;\n dataDir: string;\n}\n\n/**\n * Pre-flight client-side path check. Mirrors the prefix rules in\n * `daemon/src/config.ts:validatePrimaryVaultPath` — the daemon\n * re-runs the full validation server-side, so this is just an\n * immediate-feedback layer (no system-path denials, no parent-existence\n * check; those need fs access).\n */\nexport function validatePrimaryVaultPathClient(\n input: ValidatePrimaryVaultPathInput,\n): VaultPathIssue | null {\n const trimmed = input.path.trim();\n if (trimmed.length === 0) return \"empty\";\n if (!isClientAbsolutePath(trimmed)) {\n return \"not_absolute\";\n }\n if (input.dataDir.length > 0) {\n if (isClientPathInsideOrEqual(input.dataDir, trimmed)) {\n return \"overlaps_data_dir\";\n }\n }\n return null;\n}\n\nexport function vaultPathIssueMessage(issue: VaultPathIssue): string {\n switch (issue) {\n case \"empty\":\n return \"Pick a directory for the agent's primary vault.\";\n case \"not_absolute\":\n return \"Use an absolute path (for example `/Users/me/Vault`, `~/Vault`, or `C:\\\\Vault`).\";\n case \"overlaps_data_dir\":\n return \"Path overlaps the agent's data directory; choose a separate location.\";\n }\n}\n\n/**\n * True when the user picked \"plain\" while the daemon is still in\n * `obsidian` mode — the one case where VaultStep must call\n * `/setup/migrate-context` to walk the daemon back out of obsidian.\n */\nexport function shouldRollbackToPlain(\n pendingMode: VaultMode,\n currentMode: VaultMode | null | undefined,\n): boolean {\n return pendingMode === \"plain\" && currentMode === \"obsidian\";\n}\n\n/**\n * Continue-button enablement. Plain mode never blocks on path; obsidian\n * mode requires a valid (or at least non-empty) path. `saving` blocks\n * both branches.\n */\nexport function canContinue(input: {\n vaultMode: VaultMode;\n pathIssue: VaultPathIssue | null;\n saving: boolean;\n}): boolean {\n if (input.saving) return false;\n if (input.vaultMode === \"plain\") return true;\n return input.pathIssue === null;\n}\n\n/**\n * Build the `POST /api/setup/migrate-context` body. Plain mode does not\n * carry a path; obsidian mode trims the user input.\n */\nexport type VaultMigrationBody =\n | { targetVaultMode: \"plain\"; conflictPolicy: \"abort\" }\n | {\n targetVaultMode: \"obsidian\";\n targetVaultPath: string;\n conflictPolicy: \"abort\";\n };\n\nexport function buildVaultMigrationBody(input: {\n vaultMode: VaultMode;\n primaryVaultPath: string;\n}): VaultMigrationBody {\n if (input.vaultMode === \"plain\") {\n return { targetVaultMode: \"plain\", conflictPolicy: \"abort\" };\n }\n return {\n targetVaultMode: \"obsidian\",\n targetVaultPath: input.primaryVaultPath.trim(),\n conflictPolicy: \"abort\",\n };\n}\n\n/**\n * Inputs to the deferred-migration decision used by `ConversationStep`.\n * `currentMode` / `currentPath` come from `/api/config`; `pendingMode` /\n * `pendingPath` come from wizard state populated on the Vault step.\n */\nexport interface VaultMigrationDecisionInput {\n pendingMode: VaultMode;\n pendingPath: string;\n currentMode: VaultMode;\n currentPath: string | null;\n}\n\nexport type VaultMigrationDecision =\n | { kind: \"no_migration_needed\" }\n | { kind: \"migrate\"; mode: VaultMode; path: string };\n\n/**\n * Decide whether the deferred vault migration should run on entry to the\n * Customize Rules step, given the user's pending picks and the daemon's\n * current config. Pure — exists so the test suite can pin down the\n * branches that previously lived inside an `IIFE` in a `useEffect`.\n *\n * Rules:\n * - plain & current plain → no-op.\n * - plain & current obsidian → migrate (rollback to plain).\n * - obsidian & empty path → no-op (defensive; Vault step blocks this).\n * - obsidian & current plain → migrate.\n * - obsidian & path differs → migrate (re-target).\n * - obsidian & path matches → no-op.\n *\n * Path comparison is by exact string after trimming the pending value;\n * the daemon's `validateMigrationTargetPath` resolves `~`/relatives, so\n * we never compare against an unresolved server path.\n */\nexport function decideVaultMigration(\n input: VaultMigrationDecisionInput,\n): VaultMigrationDecision {\n if (input.pendingMode === \"plain\") {\n if (input.currentMode === \"obsidian\") {\n return { kind: \"migrate\", mode: \"plain\", path: \"\" };\n }\n return { kind: \"no_migration_needed\" };\n }\n const pendingPathTrimmed = input.pendingPath.trim();\n if (pendingPathTrimmed.length === 0) {\n return { kind: \"no_migration_needed\" };\n }\n if (input.currentMode !== \"obsidian\") {\n return { kind: \"migrate\", mode: \"obsidian\", path: pendingPathTrimmed };\n }\n if (input.currentPath !== pendingPathTrimmed) {\n return { kind: \"migrate\", mode: \"obsidian\", path: pendingPathTrimmed };\n }\n return { kind: \"no_migration_needed\" };\n}\n","\"use client\";\n\nimport { ArrowLeft, FolderSymlink } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { DirectoryPickerField } from \"@/components/directory-picker-field\";\nimport { useConfig } from \"@/lib/hooks/use-config\";\nimport { cn } from \"@/lib/utils\";\nimport {\n canContinue,\n validatePrimaryVaultPathClient,\n vaultPathIssueMessage,\n type VaultMode,\n type VaultPathIssue,\n} from \"./vault-step.logic\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * SETUP-FLOW-REDESIGN-PLAN §5.2 — vault step.\n *\n * The user picks vault mode + path here, but the actual\n * `/setup/migrate-context` call is deferred to the Customize Rules step\n * (see `conversation-step.tsx`). Holding off on file creation lets the\n * user Back-navigate from any later step and re-pick the same directory\n * without seeing it already populated with agent skeleton files.\n */\n\ninterface VaultStepProps {\n onNext: () => void;\n onBack?: () => void;\n pendingVaultMode: VaultMode;\n onPendingVaultModeChange: (mode: VaultMode) => void;\n pendingVaultPath: string;\n onPendingVaultPathChange: (path: string) => void;\n}\n\nexport function VaultStep({\n onNext,\n onBack,\n pendingVaultMode,\n onPendingVaultModeChange,\n pendingVaultPath,\n onPendingVaultPathChange,\n}: VaultStepProps) {\n const { data: config } = useConfig();\n\n const dataDir = config?.contextDir ?? \"\";\n const pathIssue: VaultPathIssue | null = pendingVaultMode === \"obsidian\"\n ? validatePrimaryVaultPathClient({ path: pendingVaultPath, dataDir })\n : null;\n const ready = canContinue({\n vaultMode: pendingVaultMode,\n pathIssue,\n saving: false,\n });\n\n return (\n <WizardStepFrame\n title=\"Vault\"\n description=\"Where should your agent store its memory? Obsidian users can pick an existing vault.\"\n onNext={onNext}\n hideNav\n >\n <div className=\"w-full max-w-xl mx-auto space-y-5 rounded-xl border border-border bg-card p-5 text-left\">\n <div className=\"grid grid-cols-1 gap-2\">\n {([\"plain\", \"obsidian\"] as const).map((mode) => (\n <button\n key={mode}\n type=\"button\"\n onClick={() => onPendingVaultModeChange(mode)}\n className={cn(\n \"rounded-md border px-3 py-2 text-left text-sm transition-colors\",\n pendingVaultMode === mode\n ? \"border-primary bg-primary/10 text-foreground\"\n : \"border-border bg-background text-muted-foreground hover:border-primary/50\",\n )}\n >\n <span className=\"block font-medium\">\n {mode === \"plain\"\n ? \"Plain markdown\"\n : \"Obsidian\"}\n </span>\n <span className=\"block text-xs text-muted-foreground\">\n {mode === \"plain\"\n ? \"Stored at ~/.personal-agent/context. Only this app reads + writes.\"\n : \"Use an existing Obsidian vault as the agent's working directory.\"}\n </span>\n </button>\n ))}\n </div>\n\n {pendingVaultMode === \"obsidian\" && (\n <div className=\"space-y-2 border-t border-border pt-4\">\n <label\n htmlFor=\"primary-vault-path\"\n className=\"text-sm font-medium text-foreground\"\n >\n Vault path\n </label>\n <p className=\"text-xs text-muted-foreground\">\n Pick an existing folder. Cloud-sync directories (iCloud,\n Dropbox, OneDrive, Google Drive) work; local SSDs are faster.\n The folder stays untouched until you reach the final step.\n </p>\n <DirectoryPickerField\n id=\"primary-vault-path\"\n value={pendingVaultPath}\n onChange={onPendingVaultPathChange}\n title=\"Choose primary vault directory\"\n placeholder=\"Choose a folder for the primary vault\"\n defaultPath={config?.primaryVaultPath || undefined}\n />\n {pathIssue && pathIssue !== \"empty\" && (\n <p className=\"text-xs text-destructive\">\n {vaultPathIssueMessage(pathIssue)}\n </p>\n )}\n </div>\n )}\n </div>\n\n <div className=\"flex justify-center gap-3 pt-4\">\n {onBack && (\n <Button variant=\"ghost\" onClick={onBack} className=\"gap-2\">\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </Button>\n )}\n <Button\n size=\"lg\"\n onClick={onNext}\n disabled={!ready}\n className=\"gap-2\"\n >\n <FolderSymlink className=\"h-4 w-4\" />\n Continue\n </Button>\n </div>\n </WizardStepFrame>\n );\n}\n","\"use client\";\n\nimport {\n AlertTriangle,\n ArrowLeft,\n ArrowRight,\n ChevronDown,\n Loader2,\n ShieldCheck,\n Unlock,\n} from \"lucide-react\";\nimport { useCallback, useState } from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport type { BackendId } from \"@aitne/shared\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { api, ApiError } from \"@/lib/api-client\";\nimport {\n BACKEND_PROVIDER_LABELS,\n BACKEND_PROVIDER_SHORT,\n} from \"@/lib/backend-ui\";\nimport { cn } from \"@/lib/utils\";\nimport { useBackends } from \"@/lib/hooks/use-backends\";\nimport { BackendApiKeyPanel } from \"@/components/settings/backend-api-key-panel\";\nimport { BackendCard } from \"@/components/settings/backend-card\";\nimport { isContinueEligible } from \"@/components/settings/backend-card.logic\";\nimport { SubscriptionAuthWarning } from \"@/components/settings/subscription-auth-warning\";\nimport {\n buildSetupModePayload,\n EMPTY_OVERRIDES,\n hasDivergentOverride,\n type ExecutionModeUi,\n type PerBackendOverrides,\n} from \"@/components/settings/execution-mode.logic\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * Wizard step for the backend selection. Subscription-plan registration\n * has been removed — Aitne is designed to run on provider API keys\n * (`ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `GEMINI_API_KEY`), so the\n * daemon does not ask the operator which Claude/Codex/Gemini tier they\n * hold. `process_backend_config` is seeded with fixed defaults (Sonnet\n * for main agent surfaces, Haiku for delegated/simple polling). The\n * user picks the main backend, authenticates it via the per-backend\n * API-key panel (or, as a fallback, signs in to the local CLI), and\n * non-main backends can be configured later from /settings/models.\n *\n * On Continue, this step calls `PUT /api/backends/main` with the\n * chosen backend, which seeds default `process_backend_config` rows\n * for that backend on a fresh install.\n */\n\nconst BACKENDS: readonly BackendId[] = [\"claude\", \"codex\", \"gemini\"];\n\ninterface BackendsStepProps {\n onNext: () => void;\n onBack?: () => void;\n}\n\ninterface InstallCheckEntry {\n status: \"idle\" | \"checking\" | \"ok\" | \"error\";\n error?: string | null;\n version?: string | null;\n}\n\nexport function BackendsStep({ onNext, onBack }: BackendsStepProps) {\n const { data: backendsData, refetch: refetchBackends } = useBackends();\n const queryClient = useQueryClient();\n\n const [mainBackend, setMainBackend] = useState<BackendId | null>(\"claude\");\n const [topMode, setTopMode] = useState<ExecutionModeUi>(\"safe\");\n const [overrides, setOverrides] = useState<PerBackendOverrides>(EMPTY_OVERRIDES);\n const [advancedOpen, setAdvancedOpen] = useState(false);\n const [saving, setSaving] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n // INTEGRATION_NATIVE_MODE_DESIGN.md §11.4 — when the wizard is re-run\n // after the operator has provisioned native rows (uncommon but possible),\n // changing the main backend cascades non-matching native rows to\n // `disabled`. Surface the cascade inline so the user finds out here\n // rather than discovering silently-disabled rows on /connections.\n const [cascadeNotice, setCascadeNotice] = useState<string | null>(null);\n const [installCheck, setInstallCheck] = useState<\n Record<BackendId, InstallCheckEntry>\n >({\n claude: { status: \"idle\" },\n codex: { status: \"idle\" },\n gemini: { status: \"idle\" },\n });\n\n const pickMain = useCallback((backendId: BackendId) => {\n setMainBackend(backendId);\n }, []);\n\n const verifyInstall = useCallback(\n async (backendId: BackendId) => {\n setInstallCheck((prev) => ({\n ...prev,\n [backendId]: { status: \"checking\" },\n }));\n try {\n const res = await api.post<{\n ok: boolean;\n cliInstalled: boolean;\n cliCommand: string;\n exitCode: number | null;\n version: string | null;\n stdout: string;\n stderr: string;\n timedOut: boolean;\n }>(`/backends/${backendId}/verify-install`);\n await refetchBackends();\n if (res.ok) {\n setInstallCheck((prev) => ({\n ...prev,\n [backendId]: { status: \"ok\", version: res.version },\n }));\n } else {\n const reason = !res.cliInstalled\n ? `${res.cliCommand} not found on PATH`\n : res.timedOut\n ? `${res.cliCommand} --version timed out`\n : (res.stderr.trim() || res.stdout.trim() || \"CLI failed to run\");\n setInstallCheck((prev) => ({\n ...prev,\n [backendId]: { status: \"error\", error: reason },\n }));\n }\n } catch (err) {\n setInstallCheck((prev) => ({\n ...prev,\n [backendId]: {\n status: \"error\",\n error: err instanceof Error ? err.message : \"Verify install failed\",\n },\n }));\n }\n },\n [refetchBackends],\n );\n\n const canContinue = isContinueEligible({ mainBackend });\n\n async function applyAndNext(): Promise<void> {\n if (!mainBackend) return;\n // INTEGRATION_NATIVE_MODE_DESIGN.md §11.4 — second click after a\n // cascade notice: the user has now acknowledged the cascade. Skip\n // re-PUTting `/backends/main` (the change already landed on the\n // first click) and proceed to the next wizard step.\n if (cascadeNotice !== null) {\n setCascadeNotice(null);\n onNext();\n return;\n }\n setSaving(true);\n setSaveError(null);\n try {\n // INTEGRATION_NATIVE_MODE_DESIGN.md §11.4 — capture `nativeUnbound`\n // from the response so the wizard can warn the user inline. Mirrors\n // the settings page toast (`backends-section.tsx`) so re-running the\n // wizard after configuring native rows doesn't silently drop them.\n const res = await api.put<{\n status?: string;\n nativeUnbound?: Array<{ key: string; priorNativeBackend: string }>;\n }>(\"/backends/main\", { backendId: mainBackend });\n // /backends/main flips `backends.enabled = 1` server-side and\n // re-seeds process_backend_config rows for the new backend.\n // Invalidate the backends query so the next step (GoogleModeStep)\n // reads the post-apply state.\n // INTEGRATION_NATIVE_MODE_DESIGN.md §11.4 — the same call cascades\n // any native rows whose `nativeBackend` no longer matches. The\n // wizard's first launch never has native rows (defaults all\n // `disabled`/`direct`), but a re-run of the wizard with an\n // operator-provisioned native row would; surface the cascade\n // through the same invalidation chain the settings page uses so\n // /connections renders the §11.5 banner consistently.\n await queryClient.invalidateQueries({ queryKey: [\"backends\"] });\n await queryClient.invalidateQueries({ queryKey: [\"integrations\"] });\n await queryClient.invalidateQueries({ queryKey: [\"health\"] });\n await queryClient.invalidateQueries({\n queryKey: [\"agent-actions\", \"native_unbound\"],\n });\n\n const modePayload = buildSetupModePayload(topMode, overrides);\n if (modePayload) {\n await api.post(\"/setup/mode\", modePayload);\n await queryClient.invalidateQueries({ queryKey: [\"config\"] });\n }\n\n // Defer the cascade-confirmation gate to *after* the mode payload\n // POST so a failure in `/setup/mode` doesn't strand the user with\n // a half-applied state. If cascade fired, hold here; the user\n // acknowledges, then clicks Next again — the early-return at the\n // top of this function advances without a redundant PUT.\n const unbound = res?.nativeUnbound ?? [];\n if (unbound.length > 0) {\n const keys = unbound.map((u) => u.key).join(\", \");\n setCascadeNotice(\n `${unbound.length} native integration${unbound.length === 1 ? \"\" : \"s\"} (${keys}) ` +\n `were bound to a different backend and are now disabled. ` +\n `Re-configure them on /settings/integrations after the wizard completes.`,\n );\n setSaving(false);\n return;\n }\n } catch (err) {\n setSaveError(\n err instanceof ApiError\n ? err.message\n : err instanceof Error\n ? err.message\n : \"Failed to apply default presets\",\n );\n setSaving(false);\n return;\n }\n onNext();\n }\n\n return (\n <WizardStepFrame\n title=\"AI Backend\"\n description=\"Pick the main backend, install its CLI, and (optionally) save a provider API key. You can skip the key setup and configure it later from Settings → Backends.\"\n onNext={onNext}\n hideNav\n maxWidth=\"max-w-4xl\"\n >\n <SubscriptionAuthWarning />\n\n <div className=\"space-y-4\">\n {BACKENDS.map((backendId) => {\n const row = backendsData?.backends.find((b) => b.id === backendId);\n return (\n <div key={backendId} className=\"space-y-2\">\n <BackendCard\n backendId={backendId}\n mode=\"wizard\"\n isMain={mainBackend === backendId}\n authStatus={row?.authStatus ?? \"unknown\"}\n authStatusDetail={row?.authDetail ?? null}\n authFirstExpiredAt={row?.authFirstExpiredAt ?? null}\n authLastSuccessAt={row?.authLastSuccessAt ?? null}\n authNotificationCount={row?.authNotificationCount ?? 0}\n cliInstalled={row?.cliInstalled ?? true}\n enabled={row?.enabled ?? true}\n webSearchEnabled={row?.webSearchEnabled ?? false}\n webSearchSupported={row?.webSearchSupported ?? false}\n permissionMode={null}\n installCheck={installCheck[backendId]}\n onCliInstalled={() => {\n void refetchBackends();\n }}\n onVerifyInstall={() => {\n void verifyInstall(backendId);\n }}\n />\n <BackendApiKeyPanel backendId={backendId} />\n </div>\n );\n })}\n\n {/* Main backend radio */}\n <div className=\"rounded-lg border border-border bg-muted/30 p-4\">\n <h3 className=\"text-sm font-semibold text-foreground\">\n Main backend\n </h3>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n The main backend runs every configurable process by default.\n </p>\n <div className=\"mt-3 flex flex-wrap gap-3\">\n {BACKENDS.map((backendId) => {\n const isActive = mainBackend === backendId;\n return (\n <label\n key={backendId}\n className={`flex flex-1 min-w-[180px] items-start gap-2 rounded-md border px-3 py-2 text-sm transition-colors ${\n isActive\n ? \"border-primary bg-primary/10\"\n : \"border-border hover:border-foreground/30\"\n }`}\n >\n <input\n type=\"radio\"\n name=\"main-backend\"\n className=\"mt-1\"\n checked={isActive}\n onChange={() => pickMain(backendId)}\n />\n <span className=\"font-medium\">\n {BACKEND_PROVIDER_SHORT[backendId]}\n </span>\n </label>\n );\n })}\n </div>\n </div>\n </div>\n\n <ExecutionModeSection\n topMode={topMode}\n overrides={overrides}\n advancedOpen={advancedOpen}\n onTopModeChange={setTopMode}\n onOverridesChange={setOverrides}\n onAdvancedOpenChange={setAdvancedOpen}\n />\n\n {saveError && (\n <p className=\"text-sm text-destructive text-center\">{saveError}</p>\n )}\n {cascadeNotice && (\n <p\n className=\"rounded-md border border-amber-300/60 bg-amber-50/60 px-3 py-2 text-xs text-amber-900 dark:border-amber-700/50 dark:bg-amber-950/30 dark:text-amber-100\"\n role=\"status\"\n >\n {cascadeNotice}\n </p>\n )}\n\n <div className=\"flex items-center justify-between gap-3 pt-2\">\n {onBack ? (\n <Button variant=\"ghost\" onClick={onBack} className=\"gap-2\">\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </Button>\n ) : (\n <div />\n )}\n <Button\n onClick={() => void applyAndNext()}\n disabled={!canContinue || saving}\n >\n {saving ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Applying defaults…\n </>\n ) : cascadeNotice ? (\n <>\n Acknowledge &amp; continue <ArrowRight className=\"ml-2 h-4 w-4\" />\n </>\n ) : (\n <>\n Next <ArrowRight className=\"ml-2 h-4 w-4\" />\n </>\n )}\n </Button>\n </div>\n </WizardStepFrame>\n );\n}\n\ninterface ExecutionModeSectionProps {\n topMode: ExecutionModeUi;\n overrides: PerBackendOverrides;\n advancedOpen: boolean;\n onTopModeChange: (mode: ExecutionModeUi) => void;\n onOverridesChange: (\n next: PerBackendOverrides | ((prev: PerBackendOverrides) => PerBackendOverrides),\n ) => void;\n onAdvancedOpenChange: (open: boolean) => void;\n}\n\nfunction ExecutionModeSection({\n topMode,\n overrides,\n advancedOpen,\n onTopModeChange,\n onOverridesChange,\n onAdvancedOpenChange,\n}: ExecutionModeSectionProps) {\n const divergent = hasDivergentOverride(topMode, overrides);\n return (\n <div className=\"rounded-lg border border-border bg-muted/30 p-4 space-y-3\">\n <div>\n <h3 className=\"text-sm font-semibold text-foreground\">\n Execution permissions\n </h3>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n Pick how freely the agent may run shell, file, and tool commands.\n Dangerous operations — recursive deletes, privilege escalation, and\n secret-file reads — remain blocked in both modes.\n </p>\n </div>\n\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <ModeCard\n icon={<ShieldCheck className=\"h-4 w-4\" />}\n title=\"Safe\"\n badge=\"Recommended\"\n selected={topMode === \"safe\"}\n onSelect={() => onTopModeChange(\"safe\")}\n >\n Strict permission checks, asks for confirmation before\n side-effectful actions.\n </ModeCard>\n <ModeCard\n icon={<Unlock className=\"h-4 w-4\" />}\n title=\"Allow\"\n selected={topMode === \"allow\"}\n onSelect={() => onTopModeChange(\"allow\")}\n >\n Runs with the skills, plugins, and MCP servers installed in your\n CLI harness.\n </ModeCard>\n </div>\n\n <Collapsible open={advancedOpen} onOpenChange={onAdvancedOpenChange}>\n <CollapsibleTrigger asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between rounded-md border border-border bg-background px-3 py-2 text-left text-xs text-muted-foreground hover:bg-muted/40\"\n >\n <span className=\"flex items-center gap-2\">\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 transition-transform\",\n advancedOpen && \"rotate-180\",\n )}\n />\n Per-backend overrides\n {divergent && (\n <span className=\"rounded bg-amber-500/15 px-1.5 py-0.5 text-[10px] font-medium text-amber-700 dark:text-amber-300\">\n mixed\n </span>\n )}\n </span>\n <span className=\"text-[11px]\">\n {advancedOpen ? \"Hide\" : \"Show\"}\n </span>\n </button>\n </CollapsibleTrigger>\n <CollapsibleContent className=\"mt-2 space-y-2 rounded-md border border-border bg-background p-3\">\n {([\"claude\", \"codex\", \"gemini\"] as const).map((backend) => (\n <BackendOverrideRow\n key={backend}\n backend={backend}\n topMode={topMode}\n override={overrides[backend]}\n onChange={(next) =>\n onOverridesChange((prev) => ({ ...prev, [backend]: next }))\n }\n />\n ))}\n </CollapsibleContent>\n </Collapsible>\n </div>\n );\n}\n\ninterface ModeCardProps {\n icon: React.ReactNode;\n title: string;\n badge?: string;\n selected: boolean;\n onSelect: () => void;\n children: React.ReactNode;\n}\n\nfunction ModeCard({\n icon,\n title,\n badge,\n selected,\n onSelect,\n children,\n}: ModeCardProps) {\n return (\n <button\n type=\"button\"\n onClick={onSelect}\n className={cn(\n \"block w-full rounded-md border p-3 text-left transition-colors\",\n selected\n ? \"border-primary bg-primary/10 shadow-sm\"\n : \"border-border bg-background hover:border-foreground/30\",\n )}\n >\n <div className=\"flex items-center gap-2 text-sm font-semibold text-foreground\">\n {icon}\n {title}\n {badge && (\n <span className=\"rounded bg-primary/15 px-1.5 py-0.5 text-[10px] font-medium text-primary\">\n {badge}\n </span>\n )}\n </div>\n <p className=\"mt-1 text-xs text-muted-foreground\">{children}</p>\n </button>\n );\n}\n\ninterface BackendOverrideRowProps {\n backend: BackendId;\n topMode: ExecutionModeUi;\n override: ExecutionModeUi | null;\n onChange: (next: ExecutionModeUi | null) => void;\n}\n\nfunction BackendOverrideRow({\n backend,\n topMode,\n override,\n onChange,\n}: BackendOverrideRowProps) {\n const effective = override ?? topMode;\n const showCodexAllowWarning = backend === \"codex\" && effective === \"allow\";\n return (\n <div className=\"rounded-md border border-border/60 px-3 py-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"text-sm\">\n <div className=\"font-medium text-foreground\">\n {BACKEND_PROVIDER_LABELS[backend]}\n <span className=\"ml-1 text-xs text-muted-foreground\">\n ({BACKEND_PROVIDER_SHORT[backend]})\n </span>\n </div>\n <div className=\"text-[11px] text-muted-foreground\">\n runs as: {effective}\n </div>\n </div>\n <div className=\"flex items-center gap-1 text-xs\">\n <OverrideChip\n active={override === null}\n label=\"Follow\"\n onClick={() => onChange(null)}\n />\n <OverrideChip\n active={override === \"safe\"}\n label=\"Safe\"\n onClick={() => onChange(\"safe\")}\n />\n <OverrideChip\n active={override === \"allow\"}\n label=\"Allow\"\n onClick={() => onChange(\"allow\")}\n />\n </div>\n </div>\n {showCodexAllowWarning && (\n <p className=\"mt-2 flex items-start gap-1.5 text-[11px] text-amber-700 dark:text-amber-300\">\n <AlertTriangle className=\"mt-0.5 h-3 w-3 shrink-0\" />\n <span>\n Codex Allow runs sandbox-off; the daemon&apos;s absolute-block\n layer cannot intercept destructive shell commands for Codex.\n </span>\n </p>\n )}\n </div>\n );\n}\n\nfunction OverrideChip({\n active,\n label,\n onClick,\n}: {\n active: boolean;\n label: string;\n onClick: () => void;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n \"rounded-md border px-2 py-1 transition-colors\",\n active\n ? \"border-primary bg-primary/10 text-foreground\"\n : \"border-border text-muted-foreground hover:border-foreground/30\",\n )}\n >\n {label}\n </button>\n );\n}\n","\"use client\";\n\nimport { GmailCard } from \"@/components/mail/gmail-card\";\nimport { OutlookCard } from \"@/components/mail/outlook-card\";\nimport { ImapCard } from \"@/components/mail/imap-card\";\nimport { GoogleCard } from \"@/components/connections/google-card\";\nimport { IntegrationCard } from \"@/components/connections/integration-card\";\nimport { useHealth } from \"@/lib/hooks/use-health\";\nimport {\n useMailAccounts,\n useMailProviders,\n} from \"@/components/mail/use-mail-data\";\nimport type { MailAccount, MailProviderKind } from \"@/components/mail/types\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * SETUP-FLOW-REDESIGN-PLAN §5.4 — Mail step.\n *\n * Each provider stacks the registry-driven `IntegrationCard` (mode\n * toggle + delegated/native backend picker) on top of the auth card\n * (GmailCard / OutlookCard) so the wizard exposes the same decisions\n * as `/connections/mail`. Outlook's descriptor declares the full mode\n * tuple (`direct` / `delegated` / `native` / `disabled`) with\n * `userManagedConnector: true`, so the IntegrationCard renders a\n * \"register an Outlook MCP on the chosen backend\" notice for both\n * delegated and native — INTEGRATION_NATIVE_MODE_DESIGN.md §5.3\n * (2026-05 amendment). IMAP has no delegated/native path (no\n * integration key in the registry); the IMAP cards stay auth-only.\n *\n * Direct-mode Gmail needs a Google OAuth credential. The wizard\n * embeds the same `GoogleCard` used on `/connections/calendar` here\n * so the user can complete OAuth without navigating out of an\n * incomplete wizard. The card is suppressed when Gmail is not in\n * direct mode (no credentials needed for delegated / native / disabled).\n */\ninterface MailStepProps {\n onNext: () => void;\n onBack?: () => void;\n}\n\nexport function MailStep({ onNext, onBack }: MailStepProps) {\n const accountsQuery = useMailAccounts();\n const providersQuery = useMailProviders();\n const health = useHealth();\n\n const accounts = accountsQuery.data?.accounts ?? [];\n const enabledKinds = providersQuery.data?.enabledKinds ?? [];\n const grouped = groupByKind(accounts);\n\n // Only show the GoogleCard when Gmail's mode requires OAuth (direct).\n // In delegated mode, auth lives in the backend's connector store, not\n // the daemon keychain; in disabled mode there is no auth to configure.\n const gmailMode = health.data?.integrationModes?.gmail?.mode ?? \"disabled\";\n const showGoogleAuth = gmailMode === \"direct\";\n\n return (\n <WizardStepFrame\n title=\"Mail\"\n description=\"Hook up the mail accounts your agent should watch. Skip any you don't use — you can configure them later from Settings → Mail.\"\n onNext={onNext}\n onBack={onBack}\n skipLabel=\"Skip\"\n maxWidth=\"max-w-2xl\"\n >\n <IntegrationCard\n integrationKey=\"gmail\"\n gmailAccountCount={grouped.gmail.length}\n />\n <GmailCard\n accounts={grouped.gmail}\n enabledKinds={enabledKinds}\n hideExternalGoogleLink\n />\n {showGoogleAuth && <GoogleCard />}\n <IntegrationCard integrationKey=\"outlook_mail\" />\n <OutlookCard accounts={grouped.outlook} enabledKinds={enabledKinds} />\n <ImapCard\n kind=\"yahoo\"\n accounts={grouped.yahoo}\n enabledKinds={enabledKinds}\n />\n <ImapCard\n kind=\"icloud\"\n accounts={grouped.icloud}\n enabledKinds={enabledKinds}\n />\n </WizardStepFrame>\n );\n}\n\nfunction groupByKind(\n accounts: MailAccount[],\n): Record<MailProviderKind, MailAccount[]> {\n const out: Record<MailProviderKind, MailAccount[]> = {\n gmail: [],\n outlook: [],\n yahoo: [],\n icloud: [],\n };\n for (const a of accounts) out[a.kind].push(a);\n return out;\n}\n","\"use client\";\n\nimport { ArrowRight } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { GoogleCard } from \"@/components/connections/google-card\";\nimport { IntegrationCard } from \"@/components/connections/integration-card\";\nimport { useHealth } from \"@/lib/hooks/use-health\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * SETUP-FLOW-REDESIGN-PLAN §5.5 — Calendar wizard step.\n *\n * Renders the registry-driven `IntegrationCard` for Google Calendar and\n * Outlook Calendar back-to-back. Mode toggles + per-mode disclosures\n * (OAuth, calendar-id picker) are owned by `IntegrationCard`; this\n * component is just the page chrome, the cards, and the nav buttons.\n *\n * Skip is first-class: Calendar is optional input. Continue advances\n * unconditionally — soft-warning state is surfaced inside each card.\n *\n * When Google Calendar is in direct mode the wizard renders the same\n * `GoogleCard` used on `/connections/calendar` so OAuth completes\n * inside the wizard rather than navigating the user out.\n */\ninterface CalendarStepProps {\n onNext: () => void;\n onBack?: () => void;\n}\n\nexport function CalendarStep({ onNext, onBack }: CalendarStepProps) {\n const health = useHealth();\n const calendarMode =\n health.data?.integrationModes?.google_calendar?.mode ?? \"disabled\";\n const showGoogleAuth = calendarMode === \"direct\";\n\n return (\n <WizardStepFrame\n title=\"Calendar\"\n description=\"Pick the calendars your agent should follow. Skip if you don't use one.\"\n onNext={onNext}\n onBack={onBack}\n skipLabel=\"Skip\"\n nextLabel=\"Continue\"\n >\n <div className=\"w-full max-w-2xl mx-auto space-y-4\">\n <IntegrationCard integrationKey=\"google_calendar\" />\n {showGoogleAuth && <GoogleCard />}\n <IntegrationCard integrationKey=\"outlook_calendar\" />\n <p className=\"text-xs text-muted-foreground text-center\">\n Outlook Calendar shares OAuth with Outlook Mail — if you connect Mail\n first, Calendar reads succeed without a second consent screen.\n Apple Calendar can be configured later under Settings → Connections.\n </p>\n </div>\n </WizardStepFrame>\n );\n}\n\n// Re-export for symmetry with other step files.\nexport { ArrowRight, Button };\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { ArrowLeft, FolderSymlink, Loader2 } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { DirectoryPickerField } from \"@/components/directory-picker-field\";\nimport { IntegrationCard } from \"@/components/connections/integration-card\";\nimport { api, ApiError } from \"@/lib/api-client\";\nimport { useConfig } from \"@/lib/hooks/use-config\";\nimport {\n DEFAULT_NOTE_STEP_FIELDS,\n buildNotePatchBody,\n canContinue,\n notePathIssueMessage,\n validateExternalVaultPathClient,\n type NotePathIssue,\n} from \"./note-step.logic\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\n/**\n * SETUP-FLOW-REDESIGN-PLAN §5.6 — Note step.\n *\n * Two sections side-by-side: Notion (existing IntegrationCard) and the\n * user's external Obsidian vault (new — `externalObsidianVaultPath` +\n * `externalObsidianWatch`). The Note Sources section in\n * `<dataDir>/integrations.md` re-renders as soon as the daemon's\n * `applyConfigUpdates` hook fires (see SETUP-FLOW-REDESIGN-PLAN §6.2).\n */\n\ninterface NoteStepProps {\n onNext: () => void;\n onBack?: () => void;\n}\n\nexport function NoteStep({ onNext, onBack }: NoteStepProps) {\n const { data: config } = useConfig();\n const queryClient = useQueryClient();\n const [path, setPath] = useState<string>(\n DEFAULT_NOTE_STEP_FIELDS.externalObsidianVaultPath,\n );\n const [watch, setWatch] = useState<boolean>(\n DEFAULT_NOTE_STEP_FIELDS.externalObsidianWatch,\n );\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const hydratedRef = useRef(false);\n\n // Hydrate once from server state. The daemon serialises\n // `externalObsidianWatch` as boolean (default true); a `null` /\n // missing value resolves to `true` so existing installs keep\n // watching by default.\n useEffect(() => {\n if (hydratedRef.current || !config) return;\n hydratedRef.current = true;\n if (\n typeof config.externalObsidianVaultPath === \"string\"\n && config.externalObsidianVaultPath.length > 0\n ) {\n setPath(config.externalObsidianVaultPath);\n }\n if (typeof config.externalObsidianWatch === \"boolean\") {\n setWatch(config.externalObsidianWatch);\n }\n }, [config]);\n\n const pathIssue: NotePathIssue | null = path.trim().length === 0\n ? null\n : validateExternalVaultPathClient({\n path,\n dataDir: config?.contextDir ?? \"\",\n primaryVaultPath: config?.primaryVaultPath ?? null,\n });\n\n const ready = canContinue({ pathIssue, saving });\n\n const handleSave = async () => {\n if (!ready) return;\n setSaving(true);\n setError(null);\n try {\n await api.patch(\n \"/config\",\n buildNotePatchBody({\n externalObsidianVaultPath: path,\n externalObsidianWatch: watch,\n }),\n );\n await queryClient.invalidateQueries({ queryKey: [\"config\"] });\n onNext();\n } catch (err) {\n if (err instanceof ApiError) {\n const body = err.body as { message?: string } | null;\n setError(body?.message ?? err.message ?? \"Failed to save Note settings\");\n } else {\n setError(err instanceof Error ? err.message : \"Failed to save Note settings\");\n }\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <WizardStepFrame\n title=\"Note\"\n description=\"Where do you keep your own notes? Skip if you don't use either.\"\n onNext={onNext}\n hideNav\n >\n <div className=\"w-full max-w-2xl mx-auto space-y-6\">\n {/* Notion card — registry-driven; mode toggle + direct API key body. */}\n <IntegrationCard integrationKey=\"notion\" />\n\n <div className=\"rounded-xl border border-border bg-card p-5 text-left space-y-4\">\n <div>\n <h3 className=\"text-sm font-semibold text-foreground\">\n Obsidian (your personal vault)\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n This is separate from the agent&rsquo;s working vault — point us\n at the vault YOU use for your own notes. The agent reads + appends\n there via the Obsidian skill.\n </p>\n </div>\n\n <DirectoryPickerField\n id=\"external-obsidian-vault-path\"\n value={path}\n onChange={setPath}\n title=\"Choose your personal Obsidian vault\"\n placeholder=\"Skip if you don't use Obsidian\"\n disabled={saving}\n />\n {pathIssue && pathIssue !== \"empty\" && (\n <p className=\"text-xs text-destructive\">\n {notePathIssueMessage(pathIssue)}\n </p>\n )}\n\n <label className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <input\n type=\"checkbox\"\n checked={watch}\n onChange={(e) => setWatch(e.currentTarget.checked)}\n className=\"h-4 w-4 rounded border-border text-primary focus:ring-primary\"\n />\n Watch this vault for changes (default ON)\n </label>\n <p className=\"text-[11px] text-muted-foreground\">\n Disabling watching keeps the path readable through the Obsidian\n skill but stops the file-change observer — useful for very large\n vaults that produce noisy events.\n </p>\n </div>\n\n {error && (\n <p className=\"text-sm text-red-600 dark:text-red-400 text-center\">\n {error}\n </p>\n )}\n </div>\n\n <div className=\"flex justify-center gap-3 pt-4\">\n {onBack && (\n <Button variant=\"ghost\" onClick={onBack} className=\"gap-2\">\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </Button>\n )}\n <Button variant=\"ghost\" onClick={onNext}>\n Skip\n </Button>\n <Button\n size=\"lg\"\n onClick={handleSave}\n disabled={!ready}\n className=\"gap-2\"\n >\n {saving ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Saving…\n </>\n ) : (\n <>\n <FolderSymlink className=\"h-4 w-4\" />\n Continue\n </>\n )}\n </Button>\n </div>\n </WizardStepFrame>\n );\n}\n","\"use client\";\n\nimport { SlackCard } from \"@/components/connections/slack-card\";\nimport { TelegramCard } from \"@/components/connections/telegram-card\";\nimport { DiscordCard } from \"@/components/connections/discord-card\";\nimport { WhatsAppCard } from \"@/components/connections/whatsapp-card\";\nimport { DestinationSelector } from \"@/components/connections/destination-selector\";\nimport { WizardStepFrame } from \"./wizard-step-frame\";\n\ninterface MessagingStepProps {\n onNext: () => void;\n onBack?: () => void;\n}\n\nexport function MessagingStep({ onNext, onBack }: MessagingStepProps) {\n return (\n <WizardStepFrame\n title=\"Messaging Channels\"\n description=\"Connect the apps you use to communicate with your agent. You can set up any combination — configure only the ones you need.\"\n onNext={onNext}\n onBack={onBack}\n skipLabel=\"Skip\"\n maxWidth=\"max-w-2xl\"\n >\n <div className=\"space-y-4\">\n <SlackCard />\n <TelegramCard />\n <DiscordCard />\n <WhatsAppCard />\n <DestinationSelector />\n </div>\n </WizardStepFrame>\n );\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState, useCallback, useMemo } from \"react\";\nimport {\n DEFAULT_AGENT_DISPLAY_NAME,\n normalizeAgentDisplayName,\n} from \"@aitne/shared\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useChat, fetchSessionMessages } from \"@/lib/hooks/use-chat\";\nimport { useConfig } from \"@/lib/hooks/use-config\";\nimport { api, ApiError } from \"@/lib/api-client\";\nimport { MessageBubble } from \"@/components/chat/message-bubble\";\nimport { ToolProgress } from \"@/components/chat/tool-progress\";\nimport { ChatInput } from \"@/components/chat/chat-input\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport { Button } from \"@/components/ui/button\";\nimport { Alert } from \"@/components/ui/alert\";\nimport { Pencil, Save, ArrowLeft, Loader2 } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n CharacterEditor,\n isCharacterOverCap,\n} from \"@/components/settings/character-editor\";\nimport type { ChatMessage } from \"@/lib/hooks/use-chat\";\nimport type {\n MigrationErrorBody,\n MigrationOkResponse,\n} from \"@/lib/api-types\";\nimport {\n readWizardState,\n writeWizardState,\n clearWizardState,\n} from \"@/lib/setup-storage\";\nimport {\n buildVaultMigrationBody,\n decideVaultMigration,\n type VaultMode,\n} from \"./vault-step.logic\";\n\n// ── Types ──\n\ninterface ConversationStepProps {\n mode: \"initial\" | \"update\";\n agentDisplayName?: string;\n onComplete: () => void;\n /**\n * SETUP-FLOW-REDESIGN-PLAN §5.8 — Back button shown above the agent\n * conversation. The legacy Phase 1 (tool selections) is gone, so the\n * step mounts directly into the chat panel.\n */\n onBack?: () => void;\n /**\n * SETUP-FLOW-REDESIGN-PLAN §5.2 — the user's pending vault choice from\n * the Vault step. Holding these here (rather than committing on the\n * vault step) lets the user Back-navigate freely; the actual\n * `/setup/migrate-context` runs on mount of this step so files only\n * appear at the chosen path once setup is essentially done. Omitted in\n * `update` mode (no vault decision is being made).\n */\n pendingVaultMode?: VaultMode;\n pendingVaultPath?: string;\n}\n\n// ── Helpers ──\n\nfunction extractRulesBlock(content: string): string | null {\n const match = content.match(/```management-rules\\n([\\s\\S]*?)```/);\n return match ? match[1].trim() : null;\n}\n\nfunction extractCharacterBlock(content: string): string | null {\n const match = content.match(/```character\\n([\\s\\S]*?)```/);\n return match ? match[1].trim() : null;\n}\n\n// Staged code blocks are rendered in the preview cards below. Replace them in\n// the chat bubble so the same content isn't shown twice.\nfunction stripStagedBlocksForDisplay(content: string): string {\n return content\n .replace(/```management-rules\\n[\\s\\S]*?```/g, \"_(management rules preview shown below ↓)_\")\n .replace(/```character\\n[\\s\\S]*?```/g, \"_(character preview shown below ↓)_\")\n .trim();\n}\n\nfunction extractChoices(content: string): string[] {\n const choices: string[] = [];\n for (const line of content.split(\"\\n\")) {\n const match = line.match(/^- \\*\\*(.+?)\\*\\*/);\n if (match) choices.push(match[1]);\n }\n return choices.length >= 2 && choices.length <= 8 ? choices : [];\n}\n\n// ── Component ──\n\nexport function ConversationStep({\n mode,\n agentDisplayName,\n onComplete,\n onBack,\n pendingVaultMode,\n pendingVaultPath,\n}: ConversationStepProps) {\n const { data: config } = useConfig();\n\n // SETUP-FLOW-REDESIGN-PLAN §5.8 — the legacy two-phase split is\n // gone; the step mounts directly into the chat panel. Persisted\n // wizard state (sessionStorage) still tracks `setupSessionId` for\n // reload-survival, but `phase` and `selections` are no longer\n // written or consumed here.\n\n // ── Chat state ──\n const {\n messages,\n restoredMessages,\n setRestoredMessages,\n streaming,\n toolProgress,\n sessionInfo,\n sendMessage,\n } = useChat({ disableHistory: true });\n const displayMessages = useMemo(\n () => [...restoredMessages, ...messages],\n [restoredMessages, messages],\n );\n const queryClient = useQueryClient();\n const scrollRef = useRef<HTMLDivElement>(null);\n const startedRef = useRef(false);\n // Synchronous in-flight latch for the vault migration. State-based\n // checks (`if (migrating) return;`) don't dedupe under React 18\n // StrictMode (the dev double-invoke sees the same pre-setState value\n // and both invocations pass the gate). A ref flips synchronously on\n // the first run and blocks the second.\n const migrationInFlightRef = useRef(false);\n\n const [rulesContent, setRulesContent] = useState<string | null>(null);\n const [editing, setEditing] = useState(false);\n const [editBuffer, setEditBuffer] = useState(\"\");\n const [saving, setSaving] = useState(false);\n const [waitingForReply, setWaitingForReply] = useState(false);\n const [startError, setStartError] = useState<string | null>(null);\n const [saveError, setSaveError] = useState<string | null>(null);\n const [startAttempt, setStartAttempt] = useState(0);\n\n // Mirror `streaming` into a ref so `handleSave` can poll its current value\n // without re-binding the callback on every chunk. Used by the bounded\n // drain-wait below — the user clicks Save while silent profile writes\n // may still be in flight, and we want to give them a brief chance to\n // land before /setup/save-rules deletes the live agent session.\n const streamingRef = useRef(streaming);\n useEffect(() => {\n streamingRef.current = streaming;\n }, [streaming]);\n\n // SETUP-FLOW-REDESIGN-PLAN §5.2 — vault migration runs HERE (not on\n // the Vault step), so the user's chosen folder stays untouched until\n // they commit by reaching this final step. `migrationReady` gates the\n // `/setup/start` effect below; in update mode (no vault decision) it\n // is true from the first render. `migrationAttempt` lets the user\n // retry after a transient failure (e.g. iCloud eviction) without\n // forcing them to back-nav.\n const [migrationReady, setMigrationReady] = useState<boolean>(\n mode === \"update\",\n );\n const [migrating, setMigrating] = useState<boolean>(false);\n const [migrationError, setMigrationError] = useState<\n MigrationErrorBody | null\n >(null);\n const [migrationAttempt, setMigrationAttempt] = useState(0);\n // Character is staged via a ```character``` code block from the agent. The\n // draft is what the user sees in the inline editor — seeded from the agent's\n // block, manually editable, committed to /api/config on Save & Finish.\n // `characterInitialized` tracks whether we've seeded the draft from either\n // the agent block or the current config, so user edits don't get clobbered\n // by a later block the agent emits during revisions.\n const [characterDraft, setCharacterDraft] = useState<string>(\"\");\n const [characterInitialized, setCharacterInitialized] = useState(false);\n const [characterUserEdited, setCharacterUserEdited] = useState(false);\n const effectiveAgentDisplayName =\n mode === \"initial\"\n ? normalizeAgentDisplayName(agentDisplayName)\n : config?.agentDisplayName ?? DEFAULT_AGENT_DISPLAY_NAME;\n\n // Reset waitingForReply on new assistant / error message\n useEffect(() => {\n if (displayMessages.length === 0) return;\n const lastMsg = displayMessages[displayMessages.length - 1];\n if (lastMsg.role === \"assistant\" || lastMsg.role === \"error\") {\n setWaitingForReply(false);\n }\n }, [displayMessages]);\n\n // Safety timeout\n useEffect(() => {\n if (!waitingForReply) return;\n const timer = setTimeout(() => setWaitingForReply(false), 120_000);\n return () => clearTimeout(timer);\n }, [waitingForReply]);\n\n const isProcessing = waitingForReply || streaming;\n\n // Auto-scroll\n useEffect(() => {\n const el = scrollRef.current;\n if (el) el.scrollTop = el.scrollHeight;\n }, [displayMessages.length, toolProgress]);\n\n // SETUP-FLOW-REDESIGN-PLAN §5.2 — commit the user's vault choice now,\n // not earlier. The Vault step writes its picks into wizard state; this\n // effect calls `/setup/migrate-context` only when the daemon's current\n // config differs from those picks, then flips `migrationReady` so the\n // `/setup/start` effect below can run. A failed migration leaves\n // `migrationReady` false; the user sees a Retry / Back path instead of\n // a half-bound chat session.\n //\n // Known limitation: if the user reaches rules once (a dashboard_chat\n // session was created by `/setup/start`), back-navigates to Vault,\n // changes the path, then forwards back to rules, the daemon's\n // active-session guard inside `/setup/migrate-context` will respond\n // with 409 `sessions_active`. We surface the daemon's message via the\n // error UI; the user must close the tab to drop the session and\n // restart, or the daemon must restart (which sweeps stale chat\n // sessions). Resolving this cleanly would require a `/setup/abandon`\n // endpoint and is out of scope for the deferred-migration change.\n useEffect(() => {\n if (mode !== \"initial\") return;\n if (migrationReady) return;\n if (migrationInFlightRef.current) return;\n // Sticky-error guard: once a migration attempt errors, the effect\n // would otherwise re-fire (because `migrating` just flipped false)\n // and hammer the daemon in a loop. The user must click Retry, which\n // clears `migrationError` and increments `migrationAttempt`.\n if (migrationError) return;\n if (!config) return;\n\n const decision = decideVaultMigration({\n pendingMode: pendingVaultMode ?? \"plain\",\n pendingPath: pendingVaultPath ?? \"\",\n currentMode: config.vaultMode === \"obsidian\" ? \"obsidian\" : \"plain\",\n currentPath: config.primaryVaultPath ?? null,\n });\n\n if (decision.kind === \"no_migration_needed\") {\n setMigrationReady(true);\n return;\n }\n\n // Latch BEFORE any setState so a StrictMode double-invoke or rapid\n // dep re-fire is dropped at the synchronous gate above.\n migrationInFlightRef.current = true;\n setMigrating(true);\n setMigrationError(null);\n api\n .post<MigrationOkResponse>(\n \"/setup/migrate-context\",\n buildVaultMigrationBody({\n vaultMode: decision.mode,\n primaryVaultPath: decision.path,\n }),\n )\n .then(async () => {\n await queryClient.invalidateQueries({ queryKey: [\"config\"] });\n await queryClient.invalidateQueries({ queryKey: [\"health\"] });\n setMigrationReady(true);\n })\n .catch((err) => {\n if (err instanceof ApiError) {\n setMigrationError((err.body ?? {}) as MigrationErrorBody);\n } else {\n setMigrationError({\n error: \"internal_error\",\n message:\n err instanceof Error ? err.message : \"Unexpected error.\",\n });\n }\n })\n .finally(() => {\n migrationInFlightRef.current = false;\n setMigrating(false);\n });\n }, [\n mode,\n migrationReady,\n migrationError,\n config,\n pendingVaultMode,\n pendingVaultPath,\n queryClient,\n migrationAttempt,\n ]);\n\n // Start agent conversation when entering phase 2.\n //\n // Resume path: if a previous run persisted a `setupSessionId` AND the SSE\n // server bound the same id (it auto-adopts the still-`active`\n // dashboard_chat session via `findActiveDashboardSessionId`), skip\n // /setup/start and just refetch history. The daemon-startup sweep in\n // `index.ts` closes leftover dashboard_chat sessions on restart, so a\n // mismatched `sessionInfo.sessionId` after restart correctly falls\n // through to a fresh /setup/start instead of resuming a stale agent\n // state with no `currentSetupMode` server-side.\n useEffect(() => {\n if (startedRef.current || !sessionInfo?.channelId) return;\n // SETUP-FLOW-REDESIGN-PLAN §5.2 — block until vault migration\n // commits. In update mode `migrationReady` is true from the first\n // render so this is a no-op.\n if (!migrationReady) return;\n\n // Resume only when the persisted session id was created under THIS\n // mode — otherwise an `initial` setupSessionId left in storage from\n // an abandoned run would wrongly skip the fresh /setup/start the\n // current `update` flow needs.\n const persistedNow = readWizardState();\n const modeMatches = persistedNow.setupSessionMode === mode;\n const resumedSessionId =\n modeMatches\n && typeof persistedNow.setupSessionId === \"number\"\n && persistedNow.setupSessionId > 0\n && sessionInfo.sessionId === persistedNow.setupSessionId\n ? persistedNow.setupSessionId\n : null;\n\n if (resumedSessionId !== null) {\n startedRef.current = true;\n fetchSessionMessages(resumedSessionId)\n .then((restored) => {\n setRestoredMessages(restored);\n })\n .catch((err) => {\n // History fetch failed — the conversation is still resumable\n // through the live SSE stream, so don't surface a fatal error.\n console.warn(\"[setup] failed to refetch resumed session history\", err);\n });\n return;\n }\n\n startedRef.current = true;\n setStartError(null);\n setWaitingForReply(true);\n\n // SETUP-FLOW-REDESIGN-PLAN §5.8 — `/setup/start` no longer takes\n // `selections`. The agent derives the Source-of-Truth table from\n // the integrations registry (steps 4–6 already configured those)\n // and asks the user only about rows it could not infer.\n api\n .post(\"/setup/start\", {\n channelId: sessionInfo.channelId,\n mode,\n ...(mode === \"initial\"\n ? { agentDisplayName: effectiveAgentDisplayName }\n : {}),\n })\n .catch((err) => {\n startedRef.current = false;\n const msg = err instanceof Error ? err.message : \"Failed to start setup\";\n setStartError(msg);\n setWaitingForReply(false);\n });\n }, [\n sessionInfo?.channelId,\n sessionInfo?.sessionId,\n mode,\n effectiveAgentDisplayName,\n startAttempt,\n migrationReady,\n setRestoredMessages,\n ]);\n\n // Persist the in-flight setup session id once the dispatcher binds it.\n // On reload the resume effect above can verify it against the SSE-\n // adopted session and skip /setup/start. Tagging with the current\n // mode lets the resume effect reject a match that came from a\n // different mode's abandoned run.\n useEffect(() => {\n if (typeof sessionInfo?.sessionId !== \"number\") return;\n writeWizardState({\n setupSessionId: sessionInfo.sessionId,\n setupSessionMode: mode,\n });\n }, [mode, sessionInfo?.sessionId]);\n\n // Detect rules + character blocks in assistant messages. Walks back\n // from the most recent message so a revision overrides an earlier\n // draft. Runs during streaming too: the regex requires a closing\n // fence so partial blocks never match. Without this, the preview\n // would only appear after the agent's silent curl writes to\n // user/profile.md (+ optional user/*.md PATCHes) finish — the SDK\n // fires `onEnd` only when the whole turn drains, which is many\n // seconds later than the rules block actually arriving.\n useEffect(() => {\n for (let i = displayMessages.length - 1; i >= 0; i--) {\n const msg = displayMessages[i];\n if (msg.role !== \"assistant\") continue;\n const rules = extractRulesBlock(msg.content);\n if (rules) {\n setRulesContent(rules);\n if (!editing) setEditBuffer(rules);\n }\n const character = extractCharacterBlock(msg.content);\n if (character !== null && !characterUserEdited) {\n setCharacterDraft(character);\n setCharacterInitialized(true);\n }\n if (rules || character !== null) break;\n }\n }, [displayMessages, editing, characterUserEdited]);\n\n // Seed the character draft from /api/config the first time the rules\n // preview appears, so the editor is never empty for an update-mode run\n // where the agent didn't emit a ```character``` block. Only runs once —\n // later agent revisions re-seed via the block-detector above, and explicit\n // user edits flip `characterUserEdited` which both branches respect.\n useEffect(() => {\n if (!rulesContent || characterInitialized) return;\n setCharacterDraft(config?.character ?? \"\");\n setCharacterInitialized(true);\n }, [rulesContent, characterInitialized, config?.character]);\n\n const handleSave = useCallback(async () => {\n const content = editing ? editBuffer : rulesContent;\n if (!content) return;\n const trimmedCharacter = characterDraft.trim();\n if (isCharacterOverCap(trimmedCharacter)) {\n setSaveError(\"Character exceeds the 1000-character cap.\");\n return;\n }\n setSaving(true);\n setSaveError(null);\n try {\n // The agent's silent curl writes (user/profile.md + optional\n // user/*.md PATCHes) follow the staged blocks in the same turn.\n // /setup/save-rules deletes the live agent session, which would\n // cut those writes off. Wait briefly for the stream to drain so\n // the writes land in the common case — but bound it so a hung\n // agent can never trap the user on a disabled-equivalent Save.\n // On timeout we proceed anyway; the skeleton seeder writes a\n // default user/profile.md and the user can flesh it out later.\n const DRAIN_TIMEOUT_MS = 15_000;\n const drainDeadline = Date.now() + DRAIN_TIMEOUT_MS;\n while (streamingRef.current && Date.now() < drainDeadline) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n // PATCH character first. If this fails, rules haven't been saved yet,\n // so the user can retry cleanly without the wizard advancing on half\n // a write. We only fire the PATCH when the draft actually differs from\n // the current config — avoids an inert write-lock row for no-op edits.\n const currentCharacter = config?.character ?? \"\";\n if (characterInitialized && trimmedCharacter !== currentCharacter) {\n await api.patch(\"/config\", { character: trimmedCharacter });\n }\n await api.post(\"/setup/save-rules\", {\n content,\n ...(mode === \"initial\"\n ? { agentDisplayName: effectiveAgentDisplayName }\n : {}),\n ...(typeof sessionInfo?.sessionId === \"number\"\n ? { sessionId: sessionInfo.sessionId }\n : {}),\n });\n // Optimistically set cache so Overview doesn't redirect back to /setup\n // (invalidateQueries only marks stale — the old needsSetup:true would be\n // returned immediately on next mount, triggering a redirect loop)\n queryClient.setQueryData([\"setup-status\"], {\n needsSetup: false,\n completedAt: new Date().toISOString(),\n });\n queryClient.invalidateQueries({ queryKey: [\"config\"] });\n queryClient.invalidateQueries({ queryKey: [\"health\"] });\n // Setup is committed — drop all persisted wizard state so a future\n // re-entry (re-setup or update mode) starts clean instead of\n // restoring stale step / selections / setupSessionId.\n clearWizardState();\n onComplete();\n } catch (err) {\n setSaveError(err instanceof Error ? err.message : \"Failed to save rules\");\n } finally {\n setSaving(false);\n }\n }, [\n editing,\n editBuffer,\n rulesContent,\n characterDraft,\n characterInitialized,\n config?.character,\n queryClient,\n onComplete,\n mode,\n effectiveAgentDisplayName,\n sessionInfo?.sessionId,\n ]);\n\n const handleChoiceClick = useCallback(\n (choice: string) => {\n sendMessage(choice);\n setWaitingForReply(true);\n },\n [sendMessage],\n );\n\n const handleSendMessage = useCallback(\n (content: string) => {\n sendMessage(content);\n setWaitingForReply(true);\n },\n [sendMessage],\n );\n\n const lastAssistantMsg = [...displayMessages].reverse().find((m) => m.role === \"assistant\");\n const choices = lastAssistantMsg && !isProcessing ? extractChoices(lastAssistantMsg.content) : [];\n\n // SETUP-FLOW-REDESIGN-PLAN §5.8 — Phase 1 (tool selections) is removed.\n // The Source-of-Truth table is derived inside the agent conversation\n // from the integrations registry; the wizard mounts directly into the\n // chat panel.\n\n // ══════════════════════════════════════════\n // Phase 2: Agent Conversation (Claude Code)\n // ══════════════════════════════════════════\n return (\n <div className=\"mx-auto flex h-full w-full max-w-4xl flex-col\">\n <div className=\"space-y-1 px-4 pt-4 text-center\">\n <h2 className=\"text-xl font-semibold\">\n {mode === \"initial\" ? \"Customize Your Rules\" : \"Update Management Rules\"}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {mode === \"initial\"\n ? \"Answer a few more questions and the agent will generate your management rules.\"\n : \"Review the current rules and let us know what you'd like to change.\"}\n </p>\n </div>\n\n {migrating && (\n <Alert className=\"mx-4 mt-4 rounded-lg px-4 py-3 text-sm\">\n <div className=\"flex items-center gap-3\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n <span>Setting up your vault…</span>\n </div>\n </Alert>\n )}\n\n {migrationError && !migrating && (\n <Alert variant=\"error\" className=\"mx-4 mt-4 rounded-lg px-4 py-3 text-sm\">\n <div className=\"flex items-start justify-between gap-3 w-full\">\n <div>\n <p className=\"font-medium\">Could not set up your vault</p>\n <p className=\"mt-0.5\">{migrationError.message}</p>\n </div>\n <div className=\"flex shrink-0 gap-2\">\n {onBack && (\n <Button size=\"sm\" variant=\"ghost\" onClick={onBack}>\n Back\n </Button>\n )}\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => {\n setMigrationError(null);\n setMigrationAttempt((prev) => prev + 1);\n }}\n >\n Retry\n </Button>\n </div>\n </div>\n </Alert>\n )}\n\n {startError && (\n <Alert variant=\"error\" className=\"mx-4 mt-4 rounded-lg px-4 py-3 text-sm\">\n <div className=\"flex items-center justify-between gap-3 w-full\">\n <span>{startError}</span>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setStartAttempt((prev) => prev + 1)}\n >\n Retry\n </Button>\n </div>\n </Alert>\n )}\n\n <ScrollArea ref={scrollRef} className=\"flex-1 px-4 py-4\">\n <div className=\"space-y-4\">\n {displayMessages.map((msg: ChatMessage) => (\n <MessageBubble\n key={msg.id}\n message={\n msg.role === \"assistant\"\n ? { ...msg, content: stripStagedBlocksForDisplay(msg.content) }\n : msg\n }\n assistantLabel={effectiveAgentDisplayName}\n />\n ))}\n <ToolProgress items={toolProgress} />\n {isProcessing && (\n <div className=\"flex justify-start\">\n <span className=\"inline-block h-5 w-1 animate-pulse rounded-full bg-foreground\" />\n </div>\n )}\n {displayMessages.length === 0\n && !isProcessing\n && !startError\n && !migrating\n && !migrationError && (\n <div className=\"flex flex-col items-center justify-center py-16 text-muted-foreground\">\n <p className=\"text-sm\">Preparing setup...</p>\n </div>\n )}\n </div>\n </ScrollArea>\n\n {choices.length > 0 && !rulesContent && (\n <div className=\"flex flex-wrap gap-2 border-t border-border bg-muted/30 px-4 py-3\">\n {choices.map((choice) => (\n <Button\n key={choice}\n size=\"sm\"\n variant=\"outline\"\n onClick={() => handleChoiceClick(choice)}\n disabled={isProcessing}\n className=\"text-xs\"\n >\n {choice}\n </Button>\n ))}\n </div>\n )}\n\n {rulesContent && (\n <div className=\"border-t border-border bg-muted/30 px-4 py-4 space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-sm font-medium\">Management Rules Preview</h3>\n <div className=\"flex items-center gap-2\">\n {isProcessing && !saving && (\n // Informational hint while the agent's silent user/profile +\n // user/*.md writes finish. Save is enabled — clicking it\n // briefly waits for the stream to drain so those writes\n // land, then proceeds (bounded; see DRAIN_TIMEOUT_MS in\n // handleSave) so a hung agent never traps the user.\n <span className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n <Loader2 className=\"h-3 w-3 animate-spin\" />\n Finalizing your profile…\n </span>\n )}\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={() => {\n if (editing) setEditBuffer(rulesContent);\n setEditing(!editing);\n }}\n className=\"gap-1 text-xs\"\n >\n <Pencil className=\"h-3 w-3\" />\n {editing ? \"Cancel\" : \"Edit\"}\n </Button>\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={saving || isCharacterOverCap(characterDraft)}\n className=\"gap-1\"\n >\n {saving ? (\n \"Saving...\"\n ) : (\n <>\n <Save className=\"h-3.5 w-3.5\" />\n Save & Finish\n </>\n )}\n </Button>\n </div>\n </div>\n\n {saveError && <Alert variant=\"error\">{saveError}</Alert>}\n\n {editing ? (\n <textarea\n value={editBuffer}\n onChange={(e) => setEditBuffer(e.target.value)}\n className=\"w-full rounded-md border border-input bg-background p-3 font-mono text-xs leading-relaxed focus:outline-none focus:ring-2 focus:ring-ring\"\n rows={16}\n />\n ) : (\n <pre className=\"max-h-96 overflow-auto rounded-md border border-border bg-background p-3 text-xs leading-relaxed\">\n {rulesContent}\n </pre>\n )}\n\n <div className=\"space-y-2 border-t border-border/60 pt-4\">\n <div>\n <h3 className=\"text-sm font-medium\">Character</h3>\n <p className=\"text-xs text-muted-foreground\">\n How the agent should talk to you — tone, language, formality.\n Applies across every session and backend. Leave blank to skip.\n </p>\n </div>\n <CharacterEditor\n value={characterDraft}\n onChange={(next) => {\n setCharacterDraft(next);\n setCharacterUserEdited(true);\n if (!characterInitialized) setCharacterInitialized(true);\n }}\n disabled={saving}\n rows={4}\n />\n </div>\n </div>\n )}\n\n {!saving && (\n <ChatInput\n onSend={handleSendMessage}\n disabled={isProcessing || displayMessages.length === 0}\n />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useRouter } from \"next/navigation\";\nimport { CheckCircle2, ArrowRight, FileText } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\n\ninterface SetupCompleteProps {\n mode: \"initial\" | \"update\";\n agentDisplayName: string;\n}\n\nexport function SetupComplete({ mode, agentDisplayName }: SetupCompleteProps) {\n const router = useRouter();\n\n return (\n <div className=\"flex flex-col items-center justify-center gap-8 py-16 text-center\">\n <div className=\"rounded-full bg-emerald-100 p-6 dark:bg-emerald-950\">\n <CheckCircle2 className=\"h-12 w-12 text-emerald-600 dark:text-emerald-400\" />\n </div>\n\n <div className=\"max-w-md space-y-3\">\n <h1 className=\"text-2xl font-bold text-foreground\">\n {mode === \"initial\" ? \"Setup Complete\" : \"Rules Updated\"}\n </h1>\n <p className=\"text-muted-foreground\">\n {mode === \"initial\"\n ? `${agentDisplayName} is ready to manage your schedule and tasks.`\n : \"Management Rules have been updated. Changes take effect immediately.\"}\n </p>\n </div>\n\n <div className=\"flex gap-3\">\n <Button\n variant=\"outline\"\n onClick={() => router.push(\"/memory\")}\n className=\"gap-2\"\n >\n <FileText className=\"h-4 w-4\" />\n View Management Rules\n </Button>\n <Button\n onClick={() => router.push(\"/\")}\n className=\"gap-2\"\n >\n Go to Overview\n <ArrowRight className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n","import createLucideIcon from '../createLucideIcon';\n\n/**\n * @component @name SkipForward\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cG9seWdvbiBwb2ludHM9IjUgNCAxNSAxMiA1IDIwIDUgNCIgLz4KICA8bGluZSB4MT0iMTkiIHgyPSIxOSIgeTE9IjUiIHkyPSIxOSIgLz4KPC9zdmc+Cg==) - https://lucide.dev/icons/skip-forward\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst SkipForward = createLucideIcon('SkipForward', [\n ['polygon', { points: '5 4 15 12 5 20 5 4', key: '16p6eg' }],\n ['line', { x1: '19', x2: '19', y1: '5', y2: '19', key: 'futhcm' }],\n]);\n\nexport default SkipForward;\n","/**\n * SETUP-FLOW-REDESIGN-PLAN §5.1 — pure decision logic for the Basics\n * step. Tests live in the `.test.ts` sibling. The component is a thin\n * shell around these helpers.\n *\n * Replaces the former Welcome step + the language portion of the old\n * Vault step. Two atomic fields persisted on Continue:\n *\n * - `agentDisplayName` — trim, length 1–40, no leading/trailing\n * whitespace.\n * - `language` — BCP-47 tag (e.g. `en-US`, `zh-Hans`); validated\n * against the same regex used by the legacy vault-step logic so\n * dashboards that already saved a custom tag round-trip cleanly.\n */\n\nexport const LANGUAGE_TAG_RE = /^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})?$/;\n\n/** UI-visible upper bound — keeps Slack/WhatsApp prefixes readable. */\nexport const AGENT_DISPLAY_NAME_MAX_LENGTH = 40;\n\nexport interface BasicsStepFields {\n agentDisplayName: string;\n language: string;\n /** Optional second-input value for the \"Other (BCP-47…)\" custom case. */\n customLanguage?: string;\n}\n\nexport const SUPPORTED_LANGUAGES: ReadonlyArray<{\n tag: string;\n label: string;\n}> = [\n { tag: \"en\", label: \"English\" },\n { tag: \"ja\", label: \"日本語 (Japanese)\" },\n { tag: \"zh\", label: \"中文 (Chinese)\" },\n { tag: \"es\", label: \"Español (Spanish)\" },\n { tag: \"fr\", label: \"Français (French)\" },\n { tag: \"de\", label: \"Deutsch (German)\" },\n { tag: \"pt\", label: \"Português (Portuguese)\" },\n { tag: \"ko\", label: \"한국어 (Korean)\" },\n { tag: \"__custom__\", label: \"Other (enter BCP-47 tag…)\" },\n];\n\nconst SUPPORTED_TAG_SET: ReadonlySet<string> = new Set(\n SUPPORTED_LANGUAGES.filter((l) => l.tag !== \"__custom__\").map((l) => l.tag),\n);\n\n/**\n * Resolve the language tag the form will POST. Mirrors the legacy\n * vault-step helper — `__custom__` falls through to the user-entered\n * BCP-47 tag, anything else is the dropdown value verbatim.\n */\nexport function resolveLanguage(\n primarySelection: string,\n customRaw: string,\n): string {\n return primarySelection === \"__custom__\"\n ? customRaw.trim()\n : primarySelection;\n}\n\nexport function isCustomLanguageInvalid(\n primarySelection: string,\n customRaw: string,\n): boolean {\n if (primarySelection !== \"__custom__\") return false;\n const trimmed = customRaw.trim();\n if (trimmed.length === 0) return false;\n return !LANGUAGE_TAG_RE.test(trimmed);\n}\n\n/**\n * True when the form is ready to POST. Blocks while a save is in flight\n * and when either field fails validation.\n */\nexport function canContinue(input: {\n agentDisplayName: string;\n resolvedLanguage: string;\n saving: boolean;\n}): boolean {\n if (input.saving) return false;\n const trimmed = input.agentDisplayName.trim();\n if (trimmed.length === 0) return false;\n if (trimmed.length > AGENT_DISPLAY_NAME_MAX_LENGTH) return false;\n if (input.resolvedLanguage.length === 0) return false;\n if (!LANGUAGE_TAG_RE.test(input.resolvedLanguage)) return false;\n return true;\n}\n\n/**\n * Build the `PATCH /api/config` body. Fields are emitted only when\n * non-empty so the API short-circuits no-op writes.\n */\nexport interface BasicsPatchBody {\n agentDisplayName: string;\n primaryLanguage: string;\n}\n\nexport function buildBasicsPatchBody(input: {\n agentDisplayName: string;\n resolvedLanguage: string;\n}): BasicsPatchBody {\n return {\n agentDisplayName: input.agentDisplayName.trim(),\n primaryLanguage: input.resolvedLanguage,\n };\n}\n\n/**\n * When hydrating from `config`, resolve a stored tag back into the\n * `(dropdown value, custom input)` pair the form expects. Unknown tags\n * land in `__custom__` so the user sees their previous choice intact.\n */\nexport function hydrateLanguageSelection(\n storedTag: string | null | undefined,\n): { primary: string; custom: string } {\n if (typeof storedTag !== \"string\" || storedTag.length === 0) {\n return { primary: \"en\", custom: \"\" };\n }\n if (SUPPORTED_TAG_SET.has(storedTag)) {\n return { primary: storedTag, custom: \"\" };\n }\n return { primary: \"__custom__\", custom: storedTag };\n}\n","\"use client\";\n\n/**\n * Wizard state persistence for `/setup`. Without this, a page reload mid-\n * setup drops the user back to `welcome` (initial mode) and a re-entry to\n * the conversation step calls `/setup/start` again, restarting the agent\n * conversation from scratch and forcing the user to redo every answer.\n *\n * Daemon-side: a startup sweep in `index.ts` closes any leftover active\n * `dashboard_chat` sessions, so a stored `setupSessionId` whose row was\n * orphaned by a daemon restart will fail the active-status check and the\n * conversation step falls through to a fresh start.\n *\n * Storage is `sessionStorage` so the state lives for the duration of the\n * tab — closing the tab discards it, which matches the user's mental\n * model of \"I left setup half-done in this tab.\"\n */\n\nimport type { IntegrationKey, IntegrationMode } from \"@aitne/shared\";\nimport type { SetupStep } from \"@/components/setup/wizard-steps.logic\";\n\nconst STORAGE_KEY = \"pa-setup-wizard-state\";\n\nexport interface PersistedWizardState {\n step?: SetupStep;\n agentDisplayName?: string;\n modeOverride?: \"plain\" | \"obsidian\" | null;\n /**\n * SETUP-FLOW-REDESIGN-PLAN §5.2 — the user's chosen primary-vault path,\n * persisted but NOT yet committed to the daemon. The actual\n * `/setup/migrate-context` call runs on entry to the Customize Rules\n * step (see `conversation-step.tsx`); deferring file creation lets the\n * user freely Back-navigate and re-pick the same directory without\n * the picker showing it as already populated.\n */\n pendingVaultPath?: string | null;\n integrationModeDraft?: Partial<Record<IntegrationKey, IntegrationMode>>;\n /**\n * Per-radio optionId pick for the Google-mode step (e.g.\n * `delegated:codex`, `direct`, `disabled`). Without this, a remount of\n * `GoogleModeStep` (Back navigation, reload while on the step) would\n * re-seed `defaultOptionId` and propagate the default through\n * `onDraftChange`, overwriting any prior user pick — and a subsequent\n * Continue would PATCH the daemon back to that default.\n */\n googleModeSelections?: Partial<Record<IntegrationKey, string>>;\n /** Same protection for the Notion single-radio step. */\n notionModeSelection?: string;\n /**\n * SETUP-FLOW-REDESIGN-PLAN §5.8 — the legacy `phase` / `selections`\n * fields are gone (Phase 1 tool selections were deleted). Kept as\n * loose-typed leftovers in this interface so a stale sessionStorage\n * entry from before the redesign deserializes cleanly via the\n * `readWizardState` JSON.parse path; new writers never set them.\n */\n phase?: \"selections\" | \"conversation\";\n selections?: {\n schedule: string | null;\n tasks: string | null;\n notes: string | null;\n projects: string | null;\n };\n /** DB id of the in-flight setup conversation. Written when /setup/start\n * resolves; checked on remount to decide between resume and fresh start. */\n setupSessionId?: number;\n /** Mode the persisted `setupSessionId` was created under. Resume must\n * reject a session id from a different mode (e.g. an initial-mode id\n * left in storage when the user later opens `?mode=update`) — a match\n * there would skip the fresh `/setup/start` the update flow needs. */\n setupSessionMode?: \"initial\" | \"update\";\n}\n\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\";\n}\n\nexport function readWizardState(): PersistedWizardState {\n if (!isBrowser()) return {};\n try {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\") return {};\n return parsed as PersistedWizardState;\n } catch {\n return {};\n }\n}\n\nexport function writeWizardState(patch: PersistedWizardState): void {\n if (!isBrowser()) return;\n try {\n const current = readWizardState();\n const merged = { ...current, ...patch };\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(merged));\n } catch {\n /* quota exceeded or sessionStorage disabled — ignore */\n }\n}\n\nexport function clearWizardState(): void {\n if (!isBrowser()) return;\n try {\n sessionStorage.removeItem(STORAGE_KEY);\n } catch {\n /* ignore */\n }\n}\n","/**\n * SETUP-FLOW-REDESIGN-PLAN §5.6 — Note step pure logic.\n *\n * The Note step writes to **two** systems:\n * 1. Notion — via `PATCH /api/integrations/notion`. Mode + (in direct\n * mode) API key + DB mappings, all owned by the existing\n * `IntegrationCard` + `NotionDirectSettingsBody` components.\n * 2. External Obsidian vault — `externalObsidianVaultPath` +\n * `externalObsidianWatch` via `PATCH /api/config`. Validation:\n * path must be absolute, must not overlap `dataDir`, must not\n * overlap the primary vault. The daemon's `validateExternalObsidianVaultPath`\n * is the source of truth; we mirror its prefix checks client-side\n * so the user gets an immediate signal without a round-trip.\n */\n\nimport {\n isClientAbsolutePath,\n isClientPathInsideOrEqual,\n} from \"@/lib/path-client\";\n\nexport interface NoteStepFields {\n externalObsidianVaultPath: string;\n externalObsidianWatch: boolean;\n}\n\nexport const DEFAULT_NOTE_STEP_FIELDS: NoteStepFields = {\n externalObsidianVaultPath: \"\",\n externalObsidianWatch: true,\n};\n\n/**\n * Pre-flight client-side path check. Mirrors the prefix rules in\n * `daemon/src/config.ts:validateExternalObsidianVaultPath` — the\n * daemon re-runs the full validation server-side, so this is just an\n * immediate-feedback layer.\n */\nexport type NotePathIssue =\n | \"empty\"\n | \"not_absolute\"\n | \"overlaps_data_dir\"\n | \"overlaps_primary_vault\";\n\nexport interface ValidateExternalVaultPathInput {\n path: string;\n dataDir: string;\n primaryVaultPath: string | null;\n}\n\nexport function validateExternalVaultPathClient(\n input: ValidateExternalVaultPathInput,\n): NotePathIssue | null {\n const trimmed = input.path.trim();\n if (trimmed.length === 0) return \"empty\";\n if (!isClientAbsolutePath(trimmed)) {\n return \"not_absolute\";\n }\n // Prefix-match against the data-dir; do a normalised strip so trailing\n // slashes don't confuse the check. The daemon does a stat-based realpath\n // resolution; here we approximate with raw prefix match. False\n // positives (a sibling that *starts with* dataDir) are rare and the\n // server re-runs the real validation.\n if (\n input.dataDir.length > 0\n && isClientPathInsideOrEqual(input.dataDir, trimmed)\n ) {\n return \"overlaps_data_dir\";\n }\n if (\n input.primaryVaultPath\n && isClientPathInsideOrEqual(input.primaryVaultPath, trimmed)\n ) {\n return \"overlaps_primary_vault\";\n }\n return null;\n}\n\n/** Human-readable inline error messages keyed off `NotePathIssue`. */\nexport function notePathIssueMessage(issue: NotePathIssue): string {\n switch (issue) {\n case \"empty\":\n return \"Pick a path or leave the field blank to skip.\";\n case \"not_absolute\":\n return \"Use an absolute path (for example `/Users/me/Vault`, `~/Vault`, or `C:\\\\Vault`).\";\n case \"overlaps_data_dir\":\n return \"Path overlaps the agent's data directory; choose a separate location.\";\n case \"overlaps_primary_vault\":\n return \"Path overlaps the agent's primary vault; choose a separate location.\";\n }\n}\n\n/**\n * Continue-button enablement. Empty path is **allowed** — the user is\n * skipping the external-vault opt-in; in that case the field is just\n * not persisted. A non-empty path with a validation issue blocks.\n */\nexport function canContinue(input: {\n pathIssue: NotePathIssue | null;\n saving: boolean;\n}): boolean {\n if (input.saving) return false;\n if (input.pathIssue === null) return true;\n // Empty is the implicit-skip path — allow.\n return input.pathIssue === \"empty\";\n}\n\n/**\n * Build the `PATCH /api/config` body for the Note step. Path is\n * trimmed; an empty path resolves to `null` so the daemon clears the\n * field (lets the user un-pair an Obsidian vault from the wizard).\n */\nexport interface NotePatchBody {\n externalObsidianVaultPath: string | null;\n externalObsidianWatch: boolean;\n}\n\nexport function buildNotePatchBody(\n fields: NoteStepFields,\n): NotePatchBody {\n const trimmed = fields.externalObsidianVaultPath.trim();\n return {\n externalObsidianVaultPath: trimmed.length === 0 ? null : trimmed,\n externalObsidianWatch: fields.externalObsidianWatch,\n };\n}\n","/**\n * SETUP-FLOW-REDESIGN-PLAN §6.5 — flow controller for the redesigned\n * setup wizard. The list collapses from 13 steps to 7 collection steps\n * + a terminal `complete`:\n *\n * 1. Basics (display name + language) — required\n * 2. Vault (mode + primary path inline) — required\n * 3. AI Backend (main backend selection) — required\n * 4. Mail (Gmail + Outlook + IMAP) — skippable\n * 5. Calendar (Google + Outlook) — skippable\n * 6. Note (Notion + external Obsidian vault) — skippable\n * 7. Messaging (Slack/Telegram/Discord/WhatsApp) — skippable\n * 8. Customize Rules (chat-driven; no tools form) — required\n * 9. Complete — terminal\n *\n * Repositories are not registered during setup — users add them\n * post-setup from Settings → Connections → Repositories. Conditional\n * sub-steps are gone: every former mode-then-credentials pair is now\n * inline inside the parent step, so `filterInitialSteps` collapses to\n * identity. The wizard list returned matches the `BASE_INITIAL_STEPS`\n * order; `app/setup/page.tsx` switches on the id to mount the right\n * component.\n */\n\nexport type SetupStep =\n | \"basics\"\n | \"vault\"\n | \"backend\"\n | \"mail\"\n | \"calendar\"\n | \"note\"\n | \"messaging\"\n | \"rules\"\n | \"complete\";\n\nexport const BASE_INITIAL_STEPS: readonly SetupStep[] = [\n \"basics\",\n \"vault\",\n \"backend\",\n \"mail\",\n \"calendar\",\n \"note\",\n \"messaging\",\n \"rules\",\n \"complete\",\n];\n\n/**\n * The required steps — the wizard cannot finish without each of these\n * having been visited at least once. (`complete` is the terminal screen\n * and is included in the set so the type system can read it as\n * required-by-existence.) Skip buttons are hidden on these steps; every\n * other step exposes Skip.\n */\nexport const REQUIRED_STEPS: ReadonlySet<SetupStep> = new Set<SetupStep>([\n \"basics\",\n \"vault\",\n \"backend\",\n \"rules\",\n \"complete\",\n]);\n\n/**\n * Human-readable labels for the stepper. Single source of truth so the\n * page header and the per-step `WizardStepFrame` titles cannot drift.\n */\nexport const STEP_LABELS: Record<SetupStep, string> = {\n basics: \"Basics\",\n vault: \"Vault\",\n backend: \"AI Backend\",\n mail: \"Mail\",\n calendar: \"Calendar\",\n note: \"Note\",\n messaging: \"Messaging\",\n rules: \"Rules\",\n complete: \"Done\",\n};\n\n/**\n * Derived vault mode for the wizard. `modeOverride` is non-null only\n * when the user explicitly toggled the choice in VaultStep; in that\n * case their click wins over whatever the daemon currently has\n * persisted. Otherwise we mirror `config.vaultMode`, defaulting to\n * \"plain\" when config is still loading (so the initial render does\n * not flicker the inline path field in and out).\n */\nexport function deriveVaultMode(\n modeOverride: \"plain\" | \"obsidian\" | null,\n configVaultMode: \"plain\" | \"obsidian\" | null | undefined,\n): \"plain\" | \"obsidian\" {\n if (modeOverride !== null) return modeOverride;\n return configVaultMode === \"obsidian\" ? \"obsidian\" : \"plain\";\n}\n\n/**\n * Identity in v1 — every former conditional sub-step (`google`,\n * `obsidian`, `notion`) is now an inline disclosure in its parent\n * step, so the list never shrinks from `BASE_INITIAL_STEPS`.\n *\n * Kept as a separate function so `app/setup/page.tsx` doesn't need a\n * conditional import path during the redesign cutover, and so future\n * conditional gating (e.g. enterprise-only steps) has an obvious home.\n */\nexport function filterInitialSteps(\n baseSteps: readonly SetupStep[] = BASE_INITIAL_STEPS,\n): SetupStep[] {\n return [...baseSteps];\n}\n\n/** True for steps the Skip button should render. */\nexport function isSkippable(step: SetupStep): boolean {\n return !REQUIRED_STEPS.has(step);\n}\n"],"names":["LANGUAGE_TAG_RE","AGENT_DISPLAY_NAME_MAX_LENGTH","SUPPORTED_LANGUAGES","tag","label","SUPPORTED_TAG_SET","map","Set","l","filter","primarySelection","resolveLanguage","trimmed","customRaw","trim","isCustomLanguageInvalid","input","length","test","canContinue","saving","agentDisplayName","resolvedLanguage","custom","has","buildBasicsPatchBody","primaryLanguage","primary","hydrateLanguageSelection","storedTag"],"mappings":"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","ignoreList":[12]}