agim-cli 1.2.134 → 1.2.135

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 (186) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/core/plan-intent.d.ts +14 -0
  3. package/dist/core/plan-intent.d.ts.map +1 -0
  4. package/dist/core/plan-intent.js +112 -0
  5. package/dist/core/plan-intent.js.map +1 -0
  6. package/dist/core/router.d.ts.map +1 -1
  7. package/dist/core/router.js +27 -1
  8. package/dist/core/router.js.map +1 -1
  9. package/dist/web/public/assets/{a2a-TmaKRhXV.js → a2a-oYRz4syc.js} +2 -2
  10. package/dist/web/public/assets/{a2a-TmaKRhXV.js.map → a2a-oYRz4syc.js.map} +1 -1
  11. package/dist/web/public/assets/{activity-Cckc7fGG.js → activity-CbMd52BC.js} +2 -2
  12. package/dist/web/public/assets/{activity-Cckc7fGG.js.map → activity-CbMd52BC.js.map} +1 -1
  13. package/dist/web/public/assets/{admins-1hMCDolP.js → admins-BtuJdXZX.js} +2 -2
  14. package/dist/web/public/assets/{admins-1hMCDolP.js.map → admins-BtuJdXZX.js.map} +1 -1
  15. package/dist/web/public/assets/{agents-3sUHlKzx.js → agents-Dm8fTAks.js} +2 -2
  16. package/dist/web/public/assets/{agents-3sUHlKzx.js.map → agents-Dm8fTAks.js.map} +1 -1
  17. package/dist/web/public/assets/{approvals-CY-_Lg4Y.js → approvals-Y7FCBVQR.js} +2 -2
  18. package/dist/web/public/assets/{approvals-CY-_Lg4Y.js.map → approvals-Y7FCBVQR.js.map} +1 -1
  19. package/dist/web/public/assets/{arrow-down-BkZ50IzL.js → arrow-down-BpfVJViL.js} +2 -2
  20. package/dist/web/public/assets/{arrow-down-BkZ50IzL.js.map → arrow-down-BpfVJViL.js.map} +1 -1
  21. package/dist/web/public/assets/{arrow-up-NWC5K6Jw.js → arrow-up-BQxFty9k.js} +2 -2
  22. package/dist/web/public/assets/{arrow-up-NWC5K6Jw.js.map → arrow-up-BQxFty9k.js.map} +1 -1
  23. package/dist/web/public/assets/{asks-VzAmpsEh.js → asks-CzeX-NCb.js} +2 -2
  24. package/dist/web/public/assets/{asks-VzAmpsEh.js.map → asks-CzeX-NCb.js.map} +1 -1
  25. package/dist/web/public/assets/{audit-fOn2LH4D.js → audit-DDonnB7I.js} +2 -2
  26. package/dist/web/public/assets/{audit-fOn2LH4D.js.map → audit-DDonnB7I.js.map} +1 -1
  27. package/dist/web/public/assets/{bell-FF7PJo1N.js → bell-QusEl0TB.js} +2 -2
  28. package/dist/web/public/assets/{bell-FF7PJo1N.js.map → bell-QusEl0TB.js.map} +1 -1
  29. package/dist/web/public/assets/{bgjobs-L0v-UwPW.js → bgjobs-BIx5fZe2.js} +2 -2
  30. package/dist/web/public/assets/{bgjobs-L0v-UwPW.js.map → bgjobs-BIx5fZe2.js.map} +1 -1
  31. package/dist/web/public/assets/{brain-CdkDpFr1.js → brain-CC9HwFtI.js} +2 -2
  32. package/dist/web/public/assets/{brain-CdkDpFr1.js.map → brain-CC9HwFtI.js.map} +1 -1
  33. package/dist/web/public/assets/{briefcase-BXbOdl7E.js → briefcase-DueOcW1K.js} +2 -2
  34. package/dist/web/public/assets/{briefcase-BXbOdl7E.js.map → briefcase-DueOcW1K.js.map} +1 -1
  35. package/dist/web/public/assets/{chat-BazMi-ik.js → chat-DahEFTcT.js} +2 -2
  36. package/dist/web/public/assets/{chat-BazMi-ik.js.map → chat-DahEFTcT.js.map} +1 -1
  37. package/dist/web/public/assets/{chevron-left-Di1Tz64J.js → chevron-left-CaGOVECz.js} +2 -2
  38. package/dist/web/public/assets/{chevron-left-Di1Tz64J.js.map → chevron-left-CaGOVECz.js.map} +1 -1
  39. package/dist/web/public/assets/{chevron-right-BLjhBkqs.js → chevron-right-BX3t8KY3.js} +2 -2
  40. package/dist/web/public/assets/{chevron-right-BLjhBkqs.js.map → chevron-right-BX3t8KY3.js.map} +1 -1
  41. package/dist/web/public/assets/{circle-check-BaxzYLlE.js → circle-check-BGjJhA0M.js} +2 -2
  42. package/dist/web/public/assets/{circle-check-BaxzYLlE.js.map → circle-check-BGjJhA0M.js.map} +1 -1
  43. package/dist/web/public/assets/{circle-check-big-C4BGLUvw.js → circle-check-big-CkxzVtPL.js} +2 -2
  44. package/dist/web/public/assets/{circle-check-big-C4BGLUvw.js.map → circle-check-big-CkxzVtPL.js.map} +1 -1
  45. package/dist/web/public/assets/{circle-x-THl-PO3_.js → circle-x-BziROBzb.js} +2 -2
  46. package/dist/web/public/assets/{circle-x-THl-PO3_.js.map → circle-x-BziROBzb.js.map} +1 -1
  47. package/dist/web/public/assets/{clock-iitpdQjZ.js → clock-80yAmtz6.js} +2 -2
  48. package/dist/web/public/assets/{clock-iitpdQjZ.js.map → clock-80yAmtz6.js.map} +1 -1
  49. package/dist/web/public/assets/{confirm-dialog-r9HgkIYf.js → confirm-dialog-DAfv5d0M.js} +2 -2
  50. package/dist/web/public/assets/{confirm-dialog-r9HgkIYf.js.map → confirm-dialog-DAfv5d0M.js.map} +1 -1
  51. package/dist/web/public/assets/{copy-DwyF4MOL.js → copy-CDQUdNjG.js} +2 -2
  52. package/dist/web/public/assets/{copy-DwyF4MOL.js.map → copy-CDQUdNjG.js.map} +1 -1
  53. package/dist/web/public/assets/{data-table-B80M8zdu.js → data-table-B_sUmaE2.js} +2 -2
  54. package/dist/web/public/assets/{data-table-B80M8zdu.js.map → data-table-B_sUmaE2.js.map} +1 -1
  55. package/dist/web/public/assets/{dialog-fGS0IXOo.js → dialog-DGdHPiTV.js} +2 -2
  56. package/dist/web/public/assets/{dialog-fGS0IXOo.js.map → dialog-DGdHPiTV.js.map} +1 -1
  57. package/dist/web/public/assets/{download-5ihiF2Gj.js → download-CTWGQ8nD.js} +2 -2
  58. package/dist/web/public/assets/{download-5ihiF2Gj.js.map → download-CTWGQ8nD.js.map} +1 -1
  59. package/dist/web/public/assets/{email-LmRMqLRU.js → email-D0CbEk1s.js} +2 -2
  60. package/dist/web/public/assets/{email-LmRMqLRU.js.map → email-D0CbEk1s.js.map} +1 -1
  61. package/dist/web/public/assets/{empty-state-CrPnUC6d.js → empty-state-CtWM3HCj.js} +2 -2
  62. package/dist/web/public/assets/{empty-state-CrPnUC6d.js.map → empty-state-CtWM3HCj.js.map} +1 -1
  63. package/dist/web/public/assets/{external-link-DIJK1MAH.js → external-link-eCDEU3zh.js} +2 -2
  64. package/dist/web/public/assets/{external-link-DIJK1MAH.js.map → external-link-eCDEU3zh.js.map} +1 -1
  65. package/dist/web/public/assets/{eye-DJJw0Ald.js → eye-BwZbiu9G.js} +2 -2
  66. package/dist/web/public/assets/{eye-DJJw0Ald.js.map → eye-BwZbiu9G.js.map} +1 -1
  67. package/dist/web/public/assets/{facts-BzImxpJD.js → facts-CilmUyo5.js} +2 -2
  68. package/dist/web/public/assets/{facts-BzImxpJD.js.map → facts-CilmUyo5.js.map} +1 -1
  69. package/dist/web/public/assets/{goals-C6p21B9N.js → goals-ClMqJOcZ.js} +2 -2
  70. package/dist/web/public/assets/{goals-C6p21B9N.js.map → goals-ClMqJOcZ.js.map} +1 -1
  71. package/dist/web/public/assets/{health-D-ugz2Gp.js → health-2Gc6vytU.js} +2 -2
  72. package/dist/web/public/assets/{health-D-ugz2Gp.js.map → health-2Gc6vytU.js.map} +1 -1
  73. package/dist/web/public/assets/{heart-pulse-DlZXcdL0.js → heart-pulse-f2ZP4fOw.js} +2 -2
  74. package/dist/web/public/assets/{heart-pulse-DlZXcdL0.js.map → heart-pulse-f2ZP4fOw.js.map} +1 -1
  75. package/dist/web/public/assets/{heartbeat-DSasg-3y.js → heartbeat-T5ecNv9f.js} +2 -2
  76. package/dist/web/public/assets/{heartbeat-DSasg-3y.js.map → heartbeat-T5ecNv9f.js.map} +1 -1
  77. package/dist/web/public/assets/{hot-D67pYtaV.js → hot-hTf3IoT7.js} +2 -2
  78. package/dist/web/public/assets/{hot-D67pYtaV.js.map → hot-hTf3IoT7.js.map} +1 -1
  79. package/dist/web/public/assets/{index-CqwhfPlr.js → index-D4Np2s3l.js} +23 -23
  80. package/dist/web/public/assets/{index-CqwhfPlr.js.map → index-D4Np2s3l.js.map} +1 -1
  81. package/dist/web/public/assets/{installed-CrIsSoQE.js → installed-3B4RqrKw.js} +2 -2
  82. package/dist/web/public/assets/{installed-CrIsSoQE.js.map → installed-3B4RqrKw.js.map} +1 -1
  83. package/dist/web/public/assets/{jobs-yAwphb1W.js → jobs-rdZMVduE.js} +2 -2
  84. package/dist/web/public/assets/{jobs-yAwphb1W.js.map → jobs-rdZMVduE.js.map} +1 -1
  85. package/dist/web/public/assets/{layout-cacmfseo.js → layout-CwEKQhrq.js} +2 -2
  86. package/dist/web/public/assets/{layout-cacmfseo.js.map → layout-CwEKQhrq.js.map} +1 -1
  87. package/dist/web/public/assets/{layout-BXZKGQAk.js → layout-DdSyLqXe.js} +2 -2
  88. package/dist/web/public/assets/{layout-BXZKGQAk.js.map → layout-DdSyLqXe.js.map} +1 -1
  89. package/dist/web/public/assets/{layout-awbFImGg.js → layout-DwNsrPtD.js} +2 -2
  90. package/dist/web/public/assets/{layout-awbFImGg.js.map → layout-DwNsrPtD.js.map} +1 -1
  91. package/dist/web/public/assets/{layout-CrtmlC8G.js → layout-cfySH7sc.js} +2 -2
  92. package/dist/web/public/assets/{layout-CrtmlC8G.js.map → layout-cfySH7sc.js.map} +1 -1
  93. package/dist/web/public/assets/{layout-CL5HFvHN.js → layout-ofBlvFCx.js} +2 -2
  94. package/dist/web/public/assets/{layout-CL5HFvHN.js.map → layout-ofBlvFCx.js.map} +1 -1
  95. package/dist/web/public/assets/{llm-C19AX6q2.js → llm-CBLl38AB.js} +2 -2
  96. package/dist/web/public/assets/{llm-C19AX6q2.js.map → llm-CBLl38AB.js.map} +1 -1
  97. package/dist/web/public/assets/{loader-circle-U-jPjmeD.js → loader-circle-BfXi9R6u.js} +2 -2
  98. package/dist/web/public/assets/{loader-circle-U-jPjmeD.js.map → loader-circle-BfXi9R6u.js.map} +1 -1
  99. package/dist/web/public/assets/{map-pin-4rE1NK87.js → map-pin-E83IWTEe.js} +2 -2
  100. package/dist/web/public/assets/{map-pin-4rE1NK87.js.map → map-pin-E83IWTEe.js.map} +1 -1
  101. package/dist/web/public/assets/{mcp-B94wc6Vi.js → mcp-B-NKHX-f.js} +2 -2
  102. package/dist/web/public/assets/{mcp-B94wc6Vi.js.map → mcp-B-NKHX-f.js.map} +1 -1
  103. package/dist/web/public/assets/{memos-CrG4zgfI.js → memos-CuY8Ai7a.js} +2 -2
  104. package/dist/web/public/assets/{memos-CrG4zgfI.js.map → memos-CuY8Ai7a.js.map} +1 -1
  105. package/dist/web/public/assets/{messengers-UWarJd_C.js → messengers-DGnu7I6n.js} +2 -2
  106. package/dist/web/public/assets/{messengers-UWarJd_C.js.map → messengers-DGnu7I6n.js.map} +1 -1
  107. package/dist/web/public/assets/{mobile-QhAUKqcJ.js → mobile-o-Aa_7VP.js} +2 -2
  108. package/dist/web/public/assets/{mobile-QhAUKqcJ.js.map → mobile-o-Aa_7VP.js.map} +1 -1
  109. package/dist/web/public/assets/native-agent-Ivct8avv.js +22 -0
  110. package/dist/web/public/assets/native-agent-Ivct8avv.js.map +1 -0
  111. package/dist/web/public/assets/{network-l6l5gLHO.js → network-B48dL6Y7.js} +2 -2
  112. package/dist/web/public/assets/{network-l6l5gLHO.js.map → network-B48dL6Y7.js.map} +1 -1
  113. package/dist/web/public/assets/{outbox-BenX_yUQ.js → outbox-CQutJNfH.js} +2 -2
  114. package/dist/web/public/assets/{outbox-BenX_yUQ.js.map → outbox-CQutJNfH.js.map} +1 -1
  115. package/dist/web/public/assets/{pagination-B4g1CBsi.js → pagination-rJwdesRS.js} +2 -2
  116. package/dist/web/public/assets/{pagination-B4g1CBsi.js.map → pagination-rJwdesRS.js.map} +1 -1
  117. package/dist/web/public/assets/{persona--3cjtl9q.js → persona-DJO6f_q5.js} +2 -2
  118. package/dist/web/public/assets/{persona--3cjtl9q.js.map → persona-DJO6f_q5.js.map} +1 -1
  119. package/dist/web/public/assets/{plans-DsHtDRlS.js → plans-D-Nf-jL2.js} +2 -2
  120. package/dist/web/public/assets/{plans-DsHtDRlS.js.map → plans-D-Nf-jL2.js.map} +1 -1
  121. package/dist/web/public/assets/{play-BG0hyTnO.js → play-DqmSNGi8.js} +2 -2
  122. package/dist/web/public/assets/{play-BG0hyTnO.js.map → play-DqmSNGi8.js.map} +1 -1
  123. package/dist/web/public/assets/{plus-Dof9AQvU.js → plus-CxClG9H0.js} +2 -2
  124. package/dist/web/public/assets/{plus-Dof9AQvU.js.map → plus-CxClG9H0.js.map} +1 -1
  125. package/dist/web/public/assets/{policy-BzHy4WbV.js → policy-Mqe38uiR.js} +2 -2
  126. package/dist/web/public/assets/{policy-BzHy4WbV.js.map → policy-Mqe38uiR.js.map} +1 -1
  127. package/dist/web/public/assets/{qr-code-yD_ztCf6.js → qr-code-BAEZ2Sel.js} +2 -2
  128. package/dist/web/public/assets/{qr-code-yD_ztCf6.js.map → qr-code-BAEZ2Sel.js.map} +1 -1
  129. package/dist/web/public/assets/{refresh-ccw-CBiHL1tY.js → refresh-ccw-C7VT3MFu.js} +2 -2
  130. package/dist/web/public/assets/{refresh-ccw-CBiHL1tY.js.map → refresh-ccw-C7VT3MFu.js.map} +1 -1
  131. package/dist/web/public/assets/{reminders-CDJlFR2Y.js → reminders--pCTIhTv.js} +2 -2
  132. package/dist/web/public/assets/{reminders-CDJlFR2Y.js.map → reminders--pCTIhTv.js.map} +1 -1
  133. package/dist/web/public/assets/{save-DVHI3V6o.js → save-B18KQmEd.js} +2 -2
  134. package/dist/web/public/assets/{save-DVHI3V6o.js.map → save-B18KQmEd.js.map} +1 -1
  135. package/dist/web/public/assets/{schedules-DYf64Fpr.js → schedules-CA4eHggo.js} +2 -2
  136. package/dist/web/public/assets/{schedules-DYf64Fpr.js.map → schedules-CA4eHggo.js.map} +1 -1
  137. package/dist/web/public/assets/{search-BYPDbBkC.js → search-CA_pO63g.js} +2 -2
  138. package/dist/web/public/assets/{search-BYPDbBkC.js.map → search-CA_pO63g.js.map} +1 -1
  139. package/dist/web/public/assets/{search-aw0y39Qs.js → search-ChcW6uXM.js} +2 -2
  140. package/dist/web/public/assets/{search-aw0y39Qs.js.map → search-ChcW6uXM.js.map} +1 -1
  141. package/dist/web/public/assets/{security-DhN1kRac.js → security-CeW9WxQO.js} +2 -2
  142. package/dist/web/public/assets/{security-DhN1kRac.js.map → security-CeW9WxQO.js.map} +1 -1
  143. package/dist/web/public/assets/{service-BhvI7Mb5.js → service-CJRR2q7Q.js} +2 -2
  144. package/dist/web/public/assets/{service-BhvI7Mb5.js.map → service-CJRR2q7Q.js.map} +1 -1
  145. package/dist/web/public/assets/{shield-alert-DjqqnTMk.js → shield-alert-0q3ul8GH.js} +2 -2
  146. package/dist/web/public/assets/{shield-alert-DjqqnTMk.js.map → shield-alert-0q3ul8GH.js.map} +1 -1
  147. package/dist/web/public/assets/{status-badge-nSFUUEfy.js → status-badge-CN17QMv6.js} +2 -2
  148. package/dist/web/public/assets/{status-badge-nSFUUEfy.js.map → status-badge-CN17QMv6.js.map} +1 -1
  149. package/dist/web/public/assets/{subtasks-C_x1RLJA.js → subtasks-gjO9Hf1a.js} +2 -2
  150. package/dist/web/public/assets/{subtasks-C_x1RLJA.js.map → subtasks-gjO9Hf1a.js.map} +1 -1
  151. package/dist/web/public/assets/{table-BNqo2xb8.js → table-C4P3KPbF.js} +2 -2
  152. package/dist/web/public/assets/{table-BNqo2xb8.js.map → table-C4P3KPbF.js.map} +1 -1
  153. package/dist/web/public/assets/{topn-NGtwNz38.js → topn-BMw-Uy1R.js} +2 -2
  154. package/dist/web/public/assets/{topn-NGtwNz38.js.map → topn-BMw-Uy1R.js.map} +1 -1
  155. package/dist/web/public/assets/{trash-2-BoFq2ZOF.js → trash-2-DOV8CHL9.js} +2 -2
  156. package/dist/web/public/assets/{trash-2-BoFq2ZOF.js.map → trash-2-DOV8CHL9.js.map} +1 -1
  157. package/dist/web/public/assets/{use-background-tasks-CY2gWPBZ.js → use-background-tasks-CgZBaDBR.js} +2 -2
  158. package/dist/web/public/assets/{use-background-tasks-CY2gWPBZ.js.map → use-background-tasks-CgZBaDBR.js.map} +1 -1
  159. package/dist/web/public/assets/{use-llm-admin-CA5tUbEU.js → use-llm-admin-BNwZKmJ9.js} +2 -2
  160. package/dist/web/public/assets/{use-llm-admin-CA5tUbEU.js.map → use-llm-admin-BNwZKmJ9.js.map} +1 -1
  161. package/dist/web/public/assets/{use-memory-CxasvYqR.js → use-memory-D4ViUoXw.js} +2 -2
  162. package/dist/web/public/assets/{use-memory-CxasvYqR.js.map → use-memory-D4ViUoXw.js.map} +1 -1
  163. package/dist/web/public/assets/{use-observability-BOepIjX5.js → use-observability-DJYRVPKp.js} +2 -2
  164. package/dist/web/public/assets/{use-observability-BOepIjX5.js.map → use-observability-DJYRVPKp.js.map} +1 -1
  165. package/dist/web/public/assets/{use-settings-DBXvAYm9.js → use-settings-XXVWFAv6.js} +2 -2
  166. package/dist/web/public/assets/{use-settings-DBXvAYm9.js.map → use-settings-XXVWFAv6.js.map} +1 -1
  167. package/dist/web/public/assets/{use-workspace-dw_69jpb.js → use-workspace-BgEM7e1m.js} +2 -2
  168. package/dist/web/public/assets/{use-workspace-dw_69jpb.js.map → use-workspace-BgEM7e1m.js.map} +1 -1
  169. package/dist/web/public/assets/{useQuery-Ds6-WURB.js → useQuery-B25CPtUF.js} +2 -2
  170. package/dist/web/public/assets/{useQuery-Ds6-WURB.js.map → useQuery-B25CPtUF.js.map} +1 -1
  171. package/dist/web/public/assets/{vector-C5WBAtlL.js → vector-Dh4Sp_ea.js} +2 -2
  172. package/dist/web/public/assets/{vector-C5WBAtlL.js.map → vector-Dh4Sp_ea.js.map} +1 -1
  173. package/dist/web/public/assets/{viewer-DQG9P7-t.js → viewer-B1vINzWu.js} +2 -2
  174. package/dist/web/public/assets/{viewer-DQG9P7-t.js.map → viewer-B1vINzWu.js.map} +1 -1
  175. package/dist/web/public/assets/{workspace-Dku83Qqr.js → workspace-uGVMiBxd.js} +2 -2
  176. package/dist/web/public/assets/{workspace-Dku83Qqr.js.map → workspace-uGVMiBxd.js.map} +1 -1
  177. package/dist/web/public/assets/{workspaces-ClLQ253x.js → workspaces-C8PjcrCq.js} +2 -2
  178. package/dist/web/public/assets/{workspaces-ClLQ253x.js.map → workspaces-C8PjcrCq.js.map} +1 -1
  179. package/dist/web/public/assets/{x-ClXUlQDe.js → x-CGfY-U_P.js} +2 -2
  180. package/dist/web/public/assets/{x-ClXUlQDe.js.map → x-CGfY-U_P.js.map} +1 -1
  181. package/dist/web/public/index.html +1 -1
  182. package/dist/web/server.js +3 -0
  183. package/dist/web/server.js.map +1 -1
  184. package/package.json +1 -1
  185. package/dist/web/public/assets/native-agent-DMf0u4dm.js +0 -22
  186. package/dist/web/public/assets/native-agent-DMf0u4dm.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"plans-DsHtDRlS.js","sources":["../../node_modules/lucide-react/dist/esm/icons/clipboard-list.js","../../node_modules/lucide-react/dist/esm/icons/pen-line.js","../../src/routes/tasks/plans.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ClipboardList = createLucideIcon(\"ClipboardList\", [\n [\"rect\", { width: \"8\", height: \"4\", x: \"8\", y: \"2\", rx: \"1\", ry: \"1\", key: \"tgr4d6\" }],\n [\n \"path\",\n {\n d: \"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\",\n key: \"116196\"\n }\n ],\n [\"path\", { d: \"M12 11h4\", key: \"1jrz19\" }],\n [\"path\", { d: \"M12 16h4\", key: \"n85exb\" }],\n [\"path\", { d: \"M8 11h.01\", key: \"1dfujw\" }],\n [\"path\", { d: \"M8 16h.01\", key: \"18s6g9\" }]\n]);\n\nexport { ClipboardList as default };\n//# sourceMappingURL=clipboard-list.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst PenLine = createLucideIcon(\"PenLine\", [\n [\"path\", { d: \"M12 20h9\", key: \"t2du7b\" }],\n [\n \"path\",\n {\n d: \"M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z\",\n key: \"1ykcvy\"\n }\n ]\n]);\n\nexport { PenLine as default };\n//# sourceMappingURL=pen-line.js.map\n","/**\n * /tasks/plans — admin view of native_exit_plan_mode handshakes\n * (v1.2.133).\n *\n * Surfaces the plan_history sqlite table populated by v1.2.131's\n * exit-plan-mode dispatcher. Each row shows what plan the model\n * proposed, what outcome the user picked (approved / rejected /\n * edited / expired), how long the operator took to decide, and\n * the rejection / edit reason if any.\n *\n * Layout mirrors /tasks/asks: header with title + count + refresh +\n * optional thread filter, then a table. Each row's plan markdown\n * is collapsed by default — click to expand into a fenced markdown\n * block (no live render; that's a v1.2.134 idea once we know\n * operators actually use this surface).\n */\n\nimport { useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport {\n CheckCircle2, ChevronDown, ChevronRight, ClipboardList,\n Edit3, Loader2, RefreshCcw, XCircle, Clock,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport { usePlansList, type PlanHistoryRow, type PlanOutcome } from '@/hooks/use-background-tasks'\n\nconst OUTCOME_ICONS: Record<PlanOutcome, JSX.Element> = {\n approved: <CheckCircle2 className=\"h-3 w-3\" />,\n rejected: <XCircle className=\"h-3 w-3\" />,\n edited: <Edit3 className=\"h-3 w-3\" />,\n expired: <Clock className=\"h-3 w-3\" />,\n}\n\nconst OUTCOME_VARIANT: Record<PlanOutcome, 'success' | 'warning' | 'info' | 'outline'> = {\n approved: 'success',\n rejected: 'warning',\n edited: 'info',\n expired: 'outline',\n}\n\nfunction fmtPending(ms: number | null): string {\n if (ms == null) return '—'\n if (ms < 1000) return `${ms}ms`\n const s = ms / 1000\n if (s < 60) return `${s.toFixed(1)}s`\n return `${(s / 60).toFixed(1)}min`\n}\n\nexport default function TasksPlansRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const [filter, setFilter] = useState('')\n const [appliedFilter, setAppliedFilter] = useState('')\n const listQuery = usePlansList({ threadKey: appliedFilter || undefined, limit: 200 })\n\n const rows = useMemo(() => listQuery.data?.plans ?? [], [listQuery.data])\n\n function applyFilter(): void {\n setAppliedFilter(filter.trim())\n }\n\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <ClipboardList className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('plans.title', { defaultValue: 'Plan history' })}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('plans.refresh', { defaultValue: 'Refresh' })}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">\n {t('plans.subtitle', {\n defaultValue:\n 'Every native_exit_plan_mode handshake (v1.2.131) lands here with outcome + the plan markdown the model proposed.',\n })}\n </p>\n\n <section className=\"flex items-end gap-2 rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-1 flex-col gap-1\">\n <Label className=\"text-xs font-medium\">\n {t('plans.filterLabel', { defaultValue: 'Filter by thread key (optional)' })}\n </Label>\n <Input\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n onKeyDown={(e) => { if (e.key === 'Enter') applyFilter() }}\n placeholder=\"tg:8754479311:default\"\n className=\"font-mono text-xs\"\n />\n </div>\n <Button size=\"sm\" onClick={applyFilter} disabled={listQuery.isFetching}>\n {t('plans.applyFilter', { defaultValue: 'Apply' })}\n </Button>\n {appliedFilter && (\n <Button\n size=\"sm\" variant=\"ghost\"\n onClick={() => { setFilter(''); setAppliedFilter('') }}\n >\n {t('plans.clearFilter', { defaultValue: 'Clear' })}\n </Button>\n )}\n </section>\n\n {listQuery.isLoading ? (\n <div className=\"h-32 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {appliedFilter\n ? t('plans.emptyFiltered', {\n defaultValue: 'No plan history for this thread. Either the thread never entered plan mode, or it was approved without going through the exit handshake (e.g. /plan off manually).',\n })\n : t('plans.empty', {\n defaultValue: 'No plans yet. Try /plan on in an IM thread and let the model build a plan.',\n })}\n </section>\n ) : (\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-8\" />\n <TableHead>{t('plans.col.outcome', { defaultValue: 'Outcome' })}</TableHead>\n <TableHead>{t('plans.col.thread', { defaultValue: 'Thread' })}</TableHead>\n <TableHead>{t('plans.col.resolvedAt', { defaultValue: 'Resolved' })}</TableHead>\n <TableHead>{t('plans.col.pending', { defaultValue: 'Wait' })}</TableHead>\n <TableHead>{t('plans.col.detail', { defaultValue: 'Detail' })}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((r) => <PlanRow key={r.id} row={r} />)}\n </TableBody>\n </Table>\n )}\n </div>\n )\n}\n\nfunction PlanRow({ row }: { row: PlanHistoryRow }): JSX.Element {\n const { t } = useTranslation(['tasks'])\n const [open, setOpen] = useState(false)\n return (\n <>\n <TableRow className=\"cursor-pointer hover:bg-surface-hover\" onClick={() => setOpen((v) => !v)}>\n <TableCell className=\"p-1 align-top text-text-dim\">\n {open ? <ChevronDown className=\"h-4 w-4\" /> : <ChevronRight className=\"h-4 w-4\" />}\n </TableCell>\n <TableCell className=\"align-top\">\n <Badge variant={OUTCOME_VARIANT[row.outcome]}>\n {OUTCOME_ICONS[row.outcome]}\n <span className=\"ml-1\">{row.outcome}</span>\n </Badge>\n </TableCell>\n <TableCell className=\"align-top\">\n <code className=\"text-[11px]\">{row.threadKey}</code>\n </TableCell>\n <TableCell className=\"align-top text-[11px] text-text-dim\">{row.resolvedAt}</TableCell>\n <TableCell className=\"align-top text-[11px] text-text-dim\">{fmtPending(row.pendingMs)}</TableCell>\n <TableCell className=\"align-top text-xs\">\n {row.detail\n ? <span title={row.detail}>{row.detail.slice(0, 80)}{row.detail.length > 80 ? '…' : ''}</span>\n : <span className=\"text-text-dim\">—</span>}\n </TableCell>\n </TableRow>\n {open && (\n <TableRow>\n <TableCell colSpan={6} className=\"bg-surface-2 p-3\">\n <div className=\"text-[11px] text-text-dim\">\n {t('plans.planMdLabel', { defaultValue: 'Plan markdown the model proposed:' })}\n </div>\n <pre className=\"mt-1 max-h-96 overflow-y-auto whitespace-pre-wrap rounded border border-border bg-surface p-3 text-[12px]\">\n {row.planMd}\n </pre>\n </TableCell>\n </TableRow>\n )}\n </>\n )\n}\n"],"names":["ClipboardList","createLucideIcon","PenLine","OUTCOME_ICONS","jsx","CheckCircle2","XCircle","Edit3","Clock","OUTCOME_VARIANT","fmtPending","ms","TasksPlansRoute","t","useTranslation","filter","setFilter","useState","appliedFilter","setAppliedFilter","listQuery","usePlansList","rows","useMemo","applyFilter","jsxs","Badge","Button","Loader2","RefreshCcw","Label","Input","e","Table","TableHeader","TableRow","TableHead","TableBody","r","PlanRow","row","open","setOpen","Fragment","v","TableCell","ChevronDown","ChevronRight"],"mappings":"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","x_google_ignoreList":[0,1]}
1
+ {"version":3,"file":"plans-D-Nf-jL2.js","sources":["../../node_modules/lucide-react/dist/esm/icons/clipboard-list.js","../../node_modules/lucide-react/dist/esm/icons/pen-line.js","../../src/routes/tasks/plans.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ClipboardList = createLucideIcon(\"ClipboardList\", [\n [\"rect\", { width: \"8\", height: \"4\", x: \"8\", y: \"2\", rx: \"1\", ry: \"1\", key: \"tgr4d6\" }],\n [\n \"path\",\n {\n d: \"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\",\n key: \"116196\"\n }\n ],\n [\"path\", { d: \"M12 11h4\", key: \"1jrz19\" }],\n [\"path\", { d: \"M12 16h4\", key: \"n85exb\" }],\n [\"path\", { d: \"M8 11h.01\", key: \"1dfujw\" }],\n [\"path\", { d: \"M8 16h.01\", key: \"18s6g9\" }]\n]);\n\nexport { ClipboardList as default };\n//# sourceMappingURL=clipboard-list.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst PenLine = createLucideIcon(\"PenLine\", [\n [\"path\", { d: \"M12 20h9\", key: \"t2du7b\" }],\n [\n \"path\",\n {\n d: \"M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z\",\n key: \"1ykcvy\"\n }\n ]\n]);\n\nexport { PenLine as default };\n//# sourceMappingURL=pen-line.js.map\n","/**\n * /tasks/plans — admin view of native_exit_plan_mode handshakes\n * (v1.2.133).\n *\n * Surfaces the plan_history sqlite table populated by v1.2.131's\n * exit-plan-mode dispatcher. Each row shows what plan the model\n * proposed, what outcome the user picked (approved / rejected /\n * edited / expired), how long the operator took to decide, and\n * the rejection / edit reason if any.\n *\n * Layout mirrors /tasks/asks: header with title + count + refresh +\n * optional thread filter, then a table. Each row's plan markdown\n * is collapsed by default — click to expand into a fenced markdown\n * block (no live render; that's a v1.2.134 idea once we know\n * operators actually use this surface).\n */\n\nimport { useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport {\n CheckCircle2, ChevronDown, ChevronRight, ClipboardList,\n Edit3, Loader2, RefreshCcw, XCircle, Clock,\n} from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport { usePlansList, type PlanHistoryRow, type PlanOutcome } from '@/hooks/use-background-tasks'\n\nconst OUTCOME_ICONS: Record<PlanOutcome, JSX.Element> = {\n approved: <CheckCircle2 className=\"h-3 w-3\" />,\n rejected: <XCircle className=\"h-3 w-3\" />,\n edited: <Edit3 className=\"h-3 w-3\" />,\n expired: <Clock className=\"h-3 w-3\" />,\n}\n\nconst OUTCOME_VARIANT: Record<PlanOutcome, 'success' | 'warning' | 'info' | 'outline'> = {\n approved: 'success',\n rejected: 'warning',\n edited: 'info',\n expired: 'outline',\n}\n\nfunction fmtPending(ms: number | null): string {\n if (ms == null) return '—'\n if (ms < 1000) return `${ms}ms`\n const s = ms / 1000\n if (s < 60) return `${s.toFixed(1)}s`\n return `${(s / 60).toFixed(1)}min`\n}\n\nexport default function TasksPlansRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const [filter, setFilter] = useState('')\n const [appliedFilter, setAppliedFilter] = useState('')\n const listQuery = usePlansList({ threadKey: appliedFilter || undefined, limit: 200 })\n\n const rows = useMemo(() => listQuery.data?.plans ?? [], [listQuery.data])\n\n function applyFilter(): void {\n setAppliedFilter(filter.trim())\n }\n\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <ClipboardList className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('plans.title', { defaultValue: 'Plan history' })}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('plans.refresh', { defaultValue: 'Refresh' })}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">\n {t('plans.subtitle', {\n defaultValue:\n 'Every native_exit_plan_mode handshake (v1.2.131) lands here with outcome + the plan markdown the model proposed.',\n })}\n </p>\n\n <section className=\"flex items-end gap-2 rounded-md border border-border bg-surface p-3\">\n <div className=\"flex flex-1 flex-col gap-1\">\n <Label className=\"text-xs font-medium\">\n {t('plans.filterLabel', { defaultValue: 'Filter by thread key (optional)' })}\n </Label>\n <Input\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n onKeyDown={(e) => { if (e.key === 'Enter') applyFilter() }}\n placeholder=\"tg:8754479311:default\"\n className=\"font-mono text-xs\"\n />\n </div>\n <Button size=\"sm\" onClick={applyFilter} disabled={listQuery.isFetching}>\n {t('plans.applyFilter', { defaultValue: 'Apply' })}\n </Button>\n {appliedFilter && (\n <Button\n size=\"sm\" variant=\"ghost\"\n onClick={() => { setFilter(''); setAppliedFilter('') }}\n >\n {t('plans.clearFilter', { defaultValue: 'Clear' })}\n </Button>\n )}\n </section>\n\n {listQuery.isLoading ? (\n <div className=\"h-32 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {appliedFilter\n ? t('plans.emptyFiltered', {\n defaultValue: 'No plan history for this thread. Either the thread never entered plan mode, or it was approved without going through the exit handshake (e.g. /plan off manually).',\n })\n : t('plans.empty', {\n defaultValue: 'No plans yet. Try /plan on in an IM thread and let the model build a plan.',\n })}\n </section>\n ) : (\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-8\" />\n <TableHead>{t('plans.col.outcome', { defaultValue: 'Outcome' })}</TableHead>\n <TableHead>{t('plans.col.thread', { defaultValue: 'Thread' })}</TableHead>\n <TableHead>{t('plans.col.resolvedAt', { defaultValue: 'Resolved' })}</TableHead>\n <TableHead>{t('plans.col.pending', { defaultValue: 'Wait' })}</TableHead>\n <TableHead>{t('plans.col.detail', { defaultValue: 'Detail' })}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((r) => <PlanRow key={r.id} row={r} />)}\n </TableBody>\n </Table>\n )}\n </div>\n )\n}\n\nfunction PlanRow({ row }: { row: PlanHistoryRow }): JSX.Element {\n const { t } = useTranslation(['tasks'])\n const [open, setOpen] = useState(false)\n return (\n <>\n <TableRow className=\"cursor-pointer hover:bg-surface-hover\" onClick={() => setOpen((v) => !v)}>\n <TableCell className=\"p-1 align-top text-text-dim\">\n {open ? <ChevronDown className=\"h-4 w-4\" /> : <ChevronRight className=\"h-4 w-4\" />}\n </TableCell>\n <TableCell className=\"align-top\">\n <Badge variant={OUTCOME_VARIANT[row.outcome]}>\n {OUTCOME_ICONS[row.outcome]}\n <span className=\"ml-1\">{row.outcome}</span>\n </Badge>\n </TableCell>\n <TableCell className=\"align-top\">\n <code className=\"text-[11px]\">{row.threadKey}</code>\n </TableCell>\n <TableCell className=\"align-top text-[11px] text-text-dim\">{row.resolvedAt}</TableCell>\n <TableCell className=\"align-top text-[11px] text-text-dim\">{fmtPending(row.pendingMs)}</TableCell>\n <TableCell className=\"align-top text-xs\">\n {row.detail\n ? <span title={row.detail}>{row.detail.slice(0, 80)}{row.detail.length > 80 ? '…' : ''}</span>\n : <span className=\"text-text-dim\">—</span>}\n </TableCell>\n </TableRow>\n {open && (\n <TableRow>\n <TableCell colSpan={6} className=\"bg-surface-2 p-3\">\n <div className=\"text-[11px] text-text-dim\">\n {t('plans.planMdLabel', { defaultValue: 'Plan markdown the model proposed:' })}\n </div>\n <pre className=\"mt-1 max-h-96 overflow-y-auto whitespace-pre-wrap rounded border border-border bg-surface p-3 text-[12px]\">\n {row.planMd}\n </pre>\n </TableCell>\n </TableRow>\n )}\n </>\n )\n}\n"],"names":["ClipboardList","createLucideIcon","PenLine","OUTCOME_ICONS","jsx","CheckCircle2","XCircle","Edit3","Clock","OUTCOME_VARIANT","fmtPending","ms","TasksPlansRoute","t","useTranslation","filter","setFilter","useState","appliedFilter","setAppliedFilter","listQuery","usePlansList","rows","useMemo","applyFilter","jsxs","Badge","Button","Loader2","RefreshCcw","Label","Input","e","Table","TableHeader","TableRow","TableHead","TableBody","r","PlanRow","row","open","setOpen","Fragment","v","TableCell","ChevronDown","ChevronRight"],"mappings":"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","x_google_ignoreList":[0,1]}
@@ -1,7 +1,7 @@
1
- import{n as o}from"./index-CqwhfPlr.js";/**
1
+ import{n as o}from"./index-D4Np2s3l.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const e=o("Play",[["polygon",{points:"6 3 20 12 6 21 6 3",key:"1oa8hb"}]]);export{e as P};
7
- //# sourceMappingURL=play-BG0hyTnO.js.map
7
+ //# sourceMappingURL=play-DqmSNGi8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"play-BG0hyTnO.js","sources":["../../node_modules/lucide-react/dist/esm/icons/play.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Play = createLucideIcon(\"Play\", [\n [\"polygon\", { points: \"6 3 20 12 6 21 6 3\", key: \"1oa8hb\" }]\n]);\n\nexport { Play as default };\n//# sourceMappingURL=play.js.map\n"],"names":["Play","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAOC,EAAiB,OAAQ,CACpC,CAAC,UAAW,CAAE,OAAQ,qBAAsB,IAAK,QAAQ,CAAE,CAC7D,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"play-DqmSNGi8.js","sources":["../../node_modules/lucide-react/dist/esm/icons/play.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Play = createLucideIcon(\"Play\", [\n [\"polygon\", { points: \"6 3 20 12 6 21 6 3\", key: \"1oa8hb\" }]\n]);\n\nexport { Play as default };\n//# sourceMappingURL=play.js.map\n"],"names":["Play","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAOC,EAAiB,OAAQ,CACpC,CAAC,UAAW,CAAE,OAAQ,qBAAsB,IAAK,QAAQ,CAAE,CAC7D,CAAC","x_google_ignoreList":[0]}
@@ -1,7 +1,7 @@
1
- import{n as e}from"./index-CqwhfPlr.js";/**
1
+ import{n as e}from"./index-D4Np2s3l.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const a=e("Plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);export{a as P};
7
- //# sourceMappingURL=plus-Dof9AQvU.js.map
7
+ //# sourceMappingURL=plus-CxClG9H0.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plus-Dof9AQvU.js","sources":["../../node_modules/lucide-react/dist/esm/icons/plus.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Plus = createLucideIcon(\"Plus\", [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }]\n]);\n\nexport { Plus as default };\n//# sourceMappingURL=plus.js.map\n"],"names":["Plus","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAOC,EAAiB,OAAQ,CACpC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"plus-CxClG9H0.js","sources":["../../node_modules/lucide-react/dist/esm/icons/plus.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Plus = createLucideIcon(\"Plus\", [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }]\n]);\n\nexport { Plus as default };\n//# sourceMappingURL=plus.js.map\n"],"names":["Plus","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAOC,EAAiB,OAAQ,CACpC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,CAAC","x_google_ignoreList":[0]}
@@ -1,2 +1,2 @@
1
- import{u as r,j as e,B as d,l as m,m as E,k as u,p as w,c as x,S as _,f as I,g as M,h as A,i as c}from"./index-CqwhfPlr.js";import{u as C,a as B}from"./use-settings-DBXvAYm9.js";import{L as S}from"./loader-circle-U-jPjmeD.js";import{R as U}from"./refresh-ccw-CBiHL1tY.js";import"./react-Cb2sDjhD.js";import"./useQuery-Ds6-WURB.js";function o(s){if(s==null)return!1;const a=s.toLowerCase();return a==="1"||a==="true"||a==="yes"||a==="on"}function K(){const{t:s}=r(["settings","common"]),a=C(),i=B();async function t(n,v){try{await i.mutateAsync({updates:{[n]:v}}),m.success(s("policy.savingToast"))}catch(y){m.error(E(y,s).message)}}const l=a.data?.env??{},h=o(l.IMHUB_DANGEROUSLY_SKIP_PERMISSIONS),g=o(l.IMHUB_MEMORY_ENABLED),j=o(l.IMHUB_VIEWER_ENABLED),N=(l.IMHUB_TIMEOUT_DEFAULT??"").toLowerCase()==="allow",b=(l.IMHUB_A2A_NOTIFY_MODE??"essential").toLowerCase();return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("policy.title")}),e.jsxs(d,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>a.refetch(),disabled:a.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[a.isFetching?e.jsx(S,{className:"h-4 w-4 animate-spin"}):e.jsx(U,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("policy.subtitle")})]}),a.isLoading?e.jsx("div",{className:"h-96 rounded-md bg-surface-2 animate-pulse"}):e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsx(O,{value:h,disabled:i.isPending,onChange:n=>void t("IMHUB_DANGEROUSLY_SKIP_PERMISSIONS",n?"1":"0")}),e.jsx(L,{allowOnTimeout:N,disabled:i.isPending,onChange:n=>void t("IMHUB_TIMEOUT_DEFAULT",n)}),e.jsx(p,{sectionKey:"memory",value:g,disabled:i.isPending,onChange:n=>void t("IMHUB_MEMORY_ENABLED",n?"1":"0")}),e.jsx(p,{sectionKey:"viewer",value:j,disabled:i.isPending,onChange:n=>void t("IMHUB_VIEWER_ENABLED",n?"1":"0")}),e.jsx(T,{value:b,disabled:i.isPending,onChange:n=>void t("IMHUB_A2A_NOTIFY_MODE",n)})]})]})}function O({value:s,disabled:a,onChange:i}){const{t}=r("settings");return e.jsx("section",{className:x("rounded-md border p-4",s?"border-danger/60 bg-danger-bg/30":"border-border bg-surface"),children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t("policy.safety.title")}),s&&e.jsxs(u,{variant:"danger",children:[e.jsx(w,{className:"h-3 w-3"}),"ON"]})]}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:t("policy.safety.description")}),!s&&e.jsx("p",{className:"mt-1 text-xs text-text-muted",children:t("policy.safety.tagWarn")}),e.jsx("code",{className:"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:t("policy.safety.envKey")})]}),e.jsx(f,{value:s,disabled:a,onChange:i})]})})}function L({allowOnTimeout:s,disabled:a,onChange:i}){const{t}=r("settings");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t("policy.approval.title")}),e.jsx("p",{className:"text-sm text-text-dim",children:t("policy.approval.description")}),e.jsx("code",{className:"self-start rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:t("policy.approval.envKey")}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2",children:[e.jsx(d,{type:"button",variant:s?"outline":"default",size:"sm",disabled:a,onClick:()=>i("deny"),children:t("policy.approval.valDeny")}),e.jsx(d,{type:"button",variant:s?"default":"outline",size:"sm",disabled:a,onClick:()=>i("allow"),children:t("policy.approval.valAllow")})]})]})})}function p({sectionKey:s,value:a,disabled:i,onChange:t}){const{t:l}=r("settings");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:l(`policy.${s}.title`)}),e.jsx(u,{variant:a?"success":"outline",children:a?"ON":"OFF"})]}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:l(`policy.${s}.description`)}),e.jsx("code",{className:"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:l(`policy.${s}.envKey`)})]}),e.jsx(f,{value:a,disabled:i,onChange:t})]})})}function T({value:s,disabled:a,onChange:i}){const{t}=r("settings");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("span",{className:"font-medium text-text",children:t("policy.a2aNotify.title")}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:t("policy.a2aNotify.description")}),e.jsx("code",{className:"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:t("policy.a2aNotify.envKey")})]}),e.jsxs(_,{value:s,onValueChange:i,disabled:a,children:[e.jsx(I,{className:"w-36",children:e.jsx(M,{})}),e.jsxs(A,{children:[e.jsx(c,{value:"essential",children:t("policy.a2aNotify.valEssential")}),e.jsx(c,{value:"verbose",children:t("policy.a2aNotify.valVerbose")}),e.jsx(c,{value:"off",children:t("policy.a2aNotify.valOff")})]})]})]})})}function f({value:s,disabled:a,onChange:i}){return e.jsx("button",{type:"button",role:"switch","aria-checked":s,disabled:a,onClick:()=>i(!s),className:x("relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full transition-colors","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg","disabled:cursor-not-allowed disabled:opacity-50",s?"bg-accent":"bg-surface-2 border border-border"),children:e.jsx("span",{className:x("inline-block h-5 w-5 rounded-full bg-white shadow transition-transform",s?"translate-x-5":"translate-x-0.5")})})}export{K as default};
2
- //# sourceMappingURL=policy-BzHy4WbV.js.map
1
+ import{u as r,j as e,B as d,l as m,m as E,k as u,p as w,c as x,S as _,f as I,g as M,h as A,i as c}from"./index-D4Np2s3l.js";import{u as C,a as B}from"./use-settings-XXVWFAv6.js";import{L as S}from"./loader-circle-BfXi9R6u.js";import{R as U}from"./refresh-ccw-C7VT3MFu.js";import"./react-Cb2sDjhD.js";import"./useQuery-B25CPtUF.js";function o(s){if(s==null)return!1;const a=s.toLowerCase();return a==="1"||a==="true"||a==="yes"||a==="on"}function K(){const{t:s}=r(["settings","common"]),a=C(),i=B();async function t(n,v){try{await i.mutateAsync({updates:{[n]:v}}),m.success(s("policy.savingToast"))}catch(y){m.error(E(y,s).message)}}const l=a.data?.env??{},h=o(l.IMHUB_DANGEROUSLY_SKIP_PERMISSIONS),g=o(l.IMHUB_MEMORY_ENABLED),j=o(l.IMHUB_VIEWER_ENABLED),N=(l.IMHUB_TIMEOUT_DEFAULT??"").toLowerCase()==="allow",b=(l.IMHUB_A2A_NOTIFY_MODE??"essential").toLowerCase();return e.jsxs("div",{className:"mx-auto flex max-w-4xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("policy.title")}),e.jsxs(d,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>a.refetch(),disabled:a.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[a.isFetching?e.jsx(S,{className:"h-4 w-4 animate-spin"}):e.jsx(U,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("policy.subtitle")})]}),a.isLoading?e.jsx("div",{className:"h-96 rounded-md bg-surface-2 animate-pulse"}):e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsx(O,{value:h,disabled:i.isPending,onChange:n=>void t("IMHUB_DANGEROUSLY_SKIP_PERMISSIONS",n?"1":"0")}),e.jsx(L,{allowOnTimeout:N,disabled:i.isPending,onChange:n=>void t("IMHUB_TIMEOUT_DEFAULT",n)}),e.jsx(p,{sectionKey:"memory",value:g,disabled:i.isPending,onChange:n=>void t("IMHUB_MEMORY_ENABLED",n?"1":"0")}),e.jsx(p,{sectionKey:"viewer",value:j,disabled:i.isPending,onChange:n=>void t("IMHUB_VIEWER_ENABLED",n?"1":"0")}),e.jsx(T,{value:b,disabled:i.isPending,onChange:n=>void t("IMHUB_A2A_NOTIFY_MODE",n)})]})]})}function O({value:s,disabled:a,onChange:i}){const{t}=r("settings");return e.jsx("section",{className:x("rounded-md border p-4",s?"border-danger/60 bg-danger-bg/30":"border-border bg-surface"),children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t("policy.safety.title")}),s&&e.jsxs(u,{variant:"danger",children:[e.jsx(w,{className:"h-3 w-3"}),"ON"]})]}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:t("policy.safety.description")}),!s&&e.jsx("p",{className:"mt-1 text-xs text-text-muted",children:t("policy.safety.tagWarn")}),e.jsx("code",{className:"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:t("policy.safety.envKey")})]}),e.jsx(f,{value:s,disabled:a,onChange:i})]})})}function L({allowOnTimeout:s,disabled:a,onChange:i}){const{t}=r("settings");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t("policy.approval.title")}),e.jsx("p",{className:"text-sm text-text-dim",children:t("policy.approval.description")}),e.jsx("code",{className:"self-start rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:t("policy.approval.envKey")}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-2",children:[e.jsx(d,{type:"button",variant:s?"outline":"default",size:"sm",disabled:a,onClick:()=>i("deny"),children:t("policy.approval.valDeny")}),e.jsx(d,{type:"button",variant:s?"default":"outline",size:"sm",disabled:a,onClick:()=>i("allow"),children:t("policy.approval.valAllow")})]})]})})}function p({sectionKey:s,value:a,disabled:i,onChange:t}){const{t:l}=r("settings");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:l(`policy.${s}.title`)}),e.jsx(u,{variant:a?"success":"outline",children:a?"ON":"OFF"})]}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:l(`policy.${s}.description`)}),e.jsx("code",{className:"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:l(`policy.${s}.envKey`)})]}),e.jsx(f,{value:a,disabled:i,onChange:t})]})})}function T({value:s,disabled:a,onChange:i}){const{t}=r("settings");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-4",children:e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("span",{className:"font-medium text-text",children:t("policy.a2aNotify.title")}),e.jsx("p",{className:"mt-1 text-sm text-text-dim",children:t("policy.a2aNotify.description")}),e.jsx("code",{className:"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted",children:t("policy.a2aNotify.envKey")})]}),e.jsxs(_,{value:s,onValueChange:i,disabled:a,children:[e.jsx(I,{className:"w-36",children:e.jsx(M,{})}),e.jsxs(A,{children:[e.jsx(c,{value:"essential",children:t("policy.a2aNotify.valEssential")}),e.jsx(c,{value:"verbose",children:t("policy.a2aNotify.valVerbose")}),e.jsx(c,{value:"off",children:t("policy.a2aNotify.valOff")})]})]})]})})}function f({value:s,disabled:a,onChange:i}){return e.jsx("button",{type:"button",role:"switch","aria-checked":s,disabled:a,onClick:()=>i(!s),className:x("relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full transition-colors","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg","disabled:cursor-not-allowed disabled:opacity-50",s?"bg-accent":"bg-surface-2 border border-border"),children:e.jsx("span",{className:x("inline-block h-5 w-5 rounded-full bg-white shadow transition-transform",s?"translate-x-5":"translate-x-0.5")})})}export{K as default};
2
+ //# sourceMappingURL=policy-Mqe38uiR.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy-BzHy4WbV.js","sources":["../../src/routes/settings/policy.tsx"],"sourcesContent":["/**\n * /settings/policy — dedicated UI for the highest-frequency env\n * toggles. Each is a one-click switch (or 2-3 option select) that\n * persists to `~/.agim/.env` via PUT /api/env immediately.\n *\n * Surfaced here:\n * * IMHUB_DANGEROUSLY_SKIP_PERMISSIONS (safety)\n * * IMHUB_TIMEOUT_DEFAULT (approval bus default)\n * * IMHUB_MEMORY_ENABLED (memory subsystem)\n * * IMHUB_VIEWER_ENABLED (long-message viewer)\n * * IMHUB_A2A_NOTIFY_MODE (cross-agent notify verbosity)\n *\n * All five are still editable in /settings/env. This page exists\n * because:\n * 1. They're the ones operators flip most often\n * 2. The env editor's table doesn't communicate \"this is a\n * boolean / 2-state / 3-state value\" — operators have to\n * know the literal strings \"1\"/\"0\"/\"allow\"/\"deny\"/etc.\n * 3. Safety toggle deserves a visible warning + danger color\n */\n\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { AlertTriangle, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { useEnv, useUpdateEnv } from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\n\n/** Treat the env value as a boolean — '1' / 'true' / 'yes' / 'on'\n * → true; everything else → false. Matches the backend's casual\n * truthy parsing in core/* modules. */\nfunction envBool(v: string | undefined): boolean {\n if (v == null) return false\n const t = v.toLowerCase()\n return t === '1' || t === 'true' || t === 'yes' || t === 'on'\n}\n\nexport default function SettingsPolicyRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const envQuery = useEnv()\n const updateEnv = useUpdateEnv()\n\n async function setValue(key: string, value: string | null): Promise<void> {\n try {\n await updateEnv.mutateAsync({ updates: { [key]: value } })\n toast.success(t('policy.savingToast'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n const env = envQuery.data?.env ?? {}\n const skipPerms = envBool(env.IMHUB_DANGEROUSLY_SKIP_PERMISSIONS)\n const memEnabled = envBool(env.IMHUB_MEMORY_ENABLED)\n const viewerEnabled = envBool(env.IMHUB_VIEWER_ENABLED)\n const timeoutAllow = (env.IMHUB_TIMEOUT_DEFAULT ?? '').toLowerCase() === 'allow'\n const a2aMode = (env.IMHUB_A2A_NOTIFY_MODE ?? 'essential').toLowerCase()\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('policy.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => envQuery.refetch()}\n disabled={envQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {envQuery.isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('policy.subtitle')}</p>\n </header>\n\n {envQuery.isLoading ? (\n <div className=\"h-96 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <div className=\"flex flex-col gap-3\">\n <SafetyCard\n value={skipPerms}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_DANGEROUSLY_SKIP_PERMISSIONS', v ? '1' : '0')}\n />\n <ApprovalCard\n allowOnTimeout={timeoutAllow}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_TIMEOUT_DEFAULT', v)}\n />\n <ToggleCard\n sectionKey=\"memory\"\n value={memEnabled}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_MEMORY_ENABLED', v ? '1' : '0')}\n />\n <ToggleCard\n sectionKey=\"viewer\"\n value={viewerEnabled}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_VIEWER_ENABLED', v ? '1' : '0')}\n />\n <A2ANotifyCard\n value={a2aMode}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_A2A_NOTIFY_MODE', v)}\n />\n </div>\n )}\n </div>\n )\n}\n\n/* ─────────────── Cards ─────────────── */\n\ninterface SafetyCardProps {\n value: boolean\n disabled: boolean\n onChange: (v: boolean) => void\n}\n\nfunction SafetyCard({ value, disabled, onChange }: SafetyCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section\n className={cn(\n 'rounded-md border p-4',\n value ? 'border-danger/60 bg-danger-bg/30' : 'border-border bg-surface',\n )}\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{t('policy.safety.title')}</span>\n {value && (\n <Badge variant=\"danger\">\n <AlertTriangle className=\"h-3 w-3\" />\n ON\n </Badge>\n )}\n </div>\n <p className=\"mt-1 text-sm text-text-dim\">{t('policy.safety.description')}</p>\n {!value && (\n <p className=\"mt-1 text-xs text-text-muted\">{t('policy.safety.tagWarn')}</p>\n )}\n <code className=\"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t('policy.safety.envKey')}\n </code>\n </div>\n <Toggle value={value} disabled={disabled} onChange={onChange} />\n </div>\n </section>\n )\n}\n\ninterface ApprovalCardProps {\n allowOnTimeout: boolean\n disabled: boolean\n onChange: (value: 'allow' | 'deny') => void\n}\n\nfunction ApprovalCard({ allowOnTimeout, disabled, onChange }: ApprovalCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex flex-col gap-2\">\n <span className=\"font-medium text-text\">{t('policy.approval.title')}</span>\n <p className=\"text-sm text-text-dim\">{t('policy.approval.description')}</p>\n <code className=\"self-start rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t('policy.approval.envKey')}\n </code>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <Button\n type=\"button\"\n variant={!allowOnTimeout ? 'default' : 'outline'}\n size=\"sm\"\n disabled={disabled}\n onClick={() => onChange('deny')}\n >\n {t('policy.approval.valDeny')}\n </Button>\n <Button\n type=\"button\"\n variant={allowOnTimeout ? 'default' : 'outline'}\n size=\"sm\"\n disabled={disabled}\n onClick={() => onChange('allow')}\n >\n {t('policy.approval.valAllow')}\n </Button>\n </div>\n </div>\n </section>\n )\n}\n\ninterface ToggleCardProps {\n sectionKey: 'memory' | 'viewer'\n value: boolean\n disabled: boolean\n onChange: (v: boolean) => void\n}\n\nfunction ToggleCard({ sectionKey, value, disabled, onChange }: ToggleCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{t(`policy.${sectionKey}.title`)}</span>\n <Badge variant={value ? 'success' : 'outline'}>{value ? 'ON' : 'OFF'}</Badge>\n </div>\n <p className=\"mt-1 text-sm text-text-dim\">{t(`policy.${sectionKey}.description`)}</p>\n <code className=\"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t(`policy.${sectionKey}.envKey`)}\n </code>\n </div>\n <Toggle value={value} disabled={disabled} onChange={onChange} />\n </div>\n </section>\n )\n}\n\ninterface A2ANotifyCardProps {\n value: string\n disabled: boolean\n onChange: (v: string) => void\n}\n\nfunction A2ANotifyCard({ value, disabled, onChange }: A2ANotifyCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <span className=\"font-medium text-text\">{t('policy.a2aNotify.title')}</span>\n <p className=\"mt-1 text-sm text-text-dim\">{t('policy.a2aNotify.description')}</p>\n <code className=\"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t('policy.a2aNotify.envKey')}\n </code>\n </div>\n <Select value={value} onValueChange={onChange} disabled={disabled}>\n <SelectTrigger className=\"w-36\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"essential\">{t('policy.a2aNotify.valEssential')}</SelectItem>\n <SelectItem value=\"verbose\">{t('policy.a2aNotify.valVerbose')}</SelectItem>\n <SelectItem value=\"off\">{t('policy.a2aNotify.valOff')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </section>\n )\n}\n\ninterface ToggleProps {\n value: boolean\n disabled: boolean\n onChange: (v: boolean) => void\n}\n\n/** Thumb-style switch styled to the agim accent. Tailwind-only,\n * no Radix dep — keeps the click feel snappy. */\nfunction Toggle({ value, disabled, onChange }: ToggleProps): JSX.Element {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={value}\n disabled={disabled}\n onClick={() => onChange(!value)}\n className={cn(\n 'relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n value ? 'bg-accent' : 'bg-surface-2 border border-border',\n )}\n >\n <span\n className={cn(\n 'inline-block h-5 w-5 rounded-full bg-white shadow transition-transform',\n value ? 'translate-x-5' : 'translate-x-0.5',\n )}\n />\n </button>\n )\n}\n"],"names":["envBool","v","t","SettingsPolicyRoute","useTranslation","envQuery","useEnv","updateEnv","useUpdateEnv","setValue","key","value","toast","err","describeError","env","skipPerms","memEnabled","viewerEnabled","timeoutAllow","a2aMode","jsxs","jsx","Button","Loader2","RefreshCcw","SafetyCard","ApprovalCard","ToggleCard","A2ANotifyCard","disabled","onChange","cn","Badge","AlertTriangle","Toggle","allowOnTimeout","sectionKey","Select","SelectTrigger","SelectValue","SelectContent","SelectItem"],"mappings":"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"}
1
+ {"version":3,"file":"policy-Mqe38uiR.js","sources":["../../src/routes/settings/policy.tsx"],"sourcesContent":["/**\n * /settings/policy — dedicated UI for the highest-frequency env\n * toggles. Each is a one-click switch (or 2-3 option select) that\n * persists to `~/.agim/.env` via PUT /api/env immediately.\n *\n * Surfaced here:\n * * IMHUB_DANGEROUSLY_SKIP_PERMISSIONS (safety)\n * * IMHUB_TIMEOUT_DEFAULT (approval bus default)\n * * IMHUB_MEMORY_ENABLED (memory subsystem)\n * * IMHUB_VIEWER_ENABLED (long-message viewer)\n * * IMHUB_A2A_NOTIFY_MODE (cross-agent notify verbosity)\n *\n * All five are still editable in /settings/env. This page exists\n * because:\n * 1. They're the ones operators flip most often\n * 2. The env editor's table doesn't communicate \"this is a\n * boolean / 2-state / 3-state value\" — operators have to\n * know the literal strings \"1\"/\"0\"/\"allow\"/\"deny\"/etc.\n * 3. Safety toggle deserves a visible warning + danger color\n */\n\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { AlertTriangle, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport { useEnv, useUpdateEnv } from '@/hooks/use-settings'\nimport { describeError } from '@/lib/api/errors'\nimport { cn } from '@/lib/utils'\n\n/** Treat the env value as a boolean — '1' / 'true' / 'yes' / 'on'\n * → true; everything else → false. Matches the backend's casual\n * truthy parsing in core/* modules. */\nfunction envBool(v: string | undefined): boolean {\n if (v == null) return false\n const t = v.toLowerCase()\n return t === '1' || t === 'true' || t === 'yes' || t === 'on'\n}\n\nexport default function SettingsPolicyRoute(): JSX.Element {\n const { t } = useTranslation(['settings', 'common'])\n const envQuery = useEnv()\n const updateEnv = useUpdateEnv()\n\n async function setValue(key: string, value: string | null): Promise<void> {\n try {\n await updateEnv.mutateAsync({ updates: { [key]: value } })\n toast.success(t('policy.savingToast'))\n } catch (err) {\n toast.error(describeError(err, t).message)\n }\n }\n\n const env = envQuery.data?.env ?? {}\n const skipPerms = envBool(env.IMHUB_DANGEROUSLY_SKIP_PERMISSIONS)\n const memEnabled = envBool(env.IMHUB_MEMORY_ENABLED)\n const viewerEnabled = envBool(env.IMHUB_VIEWER_ENABLED)\n const timeoutAllow = (env.IMHUB_TIMEOUT_DEFAULT ?? '').toLowerCase() === 'allow'\n const a2aMode = (env.IMHUB_A2A_NOTIFY_MODE ?? 'essential').toLowerCase()\n\n return (\n <div className=\"mx-auto flex max-w-4xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('policy.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => envQuery.refetch()}\n disabled={envQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {envQuery.isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('policy.subtitle')}</p>\n </header>\n\n {envQuery.isLoading ? (\n <div className=\"h-96 rounded-md bg-surface-2 animate-pulse\" />\n ) : (\n <div className=\"flex flex-col gap-3\">\n <SafetyCard\n value={skipPerms}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_DANGEROUSLY_SKIP_PERMISSIONS', v ? '1' : '0')}\n />\n <ApprovalCard\n allowOnTimeout={timeoutAllow}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_TIMEOUT_DEFAULT', v)}\n />\n <ToggleCard\n sectionKey=\"memory\"\n value={memEnabled}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_MEMORY_ENABLED', v ? '1' : '0')}\n />\n <ToggleCard\n sectionKey=\"viewer\"\n value={viewerEnabled}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_VIEWER_ENABLED', v ? '1' : '0')}\n />\n <A2ANotifyCard\n value={a2aMode}\n disabled={updateEnv.isPending}\n onChange={(v) => void setValue('IMHUB_A2A_NOTIFY_MODE', v)}\n />\n </div>\n )}\n </div>\n )\n}\n\n/* ─────────────── Cards ─────────────── */\n\ninterface SafetyCardProps {\n value: boolean\n disabled: boolean\n onChange: (v: boolean) => void\n}\n\nfunction SafetyCard({ value, disabled, onChange }: SafetyCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section\n className={cn(\n 'rounded-md border p-4',\n value ? 'border-danger/60 bg-danger-bg/30' : 'border-border bg-surface',\n )}\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{t('policy.safety.title')}</span>\n {value && (\n <Badge variant=\"danger\">\n <AlertTriangle className=\"h-3 w-3\" />\n ON\n </Badge>\n )}\n </div>\n <p className=\"mt-1 text-sm text-text-dim\">{t('policy.safety.description')}</p>\n {!value && (\n <p className=\"mt-1 text-xs text-text-muted\">{t('policy.safety.tagWarn')}</p>\n )}\n <code className=\"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t('policy.safety.envKey')}\n </code>\n </div>\n <Toggle value={value} disabled={disabled} onChange={onChange} />\n </div>\n </section>\n )\n}\n\ninterface ApprovalCardProps {\n allowOnTimeout: boolean\n disabled: boolean\n onChange: (value: 'allow' | 'deny') => void\n}\n\nfunction ApprovalCard({ allowOnTimeout, disabled, onChange }: ApprovalCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex flex-col gap-2\">\n <span className=\"font-medium text-text\">{t('policy.approval.title')}</span>\n <p className=\"text-sm text-text-dim\">{t('policy.approval.description')}</p>\n <code className=\"self-start rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t('policy.approval.envKey')}\n </code>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n <Button\n type=\"button\"\n variant={!allowOnTimeout ? 'default' : 'outline'}\n size=\"sm\"\n disabled={disabled}\n onClick={() => onChange('deny')}\n >\n {t('policy.approval.valDeny')}\n </Button>\n <Button\n type=\"button\"\n variant={allowOnTimeout ? 'default' : 'outline'}\n size=\"sm\"\n disabled={disabled}\n onClick={() => onChange('allow')}\n >\n {t('policy.approval.valAllow')}\n </Button>\n </div>\n </div>\n </section>\n )\n}\n\ninterface ToggleCardProps {\n sectionKey: 'memory' | 'viewer'\n value: boolean\n disabled: boolean\n onChange: (v: boolean) => void\n}\n\nfunction ToggleCard({ sectionKey, value, disabled, onChange }: ToggleCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-medium text-text\">{t(`policy.${sectionKey}.title`)}</span>\n <Badge variant={value ? 'success' : 'outline'}>{value ? 'ON' : 'OFF'}</Badge>\n </div>\n <p className=\"mt-1 text-sm text-text-dim\">{t(`policy.${sectionKey}.description`)}</p>\n <code className=\"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t(`policy.${sectionKey}.envKey`)}\n </code>\n </div>\n <Toggle value={value} disabled={disabled} onChange={onChange} />\n </div>\n </section>\n )\n}\n\ninterface A2ANotifyCardProps {\n value: string\n disabled: boolean\n onChange: (v: string) => void\n}\n\nfunction A2ANotifyCard({ value, disabled, onChange }: A2ANotifyCardProps): JSX.Element {\n const { t } = useTranslation('settings')\n return (\n <section className=\"rounded-md border border-border bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1\">\n <span className=\"font-medium text-text\">{t('policy.a2aNotify.title')}</span>\n <p className=\"mt-1 text-sm text-text-dim\">{t('policy.a2aNotify.description')}</p>\n <code className=\"mt-2 inline-block rounded bg-surface-2 px-1.5 py-0.5 text-xs text-text-muted\">\n {t('policy.a2aNotify.envKey')}\n </code>\n </div>\n <Select value={value} onValueChange={onChange} disabled={disabled}>\n <SelectTrigger className=\"w-36\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"essential\">{t('policy.a2aNotify.valEssential')}</SelectItem>\n <SelectItem value=\"verbose\">{t('policy.a2aNotify.valVerbose')}</SelectItem>\n <SelectItem value=\"off\">{t('policy.a2aNotify.valOff')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </section>\n )\n}\n\ninterface ToggleProps {\n value: boolean\n disabled: boolean\n onChange: (v: boolean) => void\n}\n\n/** Thumb-style switch styled to the agim accent. Tailwind-only,\n * no Radix dep — keeps the click feel snappy. */\nfunction Toggle({ value, disabled, onChange }: ToggleProps): JSX.Element {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={value}\n disabled={disabled}\n onClick={() => onChange(!value)}\n className={cn(\n 'relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-bg',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n value ? 'bg-accent' : 'bg-surface-2 border border-border',\n )}\n >\n <span\n className={cn(\n 'inline-block h-5 w-5 rounded-full bg-white shadow transition-transform',\n value ? 'translate-x-5' : 'translate-x-0.5',\n )}\n />\n </button>\n )\n}\n"],"names":["envBool","v","t","SettingsPolicyRoute","useTranslation","envQuery","useEnv","updateEnv","useUpdateEnv","setValue","key","value","toast","err","describeError","env","skipPerms","memEnabled","viewerEnabled","timeoutAllow","a2aMode","jsxs","jsx","Button","Loader2","RefreshCcw","SafetyCard","ApprovalCard","ToggleCard","A2ANotifyCard","disabled","onChange","cn","Badge","AlertTriangle","Toggle","allowOnTimeout","sectionKey","Select","SelectTrigger","SelectValue","SelectContent","SelectItem"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import{n as t}from"./index-CqwhfPlr.js";/**
1
+ import{n as t}from"./index-D4Np2s3l.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const h=t("QrCode",[["rect",{width:"5",height:"5",x:"3",y:"3",rx:"1",key:"1tu5fj"}],["rect",{width:"5",height:"5",x:"16",y:"3",rx:"1",key:"1v8r4q"}],["rect",{width:"5",height:"5",x:"3",y:"16",rx:"1",key:"1x03jg"}],["path",{d:"M21 16h-3a2 2 0 0 0-2 2v3",key:"177gqh"}],["path",{d:"M21 21v.01",key:"ents32"}],["path",{d:"M12 7v3a2 2 0 0 1-2 2H7",key:"8crl2c"}],["path",{d:"M3 12h.01",key:"nlz23k"}],["path",{d:"M12 3h.01",key:"n36tog"}],["path",{d:"M12 16v.01",key:"133mhm"}],["path",{d:"M16 12h1",key:"1slzba"}],["path",{d:"M21 12v.01",key:"1lwtk9"}],["path",{d:"M12 21v-1",key:"1880an"}]]);export{h as Q};
7
- //# sourceMappingURL=qr-code-yD_ztCf6.js.map
7
+ //# sourceMappingURL=qr-code-BAEZ2Sel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"qr-code-yD_ztCf6.js","sources":["../../node_modules/lucide-react/dist/esm/icons/qr-code.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst QrCode = createLucideIcon(\"QrCode\", [\n [\"rect\", { width: \"5\", height: \"5\", x: \"3\", y: \"3\", rx: \"1\", key: \"1tu5fj\" }],\n [\"rect\", { width: \"5\", height: \"5\", x: \"16\", y: \"3\", rx: \"1\", key: \"1v8r4q\" }],\n [\"rect\", { width: \"5\", height: \"5\", x: \"3\", y: \"16\", rx: \"1\", key: \"1x03jg\" }],\n [\"path\", { d: \"M21 16h-3a2 2 0 0 0-2 2v3\", key: \"177gqh\" }],\n [\"path\", { d: \"M21 21v.01\", key: \"ents32\" }],\n [\"path\", { d: \"M12 7v3a2 2 0 0 1-2 2H7\", key: \"8crl2c\" }],\n [\"path\", { d: \"M3 12h.01\", key: \"nlz23k\" }],\n [\"path\", { d: \"M12 3h.01\", key: \"n36tog\" }],\n [\"path\", { d: \"M12 16v.01\", key: \"133mhm\" }],\n [\"path\", { d: \"M16 12h1\", key: \"1slzba\" }],\n [\"path\", { d: \"M21 12v.01\", key: \"1lwtk9\" }],\n [\"path\", { d: \"M12 21v-1\", key: \"1880an\" }]\n]);\n\nexport { QrCode as default };\n//# sourceMappingURL=qr-code.js.map\n"],"names":["QrCode","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAASC,EAAiB,SAAU,CACxC,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,IAAK,EAAG,IAAK,EAAG,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC5E,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,IAAK,EAAG,KAAM,EAAG,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC7E,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,IAAK,EAAG,IAAK,EAAG,KAAM,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC7E,CAAC,OAAQ,CAAE,EAAG,4BAA6B,IAAK,QAAQ,CAAE,EAC1D,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,EAC3C,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAQ,CAAE,EACxD,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,EAC1C,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,EAC1C,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,EAC3C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,EAC3C,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,CAC5C,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"qr-code-BAEZ2Sel.js","sources":["../../node_modules/lucide-react/dist/esm/icons/qr-code.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst QrCode = createLucideIcon(\"QrCode\", [\n [\"rect\", { width: \"5\", height: \"5\", x: \"3\", y: \"3\", rx: \"1\", key: \"1tu5fj\" }],\n [\"rect\", { width: \"5\", height: \"5\", x: \"16\", y: \"3\", rx: \"1\", key: \"1v8r4q\" }],\n [\"rect\", { width: \"5\", height: \"5\", x: \"3\", y: \"16\", rx: \"1\", key: \"1x03jg\" }],\n [\"path\", { d: \"M21 16h-3a2 2 0 0 0-2 2v3\", key: \"177gqh\" }],\n [\"path\", { d: \"M21 21v.01\", key: \"ents32\" }],\n [\"path\", { d: \"M12 7v3a2 2 0 0 1-2 2H7\", key: \"8crl2c\" }],\n [\"path\", { d: \"M3 12h.01\", key: \"nlz23k\" }],\n [\"path\", { d: \"M12 3h.01\", key: \"n36tog\" }],\n [\"path\", { d: \"M12 16v.01\", key: \"133mhm\" }],\n [\"path\", { d: \"M16 12h1\", key: \"1slzba\" }],\n [\"path\", { d: \"M21 12v.01\", key: \"1lwtk9\" }],\n [\"path\", { d: \"M12 21v-1\", key: \"1880an\" }]\n]);\n\nexport { QrCode as default };\n//# sourceMappingURL=qr-code.js.map\n"],"names":["QrCode","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAASC,EAAiB,SAAU,CACxC,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,IAAK,EAAG,IAAK,EAAG,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC5E,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,IAAK,EAAG,KAAM,EAAG,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC7E,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,IAAK,EAAG,IAAK,EAAG,KAAM,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC7E,CAAC,OAAQ,CAAE,EAAG,4BAA6B,IAAK,QAAQ,CAAE,EAC1D,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,EAC3C,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAQ,CAAE,EACxD,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,EAC1C,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,EAC1C,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,EAC3C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,EAC3C,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,CAC5C,CAAC","x_google_ignoreList":[0]}
@@ -1,7 +1,7 @@
1
- import{n as e}from"./index-CqwhfPlr.js";/**
1
+ import{n as e}from"./index-D4Np2s3l.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const a=e("RefreshCcw",[["path",{d:"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"14sxne"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16",key:"1hlbsb"}],["path",{d:"M16 16h5v5",key:"ccwih5"}]]);export{a as R};
7
- //# sourceMappingURL=refresh-ccw-CBiHL1tY.js.map
7
+ //# sourceMappingURL=refresh-ccw-C7VT3MFu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"refresh-ccw-CBiHL1tY.js","sources":["../../node_modules/lucide-react/dist/esm/icons/refresh-ccw.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RefreshCcw = createLucideIcon(\"RefreshCcw\", [\n [\"path\", { d: \"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\", key: \"14sxne\" }],\n [\"path\", { d: \"M3 3v5h5\", key: \"1xhq8a\" }],\n [\"path\", { d: \"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16\", key: \"1hlbsb\" }],\n [\"path\", { d: \"M16 16h5v5\", key: \"ccwih5\" }]\n]);\n\nexport { RefreshCcw as default };\n//# sourceMappingURL=refresh-ccw.js.map\n"],"names":["RefreshCcw","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAaC,EAAiB,aAAc,CAChD,CAAC,OAAQ,CAAE,EAAG,qDAAsD,IAAK,QAAQ,CAAE,EACnF,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,sDAAuD,IAAK,QAAQ,CAAE,EACpF,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,CAC7C,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"refresh-ccw-C7VT3MFu.js","sources":["../../node_modules/lucide-react/dist/esm/icons/refresh-ccw.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RefreshCcw = createLucideIcon(\"RefreshCcw\", [\n [\"path\", { d: \"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\", key: \"14sxne\" }],\n [\"path\", { d: \"M3 3v5h5\", key: \"1xhq8a\" }],\n [\"path\", { d: \"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16\", key: \"1hlbsb\" }],\n [\"path\", { d: \"M16 16h5v5\", key: \"ccwih5\" }]\n]);\n\nexport { RefreshCcw as default };\n//# sourceMappingURL=refresh-ccw.js.map\n"],"names":["RefreshCcw","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAaC,EAAiB,aAAc,CAChD,CAAC,OAAQ,CAAE,EAAG,qDAAsD,IAAK,QAAQ,CAAE,EACnF,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,sDAAuD,IAAK,QAAQ,CAAE,EACpF,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,CAC7C,CAAC","x_google_ignoreList":[0]}
@@ -1,7 +1,7 @@
1
- import{n as B,a as w,b as v,d as y,u as D,e as K,j as e,k as M,B as d,T as E,S as L,f as q,g as A,h as F,i as V,l as h,m as b}from"./index-CqwhfPlr.js";import{r as x}from"./react-Cb2sDjhD.js";import{D as _}from"./data-table-B80M8zdu.js";import{E as Q}from"./empty-state-CrPnUC6d.js";import{S as $}from"./status-badge-nSFUUEfy.js";import{C as H}from"./confirm-dialog-r9HgkIYf.js";import{D as U,a as Z,b as G,c as J,d as W,e as X}from"./dialog-fGS0IXOo.js";import{u as Y}from"./useQuery-Ds6-WURB.js";import{C as ee}from"./clock-iitpdQjZ.js";import{L as se}from"./loader-circle-U-jPjmeD.js";import{R as te}from"./refresh-ccw-CBiHL1tY.js";import{B as ae}from"./bell-FF7PJo1N.js";import"./table-BNqo2xb8.js";import"./arrow-up-NWC5K6Jw.js";import"./arrow-down-BkZ50IzL.js";import"./x-ClXUlQDe.js";/**
1
+ import{n as B,a as w,b as v,d as y,u as D,e as K,j as e,k as M,B as d,T as E,S as L,f as q,g as A,h as F,i as V,l as h,m as b}from"./index-D4Np2s3l.js";import{r as x}from"./react-Cb2sDjhD.js";import{D as _}from"./data-table-B_sUmaE2.js";import{E as Q}from"./empty-state-CtWM3HCj.js";import{S as $}from"./status-badge-CN17QMv6.js";import{C as H}from"./confirm-dialog-DAfv5d0M.js";import{D as U,a as Z,b as G,c as J,d as W,e as X}from"./dialog-DGdHPiTV.js";import{u as Y}from"./useQuery-B25CPtUF.js";import{C as ee}from"./clock-80yAmtz6.js";import{L as se}from"./loader-circle-BfXi9R6u.js";import{R as te}from"./refresh-ccw-C7VT3MFu.js";import{B as ae}from"./bell-QusEl0TB.js";import"./table-C4P3KPbF.js";import"./arrow-up-BQxFty9k.js";import"./arrow-down-BpfVJViL.js";import"./x-CGfY-U_P.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const ne=B("BellOff",[["path",{d:"M10.268 21a2 2 0 0 0 3.464 0",key:"vwvbt9"}],["path",{d:"M17 17H4a1 1 0 0 1-.74-1.673C4.59 13.956 6 12.499 6 8a6 6 0 0 1 .258-1.742",key:"178tsu"}],["path",{d:"m2 2 20 20",key:"1ooewy"}],["path",{d:"M8.668 3.01A6 6 0 0 1 18 8c0 2.687.77 4.653 1.707 6.05",key:"1hqiys"}]]),C={all:["reminders"],list:s=>["reminders","list",s]};function ie(s){return Y({queryKey:C.list(s),queryFn:()=>y.listReminders(s),refetchInterval:5e3,refetchIntervalInBackground:!1})}function re(){const s=w();return v({mutationFn:a=>y.cancelReminder(a),onSuccess:()=>s.invalidateQueries({queryKey:C.all})})}function le(){const s=w();return v({mutationFn:({id:a,body:i})=>y.snoozeReminder(a,i),onSuccess:()=>s.invalidateQueries({queryKey:C.all})})}const oe=["pending","firing","fired","cancelled","failed"],ce=[{duration:"5m",i18nKey:"snooze.preset5m"},{duration:"30m",i18nKey:"snooze.preset30m"},{duration:"1h",i18nKey:"snooze.preset1h"},{duration:"1d",i18nKey:"snooze.preset1d"}];function Te(){const{t:s}=D(["reminders","common"]),[a,i]=K(),r=a.get("status")??"pending",l=x.useMemo(()=>({status:r,limit:200}),[r]),{data:o,isLoading:z,isFetching:N,refetch:T}=ie(l),P=o?.reminders??[],m=re(),c=le(),[f,S]=x.useState(null),[p,g]=x.useState(null);function k(t){const n=new URLSearchParams(a);for(const[u,j]of Object.entries(t))j==null||j===""?n.delete(u):n.set(u,j);i(n,{replace:!0})}async function R(){if(f!=null)try{await m.mutateAsync(f),h.success(s("toast.cancelled"))}catch(t){const{message:n}=b(t,s);throw h.error(n),t}}async function O(t){if(p!=null)try{await c.mutateAsync({id:p,body:{duration:t}}),h.success(s("snooze.toastOk",{duration:t})),g(null)}catch(n){const{message:u}=b(n,s);h.error(u)}}const I=x.useMemo(()=>[{id:"id",header:s("col.id"),cell:t=>e.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",t.id]}),headClassName:"w-16"},{id:"fireAt",header:s("col.fireAt"),cell:t=>e.jsx("span",{className:"font-medium tabular-nums",children:me(t.fire_at)}),headClassName:"w-40"},{id:"text",header:s("col.text"),cell:t=>e.jsx("span",{className:"line-clamp-2 text-text-dim",children:t.text}),asCardTitle:!0},{id:"status",header:s("col.status"),cell:t=>e.jsx($,{status:t.status,children:s(`status.${t.status}`,{defaultValue:t.status})}),headClassName:"w-28"},{id:"platform",header:s("col.platform"),cell:t=>e.jsx("span",{className:"text-text-dim",children:t.platform}),headClassName:"w-24",hideOnMobile:!0},{id:"recurrence",header:s("col.recurrence"),cell:t=>t.recurrence_label?e.jsx(M,{variant:"info",children:t.recurrence_label}):e.jsx("span",{className:"text-text-muted",children:"—"}),headClassName:"w-36",hideOnMobile:!0},{id:"source",header:s("col.source"),cell:t=>e.jsx("span",{className:"text-text-dim",children:s(`source.${t.source}`,{defaultValue:t.source})}),headClassName:"w-24",hideOnMobile:!0},{id:"actions",header:"",cell:t=>t.status==="pending"?e.jsxs("div",{className:"flex justify-end gap-1",children:[e.jsxs(d,{variant:"ghost",size:"sm",onClick:n=>{n.stopPropagation(),g(t.id)},disabled:c.isPending||m.isPending,children:[e.jsx(ee,{className:"h-3 w-3"}),s("action.snooze")]}),e.jsxs(d,{variant:"outline",size:"sm",onClick:n=>{n.stopPropagation(),S(t.id)},disabled:m.isPending||c.isPending,children:[e.jsx(ne,{className:"h-3 w-3"}),s("action.cancel")]})]}):null,headClassName:"w-48"}],[s,m.isPending,c.isPending]);return e.jsxs("div",{className:"flex min-h-dvh flex-col bg-bg",children:[e.jsx(E,{}),e.jsxs("main",{className:"mx-auto flex w-full max-w-7xl flex-1 flex-col gap-4 px-3 py-4 sm:px-4 pb-safe",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("pageTitle")}),e.jsxs(d,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>T(),disabled:N,"aria-label":s("actions.refresh",{ns:"common"}),children:[N?e.jsx(se,{className:"h-4 w-4 animate-spin"}):e.jsx(te,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("subtitle")})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("label",{className:"text-sm text-text-dim",htmlFor:"status-filter",children:s("filter.status")}),e.jsxs(L,{value:r,onValueChange:t=>k({status:t}),children:[e.jsx(q,{id:"status-filter",className:"w-[160px]",children:e.jsx(A,{})}),e.jsx(F,{children:oe.map(t=>e.jsx(V,{value:t,children:s(`status.${t}`,{defaultValue:t})},t))})]})]}),e.jsx(_,{columns:I,rows:P,getRowId:t=>String(t.id),loading:z,emptyState:e.jsx(Q,{icon:e.jsx(ae,{}),title:s("empty.title"),description:s("empty.description")})}),e.jsx(H,{open:f!=null,onOpenChange:t=>{t||S(null)},title:s("action.confirmCancel"),description:s("action.confirmCancelDesc"),intent:"danger",confirmLabel:s("action.cancel"),onConfirm:R}),e.jsx(de,{open:p!=null,busy:c.isPending,onOpenChange:t=>{t||g(null)},onPick:O})]})]})}function de({open:s,busy:a,onOpenChange:i,onPick:r}){const{t:l}=D(["reminders","common"]);return e.jsx(U,{open:s,onOpenChange:a?()=>{}:i,children:e.jsxs(Z,{children:[e.jsxs(G,{children:[e.jsx(J,{children:l("snooze.title")}),e.jsx(W,{children:l("snooze.description")})]}),e.jsx("div",{className:"grid grid-cols-2 gap-2",children:ce.map(o=>e.jsx(d,{type:"button",variant:"outline",disabled:a,onClick:()=>void r(o.duration),children:l(o.i18nKey)},o.duration))}),e.jsx(X,{children:e.jsx(d,{type:"button",variant:"secondary",disabled:a,onClick:()=>i(!1),children:l("actions.cancel",{ns:"common"})})})]})})}function me(s){try{const a=new Date(s);if(Number.isNaN(a.getTime()))return s;const i=new Date;return a.toDateString()===i.toDateString()?a.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"}):a.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return s}}export{Te as default};
7
- //# sourceMappingURL=reminders-CDJlFR2Y.js.map
7
+ //# sourceMappingURL=reminders--pCTIhTv.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reminders-CDJlFR2Y.js","sources":["../../node_modules/lucide-react/dist/esm/icons/bell-off.js","../../src/hooks/use-reminders.ts","../../src/routes/reminders.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst BellOff = createLucideIcon(\"BellOff\", [\n [\"path\", { d: \"M10.268 21a2 2 0 0 0 3.464 0\", key: \"vwvbt9\" }],\n [\n \"path\",\n {\n d: \"M17 17H4a1 1 0 0 1-.74-1.673C4.59 13.956 6 12.499 6 8a6 6 0 0 1 .258-1.742\",\n key: \"178tsu\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }],\n [\"path\", { d: \"M8.668 3.01A6 6 0 0 1 18 8c0 2.687.77 4.653 1.707 6.05\", key: \"1hqiys\" }]\n]);\n\nexport { BellOff as default };\n//# sourceMappingURL=bell-off.js.map\n","/**\n * useReminders — react-query wrappers for the reminders domain.\n *\n * useReminders(query) — list pending (default) or by status\n * useCancelReminder() — POST /api/reminders/:id/cancel\n * useSnoozeReminder() — POST /api/reminders/:id/snooze\n *\n * Reminders aren't on the SSE event-bus today; the page combines a\n * 5s react-query poll with a manual Refresh button. When a snooze\n * mutation lands, both the original AND the new reminder change\n * (one cancelled, one pending) — invalidating the full 'reminders'\n * key catches both.\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n CancelReminderResponse,\n ListRemindersQuery,\n ListRemindersResponse,\n SnoozeReminderBody,\n SnoozeReminderResponse,\n} from '@/types/api'\n\nexport const remindersKeys = {\n all: ['reminders'] as const,\n list: (q: ListRemindersQuery) => ['reminders', 'list', q] as const,\n}\n\nexport function useReminders(query: ListRemindersQuery) {\n return useQuery<ListRemindersResponse>({\n queryKey: remindersKeys.list(query),\n queryFn: () => api.listReminders(query),\n refetchInterval: 5000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useInvalidateReminders() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: remindersKeys.all })\n}\n\nexport function useCancelReminder() {\n const qc = useQueryClient()\n return useMutation<CancelReminderResponse, Error, number>({\n mutationFn: (id) => api.cancelReminder(id),\n onSuccess: () => qc.invalidateQueries({ queryKey: remindersKeys.all }),\n })\n}\n\nexport function useSnoozeReminder() {\n const qc = useQueryClient()\n return useMutation<\n SnoozeReminderResponse,\n Error,\n { id: number; body: SnoozeReminderBody }\n >({\n mutationFn: ({ id, body }) => api.snoozeReminder(id, body),\n onSuccess: () => qc.invalidateQueries({ queryKey: remindersKeys.all }),\n })\n}\n","/**\n * /reminders — queued-reminder list with cancel + snooze.\n *\n * Composition: Topbar + filter row + DataTable + ConfirmDialog\n * (cancel) + a custom <SnoozeDialog> with duration presets that\n * map to the backend's parseDuration vocabulary.\n *\n * Mutations only enabled on `pending` rows; firing/fired/cancelled/\n * failed stay read-only. The DataTable's last column is per-row\n * action buttons.\n *\n * No SSE channel for reminders — 5s react-query poll covers the\n * common case (reminders fire on minute boundaries; latency to\n * surface a firing transition is rarely UX-critical).\n */\n\nimport { useMemo, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Bell, BellOff, Clock, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { Topbar } from '@/components/shell/topbar'\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { StatusBadge } from '@/components/common/status-badge'\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@/components/ui/dialog'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport {\n useReminders,\n useCancelReminder,\n useSnoozeReminder,\n} from '@/hooks/use-reminders'\nimport { describeError } from '@/lib/api/errors'\nimport type { Reminder, ReminderStatus } from '@/types/api'\n\nconst STATUS_OPTIONS: ReminderStatus[] = ['pending', 'firing', 'fired', 'cancelled', 'failed']\n\ninterface SnoozePreset {\n /** Backend parseDuration string. */\n duration: string\n /** i18n key (inside the `snooze` section). */\n i18nKey: string\n}\n\nconst SNOOZE_PRESETS: SnoozePreset[] = [\n { duration: '5m', i18nKey: 'snooze.preset5m' },\n { duration: '30m', i18nKey: 'snooze.preset30m' },\n { duration: '1h', i18nKey: 'snooze.preset1h' },\n { duration: '1d', i18nKey: 'snooze.preset1d' },\n]\n\nexport default function RemindersRoute(): JSX.Element {\n const { t } = useTranslation(['reminders', 'common'])\n const [params, setParams] = useSearchParams()\n const status = (params.get('status') as ReminderStatus | null) ?? 'pending'\n\n const query = useMemo(\n () => ({ status, limit: 200 }),\n [status],\n )\n const { data, isLoading, isFetching, refetch } = useReminders(query)\n const reminders = data?.reminders ?? []\n\n const cancel = useCancelReminder()\n const snooze = useSnoozeReminder()\n\n const [confirmCancelId, setConfirmCancelId] = useState<number | null>(null)\n const [snoozeTargetId, setSnoozeTargetId] = useState<number | null>(null)\n\n function patchParams(patch: Record<string, string | null>): void {\n const next = new URLSearchParams(params)\n for (const [k, v] of Object.entries(patch)) {\n if (v == null || v === '') next.delete(k)\n else next.set(k, v)\n }\n setParams(next, { replace: true })\n }\n\n async function onConfirmCancel(): Promise<void> {\n if (confirmCancelId == null) return\n try {\n await cancel.mutateAsync(confirmCancelId)\n toast.success(t('toast.cancelled'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n async function onConfirmSnooze(duration: string): Promise<void> {\n if (snoozeTargetId == null) return\n try {\n await snooze.mutateAsync({ id: snoozeTargetId, body: { duration } })\n toast.success(t('snooze.toastOk', { duration }))\n setSnoozeTargetId(null)\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n const columns: DataTableColumn<Reminder>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'fireAt',\n header: t('col.fireAt'),\n cell: (r) => <span className=\"font-medium tabular-nums\">{formatTime(r.fire_at)}</span>,\n headClassName: 'w-40',\n },\n {\n id: 'text',\n header: t('col.text'),\n cell: (r) => <span className=\"line-clamp-2 text-text-dim\">{r.text}</span>,\n asCardTitle: true,\n },\n {\n id: 'status',\n header: t('col.status'),\n cell: (r) => (\n <StatusBadge status={r.status}>\n {t(`status.${r.status}`, { defaultValue: r.status })}\n </StatusBadge>\n ),\n headClassName: 'w-28',\n },\n {\n id: 'platform',\n header: t('col.platform'),\n cell: (r) => <span className=\"text-text-dim\">{r.platform}</span>,\n headClassName: 'w-24',\n hideOnMobile: true,\n },\n {\n id: 'recurrence',\n header: t('col.recurrence'),\n cell: (r) =>\n r.recurrence_label ? (\n <Badge variant=\"info\">{r.recurrence_label}</Badge>\n ) : (\n <span className=\"text-text-muted\">—</span>\n ),\n headClassName: 'w-36',\n hideOnMobile: true,\n },\n {\n id: 'source',\n header: t('col.source'),\n cell: (r) => (\n <span className=\"text-text-dim\">{t(`source.${r.source}`, { defaultValue: r.source })}</span>\n ),\n headClassName: 'w-24',\n hideOnMobile: true,\n },\n {\n id: 'actions',\n header: '',\n cell: (r) =>\n r.status === 'pending' ? (\n <div className=\"flex justify-end gap-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation()\n setSnoozeTargetId(r.id)\n }}\n disabled={snooze.isPending || cancel.isPending}\n >\n <Clock className=\"h-3 w-3\" />\n {t('action.snooze')}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation()\n setConfirmCancelId(r.id)\n }}\n disabled={cancel.isPending || snooze.isPending}\n >\n <BellOff className=\"h-3 w-3\" />\n {t('action.cancel')}\n </Button>\n </div>\n ) : null,\n headClassName: 'w-48',\n },\n ],\n [t, cancel.isPending, snooze.isPending],\n )\n\n return (\n <div className=\"flex min-h-dvh flex-col bg-bg\">\n <Topbar />\n\n <main className=\"mx-auto flex w-full max-w-7xl flex-1 flex-col gap-4 px-3 py-4 sm:px-4 pb-safe\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('pageTitle')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('subtitle')}</p>\n </header>\n\n {/* Filter row */}\n <div className=\"flex flex-wrap items-center gap-2\">\n <label className=\"text-sm text-text-dim\" htmlFor=\"status-filter\">\n {t('filter.status')}\n </label>\n <Select\n value={status}\n onValueChange={(v) => patchParams({ status: v })}\n >\n <SelectTrigger id=\"status-filter\" className=\"w-[160px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STATUS_OPTIONS.map((s) => (\n <SelectItem key={s} value={s}>\n {t(`status.${s}`, { defaultValue: s })}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <DataTable\n columns={columns}\n rows={reminders}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n emptyState={\n <EmptyState\n icon={<Bell />}\n title={t('empty.title')}\n description={t('empty.description')}\n />\n }\n />\n\n <ConfirmDialog\n open={confirmCancelId != null}\n onOpenChange={(open) => {\n if (!open) setConfirmCancelId(null)\n }}\n title={t('action.confirmCancel')}\n description={t('action.confirmCancelDesc')}\n intent=\"danger\"\n confirmLabel={t('action.cancel')}\n onConfirm={onConfirmCancel}\n />\n\n <SnoozeDialog\n open={snoozeTargetId != null}\n busy={snooze.isPending}\n onOpenChange={(open) => {\n if (!open) setSnoozeTargetId(null)\n }}\n onPick={onConfirmSnooze}\n />\n </main>\n </div>\n )\n}\n\ninterface SnoozeDialogProps {\n open: boolean\n busy: boolean\n onOpenChange: (open: boolean) => void\n onPick: (duration: string) => void | Promise<void>\n}\n\nfunction SnoozeDialog({ open, busy, onOpenChange, onPick }: SnoozeDialogProps): JSX.Element {\n const { t } = useTranslation(['reminders', 'common'])\n return (\n <Dialog open={open} onOpenChange={busy ? () => {} : onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{t('snooze.title')}</DialogTitle>\n <DialogDescription>{t('snooze.description')}</DialogDescription>\n </DialogHeader>\n <div className=\"grid grid-cols-2 gap-2\">\n {SNOOZE_PRESETS.map((p) => (\n <Button\n key={p.duration}\n type=\"button\"\n variant=\"outline\"\n disabled={busy}\n onClick={() => void onPick(p.duration)}\n >\n {t(p.i18nKey)}\n </Button>\n ))}\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"secondary\"\n disabled={busy}\n onClick={() => onOpenChange(false)}\n >\n {t('actions.cancel', { ns: 'common' })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction formatTime(iso: string): string {\n try {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n const now = new Date()\n const sameDay = d.toDateString() === now.toDateString()\n if (sameDay) {\n return d.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })\n }\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return iso\n }\n}\n"],"names":["BellOff","createLucideIcon","remindersKeys","q","useReminders","query","useQuery","api","useCancelReminder","qc","useQueryClient","useMutation","id","useSnoozeReminder","body","STATUS_OPTIONS","SNOOZE_PRESETS","RemindersRoute","t","useTranslation","params","setParams","useSearchParams","status","useMemo","data","isLoading","isFetching","refetch","reminders","cancel","snooze","confirmCancelId","setConfirmCancelId","useState","snoozeTargetId","setSnoozeTargetId","patchParams","patch","next","k","v","onConfirmCancel","toast","err","message","describeError","onConfirmSnooze","duration","columns","r","jsxs","jsx","formatTime","StatusBadge","Badge","Button","e","Clock","Topbar","Loader2","RefreshCcw","Select","SelectTrigger","SelectValue","SelectContent","s","SelectItem","DataTable","EmptyState","Bell","ConfirmDialog","open","SnoozeDialog","busy","onOpenChange","onPick","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","p","DialogFooter","iso","d","now"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"reminders--pCTIhTv.js","sources":["../../node_modules/lucide-react/dist/esm/icons/bell-off.js","../../src/hooks/use-reminders.ts","../../src/routes/reminders.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst BellOff = createLucideIcon(\"BellOff\", [\n [\"path\", { d: \"M10.268 21a2 2 0 0 0 3.464 0\", key: \"vwvbt9\" }],\n [\n \"path\",\n {\n d: \"M17 17H4a1 1 0 0 1-.74-1.673C4.59 13.956 6 12.499 6 8a6 6 0 0 1 .258-1.742\",\n key: \"178tsu\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }],\n [\"path\", { d: \"M8.668 3.01A6 6 0 0 1 18 8c0 2.687.77 4.653 1.707 6.05\", key: \"1hqiys\" }]\n]);\n\nexport { BellOff as default };\n//# sourceMappingURL=bell-off.js.map\n","/**\n * useReminders — react-query wrappers for the reminders domain.\n *\n * useReminders(query) — list pending (default) or by status\n * useCancelReminder() — POST /api/reminders/:id/cancel\n * useSnoozeReminder() — POST /api/reminders/:id/snooze\n *\n * Reminders aren't on the SSE event-bus today; the page combines a\n * 5s react-query poll with a manual Refresh button. When a snooze\n * mutation lands, both the original AND the new reminder change\n * (one cancelled, one pending) — invalidating the full 'reminders'\n * key catches both.\n */\n\nimport { useQueryClient, useQuery, useMutation } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type {\n CancelReminderResponse,\n ListRemindersQuery,\n ListRemindersResponse,\n SnoozeReminderBody,\n SnoozeReminderResponse,\n} from '@/types/api'\n\nexport const remindersKeys = {\n all: ['reminders'] as const,\n list: (q: ListRemindersQuery) => ['reminders', 'list', q] as const,\n}\n\nexport function useReminders(query: ListRemindersQuery) {\n return useQuery<ListRemindersResponse>({\n queryKey: remindersKeys.list(query),\n queryFn: () => api.listReminders(query),\n refetchInterval: 5000,\n refetchIntervalInBackground: false,\n })\n}\n\nexport function useInvalidateReminders() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: remindersKeys.all })\n}\n\nexport function useCancelReminder() {\n const qc = useQueryClient()\n return useMutation<CancelReminderResponse, Error, number>({\n mutationFn: (id) => api.cancelReminder(id),\n onSuccess: () => qc.invalidateQueries({ queryKey: remindersKeys.all }),\n })\n}\n\nexport function useSnoozeReminder() {\n const qc = useQueryClient()\n return useMutation<\n SnoozeReminderResponse,\n Error,\n { id: number; body: SnoozeReminderBody }\n >({\n mutationFn: ({ id, body }) => api.snoozeReminder(id, body),\n onSuccess: () => qc.invalidateQueries({ queryKey: remindersKeys.all }),\n })\n}\n","/**\n * /reminders — queued-reminder list with cancel + snooze.\n *\n * Composition: Topbar + filter row + DataTable + ConfirmDialog\n * (cancel) + a custom <SnoozeDialog> with duration presets that\n * map to the backend's parseDuration vocabulary.\n *\n * Mutations only enabled on `pending` rows; firing/fired/cancelled/\n * failed stay read-only. The DataTable's last column is per-row\n * action buttons.\n *\n * No SSE channel for reminders — 5s react-query poll covers the\n * common case (reminders fire on minute boundaries; latency to\n * surface a firing transition is rarely UX-critical).\n */\n\nimport { useMemo, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Bell, BellOff, Clock, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { Topbar } from '@/components/shell/topbar'\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { StatusBadge } from '@/components/common/status-badge'\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@/components/ui/dialog'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport {\n useReminders,\n useCancelReminder,\n useSnoozeReminder,\n} from '@/hooks/use-reminders'\nimport { describeError } from '@/lib/api/errors'\nimport type { Reminder, ReminderStatus } from '@/types/api'\n\nconst STATUS_OPTIONS: ReminderStatus[] = ['pending', 'firing', 'fired', 'cancelled', 'failed']\n\ninterface SnoozePreset {\n /** Backend parseDuration string. */\n duration: string\n /** i18n key (inside the `snooze` section). */\n i18nKey: string\n}\n\nconst SNOOZE_PRESETS: SnoozePreset[] = [\n { duration: '5m', i18nKey: 'snooze.preset5m' },\n { duration: '30m', i18nKey: 'snooze.preset30m' },\n { duration: '1h', i18nKey: 'snooze.preset1h' },\n { duration: '1d', i18nKey: 'snooze.preset1d' },\n]\n\nexport default function RemindersRoute(): JSX.Element {\n const { t } = useTranslation(['reminders', 'common'])\n const [params, setParams] = useSearchParams()\n const status = (params.get('status') as ReminderStatus | null) ?? 'pending'\n\n const query = useMemo(\n () => ({ status, limit: 200 }),\n [status],\n )\n const { data, isLoading, isFetching, refetch } = useReminders(query)\n const reminders = data?.reminders ?? []\n\n const cancel = useCancelReminder()\n const snooze = useSnoozeReminder()\n\n const [confirmCancelId, setConfirmCancelId] = useState<number | null>(null)\n const [snoozeTargetId, setSnoozeTargetId] = useState<number | null>(null)\n\n function patchParams(patch: Record<string, string | null>): void {\n const next = new URLSearchParams(params)\n for (const [k, v] of Object.entries(patch)) {\n if (v == null || v === '') next.delete(k)\n else next.set(k, v)\n }\n setParams(next, { replace: true })\n }\n\n async function onConfirmCancel(): Promise<void> {\n if (confirmCancelId == null) return\n try {\n await cancel.mutateAsync(confirmCancelId)\n toast.success(t('toast.cancelled'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n async function onConfirmSnooze(duration: string): Promise<void> {\n if (snoozeTargetId == null) return\n try {\n await snooze.mutateAsync({ id: snoozeTargetId, body: { duration } })\n toast.success(t('snooze.toastOk', { duration }))\n setSnoozeTargetId(null)\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n }\n }\n\n const columns: DataTableColumn<Reminder>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'fireAt',\n header: t('col.fireAt'),\n cell: (r) => <span className=\"font-medium tabular-nums\">{formatTime(r.fire_at)}</span>,\n headClassName: 'w-40',\n },\n {\n id: 'text',\n header: t('col.text'),\n cell: (r) => <span className=\"line-clamp-2 text-text-dim\">{r.text}</span>,\n asCardTitle: true,\n },\n {\n id: 'status',\n header: t('col.status'),\n cell: (r) => (\n <StatusBadge status={r.status}>\n {t(`status.${r.status}`, { defaultValue: r.status })}\n </StatusBadge>\n ),\n headClassName: 'w-28',\n },\n {\n id: 'platform',\n header: t('col.platform'),\n cell: (r) => <span className=\"text-text-dim\">{r.platform}</span>,\n headClassName: 'w-24',\n hideOnMobile: true,\n },\n {\n id: 'recurrence',\n header: t('col.recurrence'),\n cell: (r) =>\n r.recurrence_label ? (\n <Badge variant=\"info\">{r.recurrence_label}</Badge>\n ) : (\n <span className=\"text-text-muted\">—</span>\n ),\n headClassName: 'w-36',\n hideOnMobile: true,\n },\n {\n id: 'source',\n header: t('col.source'),\n cell: (r) => (\n <span className=\"text-text-dim\">{t(`source.${r.source}`, { defaultValue: r.source })}</span>\n ),\n headClassName: 'w-24',\n hideOnMobile: true,\n },\n {\n id: 'actions',\n header: '',\n cell: (r) =>\n r.status === 'pending' ? (\n <div className=\"flex justify-end gap-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation()\n setSnoozeTargetId(r.id)\n }}\n disabled={snooze.isPending || cancel.isPending}\n >\n <Clock className=\"h-3 w-3\" />\n {t('action.snooze')}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation()\n setConfirmCancelId(r.id)\n }}\n disabled={cancel.isPending || snooze.isPending}\n >\n <BellOff className=\"h-3 w-3\" />\n {t('action.cancel')}\n </Button>\n </div>\n ) : null,\n headClassName: 'w-48',\n },\n ],\n [t, cancel.isPending, snooze.isPending],\n )\n\n return (\n <div className=\"flex min-h-dvh flex-col bg-bg\">\n <Topbar />\n\n <main className=\"mx-auto flex w-full max-w-7xl flex-1 flex-col gap-4 px-3 py-4 sm:px-4 pb-safe\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('pageTitle')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('subtitle')}</p>\n </header>\n\n {/* Filter row */}\n <div className=\"flex flex-wrap items-center gap-2\">\n <label className=\"text-sm text-text-dim\" htmlFor=\"status-filter\">\n {t('filter.status')}\n </label>\n <Select\n value={status}\n onValueChange={(v) => patchParams({ status: v })}\n >\n <SelectTrigger id=\"status-filter\" className=\"w-[160px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STATUS_OPTIONS.map((s) => (\n <SelectItem key={s} value={s}>\n {t(`status.${s}`, { defaultValue: s })}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <DataTable\n columns={columns}\n rows={reminders}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n emptyState={\n <EmptyState\n icon={<Bell />}\n title={t('empty.title')}\n description={t('empty.description')}\n />\n }\n />\n\n <ConfirmDialog\n open={confirmCancelId != null}\n onOpenChange={(open) => {\n if (!open) setConfirmCancelId(null)\n }}\n title={t('action.confirmCancel')}\n description={t('action.confirmCancelDesc')}\n intent=\"danger\"\n confirmLabel={t('action.cancel')}\n onConfirm={onConfirmCancel}\n />\n\n <SnoozeDialog\n open={snoozeTargetId != null}\n busy={snooze.isPending}\n onOpenChange={(open) => {\n if (!open) setSnoozeTargetId(null)\n }}\n onPick={onConfirmSnooze}\n />\n </main>\n </div>\n )\n}\n\ninterface SnoozeDialogProps {\n open: boolean\n busy: boolean\n onOpenChange: (open: boolean) => void\n onPick: (duration: string) => void | Promise<void>\n}\n\nfunction SnoozeDialog({ open, busy, onOpenChange, onPick }: SnoozeDialogProps): JSX.Element {\n const { t } = useTranslation(['reminders', 'common'])\n return (\n <Dialog open={open} onOpenChange={busy ? () => {} : onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>{t('snooze.title')}</DialogTitle>\n <DialogDescription>{t('snooze.description')}</DialogDescription>\n </DialogHeader>\n <div className=\"grid grid-cols-2 gap-2\">\n {SNOOZE_PRESETS.map((p) => (\n <Button\n key={p.duration}\n type=\"button\"\n variant=\"outline\"\n disabled={busy}\n onClick={() => void onPick(p.duration)}\n >\n {t(p.i18nKey)}\n </Button>\n ))}\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"secondary\"\n disabled={busy}\n onClick={() => onOpenChange(false)}\n >\n {t('actions.cancel', { ns: 'common' })}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction formatTime(iso: string): string {\n try {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n const now = new Date()\n const sameDay = d.toDateString() === now.toDateString()\n if (sameDay) {\n return d.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })\n }\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return iso\n }\n}\n"],"names":["BellOff","createLucideIcon","remindersKeys","q","useReminders","query","useQuery","api","useCancelReminder","qc","useQueryClient","useMutation","id","useSnoozeReminder","body","STATUS_OPTIONS","SNOOZE_PRESETS","RemindersRoute","t","useTranslation","params","setParams","useSearchParams","status","useMemo","data","isLoading","isFetching","refetch","reminders","cancel","snooze","confirmCancelId","setConfirmCancelId","useState","snoozeTargetId","setSnoozeTargetId","patchParams","patch","next","k","v","onConfirmCancel","toast","err","message","describeError","onConfirmSnooze","duration","columns","r","jsxs","jsx","formatTime","StatusBadge","Badge","Button","e","Clock","Topbar","Loader2","RefreshCcw","Select","SelectTrigger","SelectValue","SelectContent","s","SelectItem","DataTable","EmptyState","Bell","ConfirmDialog","open","SnoozeDialog","busy","onOpenChange","onPick","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","p","DialogFooter","iso","d","now"],"mappings":"uxBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,GAAUC,EAAiB,UAAW,CAC1C,CAAC,OAAQ,CAAE,EAAG,+BAAgC,IAAK,QAAQ,CAAE,EAC7D,CACE,OACA,CACE,EAAG,6EACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,EAC3C,CAAC,OAAQ,CAAE,EAAG,yDAA0D,IAAK,QAAQ,CAAE,CACzF,CAAC,ECIYC,EAAgB,CAC3B,IAAM,CAAC,WAAW,EAClB,KAAOC,GAA0B,CAAC,YAAa,OAAQA,CAAC,CAC1D,EAEO,SAASC,GAAaC,EAA2B,CACtD,OAAOC,EAAgC,CACrC,SAAUJ,EAAc,KAAKG,CAAK,EAClC,QAAS,IAAME,EAAI,cAAcF,CAAK,EACtC,gBAAiB,IACjB,4BAA6B,EAAA,CAC9B,CACH,CAOO,SAASG,IAAoB,CAClC,MAAMC,EAAKC,EAAA,EACX,OAAOC,EAAmD,CACxD,WAAaC,GAAOL,EAAI,eAAeK,CAAE,EACzC,UAAW,IAAMH,EAAG,kBAAkB,CAAE,SAAUP,EAAc,IAAK,CAAA,CACtE,CACH,CAEO,SAASW,IAAoB,CAClC,MAAMJ,EAAKC,EAAA,EACX,OAAOC,EAIL,CACA,WAAY,CAAC,CAAE,GAAAC,EAAI,KAAAE,KAAWP,EAAI,eAAeK,EAAIE,CAAI,EACzD,UAAW,IAAML,EAAG,kBAAkB,CAAE,SAAUP,EAAc,IAAK,CAAA,CACtE,CACH,CCTA,MAAMa,GAAmC,CAAC,UAAW,SAAU,QAAS,YAAa,QAAQ,EASvFC,GAAiC,CACrC,CAAE,SAAU,KAAM,QAAS,iBAAA,EAC3B,CAAE,SAAU,MAAO,QAAS,kBAAA,EAC5B,CAAE,SAAU,KAAM,QAAS,iBAAA,EAC3B,CAAE,SAAU,KAAM,QAAS,iBAAA,CAC7B,EAEA,SAAwBC,IAA8B,CACpD,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAe,CAAC,YAAa,QAAQ,CAAC,EAC9C,CAACC,EAAQC,CAAS,EAAIC,EAAA,EACtBC,EAAUH,EAAO,IAAI,QAAQ,GAA+B,UAE5Df,EAAQmB,EAAAA,QACZ,KAAO,CAAE,OAAAD,EAAQ,MAAO,MACxB,CAACA,CAAM,CAAA,EAEH,CAAE,KAAAE,EAAM,UAAAC,EAAW,WAAAC,EAAY,QAAAC,CAAA,EAAYxB,GAAaC,CAAK,EAC7DwB,EAAYJ,GAAM,WAAa,CAAA,EAE/BK,EAAStB,GAAA,EACTuB,EAASlB,GAAA,EAET,CAACmB,EAAiBC,CAAkB,EAAIC,EAAAA,SAAwB,IAAI,EACpE,CAACC,EAAgBC,CAAiB,EAAIF,EAAAA,SAAwB,IAAI,EAExE,SAASG,EAAYC,EAA4C,CAC/D,MAAMC,EAAO,IAAI,gBAAgBnB,CAAM,EACvC,SAAW,CAACoB,EAAGC,CAAC,IAAK,OAAO,QAAQH,CAAK,EACnCG,GAAK,MAAQA,IAAM,GAAIF,EAAK,OAAOC,CAAC,EACnCD,EAAK,IAAIC,EAAGC,CAAC,EAEpBpB,EAAUkB,EAAM,CAAE,QAAS,EAAA,CAAM,CACnC,CAEA,eAAeG,GAAiC,CAC9C,GAAIV,GAAmB,KACvB,GAAI,CACF,MAAMF,EAAO,YAAYE,CAAe,EACxCW,EAAM,QAAQzB,EAAE,iBAAiB,CAAC,CACpC,OAAS0B,EAAK,CACZ,KAAM,CAAE,QAAAC,CAAA,EAAYC,EAAcF,EAAK1B,CAAC,EACxCyB,MAAAA,EAAM,MAAME,CAAO,EACbD,CACR,CACF,CAEA,eAAeG,EAAgBC,EAAiC,CAC9D,GAAIb,GAAkB,KACtB,GAAI,CACF,MAAMJ,EAAO,YAAY,CAAE,GAAII,EAAgB,KAAM,CAAE,SAAAa,CAAA,EAAY,EACnEL,EAAM,QAAQzB,EAAE,iBAAkB,CAAE,SAAA8B,CAAA,CAAU,CAAC,EAC/CZ,EAAkB,IAAI,CACxB,OAASQ,EAAK,CACZ,KAAM,CAAE,QAAAC,CAAA,EAAYC,EAAcF,EAAK1B,CAAC,EACxCyB,EAAM,MAAME,CAAO,CACrB,CACF,CAEA,MAAMI,EAAuCzB,EAAAA,QAC3C,IAAM,CACJ,CACE,GAAI,KACJ,OAAQN,EAAE,QAAQ,EAClB,KAAOgC,GAAMC,EAAAA,KAAC,OAAA,CAAK,UAAU,6BAA6B,SAAA,CAAA,IAAED,EAAE,EAAA,EAAG,EACjE,cAAe,MAAA,EAEjB,CACE,GAAI,SACJ,OAAQhC,EAAE,YAAY,EACtB,KAAOgC,GAAME,EAAAA,IAAC,OAAA,CAAK,UAAU,2BAA4B,SAAAC,GAAWH,EAAE,OAAO,CAAA,CAAE,EAC/E,cAAe,MAAA,EAEjB,CACE,GAAI,OACJ,OAAQhC,EAAE,UAAU,EACpB,KAAOgC,GAAME,EAAAA,IAAC,QAAK,UAAU,6BAA8B,WAAE,KAAK,EAClE,YAAa,EAAA,EAEf,CACE,GAAI,SACJ,OAAQlC,EAAE,YAAY,EACtB,KAAOgC,SACJI,EAAA,CAAY,OAAQJ,EAAE,OACpB,SAAAhC,EAAE,UAAUgC,EAAE,MAAM,GAAI,CAAE,aAAcA,EAAE,MAAA,CAAQ,EACrD,EAEF,cAAe,MAAA,EAEjB,CACE,GAAI,WACJ,OAAQhC,EAAE,cAAc,EACxB,KAAOgC,GAAME,EAAAA,IAAC,QAAK,UAAU,gBAAiB,WAAE,SAAS,EACzD,cAAe,OACf,aAAc,EAAA,EAEhB,CACE,GAAI,aACJ,OAAQlC,EAAE,gBAAgB,EAC1B,KAAOgC,GACLA,EAAE,uBACCK,EAAA,CAAM,QAAQ,OAAQ,SAAAL,EAAE,iBAAiB,EAE1CE,EAAAA,IAAC,OAAA,CAAK,UAAU,kBAAkB,SAAA,IAAC,EAEvC,cAAe,OACf,aAAc,EAAA,EAEhB,CACE,GAAI,SACJ,OAAQlC,EAAE,YAAY,EACtB,KAAOgC,GACLE,MAAC,OAAA,CAAK,UAAU,gBAAiB,SAAAlC,EAAE,UAAUgC,EAAE,MAAM,GAAI,CAAE,aAAcA,EAAE,MAAA,CAAQ,EAAE,EAEvF,cAAe,OACf,aAAc,EAAA,EAEhB,CACE,GAAI,UACJ,OAAQ,GACR,KAAOA,GACLA,EAAE,SAAW,UACXC,EAAAA,KAAC,MAAA,CAAI,UAAU,yBACb,SAAA,CAAAA,EAAAA,KAACK,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAUC,GAAM,CACdA,EAAE,gBAAA,EACFrB,EAAkBc,EAAE,EAAE,CACxB,EACA,SAAUnB,EAAO,WAAaD,EAAO,UAErC,SAAA,CAAAsB,EAAAA,IAACM,GAAA,CAAM,UAAU,SAAA,CAAU,EAC1BxC,EAAE,eAAe,CAAA,CAAA,CAAA,EAEpBiC,EAAAA,KAACK,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAUC,GAAM,CACdA,EAAE,gBAAA,EACFxB,EAAmBiB,EAAE,EAAE,CACzB,EACA,SAAUpB,EAAO,WAAaC,EAAO,UAErC,SAAA,CAAAqB,EAAAA,IAACpD,GAAA,CAAQ,UAAU,SAAA,CAAU,EAC5BkB,EAAE,eAAe,CAAA,CAAA,CAAA,CACpB,CAAA,CACF,EACE,KACN,cAAe,MAAA,CACjB,EAEF,CAACA,EAAGY,EAAO,UAAWC,EAAO,SAAS,CAAA,EAGxC,OACEoB,EAAAA,KAAC,MAAA,CAAI,UAAU,gCACb,SAAA,CAAAC,EAAAA,IAACO,EAAA,EAAO,EAERR,EAAAA,KAAC,OAAA,CAAK,UAAU,gFACd,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,sBAChB,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAC,MAAC,KAAA,CAAG,UAAU,wBAAyB,SAAAlC,EAAE,WAAW,EAAE,EACtDiC,EAAAA,KAACK,EAAA,CACC,QAAQ,QACR,KAAK,KACL,UAAU,UACV,QAAS,IAAM5B,EAAA,EACf,SAAUD,EACV,aAAYT,EAAE,kBAAmB,CAAE,GAAI,SAAU,EAEhD,SAAA,CAAAS,EAAayB,EAAAA,IAACQ,IAAQ,UAAU,sBAAA,CAAuB,EAAKR,EAAAA,IAACS,GAAA,CAAW,UAAU,SAAA,CAAU,EAC7FT,EAAAA,IAAC,OAAA,CAAK,UAAU,mBAAoB,SAAAlC,EAAE,kBAAmB,CAAE,GAAI,QAAA,CAAU,CAAA,CAAE,CAAA,CAAA,CAAA,CAC7E,EACF,QACC,IAAA,CAAE,UAAU,wBAAyB,SAAAA,EAAE,UAAU,CAAA,CAAE,CAAA,EACtD,EAGAiC,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAC,EAAAA,IAAC,SAAM,UAAU,wBAAwB,QAAQ,gBAC9C,SAAAlC,EAAE,eAAe,EACpB,EACAiC,EAAAA,KAACW,EAAA,CACC,MAAOvC,EACP,cAAgBkB,GAAMJ,EAAY,CAAE,OAAQI,EAAG,EAE/C,SAAA,CAAAW,EAAAA,IAACW,GAAc,GAAG,gBAAgB,UAAU,YAC1C,SAAAX,EAAAA,IAACY,IAAY,CAAA,CACf,EACAZ,EAAAA,IAACa,GACE,SAAAlD,GAAe,IAAKmD,GACnBd,EAAAA,IAACe,GAAmB,MAAOD,EACxB,WAAE,UAAUA,CAAC,GAAI,CAAE,aAAcA,EAAG,GADtBA,CAEjB,CACD,CAAA,CACH,CAAA,CAAA,CAAA,CACF,EACF,EAEAd,EAAAA,IAACgB,EAAA,CACC,QAAAnB,EACA,KAAMpB,EACN,SAAWqB,GAAM,OAAOA,EAAE,EAAE,EAC5B,QAASxB,EACT,WACE0B,EAAAA,IAACiB,EAAA,CACC,WAAOC,GAAA,EAAK,EACZ,MAAOpD,EAAE,aAAa,EACtB,YAAaA,EAAE,mBAAmB,CAAA,CAAA,CACpC,CAAA,EAIJkC,EAAAA,IAACmB,EAAA,CACC,KAAMvC,GAAmB,KACzB,aAAewC,GAAS,CACjBA,GAAMvC,EAAmB,IAAI,CACpC,EACA,MAAOf,EAAE,sBAAsB,EAC/B,YAAaA,EAAE,0BAA0B,EACzC,OAAO,SACP,aAAcA,EAAE,eAAe,EAC/B,UAAWwB,CAAA,CAAA,EAGbU,EAAAA,IAACqB,GAAA,CACC,KAAMtC,GAAkB,KACxB,KAAMJ,EAAO,UACb,aAAeyC,GAAS,CACjBA,GAAMpC,EAAkB,IAAI,CACnC,EACA,OAAQW,CAAA,CAAA,CACV,CAAA,CACF,CAAA,EACF,CAEJ,CASA,SAAS0B,GAAa,CAAE,KAAAD,EAAM,KAAAE,EAAM,aAAAC,EAAc,OAAAC,GAA0C,CAC1F,KAAM,CAAE,EAAA1D,CAAA,EAAMC,EAAe,CAAC,YAAa,QAAQ,CAAC,EACpD,OACEiC,EAAAA,IAACyB,EAAA,CAAO,KAAAL,EAAY,aAAcE,EAAO,IAAM,CAAC,EAAIC,EAClD,SAAAxB,EAAAA,KAAC2B,EAAA,CACC,SAAA,CAAA3B,OAAC4B,EAAA,CACC,SAAA,CAAA3B,EAAAA,IAAC4B,EAAA,CAAa,SAAA9D,EAAE,cAAc,CAAA,CAAE,EAChCkC,EAAAA,IAAC6B,EAAA,CAAmB,SAAA/D,EAAE,oBAAoB,CAAA,CAAE,CAAA,EAC9C,QACC,MAAA,CAAI,UAAU,yBACZ,SAAAF,GAAe,IAAKkE,GACnB9B,EAAAA,IAACI,EAAA,CAEC,KAAK,SACL,QAAQ,UACR,SAAUkB,EACV,QAAS,IAAM,KAAKE,EAAOM,EAAE,QAAQ,EAEpC,SAAAhE,EAAEgE,EAAE,OAAO,CAAA,EANPA,EAAE,QAAA,CAQV,EACH,QACCC,EAAA,CACC,SAAA/B,EAAAA,IAACI,EAAA,CACC,KAAK,SACL,QAAQ,YACR,SAAUkB,EACV,QAAS,IAAMC,EAAa,EAAK,EAEhC,SAAAzD,EAAE,iBAAkB,CAAE,GAAI,SAAU,CAAA,CAAA,CACvC,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CAEA,SAASmC,GAAW+B,EAAqB,CACvC,GAAI,CACF,MAAMC,EAAI,IAAI,KAAKD,CAAG,EACtB,GAAI,OAAO,MAAMC,EAAE,QAAA,CAAS,EAAG,OAAOD,EACtC,MAAME,MAAU,KAEhB,OADgBD,EAAE,aAAA,IAAmBC,EAAI,aAAA,EAEhCD,EAAE,mBAAmB,OAAW,CAAE,KAAM,UAAW,OAAQ,UAAW,EAExEA,EAAE,eAAe,OAAW,CAAE,MAAO,QAAS,IAAK,UAAW,KAAM,UAAW,OAAQ,SAAA,CAAW,CAC3G,MAAQ,CACN,OAAOD,CACT,CACF","x_google_ignoreList":[0]}
@@ -1,7 +1,7 @@
1
- import{n as a}from"./index-CqwhfPlr.js";/**
1
+ import{n as a}from"./index-D4Np2s3l.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const t=a("Save",[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]]);export{t as S};
7
- //# sourceMappingURL=save-DVHI3V6o.js.map
7
+ //# sourceMappingURL=save-B18KQmEd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"save-DVHI3V6o.js","sources":["../../node_modules/lucide-react/dist/esm/icons/save.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Save = createLucideIcon(\"Save\", [\n [\n \"path\",\n {\n d: \"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\",\n key: \"1c8476\"\n }\n ],\n [\"path\", { d: \"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\", key: \"1ydtos\" }],\n [\"path\", { d: \"M7 3v4a1 1 0 0 0 1 1h7\", key: \"t51u73\" }]\n]);\n\nexport { Save as default };\n//# sourceMappingURL=save.js.map\n"],"names":["Save","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAOC,EAAiB,OAAQ,CACpC,CACE,OACA,CACE,EAAG,qGACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,4CAA6C,IAAK,QAAQ,CAAE,EAC1E,CAAC,OAAQ,CAAE,EAAG,yBAA0B,IAAK,QAAQ,CAAE,CACzD,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"save-B18KQmEd.js","sources":["../../node_modules/lucide-react/dist/esm/icons/save.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Save = createLucideIcon(\"Save\", [\n [\n \"path\",\n {\n d: \"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\",\n key: \"1c8476\"\n }\n ],\n [\"path\", { d: \"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\", key: \"1ydtos\" }],\n [\"path\", { d: \"M7 3v4a1 1 0 0 0 1 1h7\", key: \"t51u73\" }]\n]);\n\nexport { Save as default };\n//# sourceMappingURL=save.js.map\n"],"names":["Save","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAOC,EAAiB,OAAQ,CACpC,CACE,OACA,CACE,EAAG,qGACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,4CAA6C,IAAK,QAAQ,CAAE,EAC1E,CAAC,OAAQ,CAAE,EAAG,yBAA0B,IAAK,QAAQ,CAAE,CACzD,CAAC","x_google_ignoreList":[0]}
@@ -1,7 +1,7 @@
1
- import{n as f,d as g,u as N,e as j,j as s,k as r,B as y,L as w,I as b}from"./index-CqwhfPlr.js";import{r as C}from"./react-Cb2sDjhD.js";import{D as k}from"./data-table-B80M8zdu.js";import{E as v}from"./empty-state-CrPnUC6d.js";import{u as R}from"./useQuery-Ds6-WURB.js";import{L as S}from"./loader-circle-U-jPjmeD.js";import{R as L}from"./refresh-ccw-CBiHL1tY.js";import"./table-BNqo2xb8.js";import"./arrow-up-NWC5K6Jw.js";import"./arrow-down-BkZ50IzL.js";/**
1
+ import{n as f,d as g,u as N,e as j,j as s,k as r,B as y,L as w,I as b}from"./index-D4Np2s3l.js";import{r as C}from"./react-Cb2sDjhD.js";import{D as k}from"./data-table-B_sUmaE2.js";import{E as v}from"./empty-state-CtWM3HCj.js";import{u as R}from"./useQuery-B25CPtUF.js";import{L as S}from"./loader-circle-BfXi9R6u.js";import{R as L}from"./refresh-ccw-C7VT3MFu.js";import"./table-C4P3KPbF.js";import"./arrow-up-BQxFty9k.js";import"./arrow-down-BpfVJViL.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const M=f("CalendarClock",[["path",{d:"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5",key:"1osxxc"}],["path",{d:"M16 2v4",key:"4m81vk"}],["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M3 10h5",key:"r794hk"}],["path",{d:"M17.5 17.5 16 16.3V14",key:"akvzfd"}],["circle",{cx:"16",cy:"16",r:"6",key:"qoo3c4"}]]),T={all:["schedules"],list:e=>["schedules","list",e]};function E(e){return R({queryKey:T.list(e),queryFn:()=>g.listSchedules(e)})}function V(){const{t:e}=N(["tasks","common"]),[t,i]=j(),l=t.get("agent")??"",{data:m,isLoading:o,isFetching:n,refetch:h}=E(l?{agent:l}:{}),u=m?.schedules??[];function x(a){const c=new URLSearchParams(t);a?c.set("agent",a):c.delete("agent"),i(c,{replace:!0})}const p=C.useMemo(()=>[{id:"id",header:e("schedules.col.id"),cell:a=>s.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",a.id]}),headClassName:"w-16"},{id:"name",header:e("schedules.col.name"),cell:a=>s.jsx("span",{className:"font-medium",children:a.name}),asCardTitle:!0},{id:"agent",header:e("schedules.col.agent"),cell:a=>s.jsx("span",{className:"text-text-dim",children:a.agent}),headClassName:"w-32"},{id:"cron",header:e("schedules.col.cron"),cell:a=>s.jsx("code",{className:"rounded bg-surface-2 px-1.5 py-0.5 text-xs",children:a.cron}),headClassName:"w-32"},{id:"prompt",header:e("schedules.col.prompt"),cell:a=>s.jsx("span",{className:"line-clamp-2 text-text-dim",children:a.prompt}),hideOnMobile:!0},{id:"enabled",header:e("schedules.col.enabled"),cell:a=>a.enabled?s.jsx(r,{variant:"success",children:e("schedules.enabled")}):s.jsx(r,{variant:"outline",children:e("schedules.disabled")}),headClassName:"w-20"},{id:"nextRun",header:e("schedules.col.nextRun"),cell:a=>s.jsx("span",{className:"text-text-dim",children:d(a.next_run)}),headClassName:"w-40"},{id:"lastRun",header:e("schedules.col.lastRun"),cell:a=>s.jsx("span",{className:"text-text-dim",children:d(a.last_run)}),headClassName:"w-40",hideOnMobile:!0}],[e]);return s.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[s.jsxs("header",{className:"flex flex-col gap-1",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[s.jsx("h1",{className:"text-xl font-semibold",children:e("schedules.title")}),s.jsxs(y,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>h(),disabled:n,"aria-label":e("actions.refresh",{ns:"common"}),children:[n?s.jsx(S,{className:"h-4 w-4 animate-spin"}):s.jsx(L,{className:"h-4 w-4"}),s.jsx("span",{className:"hidden sm:inline",children:e("actions.refresh",{ns:"common"})})]})]}),s.jsx("p",{className:"text-sm text-text-dim",children:e("schedules.subtitle")})]}),s.jsx("div",{className:"flex flex-wrap items-end gap-2",children:s.jsxs("div",{className:"flex flex-col gap-1",children:[s.jsx(w,{htmlFor:"agent-filter",className:"text-xs text-text-dim",children:e("schedules.filter.agent")}),s.jsx(b,{id:"agent-filter",value:l,onChange:a=>x(a.target.value),placeholder:e("schedules.filter.agentAny"),className:"w-48"})]})}),s.jsx(k,{columns:p,rows:u,getRowId:a=>String(a.id),loading:o,emptyState:s.jsx(v,{icon:s.jsx(M,{}),title:e("schedules.empty.title"),description:e("schedules.empty.description")})})]})}function d(e){if(e==null)return"—";try{const t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return e}}export{V as default};
7
- //# sourceMappingURL=schedules-DYf64Fpr.js.map
7
+ //# sourceMappingURL=schedules-CA4eHggo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schedules-DYf64Fpr.js","sources":["../../node_modules/lucide-react/dist/esm/icons/calendar-clock.js","../../src/hooks/use-schedules.ts","../../src/routes/tasks/schedules.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CalendarClock = createLucideIcon(\"CalendarClock\", [\n [\"path\", { d: \"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5\", key: \"1osxxc\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"path\", { d: \"M3 10h5\", key: \"r794hk\" }],\n [\"path\", { d: \"M17.5 17.5 16 16.3V14\", key: \"akvzfd\" }],\n [\"circle\", { cx: \"16\", cy: \"16\", r: \"6\", key: \"qoo3c4\" }]\n]);\n\nexport { CalendarClock as default };\n//# sourceMappingURL=calendar-clock.js.map\n","/**\n * useSchedules — react-query wrapper for /api/schedules.\n *\n * Read-only: schedule create / delete / toggle isn't exposed via\n * /api today (only via CLI). When that lands the mutations slot in\n * here next to useSchedules.\n */\n\nimport { useQueryClient, useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type { ListSchedulesQuery, ListSchedulesResponse } from '@/types/api'\n\nexport const schedulesKeys = {\n all: ['schedules'] as const,\n list: (q: ListSchedulesQuery) => ['schedules', 'list', q] as const,\n}\n\nexport function useSchedules(query: ListSchedulesQuery) {\n return useQuery<ListSchedulesResponse>({\n queryKey: schedulesKeys.list(query),\n queryFn: () => api.listSchedules(query),\n })\n}\n\nexport function useInvalidateSchedules() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: schedulesKeys.all })\n}\n","/**\n * /tasks/schedules — cron-style triggers list. Read-only; mutations\n * (create / delete / toggle) only exist via CLI today; the page\n * shows what's scheduled and when the next run lands.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { CalendarClock, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { useSchedules } from '@/hooks/use-schedules'\nimport type { Schedule } from '@/types/api'\n\nexport default function SchedulesRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const [params, setParams] = useSearchParams()\n const agent = params.get('agent') ?? ''\n\n const { data, isLoading, isFetching, refetch } = useSchedules(\n agent ? { agent } : {},\n )\n const schedules = data?.schedules ?? []\n\n function setAgentFilter(v: string): void {\n const next = new URLSearchParams(params)\n if (!v) next.delete('agent')\n else next.set('agent', v)\n setParams(next, { replace: true })\n }\n\n const columns: DataTableColumn<Schedule>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('schedules.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'name',\n header: t('schedules.col.name'),\n cell: (r) => <span className=\"font-medium\">{r.name}</span>,\n asCardTitle: true,\n },\n {\n id: 'agent',\n header: t('schedules.col.agent'),\n cell: (r) => <span className=\"text-text-dim\">{r.agent}</span>,\n headClassName: 'w-32',\n },\n {\n id: 'cron',\n header: t('schedules.col.cron'),\n cell: (r) => <code className=\"rounded bg-surface-2 px-1.5 py-0.5 text-xs\">{r.cron}</code>,\n headClassName: 'w-32',\n },\n {\n id: 'prompt',\n header: t('schedules.col.prompt'),\n cell: (r) => <span className=\"line-clamp-2 text-text-dim\">{r.prompt}</span>,\n hideOnMobile: true,\n },\n {\n id: 'enabled',\n header: t('schedules.col.enabled'),\n cell: (r) =>\n r.enabled ? (\n <Badge variant=\"success\">{t('schedules.enabled')}</Badge>\n ) : (\n <Badge variant=\"outline\">{t('schedules.disabled')}</Badge>\n ),\n headClassName: 'w-20',\n },\n {\n id: 'nextRun',\n header: t('schedules.col.nextRun'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.next_run)}</span>,\n headClassName: 'w-40',\n },\n {\n id: 'lastRun',\n header: t('schedules.col.lastRun'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.last_run)}</span>,\n headClassName: 'w-40',\n hideOnMobile: true,\n },\n ],\n [t],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('schedules.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('schedules.subtitle')}</p>\n </header>\n\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"agent-filter\" className=\"text-xs text-text-dim\">\n {t('schedules.filter.agent')}\n </Label>\n <Input\n id=\"agent-filter\"\n value={agent}\n onChange={(e) => setAgentFilter(e.target.value)}\n placeholder={t('schedules.filter.agentAny')}\n className=\"w-48\"\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n rows={schedules}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n emptyState={\n <EmptyState\n icon={<CalendarClock />}\n title={t('schedules.empty.title')}\n description={t('schedules.empty.description')}\n />\n }\n />\n </div>\n )\n}\n\nfunction formatTime(iso: string | undefined | null): string {\n if (iso == null) return '—'\n try {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return iso\n }\n}\n"],"names":["CalendarClock","createLucideIcon","schedulesKeys","q","useSchedules","query","useQuery","api","SchedulesRoute","t","useTranslation","params","setParams","useSearchParams","agent","data","isLoading","isFetching","refetch","schedules","setAgentFilter","v","next","columns","useMemo","r","jsxs","jsx","Badge","formatTime","Button","Loader2","RefreshCcw","Label","Input","e","DataTable","EmptyState","iso","d"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"schedules-CA4eHggo.js","sources":["../../node_modules/lucide-react/dist/esm/icons/calendar-clock.js","../../src/hooks/use-schedules.ts","../../src/routes/tasks/schedules.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CalendarClock = createLucideIcon(\"CalendarClock\", [\n [\"path\", { d: \"M21 7.5V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h3.5\", key: \"1osxxc\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"path\", { d: \"M3 10h5\", key: \"r794hk\" }],\n [\"path\", { d: \"M17.5 17.5 16 16.3V14\", key: \"akvzfd\" }],\n [\"circle\", { cx: \"16\", cy: \"16\", r: \"6\", key: \"qoo3c4\" }]\n]);\n\nexport { CalendarClock as default };\n//# sourceMappingURL=calendar-clock.js.map\n","/**\n * useSchedules — react-query wrapper for /api/schedules.\n *\n * Read-only: schedule create / delete / toggle isn't exposed via\n * /api today (only via CLI). When that lands the mutations slot in\n * here next to useSchedules.\n */\n\nimport { useQueryClient, useQuery } from '@tanstack/react-query'\nimport { api } from '@/lib/api/endpoints'\nimport type { ListSchedulesQuery, ListSchedulesResponse } from '@/types/api'\n\nexport const schedulesKeys = {\n all: ['schedules'] as const,\n list: (q: ListSchedulesQuery) => ['schedules', 'list', q] as const,\n}\n\nexport function useSchedules(query: ListSchedulesQuery) {\n return useQuery<ListSchedulesResponse>({\n queryKey: schedulesKeys.list(query),\n queryFn: () => api.listSchedules(query),\n })\n}\n\nexport function useInvalidateSchedules() {\n const qc = useQueryClient()\n return () => qc.invalidateQueries({ queryKey: schedulesKeys.all })\n}\n","/**\n * /tasks/schedules — cron-style triggers list. Read-only; mutations\n * (create / delete / toggle) only exist via CLI today; the page\n * shows what's scheduled and when the next run lands.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { CalendarClock, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { useSchedules } from '@/hooks/use-schedules'\nimport type { Schedule } from '@/types/api'\n\nexport default function SchedulesRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const [params, setParams] = useSearchParams()\n const agent = params.get('agent') ?? ''\n\n const { data, isLoading, isFetching, refetch } = useSchedules(\n agent ? { agent } : {},\n )\n const schedules = data?.schedules ?? []\n\n function setAgentFilter(v: string): void {\n const next = new URLSearchParams(params)\n if (!v) next.delete('agent')\n else next.set('agent', v)\n setParams(next, { replace: true })\n }\n\n const columns: DataTableColumn<Schedule>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('schedules.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'name',\n header: t('schedules.col.name'),\n cell: (r) => <span className=\"font-medium\">{r.name}</span>,\n asCardTitle: true,\n },\n {\n id: 'agent',\n header: t('schedules.col.agent'),\n cell: (r) => <span className=\"text-text-dim\">{r.agent}</span>,\n headClassName: 'w-32',\n },\n {\n id: 'cron',\n header: t('schedules.col.cron'),\n cell: (r) => <code className=\"rounded bg-surface-2 px-1.5 py-0.5 text-xs\">{r.cron}</code>,\n headClassName: 'w-32',\n },\n {\n id: 'prompt',\n header: t('schedules.col.prompt'),\n cell: (r) => <span className=\"line-clamp-2 text-text-dim\">{r.prompt}</span>,\n hideOnMobile: true,\n },\n {\n id: 'enabled',\n header: t('schedules.col.enabled'),\n cell: (r) =>\n r.enabled ? (\n <Badge variant=\"success\">{t('schedules.enabled')}</Badge>\n ) : (\n <Badge variant=\"outline\">{t('schedules.disabled')}</Badge>\n ),\n headClassName: 'w-20',\n },\n {\n id: 'nextRun',\n header: t('schedules.col.nextRun'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.next_run)}</span>,\n headClassName: 'w-40',\n },\n {\n id: 'lastRun',\n header: t('schedules.col.lastRun'),\n cell: (r) => <span className=\"text-text-dim\">{formatTime(r.last_run)}</span>,\n headClassName: 'w-40',\n hideOnMobile: true,\n },\n ],\n [t],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('schedules.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('schedules.subtitle')}</p>\n </header>\n\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"agent-filter\" className=\"text-xs text-text-dim\">\n {t('schedules.filter.agent')}\n </Label>\n <Input\n id=\"agent-filter\"\n value={agent}\n onChange={(e) => setAgentFilter(e.target.value)}\n placeholder={t('schedules.filter.agentAny')}\n className=\"w-48\"\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n rows={schedules}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n emptyState={\n <EmptyState\n icon={<CalendarClock />}\n title={t('schedules.empty.title')}\n description={t('schedules.empty.description')}\n />\n }\n />\n </div>\n )\n}\n\nfunction formatTime(iso: string | undefined | null): string {\n if (iso == null) return '—'\n try {\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return iso\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return iso\n }\n}\n"],"names":["CalendarClock","createLucideIcon","schedulesKeys","q","useSchedules","query","useQuery","api","SchedulesRoute","t","useTranslation","params","setParams","useSearchParams","agent","data","isLoading","isFetching","refetch","schedules","setAgentFilter","v","next","columns","useMemo","r","jsxs","jsx","Badge","formatTime","Button","Loader2","RefreshCcw","Label","Input","e","DataTable","EmptyState","iso","d"],"mappings":"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","x_google_ignoreList":[0]}