forge-openclaw-plugin 0.3.15 → 0.3.16

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 (362) hide show
  1. package/README.md +6 -6
  2. package/dist/assets/{action-bar-B9MYlps2.js → action-bar-DgrmzFrI.js} +1 -1
  3. package/dist/assets/{activity-page-DbzbChcE.js → activity-page-CF451ueg.js} +1 -1
  4. package/dist/assets/{ai-surface-workspace-CF0257Hs.js → ai-surface-workspace-DtwybxJB.js} +1 -1
  5. package/dist/assets/{atlas-panel-CO3RYAKn.js → atlas-panel-CB3uYk_K.js} +1 -1
  6. package/dist/assets/{calendar-page-BuuHKEHC.js → calendar-page-BYsDuLnh.js} +1 -1
  7. package/dist/assets/{calendar-rules-DKftgNx5.js → calendar-rules-DXuOv2J-.js} +1 -1
  8. package/dist/assets/{calendar-week-toolbar-ChIpkT-G.js → calendar-week-toolbar-8PJmiUE_.js} +1 -1
  9. package/dist/assets/{companion-sync-lab-page-BZRX4Btw.js → companion-sync-lab-page-DzWNOaBh.js} +1 -1
  10. package/dist/assets/{daily-metrics-dashboard-CXDsaAQd.js → daily-metrics-dashboard-CHcYxDhs.js} +1 -1
  11. package/dist/assets/{define-workbench-box-CpG0Zb1L.js → define-workbench-box-DcI0_QKW.js} +1 -1
  12. package/dist/assets/{entity-link-multiselect-Dl4rZqdg.js → entity-link-multiselect-C--AiCMb.js} +1 -1
  13. package/dist/assets/{entity-note-count-link-Bs1aKYyD.js → entity-note-count-link-xne6mshj.js} +1 -1
  14. package/dist/assets/{entity-notes-surface-B56XSw7M.js → entity-notes-surface-jy6Psist.js} +1 -1
  15. package/dist/assets/{execution-board-D66C_ikW.js → execution-board-BSUZCIIx.js} +1 -1
  16. package/dist/assets/{faceted-token-search-Dg2rjknH.js → faceted-token-search-BMQ1Wwzt.js} +1 -1
  17. package/dist/assets/{flagship-signal-deck-C6KVPhmM.js → flagship-signal-deck-DjcskRwF.js} +1 -1
  18. package/dist/assets/{floating-action-menu-DAFAEBcA.js → floating-action-menu-cGhbJ2tc.js} +1 -1
  19. package/dist/assets/{generic-node-view-C6DK5hJ6.js → generic-node-view-DNVwfqqq.js} +1 -1
  20. package/dist/assets/{goal-detail-page-CC4VXud6.js → goal-detail-page-dAbyCilO.js} +1 -1
  21. package/dist/assets/{goal-dialog-15hD8EBp.js → goal-dialog-DH50D0tP.js} +1 -1
  22. package/dist/assets/{goals-page-CQ2lJMzI.js → goals-page-DkMy9mPD.js} +1 -1
  23. package/dist/assets/{habits-page-a7KVPaQp.js → habits-page-CCQR8rg6.js} +1 -1
  24. package/dist/assets/{health-boxes-DqgvIYoL.js → health-boxes-BPTgGM6G.js} +1 -1
  25. package/dist/assets/index-VzCGTBS_.css +1 -0
  26. package/dist/assets/{index-FpGANF9S.js → index-izRKx6JK.js} +2 -2
  27. package/dist/assets/{inline-note-fields-COgzxr_7.js → inline-note-fields-D4mCM1gO.js} +1 -1
  28. package/dist/assets/{insight-flow-dialog-Dmb6NSGp.js → insight-flow-dialog-Btp6bkbV.js} +1 -1
  29. package/dist/assets/{insights-page-OnqR4cYI.js → insights-page-1qM4mxjS.js} +1 -1
  30. package/dist/assets/{kanban-boxes-BWUzntCV.js → kanban-boxes-u_A-UJG-.js} +1 -1
  31. package/dist/assets/{kanban-page-BI16Gzp_.js → kanban-page-CKCa_3Qb.js} +1 -1
  32. package/dist/assets/{knowledge-graph-page-DxEBaEke.js → knowledge-graph-page-BZOxRv19.js} +1 -1
  33. package/dist/assets/{life-force-page-CDEXEQai.js → life-force-page-BZlyA144.js} +1 -1
  34. package/dist/assets/{life-force-workspace-C7UOnJEf.js → life-force-workspace-CtAWZXNw.js} +1 -1
  35. package/dist/assets/{metric-tile-boeHB1R1.js → metric-tile-Bkx2btO2.js} +1 -1
  36. package/dist/assets/{movement-boxes-BUSqaTL2.js → movement-boxes-QZ2EIS9q.js} +1 -1
  37. package/dist/assets/{movement-page-DcbO0497.js → movement-page-B-3ihggI.js} +1 -1
  38. package/dist/assets/{note-markdown-DXXI3W3V.js → note-markdown-BWedRE3c.js} +1 -1
  39. package/dist/assets/{note-tags-input-CYh3TVW2.js → note-tags-input-DZkCqI1w.js} +1 -1
  40. package/dist/assets/{notes-boxes-CMJXX2K0.js → notes-boxes-DGFmt7Dp.js} +1 -1
  41. package/dist/assets/{notes-page-DvHMcQey.js → notes-page-DYkn04tz.js} +1 -1
  42. package/dist/assets/{open-in-graph-button-4UYrp1XP.js → open-in-graph-button-CjvkEj1P.js} +1 -1
  43. package/dist/assets/{orbit-map-BwK7sDaC.js → orbit-map-CRHSPenk.js} +1 -1
  44. package/dist/assets/{overview-page-Z5vaUTm3.js → overview-page-D6LsjPWe.js} +1 -1
  45. package/dist/assets/{page-hero-DvrM83_C.js → page-hero-BLhM8FF3.js} +1 -1
  46. package/dist/assets/{pill-cluster-DYI3Ibj8.js → pill-cluster-B5bYs_e2.js} +1 -1
  47. package/dist/assets/{preference-entity-handoff-button-C2ATjvws.js → preference-entity-handoff-button-CfCQl3cW.js} +1 -1
  48. package/dist/assets/{preferences-page-BAexXHye.js → preferences-page-OltGdsQ2.js} +1 -1
  49. package/dist/assets/{project-collections-B9nr-Ts-.js → project-collections-FfBIVwXu.js} +1 -1
  50. package/dist/assets/{project-detail-page-B9PqyPu9.js → project-detail-page-CCm3iZPQ.js} +1 -1
  51. package/dist/assets/{project-dialog-CBA-D65n.js → project-dialog-B_J1ESMk.js} +1 -1
  52. package/dist/assets/{project-management-hierarchy-page-DXK14jn0.js → project-management-hierarchy-page-BNzvtNZj.js} +1 -1
  53. package/dist/assets/{project-management-section-nav-DJ3QKCtr.js → project-management-section-nav-DBNHt9p5.js} +1 -1
  54. package/dist/assets/{projects-boxes-iBu_PRqe.js → projects-boxes-BvlVsO5q.js} +1 -1
  55. package/dist/assets/{projects-page-CdAk-ByT.js → projects-page-BUf7KV-_.js} +1 -1
  56. package/dist/assets/{psyche-behaviors-page-CbhhTfU2.js → psyche-behaviors-page-jtyhdpJ1.js} +1 -1
  57. package/dist/assets/{psyche-flashcards-page-DQaw_vUQ.js → psyche-flashcards-page-05606-97.js} +1 -1
  58. package/dist/assets/{psyche-goal-map-page-C-ZTVOEP.js → psyche-goal-map-page-Cw-aqS3Y.js} +1 -1
  59. package/dist/assets/{psyche-graph-DYzeClxn.js → psyche-graph-0E22QHPe.js} +1 -1
  60. package/dist/assets/{psyche-metrics-page-C9hKn10A.js → psyche-metrics-page-DBFVPeMa.js} +1 -1
  61. package/dist/assets/{psyche-mode-guide-page-CR8e984W.js → psyche-mode-guide-page-DI-LNEDT.js} +1 -1
  62. package/dist/assets/psyche-modes-page-CaMupyfi.js +1 -0
  63. package/dist/assets/{psyche-page-CTdIDkw9.js → psyche-page-CFBq0YKf.js} +1 -1
  64. package/dist/assets/{psyche-patterns-page-Drgm-f7I.js → psyche-patterns-page-sp4ikoef.js} +1 -1
  65. package/dist/assets/{psyche-questionnaire-builder-page-gRwdGXde.js → psyche-questionnaire-builder-page-DEt0UDsz.js} +1 -1
  66. package/dist/assets/{psyche-questionnaire-detail-page-CIP9b2UI.js → psyche-questionnaire-detail-page-BXQbOE6A.js} +1 -1
  67. package/dist/assets/{psyche-questionnaire-run-detail-page-SYndwtF3.js → psyche-questionnaire-run-detail-page-Cd3ClsSK.js} +1 -1
  68. package/dist/assets/{psyche-questionnaire-run-page-CXiJyd5i.js → psyche-questionnaire-run-page-D_EokOQm.js} +1 -1
  69. package/dist/assets/{psyche-questionnaires-page-CFPKwA3O.js → psyche-questionnaires-page-D1Ov2L4n.js} +1 -1
  70. package/dist/assets/{psyche-report-detail-page-dU30a2WE.js → psyche-report-detail-page-9HyPr8BJ.js} +1 -1
  71. package/dist/assets/{psyche-reports-page-Cn0EBndy.js → psyche-reports-page-BeyJg5fb.js} +1 -1
  72. package/dist/assets/{psyche-schemas-beliefs-page-Bab4xSWv.js → psyche-schemas-beliefs-page-DNmf-Vma.js} +1 -1
  73. package/dist/assets/{psyche-screen-time-page-lIe6GQxJ.js → psyche-screen-time-page-DJMDR5oo.js} +1 -1
  74. package/dist/assets/{psyche-self-observation-page-BTE3KfIl.js → psyche-self-observation-page-DFKXG1Yv.js} +1 -1
  75. package/dist/assets/{psyche-values-page-DclBZ9xw.js → psyche-values-page-TWKth89J.js} +1 -1
  76. package/dist/assets/{question-flow-dialog-Ded2E85L.js → question-flow-dialog-D-_EvoAt.js} +1 -1
  77. package/dist/assets/{report-chain-fields-DY640iqL.js → report-chain-fields-Dy-jBQDn.js} +1 -1
  78. package/dist/assets/{rewards-page-FxUXB76B.js → rewards-page-D3ymEd2X.js} +1 -1
  79. package/dist/assets/{scheduling-rules-editor-jakFfxqF.js → scheduling-rules-editor-CAd290IE.js} +1 -1
  80. package/dist/assets/{schema-badge-30B5syHA.js → schema-badge-BLaVI1D7.js} +1 -1
  81. package/dist/assets/{schemas-Db29G8NU.js → schemas-B0Pa-V-A.js} +1 -1
  82. package/dist/assets/{select-menu-BF2zI3RW.js → select-menu-DcS4Ukjf.js} +1 -1
  83. package/dist/assets/{settings-agents-page-Bh-Bv6FQ.js → settings-agents-page-Bt38HhEJ.js} +1 -1
  84. package/dist/assets/{settings-bin-page-DT8JJero.js → settings-bin-page-DqyVI1i1.js} +1 -1
  85. package/dist/assets/{settings-calendar-page-BA4_Qqiu.js → settings-calendar-page-DPSSZV3s.js} +1 -1
  86. package/dist/assets/{settings-data-page-K4kpmQJY.js → settings-data-page-BdHsD1C_.js} +1 -1
  87. package/dist/assets/{settings-logs-page-DkuNPAZo.js → settings-logs-page-D9OnWoFq.js} +1 -1
  88. package/dist/assets/{settings-mobile-page-4pCNwD91.js → settings-mobile-page-DFpsXA4M.js} +1 -1
  89. package/dist/assets/{settings-models-page-CZHG3t7W.js → settings-models-page-DaFXLp-O.js} +1 -1
  90. package/dist/assets/{settings-page-B_Be0vOY.js → settings-page-m_3iYPwU.js} +1 -1
  91. package/dist/assets/{settings-rewards-page-C6nFTWJu.js → settings-rewards-page-B2aBm-dA.js} +1 -1
  92. package/dist/assets/{settings-section-nav-Lo-VKCfZ.js → settings-section-nav-CMeU19Rx.js} +1 -1
  93. package/dist/assets/{settings-users-page-CVzNp4-m.js → settings-users-page-D8jyewJl.js} +1 -1
  94. package/dist/assets/{settings-wiki-page-DXM--7BB.js → settings-wiki-page-DjOgQJAh.js} +1 -1
  95. package/dist/assets/{sleep-page-DvPdZMKx.js → sleep-page-D8-dA4bE.js} +1 -1
  96. package/dist/assets/{sports-page-DjuZlOur.js → sports-page-CK3PgPKB.js} +1 -1
  97. package/dist/assets/{strategies-page-PE1IlatS.js → strategies-page-aFpJath-.js} +1 -1
  98. package/dist/assets/{strategy-detail-page-C4KiEGCI.js → strategy-detail-page-CobF5qLv.js} +1 -1
  99. package/dist/assets/{strategy-dialog-Cwf7Y3P5.js → strategy-dialog-Fgoaoob5.js} +1 -1
  100. package/dist/assets/{surface-ubuOfukq.js → surface-D0dqgX-k.js} +1 -1
  101. package/dist/assets/{task-detail-page-B3SMFZQ3.js → task-detail-page-CDK79bzk.js} +1 -1
  102. package/dist/assets/{task-dialog-CI_Fy_FW.js → task-dialog-eCDTF8xe.js} +4 -4
  103. package/dist/assets/{timebox-planning-dialog-BtFuVoA1.js → timebox-planning-dialog-CNZIGSpd.js} +1 -1
  104. package/dist/assets/{today-boxes-CYuxSkZf.js → today-boxes-CYfskVrM.js} +1 -1
  105. package/dist/assets/{today-page-CHGpLEZ3.js → today-page-Bnh8wopq.js} +1 -1
  106. package/dist/assets/{training-load-page-GZJF-Yy5.js → training-load-page-C7lq-jqy.js} +1 -1
  107. package/dist/assets/{user-badge-ByhC6bMU.js → user-badge-MEZuJiir.js} +1 -1
  108. package/dist/assets/{utility-widgets-ilORjDmg.js → utility-widgets-h5eG2jvc.js} +1 -1
  109. package/dist/assets/{vitals-page-mdEqIm_9.js → vitals-page-eoFnQ3XL.js} +1 -1
  110. package/dist/assets/{weekly-review-page-C8W-yg5r.js → weekly-review-page-C7BU1gkK.js} +1 -1
  111. package/dist/assets/{weight-loss-page-BApTknCn.js → weight-loss-page-Cc7Do3XY.js} +1 -1
  112. package/dist/assets/{wiki-article-markdown-DBccllQg.js → wiki-article-markdown-CCKoSptz.js} +1 -1
  113. package/dist/assets/{wiki-editor-page-BfRfH1O3.js → wiki-editor-page-BpbxZrgz.js} +1 -1
  114. package/dist/assets/{wiki-ingest-history-page-C-6H3MU6.js → wiki-ingest-history-page-D5Wfr8pc.js} +1 -1
  115. package/dist/assets/{wiki-ingest-modal-DnlhByD_.js → wiki-ingest-modal-DhRVsEwC.js} +1 -1
  116. package/dist/assets/{wiki-page-DPZ55e3x.js → wiki-page-1vf-HErs.js} +1 -1
  117. package/dist/assets/{workbench-flow-page-_-NKIx5R.js → workbench-flow-page-y9FxDbKO.js} +1 -1
  118. package/dist/assets/{workbench-page-NIAzggwX.js → workbench-page-Da16AZvN.js} +1 -1
  119. package/dist/assets/{workout-detail-page-3fxr6HL4.js → workout-detail-page-Cq0YamXF.js} +1 -1
  120. package/dist/index.html +2 -2
  121. package/dist/openclaw/api-client.js +28 -2
  122. package/dist/openclaw/local-runtime.js +31 -14
  123. package/dist/server/{server → apps/api}/src/app.js +1 -1
  124. package/dist/server/{server → apps/api}/src/connectors/box-registry.js +3 -3
  125. package/dist/server/{server → apps/api}/src/db.js +23 -4
  126. package/dist/server/{server → apps/api}/src/health-weight-loss.js +1 -1
  127. package/dist/server/{server → apps/api}/src/questionnaire-seeds.js +1 -1
  128. package/dist/server/{server → apps/api}/src/repositories/ai-connectors.js +1 -1
  129. package/dist/server/{server → apps/api}/src/repositories/habits.js +1 -1
  130. package/dist/server/{server → apps/api}/src/services/companion-iroh.js +4 -1
  131. package/dist/server/{server → apps/api}/src/services/doctor.js +3 -3
  132. package/dist/server/{server → apps/api}/src/services/gamification-assets.js +1 -1
  133. package/dist/server/{server → apps/api}/src/services/gamification.js +1 -1
  134. package/dist/server/{server → apps/api}/src/services/knowledge-graph.js +3 -3
  135. package/dist/server/{server → apps/api}/src/types.js +2 -2
  136. package/dist/server/{server → apps/api}/src/watch-mobile.js +1 -1
  137. package/openclaw.plugin.json +1 -1
  138. package/package.json +3 -3
  139. package/server/index.js +3 -3
  140. package/skills/forge-openclaw/SKILL.md +5 -5
  141. package/dist/assets/index-ClJbJhca.css +0 -1
  142. package/dist/assets/psyche-modes-page-lQdpAcY3.js +0 -1
  143. /package/dist/server/{server → apps/api}/migrations/001_core.sql +0 -0
  144. /package/dist/server/{server → apps/api}/migrations/002_psyche.sql +0 -0
  145. /package/dist/server/{server → apps/api}/migrations/003_habits.sql +0 -0
  146. /package/dist/server/{server → apps/api}/migrations/004_habit_links.sql +0 -0
  147. /package/dist/server/{server → apps/api}/migrations/005_habit_psyche_links.sql +0 -0
  148. /package/dist/server/{server → apps/api}/migrations/006_work_adjustments.sql +0 -0
  149. /package/dist/server/{server → apps/api}/migrations/007_weekly_review_closures.sql +0 -0
  150. /package/dist/server/{server → apps/api}/migrations/008_calendar_execution.sql +0 -0
  151. /package/dist/server/{server → apps/api}/migrations/009_true_calendar_events.sql +0 -0
  152. /package/dist/server/{server → apps/api}/migrations/010_calendar_selection_state.sql +0 -0
  153. /package/dist/server/{server → apps/api}/migrations/011_calendar_timezone_backfill.sql +0 -0
  154. /package/dist/server/{server → apps/api}/migrations/012_work_block_ranges.sql +0 -0
  155. /package/dist/server/{server → apps/api}/migrations/013_microsoft_local_auth_settings.sql +0 -0
  156. /package/dist/server/{server → apps/api}/migrations/014_note_tags_and_ephemeral.sql +0 -0
  157. /package/dist/server/{server → apps/api}/migrations/015_multi_user_and_strategies.sql +0 -0
  158. /package/dist/server/{server → apps/api}/migrations/016_health_companion.sql +0 -0
  159. /package/dist/server/{server → apps/api}/migrations/016_strategy_contracts_and_user_graph.sql +0 -0
  160. /package/dist/server/{server → apps/api}/migrations/017_preferences.sql +0 -0
  161. /package/dist/server/{server → apps/api}/migrations/018_preference_catalogs.sql +0 -0
  162. /package/dist/server/{server → apps/api}/migrations/019_wiki_memory.sql +0 -0
  163. /package/dist/server/{server → apps/api}/migrations/020_wiki_page_hierarchy.sql +0 -0
  164. /package/dist/server/{server → apps/api}/migrations/021_hide_evidence_from_wiki_index.sql +0 -0
  165. /package/dist/server/{server → apps/api}/migrations/022_wiki_ingest_background.sql +0 -0
  166. /package/dist/server/{server → apps/api}/migrations/023_diagnostic_logs.sql +0 -0
  167. /package/dist/server/{server → apps/api}/migrations/024_questionnaires.sql +0 -0
  168. /package/dist/server/{server → apps/api}/migrations/025_ai_model_connections.sql +0 -0
  169. /package/dist/server/{server → apps/api}/migrations/026_custom_theme_settings.sql +0 -0
  170. /package/dist/server/{server → apps/api}/migrations/027_ai_processors.sql +0 -0
  171. /package/dist/server/{server → apps/api}/migrations/028_movement_domain.sql +0 -0
  172. /package/dist/server/{server → apps/api}/migrations/029_watch_micro_capture.sql +0 -0
  173. /package/dist/server/{server → apps/api}/migrations/030_surface_layouts.sql +0 -0
  174. /package/dist/server/{server → apps/api}/migrations/031_ai_processor_runtime_upgrades.sql +0 -0
  175. /package/dist/server/{server → apps/api}/migrations/032_ai_connectors.sql +0 -0
  176. /package/dist/server/{server → apps/api}/migrations/033_movement_trip_point_sync.sql +0 -0
  177. /package/dist/server/{server → apps/api}/migrations/034_movement_segment_sync.sql +0 -0
  178. /package/dist/server/{server → apps/api}/migrations/035_google_local_auth_settings.sql +0 -0
  179. /package/dist/server/{server → apps/api}/migrations/036_google_local_auth_client_secret.sql +0 -0
  180. /package/dist/server/{server → apps/api}/migrations/037_workbench_public_inputs_and_run_inputs.sql +0 -0
  181. /package/dist/server/{server → apps/api}/migrations/038_data_management_settings.sql +0 -0
  182. /package/dist/server/{server → apps/api}/migrations/039_life_force_and_action_points.sql +0 -0
  183. /package/dist/server/{server → apps/api}/migrations/040_screen_time_domain.sql +0 -0
  184. /package/dist/server/{server → apps/api}/migrations/041_companion_source_states.sql +0 -0
  185. /package/dist/server/{server → apps/api}/migrations/042_movement_boxes.sql +0 -0
  186. /package/dist/server/{server → apps/api}/migrations/043_movement_box_overlap_overrides.sql +0 -0
  187. /package/dist/server/{server → apps/api}/migrations/044_macos_local_calendar_provider.sql +0 -0
  188. /package/dist/server/{server → apps/api}/migrations/045_sleep_nights_and_raw_segments.sql +0 -0
  189. /package/dist/server/{server → apps/api}/migrations/046_work_item_hierarchy.sql +0 -0
  190. /package/dist/server/{server → apps/api}/migrations/047_sleep_source_records.sql +0 -0
  191. /package/dist/server/{server → apps/api}/migrations/048_task_run_git_context.sql +0 -0
  192. /package/dist/server/{server → apps/api}/migrations/049_agent_runtime_sessions.sql +0 -0
  193. /package/dist/server/{server → apps/api}/migrations/050_agent_token_bootstrap_policy.sql +0 -0
  194. /package/dist/server/{server → apps/api}/migrations/051_agent_token_scope_policy.sql +0 -0
  195. /package/dist/server/{server → apps/api}/migrations/052_agent_identity_tightening.sql +0 -0
  196. /package/dist/server/{server → apps/api}/migrations/053_agent_runtime_session_canonical_labels.sql +0 -0
  197. /package/dist/server/{server → apps/api}/migrations/054_sqlite_backed_wiki_memory.sql +0 -0
  198. /package/dist/server/{server → apps/api}/migrations/055_gamification_progression.sql +0 -0
  199. /package/dist/server/{server → apps/api}/migrations/056_gamification_equipment.sql +0 -0
  200. /package/dist/server/{server → apps/api}/migrations/057_gamification_catalog_cleanup.sql +0 -0
  201. /package/dist/server/{server → apps/api}/migrations/058_gamification_theme_preference.sql +0 -0
  202. /package/dist/server/{server → apps/api}/migrations/059_data_backup_retention.sql +0 -0
  203. /package/dist/server/{server → apps/api}/migrations/060_psyche_devrage_metrics.sql +0 -0
  204. /package/dist/server/{server → apps/api}/migrations/061_health_workout_raw_evidence.sql +0 -0
  205. /package/dist/server/{server → apps/api}/migrations/062_health_mobile_sync_sessions.sql +0 -0
  206. /package/dist/server/{server → apps/api}/migrations/063_psyche_flashcards.sql +0 -0
  207. /package/dist/server/{server → apps/api}/migrations/064_health_workout_time_series_identity.sql +0 -0
  208. /package/dist/server/{server → apps/api}/migrations/065_weight_loss_nutrition_insights.sql +0 -0
  209. /package/dist/server/{server → apps/api}/migrations/066_watch_action_receipts.sql +0 -0
  210. /package/dist/server/{server → apps/api}/migrations/067_weight_loss_daily_active_overrides.sql +0 -0
  211. /package/dist/server/{server → apps/api}/migrations/068_remove_generated_movement_wiki_logs.sql +0 -0
  212. /package/dist/server/{server → apps/api}/migrations/069_psyche_devrage_cumulative_rage.sql +0 -0
  213. /package/dist/server/{server → apps/api}/migrations/070_health_mobile_sync_completion_index.sql +0 -0
  214. /package/dist/server/{server → apps/api}/migrations/071_agent_runtime_claude_identity.sql +0 -0
  215. /package/dist/server/{server → apps/api}/src/data-management-types.js +0 -0
  216. /package/dist/server/{server → apps/api}/src/debug.js +0 -0
  217. /package/dist/server/{server → apps/api}/src/demo-data.js +0 -0
  218. /package/dist/server/{server → apps/api}/src/discovery-advertiser.js +0 -0
  219. /package/dist/server/{server → apps/api}/src/e2e-server.js +0 -0
  220. /package/dist/server/{server → apps/api}/src/errors.js +0 -0
  221. /package/dist/server/{server → apps/api}/src/health-workout-adapters.js +0 -0
  222. /package/dist/server/{server → apps/api}/src/health-workout-analytics.js +0 -0
  223. /package/dist/server/{server → apps/api}/src/health.js +0 -0
  224. /package/dist/server/{server → apps/api}/src/index.js +0 -0
  225. /package/dist/server/{server → apps/api}/src/managers/base.js +0 -0
  226. /package/dist/server/{server → apps/api}/src/managers/contracts.js +0 -0
  227. /package/dist/server/{server → apps/api}/src/managers/platform/api-gateway-manager.js +0 -0
  228. /package/dist/server/{server → apps/api}/src/managers/platform/audit-manager.js +0 -0
  229. /package/dist/server/{server → apps/api}/src/managers/platform/authentication-manager.js +0 -0
  230. /package/dist/server/{server → apps/api}/src/managers/platform/authorization-manager.js +0 -0
  231. /package/dist/server/{server → apps/api}/src/managers/platform/background-job-manager.js +0 -0
  232. /package/dist/server/{server → apps/api}/src/managers/platform/configuration-manager.js +0 -0
  233. /package/dist/server/{server → apps/api}/src/managers/platform/database-manager.js +0 -0
  234. /package/dist/server/{server → apps/api}/src/managers/platform/event-bus-manager.js +0 -0
  235. /package/dist/server/{server → apps/api}/src/managers/platform/external-service-manager.js +0 -0
  236. /package/dist/server/{server → apps/api}/src/managers/platform/health-manager.js +0 -0
  237. /package/dist/server/{server → apps/api}/src/managers/platform/llm-manager.js +0 -0
  238. /package/dist/server/{server → apps/api}/src/managers/platform/migration-manager.js +0 -0
  239. /package/dist/server/{server → apps/api}/src/managers/platform/mock-workbench-provider.js +0 -0
  240. /package/dist/server/{server → apps/api}/src/managers/platform/openai-responses-provider.js +0 -0
  241. /package/dist/server/{server → apps/api}/src/managers/platform/search-index-manager.js +0 -0
  242. /package/dist/server/{server → apps/api}/src/managers/platform/secrets-manager.js +0 -0
  243. /package/dist/server/{server → apps/api}/src/managers/platform/session-manager.js +0 -0
  244. /package/dist/server/{server → apps/api}/src/managers/platform/storage-manager.js +0 -0
  245. /package/dist/server/{server → apps/api}/src/managers/platform/token-manager.js +0 -0
  246. /package/dist/server/{server → apps/api}/src/managers/platform/transaction-manager.js +0 -0
  247. /package/dist/server/{server → apps/api}/src/managers/platform/trusted-network.js +0 -0
  248. /package/dist/server/{server → apps/api}/src/managers/runtime.js +0 -0
  249. /package/dist/server/{server → apps/api}/src/managers/type-guards.js +0 -0
  250. /package/dist/server/{server → apps/api}/src/movement.js +0 -0
  251. /package/dist/server/{server → apps/api}/src/openapi.js +0 -0
  252. /package/dist/server/{server → apps/api}/src/preferences-seeds.js +0 -0
  253. /package/dist/server/{server → apps/api}/src/preferences-types.js +0 -0
  254. /package/dist/server/{server → apps/api}/src/psyche-types.js +0 -0
  255. /package/dist/server/{server → apps/api}/src/questionnaire-flow.js +0 -0
  256. /package/dist/server/{server → apps/api}/src/questionnaire-types.js +0 -0
  257. /package/dist/server/{server → apps/api}/src/repositories/activity-events.js +0 -0
  258. /package/dist/server/{server → apps/api}/src/repositories/agent-runtime-sessions.js +0 -0
  259. /package/dist/server/{server → apps/api}/src/repositories/ai-processors.js +0 -0
  260. /package/dist/server/{server → apps/api}/src/repositories/calendar.js +0 -0
  261. /package/dist/server/{server → apps/api}/src/repositories/collaboration.js +0 -0
  262. /package/dist/server/{server → apps/api}/src/repositories/deleted-entities.js +0 -0
  263. /package/dist/server/{server → apps/api}/src/repositories/diagnostic-logs.js +0 -0
  264. /package/dist/server/{server → apps/api}/src/repositories/domains.js +0 -0
  265. /package/dist/server/{server → apps/api}/src/repositories/entity-ownership.js +0 -0
  266. /package/dist/server/{server → apps/api}/src/repositories/event-log.js +0 -0
  267. /package/dist/server/{server → apps/api}/src/repositories/gamification.js +0 -0
  268. /package/dist/server/{server → apps/api}/src/repositories/goals.js +0 -0
  269. /package/dist/server/{server → apps/api}/src/repositories/model-settings.js +0 -0
  270. /package/dist/server/{server → apps/api}/src/repositories/notes.js +0 -0
  271. /package/dist/server/{server → apps/api}/src/repositories/preferences.js +0 -0
  272. /package/dist/server/{server → apps/api}/src/repositories/projects.js +0 -0
  273. /package/dist/server/{server → apps/api}/src/repositories/psyche.js +0 -0
  274. /package/dist/server/{server → apps/api}/src/repositories/questionnaires.js +0 -0
  275. /package/dist/server/{server → apps/api}/src/repositories/rewards.js +0 -0
  276. /package/dist/server/{server → apps/api}/src/repositories/settings.js +0 -0
  277. /package/dist/server/{server → apps/api}/src/repositories/strategies.js +0 -0
  278. /package/dist/server/{server → apps/api}/src/repositories/surface-layouts.js +0 -0
  279. /package/dist/server/{server → apps/api}/src/repositories/tags.js +0 -0
  280. /package/dist/server/{server → apps/api}/src/repositories/task-runs.js +0 -0
  281. /package/dist/server/{server → apps/api}/src/repositories/tasks.js +0 -0
  282. /package/dist/server/{server → apps/api}/src/repositories/users.js +0 -0
  283. /package/dist/server/{server → apps/api}/src/repositories/weekly-reviews.js +0 -0
  284. /package/dist/server/{server → apps/api}/src/repositories/wiki-memory.js +0 -0
  285. /package/dist/server/{server → apps/api}/src/repositories/work-adjustments.js +0 -0
  286. /package/dist/server/{server → apps/api}/src/runtime-data-root.js +0 -0
  287. /package/dist/server/{server → apps/api}/src/screen-time.js +0 -0
  288. /package/dist/server/{server → apps/api}/src/seed-demo.js +0 -0
  289. /package/dist/server/{server → apps/api}/src/services/calendar-runtime.js +0 -0
  290. /package/dist/server/{server → apps/api}/src/services/context.js +0 -0
  291. /package/dist/server/{server → apps/api}/src/services/dashboard.js +0 -0
  292. /package/dist/server/{server → apps/api}/src/services/data-management.js +0 -0
  293. /package/dist/server/{server → apps/api}/src/services/devrage-scanner.js +0 -0
  294. /package/dist/server/{server → apps/api}/src/services/devrage.js +0 -0
  295. /package/dist/server/{server → apps/api}/src/services/entity-crud.js +0 -0
  296. /package/dist/server/{server → apps/api}/src/services/git-helper.js +0 -0
  297. /package/dist/server/{server → apps/api}/src/services/google-calendar-oauth-config.js +0 -0
  298. /package/dist/server/{server → apps/api}/src/services/insights.js +0 -0
  299. /package/dist/server/{server → apps/api}/src/services/legacy-wiki-markdown-import.js +0 -0
  300. /package/dist/server/{server → apps/api}/src/services/life-force-model.js +0 -0
  301. /package/dist/server/{server → apps/api}/src/services/life-force.js +0 -0
  302. /package/dist/server/{server → apps/api}/src/services/macos-calendar-helper.js +0 -0
  303. /package/dist/server/{server → apps/api}/src/services/openai-codex-oauth.js +0 -0
  304. /package/dist/server/{server → apps/api}/src/services/projects.js +0 -0
  305. /package/dist/server/{server → apps/api}/src/services/psyche-observation-calendar.js +0 -0
  306. /package/dist/server/{server → apps/api}/src/services/psyche.js +0 -0
  307. /package/dist/server/{server → apps/api}/src/services/relations.js +0 -0
  308. /package/dist/server/{server → apps/api}/src/services/reviews.js +0 -0
  309. /package/dist/server/{server → apps/api}/src/services/run-recovery.js +0 -0
  310. /package/dist/server/{server → apps/api}/src/services/tagging.js +0 -0
  311. /package/dist/server/{server → apps/api}/src/services/task-run-watchdog.js +0 -0
  312. /package/dist/server/{server → apps/api}/src/services/work-time.js +0 -0
  313. /package/dist/server/{server → apps/api}/src/web.js +0 -0
  314. /package/dist/server/{src → apps/web/src}/components/customization/utility-widgets.js +0 -0
  315. /package/dist/server/{src → apps/web/src}/components/ui/info-tooltip.js +0 -0
  316. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/calendar/calendar-boxes.js +0 -0
  317. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/goals/goals-boxes.js +0 -0
  318. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/habits/habits-boxes.js +0 -0
  319. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/health/health-boxes.js +0 -0
  320. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/insights/insights-boxes.js +0 -0
  321. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/kanban/kanban-boxes.js +0 -0
  322. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/movement/movement-boxes.js +0 -0
  323. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/notes/notes-boxes.js +0 -0
  324. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/overview/overview-boxes.js +0 -0
  325. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/preferences/preferences-boxes.js +0 -0
  326. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/projects/projects-boxes.js +0 -0
  327. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/psyche/psyche-boxes.js +0 -0
  328. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/questionnaires/questionnaires-boxes.js +0 -0
  329. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/review/review-boxes.js +0 -0
  330. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/shared/define-workbench-box.js +0 -0
  331. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/shared/generic-node-view.js +0 -0
  332. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/strategies/strategies-boxes.js +0 -0
  333. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/tasks/tasks-boxes.js +0 -0
  334. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/today/today-boxes.js +0 -0
  335. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/wiki/wiki-boxes.js +0 -0
  336. /package/dist/server/{src → apps/web/src}/lib/api-error.js +0 -0
  337. /package/dist/server/{src → apps/web/src}/lib/api.js +0 -0
  338. /package/dist/server/{src → apps/web/src}/lib/calendar-name-deduper.js +0 -0
  339. /package/dist/server/{src → apps/web/src}/lib/data-management-types.js +0 -0
  340. /package/dist/server/{src → apps/web/src}/lib/date-keys.js +0 -0
  341. /package/dist/server/{src → apps/web/src}/lib/diagnostics.js +0 -0
  342. /package/dist/server/{src → apps/web/src}/lib/entity-visuals.js +0 -0
  343. /package/dist/server/{src → apps/web/src}/lib/gamification-catalog.js +0 -0
  344. /package/dist/server/{src → apps/web/src}/lib/knowledge-graph-types.js +0 -0
  345. /package/dist/server/{src → apps/web/src}/lib/knowledge-graph.js +0 -0
  346. /package/dist/server/{src → apps/web/src}/lib/psyche-schemas.js +0 -0
  347. /package/dist/server/{src → apps/web/src}/lib/psyche-types.js +0 -0
  348. /package/dist/server/{src → apps/web/src}/lib/questionnaire-types.js +0 -0
  349. /package/dist/server/{src → apps/web/src}/lib/runtime-paths.js +0 -0
  350. /package/dist/server/{src → apps/web/src}/lib/schemas.js +0 -0
  351. /package/dist/server/{src → apps/web/src}/lib/snapshot-normalizer.js +0 -0
  352. /package/dist/server/{src → apps/web/src}/lib/theme-system.js +0 -0
  353. /package/dist/server/{src → apps/web/src}/lib/types.js +0 -0
  354. /package/dist/server/{src → apps/web/src}/lib/utils.js +0 -0
  355. /package/dist/server/{src → apps/web/src}/lib/weight-loss-energy-model.js +0 -0
  356. /package/dist/server/{src → apps/web/src}/lib/weight-loss-types.js +0 -0
  357. /package/dist/server/{src → apps/web/src}/lib/workbench/boxes.js +0 -0
  358. /package/dist/server/{src → apps/web/src}/lib/workbench/contracts.js +0 -0
  359. /package/dist/server/{src → apps/web/src}/lib/workbench/nodes.js +0 -0
  360. /package/dist/server/{src → apps/web/src}/lib/workbench/registry.js +0 -0
  361. /package/dist/server/{src → apps/web/src}/lib/workbench/runtime.js +0 -0
  362. /package/dist/server/{src → apps/web/src}/lib/workbench/tool-catalog.js +0 -0
@@ -1,4 +1,4 @@
1
- import{r as v,j as e,de as Me,aK as qe,bG as Ce,c2 as Oe,bW as De,bX as Ee,df as Be,cr as He,cs as Ue}from"./vendor-BwL6m4SE.js";import{j as $e,i as R,k as L}from"./state-Bpe5dF3T.js";import{Q as Se,a as F,F as g}from"./question-flow-dialog-Ded2E85L.js";import{I as C,T as ze,k as h,B as P,S as Ke,e as ye,C as N,E as Z,b as We,d3 as Xe,d4 as Qe,d5 as Ge,d6 as Ye,d7 as Je,d8 as Ze,d9 as Ve,da as es,cU as ss,cV as ts,db as as,dc as is,dd as rs,de as ns,df as os}from"./index-FpGANF9S.js";import{a as ls}from"./schemas-Db29G8NU.js";import{R as ds,P as cs,O as us,C as ms,T as xs,D as ps,a as gs}from"./ui-B9TWEtCx.js";import{m as hs}from"./motion-DcgUnXhY.js";import{S as vs}from"./settings-section-nav-Lo-VKCfZ.js";import{P as bs}from"./page-hero-DvrM83_C.js";import{M as W}from"./metric-tile-boeHB1R1.js";import"./board-CuxQRKPJ.js";import"./forms-D1qJ3oOP.js";const G=["read","write","insights","rewards.manage","psyche.read","psyche.write","psyche.note","psyche.insight","psyche.mode"],js=[{value:"read",label:"Read",description:"Inspect goals, projects, tasks, reviews, and metrics."},{value:"write",label:"Write",description:"Create and update work through the versioned API."},{value:"insights",label:"Insights",description:"Store structured findings, rationale, and feedback."},{value:"rewards.manage",label:"Rewards",description:"Tune reward rules and issue explainable bonus XP grants."},{value:"psyche.read",label:"Psyche read",description:"Read sensitive values, patterns, and trigger analyses."},{value:"psyche.write",label:"Psyche write",description:"Create and update sensitive therapeutic records."},{value:"psyche.note",label:"Psyche note",description:"Create and edit Markdown notes linked to reflective records."},{value:"psyche.insight",label:"Psyche insight",description:"Store therapeutic insights on Psyche entities."},{value:"psyche.mode",label:"Psyche mode",description:"Name, refine, and map mode profiles and guided mode results."}],te={mode:"active_only",goalsLimit:5,projectsLimit:8,tasksLimit:10,habitsLimit:6,strategiesLimit:4,peoplePageLimit:4,includePeoplePages:!0},Q={userIds:[],projectIds:[],tagIds:[]};function V(a){return a==="review"?{mode:"active_only",goalsLimit:3,projectsLimit:5,tasksLimit:6,habitsLimit:4,strategiesLimit:3,peoplePageLimit:0,includePeoplePages:!1}:a==="operator"?{...te}:a==="autonomous"?{mode:"scoped",goalsLimit:10,projectsLimit:14,tasksLimit:16,habitsLimit:10,strategiesLimit:8,peoplePageLimit:6,includePeoplePages:!0}:{...te}}function ee(a){return Array.from(new Set(a.split(",").map(r=>r.trim()).filter(r=>r.length>0)))}function Ae(a,r,l){return r==="review"?{...a,preset:r,trustLevel:"trusted",autonomyMode:"approval_required",approvalMode:"approval_by_default",scopes:[...l],bootstrapPolicy:V(r),scopePolicy:{...Q}}:r==="operator"?{...a,preset:r,trustLevel:"trusted",autonomyMode:"scoped_write",approvalMode:"high_impact_only",scopes:[...G],bootstrapPolicy:V(r),scopePolicy:{...Q}}:r==="autonomous"?{...a,preset:r,trustLevel:"autonomous",autonomyMode:"autonomous",approvalMode:"none",scopes:[...G],bootstrapPolicy:V(r),scopePolicy:{...Q}}:{...a,preset:r}}function ke(a,r,l){const p={preset:a,label:"Forge Pilot Token",agentLabel:r,agentType:"assistant",description:"Collaborative planning agent.",trustLevel:"trusted",autonomyMode:"scoped_write",approvalMode:"high_impact_only",scopes:[...G],bootstrapPolicy:{...te},scopePolicy:{...Q}};return Ae(p,a,l)}function fs({open:a,onOpenChange:r,pending:l=!1,initialPreset:p="operator",defaultAgentLabel:m="OpenClaw",recommendedScopes:b=[...G],onSubmit:k}){const[u,f]=v.useState(()=>ke(p,m,b)),[M,j]=v.useState(null);v.useEffect(()=>{a&&(f(ke(p,m,b)),j(null))},[a,p,m,b]);const A=[{id:"preset",eyebrow:"Agent token",title:"Choose a starting point for this token",description:"Each preset locks in a sensible trust, autonomy, and approval policy. You can tune any setting in the next steps.",render:(i,n)=>e.jsx(F,{columns:3,value:i.preset,onChange:t=>n(Ae(i,t,b)),options:[{value:"review",label:"Review-first",description:"Every action waits for your approval. Safe starting point for a new agent you have not yet trusted."},{value:"operator",label:"Full operator",description:"Trusted collaborator with full scopes. High-impact actions still ask for approval."},{value:"autonomous",label:"Autonomous pilot",description:"No approval gates. Use only for agents you have fully verified in a controlled setup."},{value:"custom",label:"Custom",description:"Start from a blank slate and configure every dimension yourself."}]})},{id:"identity",eyebrow:"Agent identity",title:"Name the agent and this token",description:"The agent name appears in logs, approval requests, and audit trails. The token label is for your reference.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(g,{label:"Agent name",labelHelp:"This label identifies the agent in every log entry, approval notification, and XP attribution. Pick something memorable.",children:e.jsx(C,{value:i.agentLabel,placeholder:"OpenClaw",onChange:t=>n({agentLabel:t.target.value})})}),e.jsx(g,{label:"Token label",description:"A short name for this credential — mainly for your reference in the token list.",children:e.jsx(C,{value:i.label,placeholder:"Forge Pilot Token",onChange:t=>n({label:t.target.value})})}),e.jsxs("div",{className:"grid gap-5 md:grid-cols-2",children:[e.jsx(g,{label:"Agent type",labelHelp:"Use 'assistant' for interactive agents. Use 'automation' for scripts or scheduled jobs with no conversational layer.",children:e.jsxs("select",{className:"rounded-[14px] bg-[var(--ui-surface-2)] px-3 py-3 text-[var(--ui-ink-strong)]",value:i.agentType,onChange:t=>n({agentType:t.target.value}),children:[e.jsx("option",{value:"assistant",children:"assistant"}),e.jsx("option",{value:"automation",children:"automation"}),e.jsx("option",{value:"observer",children:"observer"})]})}),e.jsx(g,{label:"Description",description:"Optional note about what this agent does.",children:e.jsx(C,{value:i.description,placeholder:"Collaborative planning agent.",onChange:t=>n({description:t.target.value})})})]})]})},{id:"policy",eyebrow:"Access policy",title:"Set trust level and approval behaviour",description:"These three settings control how much autonomy the agent has and when it needs your sign-off. The preset you chose filled sensible defaults — adjust only if needed.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(g,{label:"Trust level",labelHelp:"Standard agents are sandboxed readers. Trusted agents can write with policy guardrails. Autonomous agents bypass all trust checks — use with care.",children:e.jsx(F,{columns:3,value:i.trustLevel,onChange:t=>n({trustLevel:t}),options:[{value:"standard",label:"Standard",description:"Read-only by default, limited write surface."},{value:"trusted",label:"Trusted",description:"Full write surface with policy guardrails active."},{value:"autonomous",label:"Autonomous",description:"All checks bypassed — maximum capability."}]})}),e.jsx(g,{label:"Autonomy mode",labelHelp:"Approval-required means every mutation is held for review. Scoped write lets the agent act within its scopes. Autonomous skips all gates.",children:e.jsx(F,{columns:3,value:i.autonomyMode,onChange:t=>n({autonomyMode:t}),options:[{value:"approval_required",label:"Approval required",description:"Every write action queues for your review."},{value:"scoped_write",label:"Scoped write",description:"Acts freely within its assigned scopes."},{value:"autonomous",label:"Autonomous",description:"No gates — full freedom to write."}]})}),e.jsx(g,{label:"Approval policy",labelHelp:"Controls which actions trigger the approval queue. High-impact-only is the balanced default: routine writes go through, large mutations get reviewed.",children:e.jsx(F,{columns:3,value:i.approvalMode,onChange:t=>n({approvalMode:t}),options:[{value:"approval_by_default",label:"Approve by default",description:"Everything needs a sign-off unless explicitly exempt."},{value:"high_impact_only",label:"High impact only",description:"Routine writes pass through; high-stakes actions are held."},{value:"none",label:"None",description:"No approval gates — actions execute immediately."}]})})]})},{id:"scopes",eyebrow:"Scopes",title:"Select what this agent can access",description:"Scope selection follows the principle of least privilege — only grant what the agent actually needs. The full operator bundle covers every capability.",render:(i,n)=>e.jsxs(g,{label:"Capabilities",labelHelp:"Read lets the agent inspect the system. Write lets it create and update work. Rewards and Psyche scopes unlock more sensitive subsystems.",children:[e.jsx("div",{className:"grid gap-3 md:grid-cols-3",children:js.map(t=>{const y=i.scopes.includes(t.value);return e.jsxs("button",{type:"button",className:`rounded-[18px] border px-4 py-4 text-left transition ${y?"border-[color-mix(in_srgb,var(--primary)_28%,transparent)] bg-[var(--ui-accent-soft)] text-[var(--ui-ink-strong)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-muted)] hover:bg-[var(--ui-surface-2)]"}`,onClick:()=>{if(y){if(i.scopes.length===1)return;n({scopes:i.scopes.filter(S=>S!==t.value)})}else n({scopes:[...i.scopes,t.value]})},children:[e.jsx("div",{className:"font-medium",children:t.label}),e.jsx("div",{className:"mt-1 text-xs leading-5 text-[var(--ui-ink-muted)]",children:t.description})]},t.value)})}),e.jsxs("div",{className:"mt-2 text-xs text-[var(--ui-ink-muted)]",children:[i.scopes.length," scope",i.scopes.length!==1?"s":""," ","selected"]})]})},{id:"default-scope",eyebrow:"Default read scope",title:"Decide which owners and slices this agent sees by default",description:"Leave these blank for broad reads. When set, Forge automatically narrows overview, context, and bootstrap reads for this token unless the request narrows further.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(g,{label:"Default user IDs",description:"Comma-separated owner ids such as user_operator or user_forge_bot.",labelHelp:"If you set user ids here, this token only sees that owner slice by default. Explicit userIds in a request can narrow further, but they will not silently widen beyond this list.",children:e.jsx(C,{value:i.scopePolicy.userIds.join(", "),placeholder:"user_operator, user_forge_bot",onChange:t=>n({scopePolicy:{...i.scopePolicy,userIds:ee(t.target.value)}})})}),e.jsx(g,{label:"Project IDs",description:"Optional project-level boundary for overview, context, and bootstrap reads.",children:e.jsx(C,{value:i.scopePolicy.projectIds.join(", "),placeholder:"project_123, project_456",onChange:t=>n({scopePolicy:{...i.scopePolicy,projectIds:ee(t.target.value)}})})}),e.jsx(g,{label:"Tag IDs",description:"Optional tag-level boundary for overview, context, and bootstrap reads.",children:e.jsx(C,{value:i.scopePolicy.tagIds.join(", "),placeholder:"tag_focus, tag_client",onChange:t=>n({scopePolicy:{...i.scopePolicy,tagIds:ee(t.target.value)}})})}),e.jsxs("div",{className:"rounded-[16px] bg-[var(--ui-surface-2)] px-4 py-3 text-sm leading-6 text-[var(--ui-ink-medium)]",children:["Default scope summary:"," ",i.scopePolicy.userIds.length>0?`${i.scopePolicy.userIds.length} user slice${i.scopePolicy.userIds.length===1?"":"s"}`:"all visible users",i.scopePolicy.projectIds.length>0?` · ${i.scopePolicy.projectIds.length} project ${i.scopePolicy.projectIds.length===1?"boundary":"boundaries"}`:"",i.scopePolicy.tagIds.length>0?` · ${i.scopePolicy.tagIds.length} tag ${i.scopePolicy.tagIds.length===1?"boundary":"boundaries"}`:""]})]})},{id:"bootstrap",eyebrow:"Bootstrap",title:"Decide how much Forge context is injected at session start",description:"This controls the automatic BOOTSTRAP snapshot for agent sessions. Keep it lean unless the agent genuinely needs broad context on every new session.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(g,{label:"Bootstrap mode",labelHelp:"Disabled injects nothing. Active-only keeps a compact current-work snapshot. Scoped keeps budgets but not status filters. Full mirrors the legacy broad bootstrap.",children:e.jsx(F,{columns:3,value:i.bootstrapPolicy.mode,onChange:t=>n({bootstrapPolicy:{...i.bootstrapPolicy,mode:t}}),options:[{value:"disabled",label:"Disabled",description:"No automatic Forge snapshot is injected."},{value:"active_only",label:"Active only",description:"Only active projects, focus tasks, due habits, and bounded summaries."},{value:"scoped",label:"Scoped",description:"Bounded lists without forcing only active items."},{value:"full",label:"Full",description:"Legacy broad bootstrap. Highest context cost."}]})}),e.jsx("div",{className:"grid gap-5 md:grid-cols-3",children:[["goalsLimit","Goals"],["projectsLimit","Projects"],["tasksLimit","Tasks"],["habitsLimit","Habits"],["strategiesLimit","Strategies"],["peoplePageLimit","People pages"]].map(([t,y])=>e.jsx(g,{label:y,children:e.jsx(C,{type:"number",min:0,max:t==="peoplePageLimit"?50:100,value:i.bootstrapPolicy[t],onChange:S=>n({bootstrapPolicy:{...i.bootstrapPolicy,[t]:Number(S.target.value||0)}})})},t))}),e.jsxs("label",{className:"flex items-center gap-3 rounded-[16px] bg-[var(--ui-surface-2)] px-4 py-3 text-sm text-[var(--ui-ink-medium)]",children:[e.jsx("input",{type:"checkbox",checked:i.bootstrapPolicy.includePeoplePages,onChange:t=>n({bootstrapPolicy:{...i.bootstrapPolicy,includePeoplePages:t.target.checked}})}),"Include People wiki pages in the bootstrap snapshot"]})]})}];return e.jsx(Se,{open:a,onOpenChange:r,eyebrow:"Agent setup",title:"Issue an agent token",description:"Configure a new agent token step by step. The preset fills sensible defaults — adjust what you need.",value:u,onChange:f,draftPersistenceKey:"settings.agent-token.new",steps:A,submitLabel:"Issue token",pending:l,pendingLabel:"Issuing token…",error:M,onSubmit:async()=>{j(null);const i=ls.safeParse({label:u.label,agentLabel:u.agentLabel,agentType:u.agentType,description:u.description,trustLevel:u.trustLevel,autonomyMode:u.autonomyMode,approvalMode:u.approvalMode,scopes:u.scopes,bootstrapPolicy:u.bootstrapPolicy,scopePolicy:u.scopePolicy});if(!i.success){const n=i.error.issues[0];j((n==null?void 0:n.message)??"Check the agent name and at least one scope before issuing.");return}try{await k(i.data),r(!1)}catch(n){j(n instanceof Error?n.message:"Could not issue the token right now.")}}})}function we(a){return{source:"new",taskId:"",title:"",description:"",owner:a,projectId:"",status:"done",points:40}}function ys({open:a,onOpenChange:r,pending:l=!1,defaultOwner:p="",availableTasks:m=[],availableProjects:b=[],onSubmit:k}){const[u,f]=v.useState(()=>we(p)),[M,j]=v.useState(null);v.useEffect(()=>{a&&(f(we(p)),j(null))},[a,p]);const A=[{id:"source",eyebrow:"Log work",title:"Is this work already tracked?",description:"If a task exists, link the work to it so Forge can update the record with the right status and XP. If not, a new task will be created from what you describe.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(F,{columns:2,value:i.source,onChange:t=>n({source:t,taskId:""}),options:[{value:"new",label:"New task",description:"The work is not tracked yet — Forge will create a task and log the time against it."},{value:"existing",label:"Existing task",description:"Pick a task already in the board. The log will update its record and award XP."}]}),i.source==="existing"&&m.length>0?e.jsx(g,{label:"Pick the task",description:"Select the task this work belongs to.",children:e.jsxs("select",{className:"rounded-[14px] bg-[var(--ui-surface-2)] px-3 py-3 text-[var(--ui-ink-strong)]",value:i.taskId,onChange:t=>n({taskId:t.target.value}),children:[e.jsx("option",{value:"",children:"— choose a task —"}),m.map(t=>e.jsxs("option",{value:t.id,children:[t.title," · ",t.status.replaceAll("_"," ")]},t.id))]})}):i.source==="existing"&&m.length===0?e.jsx("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] px-4 py-3 text-sm text-[var(--ui-ink-muted)]",children:'No tasks are loaded yet. Switch to "New task" to create one from scratch.'}):null]})},{id:"details",eyebrow:"Work details",title:"Describe what was done",description:"Give the work a clear title and enough context to understand it later. These become the task record if you are creating a new one.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(g,{label:"Title",labelHelp:"Write the title like a short achievement: what was completed, not what was started.",children:e.jsx(C,{value:i.title,placeholder:"Write postmortem draft",onChange:t=>n({title:t.target.value})})}),e.jsx(g,{label:"Owner",description:"Who did this work? Defaults to the operator name.",children:e.jsx(C,{value:i.owner,placeholder:"Your name",onChange:t=>n({owner:t.target.value})})}),e.jsx(g,{label:"Description",description:"What moved forward? What should remain visible in the project history?",children:e.jsx(ze,{className:"min-h-28",value:i.description,placeholder:"Wrote the full incident timeline and drafted the three key learnings for the team retrospective.",onChange:t=>n({description:t.target.value})})})]})},{id:"placement",eyebrow:"Placement",title:"Set the context and XP value",description:"Assign the work to a project and choose its final status. The XP value controls how much this work contributes to the operator's progress curve.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid gap-5 md:grid-cols-2",children:[e.jsx(g,{label:"Project",description:"Link this work to an active project if it belongs to one.",children:e.jsxs("select",{className:"rounded-[14px] bg-[var(--ui-surface-2)] px-3 py-3 text-[var(--ui-ink-strong)]",value:i.projectId,onChange:t=>n({projectId:t.target.value}),children:[e.jsx("option",{value:"",children:"No project link"}),b.map(t=>e.jsx("option",{value:t.id,children:t.title},t.id))]})}),e.jsx(g,{label:"Final status",labelHelp:"'Done' is the most common choice. Use 'In progress' if the work was real but the task is still open.",children:e.jsx(F,{columns:2,value:i.status,onChange:t=>n({status:t}),options:[{value:"done",label:"Done",description:"Work is complete."},{value:"in_progress",label:"In progress",description:"Still active but already worth logging."},{value:"focus",label:"Focus",description:"Moved into focus."},{value:"blocked",label:"Blocked",description:"Work hit a wall."}]})})]}),e.jsx(g,{label:"XP value",labelHelp:"Typical task XP ranges from 20 to 100. Use 40 for routine tasks, 80+ for complex deliverables.",children:e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx(C,{type:"number",min:5,max:500,className:"w-36",value:i.points,onChange:t=>n({points:Number(t.target.value)})}),e.jsx("div",{className:"flex gap-2",children:[20,40,80,120].map(t=>e.jsxs("button",{type:"button",className:`rounded-full px-3 py-1.5 text-xs transition ${i.points===t?"bg-[var(--ui-surface-3)] text-[var(--ui-ink-strong)]":"bg-[var(--ui-surface-2)] text-[var(--ui-ink-muted)] hover:bg-[var(--ui-surface-2)]"}`,onClick:()=>n({points:t}),children:[t," xp"]},t))})]})})]})}];return e.jsx(Se,{open:a,onOpenChange:r,eyebrow:"Log work",title:"Log retroactive work",description:"Capture work that happened outside the timer so it counts toward progress and XP.",value:u,onChange:f,draftPersistenceKey:"settings.log-work",steps:A,submitLabel:"Log work",pending:l,pendingLabel:"Logging work…",error:M,onSubmit:async()=>{if(j(null),u.source==="new"&&u.title.trim().length===0){j("Add a title so Forge knows what work to create.");return}if(u.source==="existing"&&!u.taskId){j("Pick an existing task or switch to New task.");return}try{await k({taskId:u.source==="existing"&&u.taskId?u.taskId:void 0,title:u.source==="new"&&u.title.trim()?u.title.trim():void 0,description:u.description.trim()||void 0,owner:u.owner.trim()||void 0,projectId:u.projectId||null,status:u.status,points:u.points}),r(!1)}catch(i){j(i instanceof Error?i.message:"Could not log the work right now.")}}})}function Te({text:a}){const[r,l]=v.useState(!1),p=async()=>{try{await navigator.clipboard.writeText(a),l(!0),setTimeout(()=>l(!1),2200)}catch{}};return e.jsxs("button",{type:"button",onClick:()=>void p(),className:"flex items-center gap-1.5 rounded-full bg-[var(--ui-surface-2)] px-3 py-1.5 text-xs font-medium text-[var(--ui-ink-medium)] transition hover:bg-[var(--ui-surface-2)] hover:text-[var(--ui-ink-strong)]",children:[r?e.jsx(Ce,{className:"size-3 text-[var(--success)]"}):e.jsx(Oe,{className:"size-3"}),r?"Copied":"Copy"]})}function se({label:a,children:r,copyText:l}){return e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:a}),e.jsx(Te,{text:l??r})]}),e.jsx("pre",{className:"mt-3 overflow-x-auto rounded-[14px] bg-[var(--ui-code-bg)] p-3 text-xs leading-6 text-[var(--ui-ink-medium)]",children:e.jsx("code",{children:r})})]})}function ks({open:a,onOpenChange:r,state:l}){if(!l)return null;const{tokenString:p,agentLabel:m,onboarding:b}=l,k=JSON.stringify({baseUrl:b.forgeBaseUrl,apiToken:p,actorLabel:m,timeoutMs:b.defaultTimeoutMs},null,2),u=[`curl -s ${b.healthUrl} \\`,` -H "Authorization: Bearer ${p}" \\`,' -H "X-Forge-Source: agent" \\',` -H "X-Forge-Actor: ${m}"`].join(`
1
+ import{r as v,j as e,de as Me,aK as qe,bG as Ce,c2 as Oe,bW as De,bX as Ee,df as Be,cr as He,cs as Ue}from"./vendor-BwL6m4SE.js";import{j as $e,i as R,k as L}from"./state-Bpe5dF3T.js";import{Q as Se,a as F,F as g}from"./question-flow-dialog-D-_EvoAt.js";import{I as C,T as ze,k as h,B as P,S as Ke,e as ye,C as N,E as Z,b as We,d3 as Xe,d4 as Qe,d5 as Ge,d6 as Ye,d7 as Je,d8 as Ze,d9 as Ve,da as es,cU as ss,cV as ts,db as as,dc as is,dd as rs,de as ns,df as os}from"./index-izRKx6JK.js";import{a as ls}from"./schemas-B0Pa-V-A.js";import{R as ds,P as cs,O as us,C as ms,T as xs,D as ps,a as gs}from"./ui-B9TWEtCx.js";import{m as hs}from"./motion-DcgUnXhY.js";import{S as vs}from"./settings-section-nav-CMeU19Rx.js";import{P as bs}from"./page-hero-BLhM8FF3.js";import{M as W}from"./metric-tile-Bkx2btO2.js";import"./board-CuxQRKPJ.js";import"./forms-D1qJ3oOP.js";const G=["read","write","insights","rewards.manage","psyche.read","psyche.write","psyche.note","psyche.insight","psyche.mode"],js=[{value:"read",label:"Read",description:"Inspect goals, projects, tasks, reviews, and metrics."},{value:"write",label:"Write",description:"Create and update work through the versioned API."},{value:"insights",label:"Insights",description:"Store structured findings, rationale, and feedback."},{value:"rewards.manage",label:"Rewards",description:"Tune reward rules and issue explainable bonus XP grants."},{value:"psyche.read",label:"Psyche read",description:"Read sensitive values, patterns, and trigger analyses."},{value:"psyche.write",label:"Psyche write",description:"Create and update sensitive therapeutic records."},{value:"psyche.note",label:"Psyche note",description:"Create and edit Markdown notes linked to reflective records."},{value:"psyche.insight",label:"Psyche insight",description:"Store therapeutic insights on Psyche entities."},{value:"psyche.mode",label:"Psyche mode",description:"Name, refine, and map mode profiles and guided mode results."}],te={mode:"active_only",goalsLimit:5,projectsLimit:8,tasksLimit:10,habitsLimit:6,strategiesLimit:4,peoplePageLimit:4,includePeoplePages:!0},Q={userIds:[],projectIds:[],tagIds:[]};function V(a){return a==="review"?{mode:"active_only",goalsLimit:3,projectsLimit:5,tasksLimit:6,habitsLimit:4,strategiesLimit:3,peoplePageLimit:0,includePeoplePages:!1}:a==="operator"?{...te}:a==="autonomous"?{mode:"scoped",goalsLimit:10,projectsLimit:14,tasksLimit:16,habitsLimit:10,strategiesLimit:8,peoplePageLimit:6,includePeoplePages:!0}:{...te}}function ee(a){return Array.from(new Set(a.split(",").map(r=>r.trim()).filter(r=>r.length>0)))}function Ae(a,r,l){return r==="review"?{...a,preset:r,trustLevel:"trusted",autonomyMode:"approval_required",approvalMode:"approval_by_default",scopes:[...l],bootstrapPolicy:V(r),scopePolicy:{...Q}}:r==="operator"?{...a,preset:r,trustLevel:"trusted",autonomyMode:"scoped_write",approvalMode:"high_impact_only",scopes:[...G],bootstrapPolicy:V(r),scopePolicy:{...Q}}:r==="autonomous"?{...a,preset:r,trustLevel:"autonomous",autonomyMode:"autonomous",approvalMode:"none",scopes:[...G],bootstrapPolicy:V(r),scopePolicy:{...Q}}:{...a,preset:r}}function ke(a,r,l){const p={preset:a,label:"Forge Pilot Token",agentLabel:r,agentType:"assistant",description:"Collaborative planning agent.",trustLevel:"trusted",autonomyMode:"scoped_write",approvalMode:"high_impact_only",scopes:[...G],bootstrapPolicy:{...te},scopePolicy:{...Q}};return Ae(p,a,l)}function fs({open:a,onOpenChange:r,pending:l=!1,initialPreset:p="operator",defaultAgentLabel:m="OpenClaw",recommendedScopes:b=[...G],onSubmit:k}){const[u,f]=v.useState(()=>ke(p,m,b)),[M,j]=v.useState(null);v.useEffect(()=>{a&&(f(ke(p,m,b)),j(null))},[a,p,m,b]);const A=[{id:"preset",eyebrow:"Agent token",title:"Choose a starting point for this token",description:"Each preset locks in a sensible trust, autonomy, and approval policy. You can tune any setting in the next steps.",render:(i,n)=>e.jsx(F,{columns:3,value:i.preset,onChange:t=>n(Ae(i,t,b)),options:[{value:"review",label:"Review-first",description:"Every action waits for your approval. Safe starting point for a new agent you have not yet trusted."},{value:"operator",label:"Full operator",description:"Trusted collaborator with full scopes. High-impact actions still ask for approval."},{value:"autonomous",label:"Autonomous pilot",description:"No approval gates. Use only for agents you have fully verified in a controlled setup."},{value:"custom",label:"Custom",description:"Start from a blank slate and configure every dimension yourself."}]})},{id:"identity",eyebrow:"Agent identity",title:"Name the agent and this token",description:"The agent name appears in logs, approval requests, and audit trails. The token label is for your reference.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(g,{label:"Agent name",labelHelp:"This label identifies the agent in every log entry, approval notification, and XP attribution. Pick something memorable.",children:e.jsx(C,{value:i.agentLabel,placeholder:"OpenClaw",onChange:t=>n({agentLabel:t.target.value})})}),e.jsx(g,{label:"Token label",description:"A short name for this credential — mainly for your reference in the token list.",children:e.jsx(C,{value:i.label,placeholder:"Forge Pilot Token",onChange:t=>n({label:t.target.value})})}),e.jsxs("div",{className:"grid gap-5 md:grid-cols-2",children:[e.jsx(g,{label:"Agent type",labelHelp:"Use 'assistant' for interactive agents. Use 'automation' for scripts or scheduled jobs with no conversational layer.",children:e.jsxs("select",{className:"rounded-[14px] bg-[var(--ui-surface-2)] px-3 py-3 text-[var(--ui-ink-strong)]",value:i.agentType,onChange:t=>n({agentType:t.target.value}),children:[e.jsx("option",{value:"assistant",children:"assistant"}),e.jsx("option",{value:"automation",children:"automation"}),e.jsx("option",{value:"observer",children:"observer"})]})}),e.jsx(g,{label:"Description",description:"Optional note about what this agent does.",children:e.jsx(C,{value:i.description,placeholder:"Collaborative planning agent.",onChange:t=>n({description:t.target.value})})})]})]})},{id:"policy",eyebrow:"Access policy",title:"Set trust level and approval behaviour",description:"These three settings control how much autonomy the agent has and when it needs your sign-off. The preset you chose filled sensible defaults — adjust only if needed.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(g,{label:"Trust level",labelHelp:"Standard agents are sandboxed readers. Trusted agents can write with policy guardrails. Autonomous agents bypass all trust checks — use with care.",children:e.jsx(F,{columns:3,value:i.trustLevel,onChange:t=>n({trustLevel:t}),options:[{value:"standard",label:"Standard",description:"Read-only by default, limited write surface."},{value:"trusted",label:"Trusted",description:"Full write surface with policy guardrails active."},{value:"autonomous",label:"Autonomous",description:"All checks bypassed — maximum capability."}]})}),e.jsx(g,{label:"Autonomy mode",labelHelp:"Approval-required means every mutation is held for review. Scoped write lets the agent act within its scopes. Autonomous skips all gates.",children:e.jsx(F,{columns:3,value:i.autonomyMode,onChange:t=>n({autonomyMode:t}),options:[{value:"approval_required",label:"Approval required",description:"Every write action queues for your review."},{value:"scoped_write",label:"Scoped write",description:"Acts freely within its assigned scopes."},{value:"autonomous",label:"Autonomous",description:"No gates — full freedom to write."}]})}),e.jsx(g,{label:"Approval policy",labelHelp:"Controls which actions trigger the approval queue. High-impact-only is the balanced default: routine writes go through, large mutations get reviewed.",children:e.jsx(F,{columns:3,value:i.approvalMode,onChange:t=>n({approvalMode:t}),options:[{value:"approval_by_default",label:"Approve by default",description:"Everything needs a sign-off unless explicitly exempt."},{value:"high_impact_only",label:"High impact only",description:"Routine writes pass through; high-stakes actions are held."},{value:"none",label:"None",description:"No approval gates — actions execute immediately."}]})})]})},{id:"scopes",eyebrow:"Scopes",title:"Select what this agent can access",description:"Scope selection follows the principle of least privilege — only grant what the agent actually needs. The full operator bundle covers every capability.",render:(i,n)=>e.jsxs(g,{label:"Capabilities",labelHelp:"Read lets the agent inspect the system. Write lets it create and update work. Rewards and Psyche scopes unlock more sensitive subsystems.",children:[e.jsx("div",{className:"grid gap-3 md:grid-cols-3",children:js.map(t=>{const y=i.scopes.includes(t.value);return e.jsxs("button",{type:"button",className:`rounded-[18px] border px-4 py-4 text-left transition ${y?"border-[color-mix(in_srgb,var(--primary)_28%,transparent)] bg-[var(--ui-accent-soft)] text-[var(--ui-ink-strong)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-muted)] hover:bg-[var(--ui-surface-2)]"}`,onClick:()=>{if(y){if(i.scopes.length===1)return;n({scopes:i.scopes.filter(S=>S!==t.value)})}else n({scopes:[...i.scopes,t.value]})},children:[e.jsx("div",{className:"font-medium",children:t.label}),e.jsx("div",{className:"mt-1 text-xs leading-5 text-[var(--ui-ink-muted)]",children:t.description})]},t.value)})}),e.jsxs("div",{className:"mt-2 text-xs text-[var(--ui-ink-muted)]",children:[i.scopes.length," scope",i.scopes.length!==1?"s":""," ","selected"]})]})},{id:"default-scope",eyebrow:"Default read scope",title:"Decide which owners and slices this agent sees by default",description:"Leave these blank for broad reads. When set, Forge automatically narrows overview, context, and bootstrap reads for this token unless the request narrows further.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(g,{label:"Default user IDs",description:"Comma-separated owner ids such as user_operator or user_forge_bot.",labelHelp:"If you set user ids here, this token only sees that owner slice by default. Explicit userIds in a request can narrow further, but they will not silently widen beyond this list.",children:e.jsx(C,{value:i.scopePolicy.userIds.join(", "),placeholder:"user_operator, user_forge_bot",onChange:t=>n({scopePolicy:{...i.scopePolicy,userIds:ee(t.target.value)}})})}),e.jsx(g,{label:"Project IDs",description:"Optional project-level boundary for overview, context, and bootstrap reads.",children:e.jsx(C,{value:i.scopePolicy.projectIds.join(", "),placeholder:"project_123, project_456",onChange:t=>n({scopePolicy:{...i.scopePolicy,projectIds:ee(t.target.value)}})})}),e.jsx(g,{label:"Tag IDs",description:"Optional tag-level boundary for overview, context, and bootstrap reads.",children:e.jsx(C,{value:i.scopePolicy.tagIds.join(", "),placeholder:"tag_focus, tag_client",onChange:t=>n({scopePolicy:{...i.scopePolicy,tagIds:ee(t.target.value)}})})}),e.jsxs("div",{className:"rounded-[16px] bg-[var(--ui-surface-2)] px-4 py-3 text-sm leading-6 text-[var(--ui-ink-medium)]",children:["Default scope summary:"," ",i.scopePolicy.userIds.length>0?`${i.scopePolicy.userIds.length} user slice${i.scopePolicy.userIds.length===1?"":"s"}`:"all visible users",i.scopePolicy.projectIds.length>0?` · ${i.scopePolicy.projectIds.length} project ${i.scopePolicy.projectIds.length===1?"boundary":"boundaries"}`:"",i.scopePolicy.tagIds.length>0?` · ${i.scopePolicy.tagIds.length} tag ${i.scopePolicy.tagIds.length===1?"boundary":"boundaries"}`:""]})]})},{id:"bootstrap",eyebrow:"Bootstrap",title:"Decide how much Forge context is injected at session start",description:"This controls the automatic BOOTSTRAP snapshot for agent sessions. Keep it lean unless the agent genuinely needs broad context on every new session.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(g,{label:"Bootstrap mode",labelHelp:"Disabled injects nothing. Active-only keeps a compact current-work snapshot. Scoped keeps budgets but not status filters. Full mirrors the legacy broad bootstrap.",children:e.jsx(F,{columns:3,value:i.bootstrapPolicy.mode,onChange:t=>n({bootstrapPolicy:{...i.bootstrapPolicy,mode:t}}),options:[{value:"disabled",label:"Disabled",description:"No automatic Forge snapshot is injected."},{value:"active_only",label:"Active only",description:"Only active projects, focus tasks, due habits, and bounded summaries."},{value:"scoped",label:"Scoped",description:"Bounded lists without forcing only active items."},{value:"full",label:"Full",description:"Legacy broad bootstrap. Highest context cost."}]})}),e.jsx("div",{className:"grid gap-5 md:grid-cols-3",children:[["goalsLimit","Goals"],["projectsLimit","Projects"],["tasksLimit","Tasks"],["habitsLimit","Habits"],["strategiesLimit","Strategies"],["peoplePageLimit","People pages"]].map(([t,y])=>e.jsx(g,{label:y,children:e.jsx(C,{type:"number",min:0,max:t==="peoplePageLimit"?50:100,value:i.bootstrapPolicy[t],onChange:S=>n({bootstrapPolicy:{...i.bootstrapPolicy,[t]:Number(S.target.value||0)}})})},t))}),e.jsxs("label",{className:"flex items-center gap-3 rounded-[16px] bg-[var(--ui-surface-2)] px-4 py-3 text-sm text-[var(--ui-ink-medium)]",children:[e.jsx("input",{type:"checkbox",checked:i.bootstrapPolicy.includePeoplePages,onChange:t=>n({bootstrapPolicy:{...i.bootstrapPolicy,includePeoplePages:t.target.checked}})}),"Include People wiki pages in the bootstrap snapshot"]})]})}];return e.jsx(Se,{open:a,onOpenChange:r,eyebrow:"Agent setup",title:"Issue an agent token",description:"Configure a new agent token step by step. The preset fills sensible defaults — adjust what you need.",value:u,onChange:f,draftPersistenceKey:"settings.agent-token.new",steps:A,submitLabel:"Issue token",pending:l,pendingLabel:"Issuing token…",error:M,onSubmit:async()=>{j(null);const i=ls.safeParse({label:u.label,agentLabel:u.agentLabel,agentType:u.agentType,description:u.description,trustLevel:u.trustLevel,autonomyMode:u.autonomyMode,approvalMode:u.approvalMode,scopes:u.scopes,bootstrapPolicy:u.bootstrapPolicy,scopePolicy:u.scopePolicy});if(!i.success){const n=i.error.issues[0];j((n==null?void 0:n.message)??"Check the agent name and at least one scope before issuing.");return}try{await k(i.data),r(!1)}catch(n){j(n instanceof Error?n.message:"Could not issue the token right now.")}}})}function we(a){return{source:"new",taskId:"",title:"",description:"",owner:a,projectId:"",status:"done",points:40}}function ys({open:a,onOpenChange:r,pending:l=!1,defaultOwner:p="",availableTasks:m=[],availableProjects:b=[],onSubmit:k}){const[u,f]=v.useState(()=>we(p)),[M,j]=v.useState(null);v.useEffect(()=>{a&&(f(we(p)),j(null))},[a,p]);const A=[{id:"source",eyebrow:"Log work",title:"Is this work already tracked?",description:"If a task exists, link the work to it so Forge can update the record with the right status and XP. If not, a new task will be created from what you describe.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(F,{columns:2,value:i.source,onChange:t=>n({source:t,taskId:""}),options:[{value:"new",label:"New task",description:"The work is not tracked yet — Forge will create a task and log the time against it."},{value:"existing",label:"Existing task",description:"Pick a task already in the board. The log will update its record and award XP."}]}),i.source==="existing"&&m.length>0?e.jsx(g,{label:"Pick the task",description:"Select the task this work belongs to.",children:e.jsxs("select",{className:"rounded-[14px] bg-[var(--ui-surface-2)] px-3 py-3 text-[var(--ui-ink-strong)]",value:i.taskId,onChange:t=>n({taskId:t.target.value}),children:[e.jsx("option",{value:"",children:"— choose a task —"}),m.map(t=>e.jsxs("option",{value:t.id,children:[t.title," · ",t.status.replaceAll("_"," ")]},t.id))]})}):i.source==="existing"&&m.length===0?e.jsx("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] px-4 py-3 text-sm text-[var(--ui-ink-muted)]",children:'No tasks are loaded yet. Switch to "New task" to create one from scratch.'}):null]})},{id:"details",eyebrow:"Work details",title:"Describe what was done",description:"Give the work a clear title and enough context to understand it later. These become the task record if you are creating a new one.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsx(g,{label:"Title",labelHelp:"Write the title like a short achievement: what was completed, not what was started.",children:e.jsx(C,{value:i.title,placeholder:"Write postmortem draft",onChange:t=>n({title:t.target.value})})}),e.jsx(g,{label:"Owner",description:"Who did this work? Defaults to the operator name.",children:e.jsx(C,{value:i.owner,placeholder:"Your name",onChange:t=>n({owner:t.target.value})})}),e.jsx(g,{label:"Description",description:"What moved forward? What should remain visible in the project history?",children:e.jsx(ze,{className:"min-h-28",value:i.description,placeholder:"Wrote the full incident timeline and drafted the three key learnings for the team retrospective.",onChange:t=>n({description:t.target.value})})})]})},{id:"placement",eyebrow:"Placement",title:"Set the context and XP value",description:"Assign the work to a project and choose its final status. The XP value controls how much this work contributes to the operator's progress curve.",render:(i,n)=>e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid gap-5 md:grid-cols-2",children:[e.jsx(g,{label:"Project",description:"Link this work to an active project if it belongs to one.",children:e.jsxs("select",{className:"rounded-[14px] bg-[var(--ui-surface-2)] px-3 py-3 text-[var(--ui-ink-strong)]",value:i.projectId,onChange:t=>n({projectId:t.target.value}),children:[e.jsx("option",{value:"",children:"No project link"}),b.map(t=>e.jsx("option",{value:t.id,children:t.title},t.id))]})}),e.jsx(g,{label:"Final status",labelHelp:"'Done' is the most common choice. Use 'In progress' if the work was real but the task is still open.",children:e.jsx(F,{columns:2,value:i.status,onChange:t=>n({status:t}),options:[{value:"done",label:"Done",description:"Work is complete."},{value:"in_progress",label:"In progress",description:"Still active but already worth logging."},{value:"focus",label:"Focus",description:"Moved into focus."},{value:"blocked",label:"Blocked",description:"Work hit a wall."}]})})]}),e.jsx(g,{label:"XP value",labelHelp:"Typical task XP ranges from 20 to 100. Use 40 for routine tasks, 80+ for complex deliverables.",children:e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx(C,{type:"number",min:5,max:500,className:"w-36",value:i.points,onChange:t=>n({points:Number(t.target.value)})}),e.jsx("div",{className:"flex gap-2",children:[20,40,80,120].map(t=>e.jsxs("button",{type:"button",className:`rounded-full px-3 py-1.5 text-xs transition ${i.points===t?"bg-[var(--ui-surface-3)] text-[var(--ui-ink-strong)]":"bg-[var(--ui-surface-2)] text-[var(--ui-ink-muted)] hover:bg-[var(--ui-surface-2)]"}`,onClick:()=>n({points:t}),children:[t," xp"]},t))})]})})]})}];return e.jsx(Se,{open:a,onOpenChange:r,eyebrow:"Log work",title:"Log retroactive work",description:"Capture work that happened outside the timer so it counts toward progress and XP.",value:u,onChange:f,draftPersistenceKey:"settings.log-work",steps:A,submitLabel:"Log work",pending:l,pendingLabel:"Logging work…",error:M,onSubmit:async()=>{if(j(null),u.source==="new"&&u.title.trim().length===0){j("Add a title so Forge knows what work to create.");return}if(u.source==="existing"&&!u.taskId){j("Pick an existing task or switch to New task.");return}try{await k({taskId:u.source==="existing"&&u.taskId?u.taskId:void 0,title:u.source==="new"&&u.title.trim()?u.title.trim():void 0,description:u.description.trim()||void 0,owner:u.owner.trim()||void 0,projectId:u.projectId||null,status:u.status,points:u.points}),r(!1)}catch(i){j(i instanceof Error?i.message:"Could not log the work right now.")}}})}function Te({text:a}){const[r,l]=v.useState(!1),p=async()=>{try{await navigator.clipboard.writeText(a),l(!0),setTimeout(()=>l(!1),2200)}catch{}};return e.jsxs("button",{type:"button",onClick:()=>void p(),className:"flex items-center gap-1.5 rounded-full bg-[var(--ui-surface-2)] px-3 py-1.5 text-xs font-medium text-[var(--ui-ink-medium)] transition hover:bg-[var(--ui-surface-2)] hover:text-[var(--ui-ink-strong)]",children:[r?e.jsx(Ce,{className:"size-3 text-[var(--success)]"}):e.jsx(Oe,{className:"size-3"}),r?"Copied":"Copy"]})}function se({label:a,children:r,copyText:l}){return e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:a}),e.jsx(Te,{text:l??r})]}),e.jsx("pre",{className:"mt-3 overflow-x-auto rounded-[14px] bg-[var(--ui-code-bg)] p-3 text-xs leading-6 text-[var(--ui-ink-medium)]",children:e.jsx("code",{children:r})})]})}function ks({open:a,onOpenChange:r,state:l}){if(!l)return null;const{tokenString:p,agentLabel:m,onboarding:b}=l,k=JSON.stringify({baseUrl:b.forgeBaseUrl,apiToken:p,actorLabel:m,timeoutMs:b.defaultTimeoutMs},null,2),u=[`curl -s ${b.healthUrl} \\`,` -H "Authorization: Bearer ${p}" \\`,' -H "X-Forge-Source: agent" \\',` -H "X-Forge-Actor: ${m}"`].join(`
2
2
  `),f=["openclaw gateway restart",'openclaw agent --message "forge_get_operator_overview"'].join(`
3
3
  `);return e.jsx(ds,{open:a,onOpenChange:r,children:e.jsxs(cs,{children:[e.jsx(us,{className:"fixed inset-0 z-40 bg-[var(--overlay)] backdrop-blur-xl"}),e.jsxs(ms,{className:"fixed left-1/2 top-1/2 z-50 flex h-[min(52rem,calc(100vh-1rem))] w-[min(52rem,calc(100vw-1.5rem))] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-[34px] border border-[color-mix(in_srgb,var(--primary)_28%,transparent)] bg-[image:var(--ui-surface-modal)] shadow-[var(--ui-shadow-floating)]",children:[e.jsx(xs,{className:"sr-only",children:"Token issued — setup instructions"}),e.jsx(ps,{className:"sr-only",children:"Your new agent token has been issued. Copy it now and follow the setup guide."}),e.jsxs("div",{className:"flex shrink-0 items-start justify-between gap-4 border-b border-[var(--ui-border-subtle)] px-6 py-5",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"flex size-10 shrink-0 items-center justify-center rounded-full bg-[var(--ui-accent-soft)]",children:e.jsx(Me,{className:"size-5 text-[var(--primary)]"})}),e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Token issued"}),e.jsx("div",{className:"mt-0.5 font-display text-xl text-[var(--ui-ink-strong)]",children:"Save your token now"})]})]}),e.jsx(gs,{asChild:!0,children:e.jsx("button",{type:"button","aria-label":"Close",className:"rounded-full bg-[var(--ui-surface-3)] p-2 text-[var(--ui-ink-muted)] transition hover:bg-[var(--ui-surface-3)] hover:text-[var(--ui-ink-strong)]",children:e.jsx(qe,{className:"size-4"})})})]}),e.jsx("div",{className:"flex-1 overflow-y-auto px-6 py-5",children:e.jsxs(hs.div,{initial:{opacity:0,y:16},animate:{opacity:1,y:0},transition:{duration:.3,ease:"easeOut"},className:"grid gap-5",children:[e.jsxs("div",{className:"rounded-[20px] border border-[color-mix(in_srgb,var(--warning)_28%,transparent)] bg-[var(--ui-warning-soft)] p-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(h,{className:"text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]",children:"One-time reveal"}),e.jsx("span",{className:"text-sm text-[var(--ui-ink-medium)]",children:"This value will not be shown again."})]}),e.jsxs("div",{className:"mt-3 flex items-center justify-between gap-3 rounded-[14px] bg-[var(--ui-code-bg)] px-4 py-3",children:[e.jsx("code",{className:"min-w-0 flex-1 break-all text-xs text-[var(--ui-ink-medium)]",children:p}),e.jsx(Te,{text:p})]}),e.jsx("div",{className:"mt-2 text-xs text-[var(--ui-ink-muted)]",children:"Forge stores only a hash — the raw token is unrecoverable after you close this dialog. If lost, rotate the token from the Agents settings page."})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-3 flex items-center gap-2",children:[e.jsx("div",{className:"flex size-5 items-center justify-center rounded-full bg-[var(--ui-surface-3)] text-xs font-semibold text-[var(--ui-ink-strong)]",children:"1"}),e.jsx("span",{className:"text-sm font-medium text-[var(--ui-ink-strong)]",children:"Add the token to your OpenClaw plugin config"})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4 text-sm leading-6 text-[var(--ui-ink-medium)]",children:["Open your ",e.jsx("code",{className:"rounded-md bg-[var(--ui-surface-2)] px-1.5 py-0.5 text-xs text-[var(--ui-ink-medium)]",children:"openclaw.json"})," file and find the"," ",e.jsx("code",{className:"rounded-md bg-[var(--ui-surface-2)] px-1.5 py-0.5 text-xs text-[var(--ui-ink-medium)]",children:"forge"})," plugin entry under"," ",e.jsx("code",{className:"rounded-md bg-[var(--ui-surface-2)] px-1.5 py-0.5 text-xs text-[var(--ui-ink-medium)]",children:"plugins"}),". Add or replace its"," ",e.jsx("code",{className:"rounded-md bg-[var(--ui-surface-2)] px-1.5 py-0.5 text-xs text-[var(--ui-ink-medium)]",children:"params"})," with the config block below."]}),e.jsx("div",{className:"mt-3",children:e.jsx(se,{label:"Plugin params — paste into openclaw.json → plugins → forge → params",copyText:k,children:k})})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-3 flex items-center gap-2",children:[e.jsx("div",{className:"flex size-5 items-center justify-center rounded-full bg-[var(--ui-surface-3)] text-xs font-semibold text-[var(--ui-ink-strong)]",children:"2"}),e.jsx("span",{className:"text-sm font-medium text-[var(--ui-ink-strong)]",children:"Restart the gateway and confirm the agent can connect"})]}),e.jsx(se,{label:"Run in terminal",copyText:f,children:f})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"mb-3 flex items-center gap-2",children:[e.jsx("div",{className:"flex size-5 items-center justify-center rounded-full bg-[var(--ui-surface-3)] text-xs font-semibold text-[var(--ui-ink-strong)]",children:"3"}),e.jsx("span",{className:"text-sm font-medium text-[var(--ui-ink-strong)]",children:"Verify the token is accepted by the API"})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4 text-sm leading-6 text-[var(--ui-ink-medium)]",children:["Run the curl below. A"," ",e.jsx("code",{className:"rounded-md bg-[var(--ui-surface-2)] px-1.5 py-0.5 text-xs text-[color-mix(in_srgb,var(--success)_78%,var(--ui-ink-strong)_22%)]",children:"200 OK"})," response means the token works and the agent"," ",e.jsx("strong",{className:"text-[var(--ui-ink-medium)]",children:m})," is authenticated."]}),e.jsx("div",{className:"mt-3",children:e.jsx(se,{label:"Verify token — run in terminal",copyText:u,children:u})})]}),e.jsxs("div",{className:"rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-4 py-3 text-sm leading-6 text-[var(--ui-ink-muted)]",children:[e.jsx("strong",{className:"text-[var(--ui-ink-medium)]",children:"Tip:"})," If you ever lose this token, go to ",e.jsx("strong",{className:"text-[var(--ui-ink-medium)]",children:"Settings → Agents → Agent tokens"}),", find the entry, and click"," ",e.jsx("strong",{className:"text-[var(--ui-ink-medium)]",children:"Rotate & reveal"})," to get a fresh value without creating a new agent identity."]})]})}),e.jsx("div",{className:"shrink-0 border-t border-[var(--ui-border-subtle)] px-6 py-4",children:e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-muted)]",children:"Token saved? Close this dialog when you are ready."}),e.jsxs(P,{onClick:()=>r(!1),children:[e.jsx(Ce,{className:"size-4"}),"Done"]})]})})]})]})})}function X(a,r){return r.every(l=>a.scopes.includes(l))}function K(a){if(!a)return"Never";try{return new Intl.DateTimeFormat(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}).format(new Date(a))}catch{return a}}function Ne(a){return a==="connected"?"text-[color-mix(in_srgb,var(--success)_78%,var(--ui-ink-strong)_22%)]":a==="stale"||a==="reconnecting"?"text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]":a==="error"?"text-[color-mix(in_srgb,var(--danger)_78%,var(--ui-ink-strong)_22%)]":"text-[var(--ui-ink-muted)]"}function ws(a){return a.some(r=>r.status==="connected")?"connected":a.some(r=>r.status==="reconnecting")?"reconnecting":a.some(r=>r.status==="error")?"error":a.some(r=>r.status==="stale")?"stale":"disconnected"}function Ns(a){const r=new Map;for(const l of a){const p=l.agentId??`${l.provider}:${l.agentLabel}`,m=r.get(p);if(!m){r.set(p,{key:p,agentId:l.agentId,agentLabel:l.agentLabel,provider:l.provider,status:l.status,primary:l,sessions:[l],actionCount:l.actionCount,eventCount:l.eventCount});continue}m.sessions.push(l),m.actionCount+=l.actionCount,m.eventCount+=l.eventCount,m.sessions.sort((b,k)=>Date.parse(k.lastHeartbeatAt)-Date.parse(b.lastHeartbeatAt)),m.primary=m.sessions[0]??m.primary,m.status=ws(m.sessions)}return Array.from(r.values()).sort((l,p)=>Date.parse(p.primary.lastHeartbeatAt)-Date.parse(l.primary.lastHeartbeatAt))}function Pe(a){return a.replaceAll("_"," ")}function Ps(a){const r=[];return a.scopePolicy.userIds.length>0?r.push(`${a.scopePolicy.userIds.length} user${a.scopePolicy.userIds.length===1?"":"s"}`):r.push("all visible users"),a.scopePolicy.projectIds.length>0&&r.push(`${a.scopePolicy.projectIds.length} project${a.scopePolicy.projectIds.length===1?"":"s"}`),a.scopePolicy.tagIds.length>0&&r.push(`${a.scopePolicy.tagIds.length} tag${a.scopePolicy.tagIds.length===1?"":"s"}`),r.join(" · ")}function Ds(){var ge,he,ve,be,je,fe;const a=$e(),[r,l]=v.useState(!1),[p,m]=v.useState("operator"),[b,k]=v.useState(null),[u,f]=v.useState(!1),[M,j]=v.useState(!1),[A,i]=v.useState(!1),[n,t]=v.useState(null),y=R({queryKey:["forge-operator-session"],queryFn:ss}),S=y.isSuccess,q=R({queryKey:["forge-settings"],queryFn:ts,enabled:S}),_e=R({queryKey:["forge-approval-requests"],queryFn:as,enabled:S}),ae=R({queryKey:["forge-agent-onboarding"],queryFn:is}),Y=R({queryKey:["forge-agent-runtime-sessions"],queryFn:rs,enabled:S}),J=R({queryKey:["forge-agent-runtime-session-history",n],queryFn:()=>ns(n),enabled:S&&!!n}),Le=R({queryKey:["forge-operator-context"],queryFn:os,enabled:S}),T=async()=>{await Promise.all([a.invalidateQueries({queryKey:["forge-operator-session"]}),a.invalidateQueries({queryKey:["forge-settings"]}),a.invalidateQueries({queryKey:["forge-approval-requests"]}),a.invalidateQueries({queryKey:["forge-agent-onboarding"]}),a.invalidateQueries({queryKey:["forge-agent-runtime-sessions"]}),a.invalidateQueries({queryKey:["forge-agent-runtime-session-history"]}),a.invalidateQueries({queryKey:["forge-operator-context"]})])},ie=L({mutationFn:s=>Xe(s),onSuccess:T}),re=L({mutationFn:s=>Je(s),onSuccess:async s=>{if(await T(),o){const d=s.token;k({tokenString:d.token,agentLabel:d.tokenSummary.agentLabel??"forge-agent",onboarding:o}),f(!0)}}}),ne=L({mutationFn:s=>Ze(s),onSuccess:T}),oe=L({mutationFn:s=>Ve(s),onSuccess:T}),le=L({mutationFn:s=>es(s),onSuccess:T}),de=L({mutationFn:({sessionId:s,note:d})=>Ge(s,d),onSuccess:T}),ce=L({mutationFn:({sessionId:s,note:d,lastError:c})=>Ye(s,{note:d,lastError:c}),onSuccess:T}),O=L({mutationFn:Qe,onSuccess:T}),w=(ge=q.data)==null?void 0:ge.settings,D=((he=_e.data)==null?void 0:he.approvalRequests)??[],o=(ve=ae.data)==null?void 0:ve.onboarding,ue=v.useMemo(()=>{var s;return((s=Y.data)==null?void 0:s.sessions)??[]},[(be=Y.data)==null?void 0:be.sessions]),E=v.useMemo(()=>Ns(ue),[ue]),I=J.data,x=(je=Le.data)==null?void 0:je.context,_=(w==null?void 0:w.agentTokens.filter(s=>s.status==="active"))??[],me=(o==null?void 0:o.recommendedScopes)??[],B=_.some(s=>X(s,me)),H=_.some(s=>X(s,["rewards.manage"])),U=_.some(s=>X(s,["psyche.write"])),$=_.some(s=>s.autonomyMode!=="approval_required"&&X(s,["write"])),z=_.length>0,xe=E.filter(s=>s.status==="connected"),pe=E.filter(s=>s.status==="stale"),Ie=v.useMemo(()=>{if(!x)return[];const s=[...x.focusTasks,...x.currentBoard.backlog,...x.currentBoard.focus,...x.currentBoard.inProgress,...x.currentBoard.blocked,...x.currentBoard.done],d=new Map;for(const c of s)d.set(c.id,c);return[...d.values()]},[x]),Re=(w==null?void 0:w.profile.operatorName)??"",Fe=[{label:"Operator session",ok:!0,badge:"active",badgeTone:"emerald",detail:(fe=y.data)!=null&&fe.session?`Session open as ${y.data.session.actorLabel}. Works for localhost and Tailscale without a token.`:"Passwordless session is active for local and Tailscale access.",action:null},{label:"Agent token",ok:z,badge:z?`${_.length} active`:"none issued",badgeTone:z?"emerald":"amber",detail:z?`${_.length} active token${_.length===1?"":"s"} allow external agents and scripts to authenticate.`:"No token yet. Issue one to let external agents connect via the API.",action:z?null:{label:"Issue token",preset:"operator",onClick:()=>{m("operator"),l(!0)}}},{label:"Full operator bundle",ok:B,badge:B?"ready":"optional",badgeTone:B?"emerald":"neutral",detail:B?"A token covers all recommended scopes for full operator collaboration.":"No token covers the full recommended scope bundle. Issue one to unlock complete agent collaboration.",action:B?null:{label:"Set up",preset:"operator",onClick:()=>{m("operator"),l(!0)}}},{label:"Reward control",ok:H,badge:H?"ready":"optional",badgeTone:H?"emerald":"neutral",detail:H?"An agent can tune reward rules and issue bonus XP grants.":"No token has rewards.manage — agents cannot adjust XP rules or issue bonuses.",action:H?null:{label:"Add scope",preset:"operator",onClick:()=>{m("operator"),l(!0)}}},{label:"Psyche writes",ok:U,badge:U?"ready":"optional",badgeTone:U?"emerald":"neutral",detail:U?"Sensitive Psyche collaboration is enabled — agents can create and update therapeutic records.":"No token has psyche.write — agent collaboration on sensitive Psyche records is disabled.",action:U?null:{label:"Add scope",preset:"operator",onClick:()=>{m("operator"),l(!0)}}},{label:"Scoped writes",ok:$,badge:$?"ready":"optional",badgeTone:$?"emerald":"neutral",detail:$?"A trusted agent can write without constant approval prompts.":"All write tokens are approval-required. Agents must queue every mutation for your review.",action:$?null:{label:"Configure",preset:"operator",onClick:()=>{m("operator"),l(!0)}}}];return y.isLoading||q.isLoading?e.jsx(Ke,{eyebrow:"Settings · Agents",title:"Loading agent console",description:"Establishing the operator session and loading agent configuration.",columns:2,blocks:6}):y.isError?e.jsx(ye,{eyebrow:"Settings · Agents",error:y.error,onRetry:()=>void y.refetch()}):q.isError||!w?e.jsx(ye,{eyebrow:"Settings · Agents",error:q.error??new Error("Could not load settings."),onRetry:()=>void q.refetch()}):e.jsxs("div",{className:"mx-auto grid w-full max-w-[1220px] gap-5",children:[e.jsx(bs,{title:"Agents",description:"Connection status, capability access, tokens, approval queue, and work logging."}),e.jsx(vs,{}),e.jsx(fs,{open:r,onOpenChange:l,pending:ie.isPending,initialPreset:p,defaultAgentLabel:(o==null?void 0:o.defaultActorLabel)??"OpenClaw",recommendedScopes:me,onSubmit:async s=>{const d=await ie.mutateAsync(s);l(!1),o&&(k({tokenString:d.token.token,agentLabel:s.agentLabel,onboarding:o}),f(!0))}}),e.jsx(ks,{open:u,onOpenChange:f,state:b}),e.jsx(ys,{open:M,onOpenChange:j,pending:O.isPending,defaultOwner:Re,availableTasks:Ie,availableProjects:(x==null?void 0:x.activeProjects)??[],onSubmit:async s=>{await O.mutateAsync(s)}}),e.jsxs("div",{className:"grid gap-5",children:[x?e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2 xl:grid-cols-4",children:[e.jsx(W,{label:"Active sessions",value:xe.length,tone:"core"}),e.jsx(W,{label:"Stale sessions",value:pe.length,tone:"core"}),e.jsx(W,{label:"Pending approvals",value:D.filter(s=>s.status==="pending").length,tone:"core"}),e.jsx(W,{label:"Operator level",value:x.xp.profile.level,tone:"core",detail:`${x.xp.profile.totalXp} total XP`})]}):null,e.jsxs(N,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Capability status"}),e.jsx("div",{className:"mt-4 grid gap-3",children:Fe.map(s=>e.jsxs("div",{className:"flex items-start justify-between gap-4 rounded-[18px] bg-[var(--ui-surface-2)] px-4 py-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("span",{className:"font-medium text-[var(--ui-ink-strong)]",children:s.label}),e.jsx(h,{className:s.badgeTone==="emerald"?"text-[color-mix(in_srgb,var(--success)_78%,var(--ui-ink-strong)_22%)]":s.badgeTone==="amber"?"text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]":"text-[var(--ui-ink-muted)]",children:s.badge})]}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-[var(--ui-ink-muted)]",children:s.detail})]}),s.action?e.jsxs("button",{type:"button",onClick:s.action.onClick,className:"mt-0.5 flex shrink-0 items-center gap-1.5 rounded-full bg-[var(--ui-surface-2)] px-3 py-1.5 text-xs font-medium text-[var(--ui-ink-medium)] transition hover:bg-[var(--ui-surface-2)] hover:text-[var(--ui-ink-strong)]",children:[s.action.label,e.jsx(De,{className:"size-3"})]}):null]},s.label))})]}),e.jsxs(N,{children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Runtime sessions"}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-muted)]",children:"Live OpenClaw, Hermes, and Codex sessions registered against this Forge runtime, with stale detection and reconnect guidance."})]}),E.length>0?e.jsxs(h,{className:"text-[var(--ui-ink-medium)]",children:[xe.length," live ·"," ",pe.length," stale"]}):null]}),e.jsx("div",{className:"mt-4 grid gap-3",children:Y.isLoading?e.jsx("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] px-4 py-4 text-sm text-[var(--ui-ink-muted)]",children:"Loading agent runtime sessions…"}):E.length===0?e.jsx("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] px-4 py-4 text-sm text-[var(--ui-ink-muted)]",children:"No runtime sessions have registered yet. OpenClaw, Hermes, and Codex now self-register here when their Forge adapter starts."}):E.map(s=>{const d=s.primary;return e.jsxs("div",{className:"min-w-0 rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-3 lg:flex-row lg:items-start lg:justify-between",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2.5",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:s.agentLabel}),e.jsx(h,{className:Ne(s.status),children:s.status})]}),e.jsxs("div",{className:"mt-1 text-sm text-[var(--ui-ink-muted)]",children:[s.provider," ·"," ",d.connectionMode.replaceAll("_"," ")," · last heartbeat ",K(d.lastHeartbeatAt)]}),e.jsxs("div",{className:"mt-2 flex min-w-0 flex-wrap gap-x-4 gap-y-1 text-xs text-[var(--ui-ink-muted)]",children:[e.jsxs("span",{children:[s.sessions.length," runtime session",s.sessions.length===1?"":"s"]}),e.jsxs("span",{className:"min-w-0 break-all",children:["Current key ",d.sessionKey]}),e.jsxs("span",{children:[s.actionCount," recorded actions"]}),e.jsxs("span",{children:[s.eventCount," session events"]})]}),d.lastError?e.jsx("div",{className:"mt-3 text-sm text-[color-mix(in_srgb,var(--danger)_78%,var(--ui-ink-strong)_22%)]",children:d.lastError}):null]}),e.jsxs("div",{className:"flex min-w-0 flex-wrap gap-2 lg:shrink-0 lg:justify-end",children:[s.status!=="connected"?e.jsx(P,{variant:"secondary",size:"sm",className:"flex-1 sm:flex-none",pending:de.isPending,pendingLabel:"Requesting",onClick:()=>void de.mutateAsync({sessionId:d.id}),children:"Reconnect"}):null,e.jsx(P,{variant:"secondary",size:"sm",className:"flex-1 sm:flex-none",onClick:()=>t(c=>c===d.id?null:d.id),children:n===d.id?"Hide history":"View history"}),s.status!=="disconnected"?e.jsx(P,{variant:"ghost",size:"sm",className:"flex-1 sm:flex-none",pending:ce.isPending,pendingLabel:"Closing",onClick:()=>void ce.mutateAsync({sessionId:d.id,note:"Marked disconnected from the Forge agents console."}),children:"Mark offline"}):null]})]}),d.recentEvents.length>0?e.jsx("div",{className:"mt-4 grid gap-2",children:d.recentEvents.slice(0,3).map(c=>e.jsxs("div",{className:"flex items-start justify-between gap-3 rounded-[16px] bg-[var(--ui-surface-2)] px-3 py-2.5",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-strong)]",children:c.title}),e.jsx("div",{className:"mt-0.5 text-xs leading-5 text-[var(--ui-ink-muted)]",children:c.summary||c.eventType})]}),e.jsx("div",{className:"shrink-0 text-xs text-[var(--ui-ink-muted)]",children:K(c.createdAt)})]},c.id))}):null,e.jsxs("div",{className:"mt-4 rounded-[16px] bg-[var(--ui-code-bg)] p-3",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Reconnect plan"}),e.jsx("div",{className:"mt-2 text-sm text-[var(--ui-ink-medium)]",children:d.reconnectPlan.summary}),e.jsx("pre",{className:"mt-3 whitespace-pre-wrap break-words text-xs leading-6 text-[var(--ui-ink-medium)] md:overflow-x-auto md:whitespace-pre",children:e.jsx("code",{className:"break-words",children:d.reconnectPlan.commands.join(`
4
4
  `)})})]}),s.sessions.length>1?e.jsxs("div",{className:"mt-4 rounded-[16px] bg-[var(--ui-code-bg)] p-3",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Session history under this agent"}),e.jsx("div",{className:"mt-2 grid gap-2",children:s.sessions.slice(0,6).map(c=>e.jsxs("div",{className:"grid min-w-0 gap-1 rounded-[12px] bg-[var(--ui-surface-2)] px-3 py-2 text-xs text-[var(--ui-ink-muted)] sm:flex sm:items-center sm:justify-between sm:gap-2",children:[e.jsx("span",{className:"min-w-0 break-all sm:truncate",children:c.sessionKey}),e.jsxs("span",{className:`${Ne(c.status)} min-w-0 break-words sm:shrink-0`,children:[c.status," ·"," ",K(c.lastHeartbeatAt)]})]},c.id))})]}):null,n===d.id?e.jsxs("div",{className:"mt-4 rounded-[16px] bg-[var(--ui-code-bg)] p-3",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Work history"}),J.isLoading?e.jsx("div",{className:"mt-3 text-sm text-[var(--ui-ink-muted)]",children:"Loading session history…"}):J.isError?e.jsx("div",{className:"mt-3 text-sm text-[color-mix(in_srgb,var(--danger)_78%,var(--ui-ink-strong)_22%)]",children:"Could not load session history."}):(I==null?void 0:I.session.id)===d.id?e.jsxs("div",{className:"mt-3 grid gap-4 lg:grid-cols-2",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Agent actions"}),e.jsx("div",{className:"mt-2 grid gap-2",children:I.actions.length>0?I.actions.map(c=>e.jsxs("div",{className:"rounded-[14px] bg-[var(--ui-surface-2)] px-3 py-2.5",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-strong)]",children:c.title}),e.jsx(h,{className:"text-[var(--ui-ink-muted)]",children:c.status})]}),e.jsx("div",{className:"mt-1 text-xs leading-5 text-[var(--ui-ink-muted)]",children:c.summary||c.actionType}),e.jsx("div",{className:"mt-1 text-xs text-[var(--ui-ink-muted)]",children:K(c.createdAt)})]},c.id)):e.jsx("div",{className:"rounded-[14px] bg-[var(--ui-surface-2)] px-3 py-2.5 text-sm text-[var(--ui-ink-muted)]",children:"No recorded agent actions for this session yet."})})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Session events"}),e.jsx("div",{className:"mt-2 grid gap-2",children:I.events.length>0?I.events.map(c=>e.jsxs("div",{className:"rounded-[14px] bg-[var(--ui-surface-2)] px-3 py-2.5",children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-strong)]",children:c.title}),e.jsx(h,{className:"text-[var(--ui-ink-muted)]",children:c.level})]}),e.jsx("div",{className:"mt-1 text-xs leading-5 text-[var(--ui-ink-muted)]",children:c.summary||c.eventType}),e.jsx("div",{className:"mt-1 text-xs text-[var(--ui-ink-muted)]",children:K(c.createdAt)})]},c.id)):e.jsx("div",{className:"rounded-[14px] bg-[var(--ui-surface-2)] px-3 py-2.5 text-sm text-[var(--ui-ink-muted)]",children:"No session events recorded yet."})})]})]}):null]}):null]},s.key)})})]}),e.jsxs(N,{children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Agent tokens"}),e.jsxs(P,{size:"sm",variant:"secondary",onClick:()=>{m("operator"),l(!0)},children:[e.jsx(Ee,{className:"size-3.5"}),"Issue token"]})]}),e.jsx("div",{className:"mt-4 grid gap-3",children:w.agentTokens.length===0?e.jsx("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] px-4 py-4 text-sm text-[var(--ui-ink-muted)]",children:"No tokens yet. Issue one to let external agents or scripts authenticate with Forge."}):w.agentTokens.map(s=>e.jsxs("div",{className:"min-w-0 rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:s.label}),e.jsxs("div",{className:"mt-0.5 text-sm text-[var(--ui-ink-muted)]",children:[s.agentLabel??"Unassigned agent"," ·"," ",e.jsx("span",{className:"break-all font-mono text-xs",children:s.tokenPrefix})]})]}),e.jsx(h,{className:`${s.status==="active"?"text-[color-mix(in_srgb,var(--success)_78%,var(--ui-ink-strong)_22%)]":"text-[var(--ui-ink-muted)]"} self-start`,children:s.status})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2 text-xs text-[var(--ui-ink-muted)]",children:[e.jsx("span",{children:s.trustLevel}),e.jsx("span",{children:"·"}),e.jsx("span",{children:s.autonomyMode.replaceAll("_"," ")}),e.jsx("span",{children:"·"}),e.jsx("span",{children:s.approvalMode.replaceAll("_"," ")})]}),e.jsxs("div",{className:"mt-2 text-xs text-[var(--ui-ink-muted)]",children:["Bootstrap: ",Pe(s.bootstrapPolicy.mode)," · ",s.bootstrapPolicy.projectsLimit," projects"," · ",s.bootstrapPolicy.tasksLimit," tasks",s.bootstrapPolicy.includePeoplePages?` · ${s.bootstrapPolicy.peoplePageLimit} people pages`:" · no people pages"]}),e.jsxs("div",{className:"mt-1 text-xs text-[var(--ui-ink-muted)]",children:["Default read scope: ",Ps(s)]}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-1.5",children:["write","rewards.manage","psyche.write"].map(d=>e.jsx(h,{className:s.scopes.includes(d)?"text-[color-mix(in_srgb,var(--success)_78%,var(--ui-ink-strong)_22%)]":"text-[var(--ui-ink-muted)]",children:d},d))}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-2",children:[e.jsx(P,{variant:"secondary",size:"sm",pending:re.isPending,pendingLabel:"Rotating",onClick:()=>void re.mutateAsync(s.id),children:"Rotate & reveal new token"}),e.jsx(P,{variant:"ghost",size:"sm",pending:ne.isPending,pendingLabel:"Revoking",onClick:()=>void ne.mutateAsync(s.id),children:"Revoke"})]})]},s.id))}),e.jsx("div",{className:"mt-3 px-1 text-xs text-[var(--ui-ink-muted)]",children:"Raw token values are shown once and are never recoverable. If a token is lost, rotate or issue a new one."})]}),w.agents.length>0?e.jsxs(N,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Connected agents"}),e.jsx("div",{className:"mt-4 grid gap-3",children:w.agents.map(s=>e.jsxs("div",{className:"flex min-w-0 flex-col gap-3 rounded-[18px] bg-[var(--ui-surface-2)] p-4 sm:flex-row sm:items-start sm:justify-between",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:s.label}),s.description?e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-muted)]",children:s.description}):null,s.linkedUsers.length>0?e.jsx("div",{className:"mt-2 flex flex-wrap gap-2",children:s.linkedUsers.map(d=>{var c;return e.jsx(h,{className:"text-[var(--ui-ink-muted)]",children:((c=d.user)==null?void 0:c.displayName)??d.userId},d.userId)})}):null,e.jsxs("div",{className:"mt-2 flex min-w-0 flex-wrap gap-x-4 gap-y-1 text-sm text-[var(--ui-ink-muted)]",children:[e.jsx("span",{children:s.agentType}),s.identityKey?e.jsx("span",{className:"min-w-0 break-all font-mono text-xs",children:s.identityKey}):null,e.jsx("span",{children:s.autonomyMode.replaceAll("_"," ")}),e.jsxs("span",{children:[s.activeTokenCount," active token",s.activeTokenCount!==1?"s":""]})]})]}),e.jsx(h,{className:"self-start text-[var(--ui-ink-medium)]",children:s.trustLevel})]},s.id))})]}):null,x?e.jsxs("div",{className:"grid gap-3 lg:grid-cols-[minmax(0,1.05fr)_minmax(0,0.95fr)]",children:[e.jsxs(N,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Recommended next move"}),x.recommendedNextTask?e.jsxs("div",{className:"mt-4 grid gap-2",children:[e.jsx(Z,{kind:"task",label:x.recommendedNextTask.title,variant:"heading",size:"lg"}),e.jsx("div",{className:"text-sm leading-6 text-[var(--ui-ink-muted)]",children:x.recommendedNextTask.description||"No extra notes yet."}),e.jsxs("div",{className:"mt-1 flex flex-wrap gap-2",children:[e.jsx(h,{children:x.recommendedNextTask.status.replaceAll("_"," ")}),e.jsxs(h,{children:[x.recommendedNextTask.points," xp"]}),e.jsx(h,{children:x.recommendedNextTask.owner})]})]}):e.jsx("div",{className:"mt-4 text-sm text-[var(--ui-ink-muted)]",children:"Board is clear. No recommended task right now."})]}),e.jsxs(N,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Board pulse"}),e.jsx("div",{className:"mt-4 grid grid-cols-2 gap-3",children:[{label:"Backlog",value:x.currentBoard.backlog.length},{label:"Focus",value:x.currentBoard.focus.length},{label:"In progress",value:x.currentBoard.inProgress.length},{label:"Blocked",value:x.currentBoard.blocked.length}].map(s=>e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:s.label}),e.jsx("div",{className:"mt-2 font-display text-3xl text-[var(--ui-ink-strong)]",children:s.value})]},s.label))})]})]}):null,x&&x.activeProjects.length>0?e.jsxs(N,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Active projects"}),e.jsx("div",{className:"mt-4 grid gap-3 sm:grid-cols-2",children:x.activeProjects.slice(0,6).map(s=>e.jsxs("div",{className:"min-w-0 rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsxs("div",{className:"flex min-w-0 flex-col gap-2 sm:flex-row sm:items-start sm:justify-between",children:[e.jsx("div",{className:"min-w-0",children:e.jsx(Z,{kind:"project",label:s.title})}),e.jsxs(h,{className:"self-start",children:[s.progress,"%"]})]}),e.jsx("div",{className:"mt-2",children:e.jsx(We,{kind:"goal",label:s.goalTitle,compact:!0,gradient:!1})}),e.jsxs("div",{className:"mt-2 text-xs text-[var(--ui-ink-muted)]",children:[s.activeTaskCount," active ·"," ",s.completedTaskCount," done"]})]},s.id))})]}):null,e.jsxs(N,{children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Approval queue"}),D.filter(s=>s.status==="pending").length>0?e.jsxs(h,{className:"text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]",children:[D.filter(s=>s.status==="pending").length," pending"]}):null]}),e.jsx("div",{className:"mt-4 grid gap-3",children:D.length===0?e.jsx("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] px-4 py-4 text-sm text-[var(--ui-ink-muted)]",children:"No pending approvals. Agent actions are flowing through."}):D.map(s=>e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:s.title}),e.jsx("div",{className:"mt-0.5 text-sm text-[var(--ui-ink-muted)]",children:s.summary||s.actionType})]}),e.jsx(h,{className:s.status==="pending"?"text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]":"text-[var(--ui-ink-muted)]",children:s.status})]}),s.status==="pending"?e.jsxs("div",{className:"mt-4 flex flex-wrap gap-2",children:[e.jsx(P,{variant:"secondary",size:"sm",pending:oe.isPending,pendingLabel:"Approving",onClick:()=>void oe.mutateAsync(s.id),children:"Approve"}),e.jsx(P,{variant:"ghost",size:"sm",pending:le.isPending,pendingLabel:"Rejecting",onClick:()=>void le.mutateAsync(s.id),children:"Reject"})]}):null]},s.id))})]}),e.jsxs(N,{children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Retroactive work log"}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-muted)]",children:"Capture work done outside the timer so it counts toward progress and XP."})]}),e.jsxs(P,{variant:"secondary",size:"sm",onClick:()=>j(!0),children:[e.jsx(Be,{className:"size-3.5"}),"Log work"]})]}),O.data?e.jsxs("div",{className:"mt-4 rounded-[18px] bg-[var(--ui-accent-soft)] px-4 py-3 text-sm text-[var(--ui-ink-strong)]",children:["Logged"," ",e.jsx("span",{className:"inline-block align-middle",children:e.jsx(Z,{kind:"task",label:O.data.task.title,showKind:!1})}),". Operator XP updated to ",O.data.xp.profile.totalXp,"."]}):null]}),e.jsxs(N,{children:[e.jsxs("button",{type:"button",className:"flex w-full items-center justify-between gap-4 text-left",onClick:()=>i(s=>!s),children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-muted)]",children:"Connection & onboarding"}),o?e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-muted)]",children:o.forgeBaseUrl}):null]}),A?e.jsx(He,{className:"size-4 shrink-0 text-[var(--ui-ink-muted)]"}):e.jsx(Ue,{className:"size-4 shrink-0 text-[var(--ui-ink-muted)]"})]}),A&&o?e.jsxs("div",{className:"mt-5 grid gap-4",children:[e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Forge API"}),e.jsx("div",{className:"mt-2 break-all text-sm text-[var(--ui-ink-strong)]",children:o.forgeBaseUrl})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Web app"}),e.jsx("div",{className:"mt-2 break-all text-sm text-[var(--ui-ink-strong)]",children:o.webAppUrl})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"OpenAPI spec"}),e.jsx("div",{className:"mt-2 break-all text-sm text-[var(--ui-ink-strong)]",children:o.openApiUrl})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Default policy"}),e.jsxs("div",{className:"mt-2 text-sm text-[var(--ui-ink-strong)]",children:[o.recommendedTrustLevel," ·"," ",o.recommendedAutonomyMode.replaceAll("_"," ")," ·"," ",o.recommendedApprovalMode.replaceAll("_"," ")]}),e.jsxs("div",{className:"mt-2 text-xs text-[var(--ui-ink-muted)]",children:["Bootstrap default:"," ",Pe(o.defaultBootstrapPolicy.mode)," · ",o.defaultBootstrapPolicy.projectsLimit," projects"," · ",o.defaultBootstrapPolicy.tasksLimit," tasks"]})]})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:o.authModes.operatorSession.label}),e.jsx(h,{className:"mt-1 text-[color-mix(in_srgb,var(--success)_78%,var(--ui-ink-strong)_22%)]",children:o.defaultConnectionMode==="operator_session"?"default":"available"}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-[var(--ui-ink-medium)]",children:o.authModes.operatorSession.summary}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:o.authModes.operatorSession.trustedTargets.map(s=>e.jsx(h,{className:"text-[var(--ui-ink-medium)]",children:s},s))})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:o.authModes.managedToken.label}),e.jsx(h,{className:"mt-1 text-[var(--ui-ink-muted)]",children:"optional"}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-[var(--ui-ink-medium)]",children:o.authModes.managedToken.summary}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-muted)]",children:o.tokenRecovery.rotationSummary})]})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Shared runtime"}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-[var(--ui-ink-medium)]",children:"Keep Forge, OpenClaw, Hermes, and the browser on the same runtime when they should see one shared user directory, one strategy graph, and one task history."}),e.jsxs("div",{className:"mt-3 text-xs leading-5 text-[var(--ui-ink-muted)]",children:["Base URL: ",o.forgeBaseUrl]})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Agent identity"}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-[var(--ui-ink-medium)]",children:"Create each agent as a bot user, then write with that user's `userId`. The relationship graph in Settings -> Users controls what each direction can see, message, share, plan, and affect."}),e.jsx("div",{className:"mt-3 text-xs leading-5 text-[var(--ui-ink-muted)]",children:"Cross-owner links stay valid even when ownership differs."})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Contract timing"}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-[var(--ui-ink-medium)]",children:"Leave strategies editable while humans and bots refine the graph. Lock them only when the plan becomes the contract the alignment metrics should judge."}),e.jsx("div",{className:"mt-3 text-xs leading-5 text-[var(--ui-ink-muted)]",children:"Coverage, sequencing, scope discipline, and quality all contribute to alignment now."})]})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Fast onboarding checklist"}),e.jsxs("div",{className:"mt-3 grid gap-2 text-sm leading-6 text-[var(--ui-ink-medium)]",children:[e.jsx("div",{children:"1. Create the human and bot users in Settings -> Users."}),e.jsx("div",{children:"2. Keep the default graph permissive until collaboration is flowing cleanly."}),e.jsx("div",{children:"3. Point OpenClaw and Hermes at the same Forge runtime and storage root when they should collaborate."}),e.jsx("div",{children:"4. Give each adapter a distinct actor label so activity stays readable."}),e.jsx("div",{children:"5. Build strategies as drafts first, then lock when the plan is ready to become the contract."})]})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Rights language"}),e.jsxs("div",{className:"mt-3 grid gap-2 text-sm leading-6 text-[var(--ui-ink-medium)]",children:[e.jsx("div",{children:"`See` means discover, search, and read another owner."}),e.jsx("div",{children:"`Message` means coordinate and hand off through Forge."}),e.jsx("div",{children:"`Plan` means draft or edit that owner's strategies."}),e.jsx("div",{children:"`Affect` means create or mutate that owner's work."})]})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Strategy lifecycle"}),e.jsxs("div",{className:"mt-3 grid gap-2 text-sm leading-6 text-[var(--ui-ink-medium)]",children:[e.jsx("div",{children:"1. Save an incomplete draft while the plan is still being negotiated."}),e.jsx("div",{children:"2. Let humans and bots refine targets, nodes, and sequence together."}),e.jsx("div",{children:"3. Lock only when the graph becomes the contract for alignment."}),e.jsx("div",{children:"4. Unlock only when the contract itself is being renegotiated."})]})]})]}),e.jsxs("div",{className:"rounded-[18px] bg-[var(--ui-surface-2)] p-4",children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-muted)]",children:"Quick-connect verification"}),e.jsx("pre",{className:"mt-3 overflow-x-auto rounded-[16px] bg-[var(--ui-code-bg)] p-4 text-xs leading-6 text-[var(--ui-ink-medium)]",children:e.jsx("code",{children:[`curl -s ${o.healthUrl}`,"openclaw plugins install ./projects/forge","openclaw gateway restart"].join(`
@@ -1 +1 @@
1
- import{r as u,j as e,b7 as q,c$ as E,c1 as R}from"./vendor-BwL6m4SE.js";import{j as Q,i as B,k as h}from"./state-Bpe5dF3T.js";import{S as K}from"./settings-section-nav-Lo-VKCfZ.js";import{S as H,e as P,C as x,I as W,c as G,B as y,b as V,dg as A,dh as $,cU as Y,di as O}from"./index-FpGANF9S.js";import{P as U}from"./page-hero-DvrM83_C.js";import"./motion-DcgUnXhY.js";import"./ui-B9TWEtCx.js";import"./board-CuxQRKPJ.js";import"./forms-D1qJ3oOP.js";const a={goal:"Goals",project:"Projects",task:"Tasks",strategy:"Strategies",habit:"Habits",tag:"Tags",note:"Notes",insight:"Insights",psyche_value:"Values",behavior_pattern:"Patterns",behavior:"Behaviors",belief_entry:"Beliefs",mode_profile:"Modes",mode_guide_session:"Mode guides",flashcard:"Flashcards",event_type:"Event types",emotion_definition:"Emotions",trigger_report:"Reports",calendar_event:"Calendar events",work_block_template:"Work blocks",task_timebox:"Timeboxes",preference_catalog:"Preference catalogs",preference_catalog_item:"Preference catalog items",preference_context:"Preference contexts",preference_item:"Preference items",questionnaire_instrument:"Questionnaires",sleep_session:"Sleep sessions",workout_session:"Workout sessions"},J={goal:"goal",project:"project",task:"task",strategy:"strategy",habit:"habit",tag:null,note:null,insight:"report",psyche_value:"value",behavior_pattern:"pattern",behavior:"behavior",belief_entry:"belief",mode_profile:"mode",mode_guide_session:"mode",flashcard:"flashcard",event_type:null,emotion_definition:null,trigger_report:"report",calendar_event:null,work_block_template:null,task_timebox:null,preference_catalog:null,preference_catalog_item:null,preference_context:null,preference_item:null,questionnaire_instrument:null,sleep_session:null,workout_session:null},v="font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",X="text-[var(--ui-ink-strong)]",j="text-[var(--ui-ink-soft)]",m="text-[var(--ui-ink-faint)]",Z="border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]",ee="border-[color-mix(in_srgb,var(--primary)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-accent-soft)] text-[var(--primary)]",te="grid min-w-0 gap-3 rounded-[22px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4 lg:grid-cols-[minmax(0,1fr)_auto]";function se(f){return new Date(f).toLocaleString()}function me(){var C,T;const f=Q(),[b,D]=u.useState(""),[l,L]=u.useState([]),c=B({queryKey:["forge-operator-session"],queryFn:Y}),M=c.isSuccess,o=B({queryKey:["forge-settings-bin"],queryFn:O,enabled:M}),p=async()=>{await f.invalidateQueries({predicate:t=>Array.isArray(t.queryKey)&&typeof t.queryKey[0]=="string"&&t.queryKey[0].startsWith("forge-")})},_=h({mutationFn:t=>A({operations:[{entityType:t.entityType,id:t.entityId}]}),onSuccess:p}),w=h({mutationFn:t=>$({operations:[{entityType:t.entityType,id:t.entityId,mode:"hard"}]}),onSuccess:p}),k=h({mutationFn:t=>A({operations:t.map(s=>({entityType:s.entityType,id:s.entityId}))}),onSuccess:p}),N=h({mutationFn:t=>$({operations:t.map(s=>({entityType:s.entityType,id:s.entityId,mode:"hard"}))}),onSuccess:p}),d=((C=o.data)==null?void 0:C.bin.records)??[],g=b.trim().toLowerCase(),r=u.useMemo(()=>d.filter(t=>l.length===0||l.includes(t.entityType)?g?[t.title,t.subtitle??"",t.entityType,t.entityId,t.deletedByActor??"",t.deletedSource??"",t.deleteReason??""].join(" ").toLowerCase().includes(g):!0:!1),[g,d,l]),S=u.useMemo(()=>{const t=new Map;for(const s of r){const i=t.get(s.entityType)??[];i.push(s),t.set(s.entityType,i)}return[...t.entries()].sort((s,i)=>a[s[0]].localeCompare(a[i[0]]))},[r]),I=u.useMemo(()=>[...new Set(d.map(t=>t.entityType))].sort((t,s)=>a[t].localeCompare(a[s])),[d]);function z(t){L(s=>s.includes(t)?s.filter(i=>i!==t):[...s,t])}async function F(){r.length===0||!window.confirm(`Permanently delete ${r.length} item${r.length===1?"":"s"} from the bin? This cannot be undone.`)||await N.mutateAsync(r)}return c.isLoading||o.isLoading?e.jsx(H,{eyebrow:"Settings",title:"Loading bin",description:"Loading deleted items and restore controls.",columns:2,blocks:6}):c.isError?e.jsx(P,{eyebrow:"Settings",error:c.error,onRetry:()=>void c.refetch()}):o.isError?e.jsx(P,{eyebrow:"Settings",error:o.error,onRetry:()=>void o.refetch()}):e.jsxs("div",{className:"mx-auto grid w-full max-w-[1220px] gap-5",children:[e.jsx(U,{title:"Bin",description:"Restore soft-deleted items or permanently remove them when you really mean it.",badge:`${((T=o.data)==null?void 0:T.bin.totalCount)??0} deleted items`}),e.jsx(K,{}),e.jsxs(x,{className:"grid gap-4",children:[e.jsxs("div",{className:"grid gap-4 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-start",children:[e.jsxs("div",{className:"grid gap-4",children:[e.jsx("div",{className:v,children:"Find deleted items"}),e.jsxs("div",{className:"relative",children:[e.jsx(q,{className:`pointer-events-none absolute left-4 top-1/2 size-4 -translate-y-1/2 ${m}`}),e.jsx(W,{value:b,onChange:t=>D(t.target.value),placeholder:"Search title, id, reason, or source",className:"pl-11"})]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:I.map(t=>{const s=l.includes(t);return e.jsx("button",{type:"button",onClick:()=>z(t),className:G("rounded-full border px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] transition",s?ee:Z),children:a[t]},t)})})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 lg:max-w-[22rem] lg:justify-end",children:[e.jsxs(y,{variant:"secondary",size:"sm",disabled:r.length===0,pending:k.isPending,pendingLabel:"Restoring",onClick:()=>void k.mutateAsync(r),children:[e.jsx(E,{className:"size-4"}),e.jsx("span",{children:"Restore visible"})]}),e.jsxs(y,{variant:"secondary",size:"sm",disabled:r.length===0,pending:N.isPending,pendingLabel:"Deleting",onClick:()=>void F(),children:[e.jsx(R,{className:"size-4"}),e.jsx("span",{children:"Delete visible forever"})]})]})]}),e.jsxs("div",{className:`flex flex-wrap gap-3 text-sm ${m}`,children:[e.jsxs("span",{children:[r.length," visible"]}),l.length>0?e.jsxs("span",{children:[l.length," type filters active"]}):null,g?e.jsxs("span",{children:["Search: “",b.trim(),"”"]}):null]})]}),d.length===0?e.jsxs(x,{children:[e.jsx("div",{className:v,children:"Deleted items"}),e.jsx("div",{className:`mt-4 ${j}`,children:"Nothing is in the bin right now."})]}):S.length===0?e.jsxs(x,{children:[e.jsx("div",{className:v,children:"Deleted items"}),e.jsx("div",{className:`mt-4 ${j}`,children:"No deleted items match the current search or filters."})]}):e.jsx("div",{className:"grid gap-5",children:S.map(([t,s])=>{const i=J[t];return e.jsxs(x,{children:[e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-3",children:e.jsxs("div",{className:"flex items-center gap-3",children:[i?e.jsx(V,{kind:i,label:a[t],compact:!0}):null,i?null:e.jsx("div",{className:`rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-1 text-[11px] uppercase tracking-[0.16em] ${m}`,children:a[t]}),e.jsxs("div",{className:`text-sm ${m}`,children:[s.length," deleted"]})]})}),e.jsx("div",{className:"mt-4 grid gap-3",children:s.map(n=>e.jsxs("div",{className:te,children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:`break-words text-lg font-medium [overflow-wrap:anywhere] ${X}`,children:n.title}),n.subtitle?e.jsx("div",{className:`mt-1 break-words text-sm [overflow-wrap:anywhere] ${j}`,children:n.subtitle}):null,e.jsxs("div",{className:`mt-3 flex flex-wrap gap-3 break-words text-xs [overflow-wrap:anywhere] ${m}`,children:[e.jsxs("span",{children:["Deleted ",se(n.deletedAt)]}),n.deletedByActor?e.jsxs("span",{children:["By ",n.deletedByActor]}):null,n.deletedSource?e.jsxs("span",{children:["Source ",n.deletedSource]}):null,n.deleteReason?e.jsxs("span",{children:["Reason: ",n.deleteReason]}):null]})]}),e.jsxs("div",{className:"flex flex-wrap items-start justify-end gap-2",children:[e.jsxs(y,{variant:"secondary",size:"sm",pending:_.isPending,pendingLabel:"Restoring",onClick:()=>void _.mutateAsync(n),children:[e.jsx(E,{className:"size-4"}),e.jsx("span",{children:"Restore"})]}),e.jsxs(y,{variant:"secondary",size:"sm",pending:w.isPending,pendingLabel:"Deleting",onClick:()=>void w.mutateAsync(n),children:[e.jsx(R,{className:"size-4"}),e.jsx("span",{children:"Delete forever"})]})]})]},`${n.entityType}:${n.entityId}`))})]},t)})})]})}export{me as SettingsBinPage};
1
+ import{r as u,j as e,b7 as q,c$ as E,c1 as R}from"./vendor-BwL6m4SE.js";import{j as Q,i as B,k as h}from"./state-Bpe5dF3T.js";import{S as K}from"./settings-section-nav-CMeU19Rx.js";import{S as H,e as P,C as x,I as W,c as G,B as y,b as V,dg as A,dh as $,cU as Y,di as O}from"./index-izRKx6JK.js";import{P as U}from"./page-hero-BLhM8FF3.js";import"./motion-DcgUnXhY.js";import"./ui-B9TWEtCx.js";import"./board-CuxQRKPJ.js";import"./forms-D1qJ3oOP.js";const a={goal:"Goals",project:"Projects",task:"Tasks",strategy:"Strategies",habit:"Habits",tag:"Tags",note:"Notes",insight:"Insights",psyche_value:"Values",behavior_pattern:"Patterns",behavior:"Behaviors",belief_entry:"Beliefs",mode_profile:"Modes",mode_guide_session:"Mode guides",flashcard:"Flashcards",event_type:"Event types",emotion_definition:"Emotions",trigger_report:"Reports",calendar_event:"Calendar events",work_block_template:"Work blocks",task_timebox:"Timeboxes",preference_catalog:"Preference catalogs",preference_catalog_item:"Preference catalog items",preference_context:"Preference contexts",preference_item:"Preference items",questionnaire_instrument:"Questionnaires",sleep_session:"Sleep sessions",workout_session:"Workout sessions"},J={goal:"goal",project:"project",task:"task",strategy:"strategy",habit:"habit",tag:null,note:null,insight:"report",psyche_value:"value",behavior_pattern:"pattern",behavior:"behavior",belief_entry:"belief",mode_profile:"mode",mode_guide_session:"mode",flashcard:"flashcard",event_type:null,emotion_definition:null,trigger_report:"report",calendar_event:null,work_block_template:null,task_timebox:null,preference_catalog:null,preference_catalog_item:null,preference_context:null,preference_item:null,questionnaire_instrument:null,sleep_session:null,workout_session:null},v="font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",X="text-[var(--ui-ink-strong)]",j="text-[var(--ui-ink-soft)]",m="text-[var(--ui-ink-faint)]",Z="border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]",ee="border-[color-mix(in_srgb,var(--primary)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-accent-soft)] text-[var(--primary)]",te="grid min-w-0 gap-3 rounded-[22px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4 lg:grid-cols-[minmax(0,1fr)_auto]";function se(f){return new Date(f).toLocaleString()}function me(){var C,T;const f=Q(),[b,D]=u.useState(""),[l,L]=u.useState([]),c=B({queryKey:["forge-operator-session"],queryFn:Y}),M=c.isSuccess,o=B({queryKey:["forge-settings-bin"],queryFn:O,enabled:M}),p=async()=>{await f.invalidateQueries({predicate:t=>Array.isArray(t.queryKey)&&typeof t.queryKey[0]=="string"&&t.queryKey[0].startsWith("forge-")})},_=h({mutationFn:t=>A({operations:[{entityType:t.entityType,id:t.entityId}]}),onSuccess:p}),w=h({mutationFn:t=>$({operations:[{entityType:t.entityType,id:t.entityId,mode:"hard"}]}),onSuccess:p}),k=h({mutationFn:t=>A({operations:t.map(s=>({entityType:s.entityType,id:s.entityId}))}),onSuccess:p}),N=h({mutationFn:t=>$({operations:t.map(s=>({entityType:s.entityType,id:s.entityId,mode:"hard"}))}),onSuccess:p}),d=((C=o.data)==null?void 0:C.bin.records)??[],g=b.trim().toLowerCase(),r=u.useMemo(()=>d.filter(t=>l.length===0||l.includes(t.entityType)?g?[t.title,t.subtitle??"",t.entityType,t.entityId,t.deletedByActor??"",t.deletedSource??"",t.deleteReason??""].join(" ").toLowerCase().includes(g):!0:!1),[g,d,l]),S=u.useMemo(()=>{const t=new Map;for(const s of r){const i=t.get(s.entityType)??[];i.push(s),t.set(s.entityType,i)}return[...t.entries()].sort((s,i)=>a[s[0]].localeCompare(a[i[0]]))},[r]),I=u.useMemo(()=>[...new Set(d.map(t=>t.entityType))].sort((t,s)=>a[t].localeCompare(a[s])),[d]);function z(t){L(s=>s.includes(t)?s.filter(i=>i!==t):[...s,t])}async function F(){r.length===0||!window.confirm(`Permanently delete ${r.length} item${r.length===1?"":"s"} from the bin? This cannot be undone.`)||await N.mutateAsync(r)}return c.isLoading||o.isLoading?e.jsx(H,{eyebrow:"Settings",title:"Loading bin",description:"Loading deleted items and restore controls.",columns:2,blocks:6}):c.isError?e.jsx(P,{eyebrow:"Settings",error:c.error,onRetry:()=>void c.refetch()}):o.isError?e.jsx(P,{eyebrow:"Settings",error:o.error,onRetry:()=>void o.refetch()}):e.jsxs("div",{className:"mx-auto grid w-full max-w-[1220px] gap-5",children:[e.jsx(U,{title:"Bin",description:"Restore soft-deleted items or permanently remove them when you really mean it.",badge:`${((T=o.data)==null?void 0:T.bin.totalCount)??0} deleted items`}),e.jsx(K,{}),e.jsxs(x,{className:"grid gap-4",children:[e.jsxs("div",{className:"grid gap-4 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-start",children:[e.jsxs("div",{className:"grid gap-4",children:[e.jsx("div",{className:v,children:"Find deleted items"}),e.jsxs("div",{className:"relative",children:[e.jsx(q,{className:`pointer-events-none absolute left-4 top-1/2 size-4 -translate-y-1/2 ${m}`}),e.jsx(W,{value:b,onChange:t=>D(t.target.value),placeholder:"Search title, id, reason, or source",className:"pl-11"})]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:I.map(t=>{const s=l.includes(t);return e.jsx("button",{type:"button",onClick:()=>z(t),className:G("rounded-full border px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] transition",s?ee:Z),children:a[t]},t)})})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 lg:max-w-[22rem] lg:justify-end",children:[e.jsxs(y,{variant:"secondary",size:"sm",disabled:r.length===0,pending:k.isPending,pendingLabel:"Restoring",onClick:()=>void k.mutateAsync(r),children:[e.jsx(E,{className:"size-4"}),e.jsx("span",{children:"Restore visible"})]}),e.jsxs(y,{variant:"secondary",size:"sm",disabled:r.length===0,pending:N.isPending,pendingLabel:"Deleting",onClick:()=>void F(),children:[e.jsx(R,{className:"size-4"}),e.jsx("span",{children:"Delete visible forever"})]})]})]}),e.jsxs("div",{className:`flex flex-wrap gap-3 text-sm ${m}`,children:[e.jsxs("span",{children:[r.length," visible"]}),l.length>0?e.jsxs("span",{children:[l.length," type filters active"]}):null,g?e.jsxs("span",{children:["Search: “",b.trim(),"”"]}):null]})]}),d.length===0?e.jsxs(x,{children:[e.jsx("div",{className:v,children:"Deleted items"}),e.jsx("div",{className:`mt-4 ${j}`,children:"Nothing is in the bin right now."})]}):S.length===0?e.jsxs(x,{children:[e.jsx("div",{className:v,children:"Deleted items"}),e.jsx("div",{className:`mt-4 ${j}`,children:"No deleted items match the current search or filters."})]}):e.jsx("div",{className:"grid gap-5",children:S.map(([t,s])=>{const i=J[t];return e.jsxs(x,{children:[e.jsx("div",{className:"flex flex-wrap items-center justify-between gap-3",children:e.jsxs("div",{className:"flex items-center gap-3",children:[i?e.jsx(V,{kind:i,label:a[t],compact:!0}):null,i?null:e.jsx("div",{className:`rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-1 text-[11px] uppercase tracking-[0.16em] ${m}`,children:a[t]}),e.jsxs("div",{className:`text-sm ${m}`,children:[s.length," deleted"]})]})}),e.jsx("div",{className:"mt-4 grid gap-3",children:s.map(n=>e.jsxs("div",{className:te,children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:`break-words text-lg font-medium [overflow-wrap:anywhere] ${X}`,children:n.title}),n.subtitle?e.jsx("div",{className:`mt-1 break-words text-sm [overflow-wrap:anywhere] ${j}`,children:n.subtitle}):null,e.jsxs("div",{className:`mt-3 flex flex-wrap gap-3 break-words text-xs [overflow-wrap:anywhere] ${m}`,children:[e.jsxs("span",{children:["Deleted ",se(n.deletedAt)]}),n.deletedByActor?e.jsxs("span",{children:["By ",n.deletedByActor]}):null,n.deletedSource?e.jsxs("span",{children:["Source ",n.deletedSource]}):null,n.deleteReason?e.jsxs("span",{children:["Reason: ",n.deleteReason]}):null]})]}),e.jsxs("div",{className:"flex flex-wrap items-start justify-end gap-2",children:[e.jsxs(y,{variant:"secondary",size:"sm",pending:_.isPending,pendingLabel:"Restoring",onClick:()=>void _.mutateAsync(n),children:[e.jsx(E,{className:"size-4"}),e.jsx("span",{children:"Restore"})]}),e.jsxs(y,{variant:"secondary",size:"sm",pending:w.isPending,pendingLabel:"Deleting",onClick:()=>void w.mutateAsync(n),children:[e.jsx(R,{className:"size-4"}),e.jsx("span",{children:"Delete forever"})]})]})]},`${n.entityType}:${n.entityId}`))})]},t)})})]})}export{me as SettingsBinPage};
@@ -1,4 +1,4 @@
1
- import{j as e,de as $e,bz as Qe,c8 as Rr,d5 as Ze,cN as ke,c5 as Re,aN as Tr,dg as Pr,r as c,bY as Dr,cV as $r,c1 as zr,aV as er}from"./vendor-BwL6m4SE.js";import{j as Fr,k as ee,i as Me}from"./state-Bpe5dF3T.js";import{F as q,a as qr,Q as rr}from"./question-flow-dialog-Ded2E85L.js";import{I as re,k,B as M,a4 as Br,C as We,p as Ve,dj as Kr,dk as dr,dl as Wr,dm as Vr,cP as ur,dn as Qr,W as Hr,dp as Yr,dq as Xr,dr as Jr,ds as Zr,dt as es,S as rs,e as hr,du as ss,dv as as,i as ns,dw as ts,dx as os,cU as is,cV as ls,dy as cs,dz as ds,dA as us}from"./index-FpGANF9S.js";import{S as hs}from"./settings-section-nav-Lo-VKCfZ.js";import{P as gs}from"./page-hero-DvrM83_C.js";import{r as ps,b as ms,w as fs}from"./calendar-display-preferences-Cid-2RnL.js";import"./ui-B9TWEtCx.js";import"./motion-DcgUnXhY.js";import"./board-CuxQRKPJ.js";import"./forms-D1qJ3oOP.js";const gr="/api/v1/calendar/oauth/microsoft/callback",vs=/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,pr=1e3,He={google:{label:"Primary Google",serverUrl:""},apple:{label:"Primary Apple",serverUrl:"https://caldav.icloud.com"},microsoft:{label:"Primary Exchange Online",serverUrl:""},macos_local:{label:"Calendars On This Mac",serverUrl:"forge-macos-local://eventkit/"},caldav:{label:"Primary CalDAV",serverUrl:"https://caldav.example.com"}};function Ye(r){return{provider:r,label:He[r].label,serverUrl:He[r].serverUrl,username:"",password:"",selectedCalendarUrls:[],forgeCalendarUrl:null,createForgeCalendar:!1,sourceId:null,replaceConnectionIds:[]}}function ge(r,t){const i=t.trim();return i.length>0?i:He[r].label}function qe(r){return{clientId:r.clientId,tenantId:r.tenantId,redirectUri:r.redirectUri}}function Ge(r){return{clientId:r.storedClientId??"",clientSecret:r.storedClientSecret??""}}function xs(r){return r.replace(/\s*No GOOGLE_CLIENT_SECRET is used in this local PKCE flow\./gi,"").replace(/\s{2,}/g," ").trim()}function mr(){return["Google OAuth credentials are not set for this Forge install.","- Save a Google desktop-app client ID and client secret below for this Forge install.","- Or rely on the packaged or environment defaults for the Forge runtime."].join(`
1
+ import{j as e,de as $e,bz as Qe,c8 as Rr,d5 as Ze,cN as ke,c5 as Re,aN as Tr,dg as Pr,r as c,bY as Dr,cV as $r,c1 as zr,aV as er}from"./vendor-BwL6m4SE.js";import{j as Fr,k as ee,i as Me}from"./state-Bpe5dF3T.js";import{F as q,a as qr,Q as rr}from"./question-flow-dialog-D-_EvoAt.js";import{I as re,k,B as M,a4 as Br,C as We,p as Ve,dj as Kr,dk as dr,dl as Wr,dm as Vr,cP as ur,dn as Qr,W as Hr,dp as Yr,dq as Xr,dr as Jr,ds as Zr,dt as es,S as rs,e as hr,du as ss,dv as as,i as ns,dw as ts,dx as os,cU as is,cV as ls,dy as cs,dz as ds,dA as us}from"./index-izRKx6JK.js";import{S as hs}from"./settings-section-nav-CMeU19Rx.js";import{P as gs}from"./page-hero-BLhM8FF3.js";import{r as ps,b as ms,w as fs}from"./calendar-display-preferences-Cid-2RnL.js";import"./ui-B9TWEtCx.js";import"./motion-DcgUnXhY.js";import"./board-CuxQRKPJ.js";import"./forms-D1qJ3oOP.js";const gr="/api/v1/calendar/oauth/microsoft/callback",vs=/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/,pr=1e3,He={google:{label:"Primary Google",serverUrl:""},apple:{label:"Primary Apple",serverUrl:"https://caldav.icloud.com"},microsoft:{label:"Primary Exchange Online",serverUrl:""},macos_local:{label:"Calendars On This Mac",serverUrl:"forge-macos-local://eventkit/"},caldav:{label:"Primary CalDAV",serverUrl:"https://caldav.example.com"}};function Ye(r){return{provider:r,label:He[r].label,serverUrl:He[r].serverUrl,username:"",password:"",selectedCalendarUrls:[],forgeCalendarUrl:null,createForgeCalendar:!1,sourceId:null,replaceConnectionIds:[]}}function ge(r,t){const i=t.trim();return i.length>0?i:He[r].label}function qe(r){return{clientId:r.clientId,tenantId:r.tenantId,redirectUri:r.redirectUri}}function Ge(r){return{clientId:r.storedClientId??"",clientSecret:r.storedClientSecret??""}}function xs(r){return r.replace(/\s*No GOOGLE_CLIENT_SECRET is used in this local PKCE flow\./gi,"").replace(/\s{2,}/g," ").trim()}function mr(){return["Google OAuth credentials are not set for this Forge install.","- Save a Google desktop-app client ID and client secret below for this Forge install.","- Or rely on the packaged or environment defaults for the Forge runtime."].join(`
2
2
  `)}function fr(r,t){return[r,"- Open Forge from a local browser on the host running Forge.",`- Use one of these local addresses: ${t.join(", ")}.`].join(`
3
3
  `)}function Sr(r){return{clientId:(r.clientId??"").trim(),clientSecret:(r.clientSecret??"").trim()}}function bs(r,t){return r.clientId.trim()===t.clientId.trim()&&r.clientSecret.trim()===t.clientSecret.trim()}function ws(r){const t=Sr(r),i={},h=t.clientId.length>0,b=t.clientSecret.length>0;if(h!==b){const f="When overriding Google OAuth credentials, save the client ID and client secret together, or clear both to use the bundled defaults.";h||(i.clientId=f),b||(i.clientSecret=f)}return{normalized:t,issues:i,isValid:Object.keys(i).length===0}}function sr(r){return{clientId:r.clientId.trim(),tenantId:r.tenantId.trim()||"common",redirectUri:r.redirectUri.trim()}}function Cs(r){const t=sr(r),i={};if(t.clientId?vs.test(t.clientId)||(i.clientId="Use the Microsoft app registration client ID GUID."):i.clientId="Microsoft client ID is required.",!t.redirectUri)i.redirectUri="Redirect URI is required.";else try{const h=new URL(t.redirectUri);h.protocol!=="http:"&&h.protocol!=="https:"?i.redirectUri="Redirect URI must use http or https.":h.pathname!==gr&&(i.redirectUri=`Redirect URI must end with ${gr}.`)}catch{i.redirectUri="Redirect URI must be a full URL."}return{normalized:t,issues:i,isValid:Object.keys(i).length===0}}function ys(r,t){return r.clientId.trim()===t.clientId.trim()&&r.tenantId.trim()===t.tenantId.trim()&&r.redirectUri.trim()===t.redirectUri.trim()}function ar(r){return r==="127.0.0.1"||r==="localhost"}function js(r){return r.endsWith(".ts.net")}function Ns(r){r.allowedOrigins.filter(h=>{try{return ar(new URL(h).hostname)}catch{return!1}});const t=(()=>{try{return new URL(r.redirectUri).hostname}catch{return""}})();let i="";try{i=new URL(r.currentOrigin).hostname}catch{i=""}return js(i)&&ar(t)?`Google sign-in has to start from a local browser on the host running Forge. Forge is currently open through Tailscale at ${r.currentOrigin}, but Google sends the callback to localhost on the device that opens the popup. On a phone or another computer, that callback goes to that device instead of the Forge host.`:r.isLocalOnly?"Google sign-in has to start from a local browser on the host running Forge. Google sends the callback to localhost, so if Forge is opened remotely, the callback goes to the other device instead of the Forge host.":`Google sign-in is only enabled from the configured Forge host for this deployment. Open Forge on ${r.appBaseUrl}. Current browser origin: ${r.currentOrigin}.`}const or="rounded-[24px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)]",Te="rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)]",vr="flex min-h-11 min-w-0 items-center overflow-hidden rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-4 text-sm text-[var(--ui-ink-faint)]",xr="inline-flex size-9 shrink-0 items-center justify-center rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] transition hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]",pe="text-sm leading-6 text-[var(--ui-ink-soft)]",oe="font-medium text-[var(--ui-ink-strong)]",kr="bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",Pe="bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_74%,var(--ui-ink-strong)_26%)]",Fs="bg-[var(--ui-info-soft)] text-[color-mix(in_srgb,var(--info)_76%,var(--ui-ink-strong)_24%)]",Ss="rounded-[18px] border border-[var(--ui-info-soft)] bg-[var(--ui-info-soft)] px-4 py-3 text-sm leading-6 text-[var(--ui-ink-strong)]",Er="mt-4 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-4 py-3 text-sm leading-6 text-[var(--ui-ink-soft)]",ks="border-[color-mix(in_srgb,var(--primary)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-accent-soft)] text-[var(--ui-ink-strong)]",Es="border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] hover:bg-[var(--ui-surface-hover)]";function Is({value:r,setValue:t,macosStatus:i,macosDiscovery:h,requestMacosAccess:b,requestMacosAccessPending:f,checkMacosStatus:u,checkMacosStatusPending:A,runDiscovery:j,discoveryPending:v,applyMacosSource:E,activeGoogleSetup:s,googleRedirectOrigin:m,currentBrowserOrigin:L,googleClientIdEditing:g,setGoogleClientIdEditing:N,googleSettingsDraft:p,setGoogleSettingsDraft:I,savedGoogleSettingsDraft:_,googleValidation:G,hasUnsavedGoogleSettings:P,saveGoogleSettings:F,saveGoogleSettingsPending:U,googleSetupMessage:S,setGoogleSetupMessage:W,startGoogleFlow:w,googlePairingAllowedFromCurrentOrigin:ie,googleSession:B,microsoftSettingsDraft:H,setMicrosoftSettingsDraft:V,microsoftValidation:se,hasUnsavedMicrosoftSettings:Ce,saveMicrosoftSettings:ae,saveMicrosoftSettingsPending:Y,testMicrosoftSettings:O,testMicrosoftSettingsPending:D,microsoftSetupMessage:le,setMicrosoftSetupMessage:R,startMicrosoftFlow:fe,microsoftSession:ve}){return e.jsxs("div",{className:"grid gap-4",children:[e.jsx(q,{label:"Connection label",description:"This is the readable label Forge shows in settings and the calendar health cards.",children:e.jsx(re,{value:r.label,onChange:X=>t({label:X.target.value}),placeholder:He[r.provider].label})}),r.provider==="macos_local"?e.jsx(Us,{value:r,setValue:t,macosStatus:i,macosDiscovery:h,requestMacosAccess:b,requestMacosAccessPending:f,checkMacosStatus:u,checkMacosStatusPending:A,runDiscovery:j,discoveryPending:v,applyMacosSource:E}):r.provider==="google"?e.jsx(As,{activeGoogleSetup:s,googleRedirectOrigin:m,currentBrowserOrigin:L,googleClientIdEditing:g,setGoogleClientIdEditing:N,googleSettingsDraft:p,setGoogleSettingsDraft:I,savedGoogleSettingsDraft:_,googleValidation:G,hasUnsavedGoogleSettings:P,saveGoogleSettings:F,saveGoogleSettingsPending:U,googleSetupMessage:S,setGoogleSetupMessage:W,startGoogleFlow:w,googlePairingAllowedFromCurrentOrigin:ie,googleSession:B}):r.provider==="microsoft"?e.jsx(Ls,{microsoftSettingsDraft:H,setMicrosoftSettingsDraft:V,microsoftValidation:se,hasUnsavedMicrosoftSettings:Ce,saveMicrosoftSettings:ae,saveMicrosoftSettingsPending:Y,testMicrosoftSettings:O,testMicrosoftSettingsPending:D,microsoftSetupMessage:le,setMicrosoftSetupMessage:R,startMicrosoftFlow:fe,microsoftSession:ve}):e.jsx(_s,{value:r,setValue:t})]})}function Us({value:r,setValue:t,macosStatus:i,macosDiscovery:h,requestMacosAccess:b,requestMacosAccessPending:f,checkMacosStatus:u,checkMacosStatusPending:A,runDiscovery:j,discoveryPending:v,applyMacosSource:E}){var s;return e.jsx("div",{className:"grid gap-4",children:e.jsxs("div",{className:`${or} p-5`,children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:oe,children:"macOS Calendar access"}),e.jsx("p",{className:`mt-2 max-w-2xl ${pe}`,children:"Forge uses EventKit to read and write the calendars already configured in Calendar.app on this Mac. Grant Calendar full access, then discover the available account sources."})]}),e.jsx(k,{className:i==="full_access"?Pe:kr,children:i==="full_access"?"Full access":i.replaceAll("_"," ")})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-3",children:[e.jsxs(M,{type:"button",onClick:b,pending:f,pendingLabel:"Waiting for macOS",children:[e.jsx($e,{className:"size-4"}),"Request Calendar access"]}),e.jsxs(M,{type:"button",variant:"secondary",onClick:u,pending:A,pendingLabel:"Checking",children:[e.jsx(Qe,{className:"size-4"}),"Check access"]}),e.jsxs(M,{type:"button",onClick:j,disabled:i!=="full_access",pending:v,pendingLabel:"Discovering",children:[e.jsx(Qe,{className:"size-4"}),"Discover host calendars"]})]}),(s=h==null?void 0:h.sources)!=null&&s.length?e.jsxs("div",{className:"mt-5 grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-[var(--ui-ink-strong)]",children:"Host calendar sources"}),h.sources.map(m=>{const L=r.sourceId===m.sourceId;return e.jsxs("button",{type:"button",className:`rounded-[20px] border px-4 py-3 text-left transition ${L?ks:Es}`,onClick:()=>{t({sourceId:m.sourceId}),E({provider:"macos_local",accountLabel:m.accountLabel,serverUrl:r.serverUrl,principalUrl:null,homeUrl:null,calendars:m.calendars})},children:[e.jsx("div",{className:"font-medium",children:m.accountLabel||m.sourceTitle}),e.jsxs("div",{className:"mt-1 text-sm text-[var(--ui-ink-soft)]",children:[m.sourceType," · ",m.calendars.length," calendars"]})]},m.sourceId)})]}):null]})})}function As({activeGoogleSetup:r,googleRedirectOrigin:t,currentBrowserOrigin:i,googleClientIdEditing:h,setGoogleClientIdEditing:b,googleSettingsDraft:f,setGoogleSettingsDraft:u,savedGoogleSettingsDraft:A,googleValidation:j,hasUnsavedGoogleSettings:v,saveGoogleSettings:E,saveGoogleSettingsPending:s,googleSetupMessage:m,setGoogleSetupMessage:L,startGoogleFlow:g,googlePairingAllowedFromCurrentOrigin:N,googleSession:p}){const I=!!(r.storedClientId||r.storedClientSecret);return e.jsx("div",{className:"grid gap-4",children:e.jsxs("div",{className:`${or} p-5`,children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:oe,children:"How Google sign-in works"}),e.jsx("p",{className:`mt-2 max-w-2xl ${pe}`,children:"Start the popup from the host running Forge. Google returns to Forge on localhost, Forge completes the PKCE exchange on the backend, then Forge discovers the calendars for that account."})]}),e.jsx(k,{className:Pe,children:"Auth code + PKCE"})]}),e.jsxs("div",{className:`mt-4 ${Te} px-4 py-3 ${pe}`,children:[e.jsxs("div",{children:["Forge runtime:"," ",e.jsx("span",{className:oe,children:r.appBaseUrl})]}),e.jsxs("div",{className:"break-all",children:["Redirect URI:"," ",e.jsx("span",{className:oe,children:r.redirectUri})]}),e.jsxs("div",{className:"break-all",children:["Redirect origin:"," ",e.jsx("span",{className:oe,children:t||"Unavailable"})]}),e.jsxs("div",{children:["Allowed local browser origins:"," ",e.jsx("span",{className:oe,children:r.allowedOrigins.join(", ")})]}),e.jsxs("div",{className:"break-all",children:["Detected browser origin:"," ",e.jsx("span",{className:oe,children:i||"Unavailable"})]})]}),e.jsx("div",{className:`mt-4 ${Te} p-4`,children:h?e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:oe,children:"Google OAuth override"}),e.jsx("p",{className:`mt-2 max-w-2xl ${pe}`,children:"Save both the client ID and client secret only when this Forge install should use a different Google desktop OAuth app than the packaged default."})]}),e.jsx("button",{type:"button","aria-label":"Done editing Google OAuth client",className:xr,onClick:()=>{L(null),u(Ge(r)),b(!1)},children:e.jsx(Ze,{className:"size-4"})})]}),e.jsxs(q,{label:"Client ID",description:"Override the packaged Google desktop-app client ID for this Forge install.",children:[e.jsx(re,{"aria-label":"Client ID",value:f.clientId,onChange:_=>{L(null),u({...f,clientId:_.target.value})},placeholder:"1234567890-abcdef.apps.googleusercontent.com"}),j.issues.clientId?e.jsx("p",{className:"mt-2 text-sm text-[var(--danger)]",children:j.issues.clientId}):null]}),e.jsxs(q,{label:"Client secret",description:"Override the packaged Google desktop-app client secret for this Forge install.",children:[e.jsx(re,{"aria-label":"Client secret",value:f.clientSecret,onChange:_=>{L(null),u({...f,clientSecret:_.target.value})},placeholder:"GOCSPX-..."}),j.issues.clientSecret?e.jsx("p",{className:"mt-2 text-sm text-[var(--danger)]",children:j.issues.clientSecret}):null]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx(M,{type:"button",onClick:()=>E(f),disabled:!v||!j.isValid,pending:s,pendingLabel:"Saving",children:"Save Google OAuth override"}),e.jsx(M,{type:"button",variant:"secondary",onClick:()=>{L(null),u({clientId:"",clientSecret:""})},disabled:s||!A.clientId&&!A.clientSecret&&f.clientId.length===0&&f.clientSecret.length===0,children:A.clientId||A.clientSecret?"Clear override":"Use packaged default"})]})]}):e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"grid min-w-0 gap-3",children:e.jsxs("div",{className:"flex min-w-0 items-center justify-between gap-3",children:[e.jsx("div",{className:"min-w-0 flex-1",children:e.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[e.jsx("span",{className:"truncate font-medium text-[var(--ui-ink-strong)]",children:"Google OAuth client"}),e.jsx(k,{className:I?Pe:kr,children:I?"Stored on server":"Using packaged default"}),e.jsx(Br,{content:"Forge ships with a packaged Google desktop OAuth client by default. Save both fields only when this Forge install should use a different client ID and client secret pair.",label:"Explain Google OAuth client",className:"shrink-0"})]})}),e.jsx("button",{type:"button","aria-label":"Edit Google OAuth client",className:xr,onClick:()=>{L(null),b(!0)},children:e.jsx(Rr,{className:"size-4"})})]})}),e.jsx(q,{label:"Effective client ID",description:"This is the Google desktop-app client ID Forge will use right now.",children:e.jsx("div",{className:vr,children:e.jsx("span",{className:"block min-w-0 truncate",title:r.clientId,children:r.clientId})})}),e.jsx(q,{label:"Effective client secret",description:"Forge uses this value on the local backend when exchanging and refreshing Google tokens.",children:e.jsx("div",{className:vr,children:e.jsx("span",{className:"block min-w-0 truncate",title:r.clientSecret||"",children:r.clientSecret||""})})})]})}),m?e.jsx("div",{className:Er,children:m}):null,e.jsx("div",{className:`mt-4 ${Ss}`,children:"If you open Forge on a phone or another remote route, Google redirects to localhost on that other device instead of back to Forge."}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-3",children:[e.jsxs(M,{type:"button",onClick:g,disabled:!r.isReadyForPairing||!N||v||s,pending:(p==null?void 0:p.status)==="pending",pendingLabel:"Waiting for Google",children:[e.jsx(ke,{className:"size-4"}),(p==null?void 0:p.status)==="authorized"?"Sign in again":"Sign in with Google"]}),p!=null&&p.accountLabel?e.jsxs(k,{className:Pe,children:[e.jsx(Ze,{className:"mr-1 size-3.5"}),p.accountLabel]}):null]})]})})}function Ls({microsoftSettingsDraft:r,setMicrosoftSettingsDraft:t,microsoftValidation:i,hasUnsavedMicrosoftSettings:h,saveMicrosoftSettings:b,saveMicrosoftSettingsPending:f,testMicrosoftSettings:u,testMicrosoftSettingsPending:A,microsoftSetupMessage:j,setMicrosoftSetupMessage:v,startMicrosoftFlow:E,microsoftSession:s}){return e.jsx("div",{className:"grid gap-4",children:e.jsxs("div",{className:`${or} p-5`,children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:oe,children:"Guided Microsoft setup"}),e.jsx("p",{className:`mt-2 max-w-2xl ${pe}`,children:"Save the Microsoft app registration details for this Forge instance here, optionally test them, then continue into the Microsoft sign-in popup. Exchange Online stays read-only for now."})]}),e.jsx(k,{className:Fs,children:"Read only"})]}),e.jsxs("div",{className:"mt-4 grid gap-4 md:grid-cols-2",children:[e.jsxs(q,{label:"Microsoft client ID",description:"Use the Application (client) ID from the Microsoft Entra app registration for this Forge instance.",children:[e.jsx(re,{value:r.clientId,onChange:m=>{v(null),t({...r,clientId:m.target.value})},placeholder:"00000000-0000-0000-0000-000000000000"}),i.issues.clientId?e.jsx("div",{className:"text-sm text-[var(--danger)]",children:i.issues.clientId}):null]}),e.jsx(q,{label:"Tenant / authority",description:"Use common unless you need a tenant-specific authority.",children:e.jsx(re,{value:r.tenantId,onChange:m=>{v(null),t({...r,tenantId:m.target.value})},placeholder:"common"})})]}),e.jsxs(q,{label:"Redirect URI",description:"Register this exact Forge callback URI in the Microsoft app registration.",children:[e.jsx(re,{value:r.redirectUri,onChange:m=>{v(null),t({...r,redirectUri:m.target.value})},placeholder:"http://127.0.0.1:4317/api/v1/calendar/oauth/microsoft/callback"}),i.issues.redirectUri?e.jsx("div",{className:"text-sm text-[var(--danger)]",children:i.issues.redirectUri}):null]}),e.jsx("div",{className:`mt-4 ${Te} px-4 py-3 ${pe}`,children:"Forge saves the client ID, tenant, and redirect URI for this local instance, then handles Microsoft sign-in in a popup."}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center gap-3",children:[e.jsx(M,{type:"button",onClick:()=>b(r),disabled:!i.isValid,pending:f,pendingLabel:"Saving",children:"Save Microsoft settings"}),e.jsx(M,{type:"button",variant:"secondary",onClick:()=>u(r),disabled:!i.isValid,pending:A,pendingLabel:"Testing",children:"Test Microsoft configuration"}),e.jsxs(M,{type:"button",onClick:E,disabled:!i.isValid||h||f,pending:(s==null?void 0:s.status)==="pending",pendingLabel:"Waiting for Microsoft",children:[e.jsx(ke,{className:"size-4"}),(s==null?void 0:s.status)==="authorized"?"Sign in again":"Sign in with Microsoft"]}),s!=null&&s.accountLabel?e.jsxs(k,{className:Pe,children:[e.jsx(Ze,{className:"mr-1 size-3.5"}),s.accountLabel]}):null]}),e.jsxs("div",{className:"mt-4 grid gap-3 md:grid-cols-2",children:[e.jsx("div",{className:`${Te} px-4 py-3 ${pe}`,children:"Save before sign-in. The Microsoft popup always uses the latest saved client ID, tenant, and redirect URI."}),e.jsx("div",{className:`${Te} px-4 py-3 ${pe}`,children:"After sign-in, Forge will let you choose which Exchange Online calendars to mirror into the Calendar page."})]}),j?e.jsx("div",{className:Er,children:j}):null]})})}function _s({value:r,setValue:t}){return e.jsxs(e.Fragment,{children:[r.provider==="caldav"?e.jsx(q,{label:"CalDAV base URL",description:"Use the account-level CalDAV server URL, not an individual calendar collection URL.",children:e.jsx(re,{value:r.serverUrl,onChange:i=>t({serverUrl:i.target.value}),placeholder:"https://caldav.example.com"})}):null,r.provider==="apple"?e.jsx(q,{label:"Apple CalDAV base URL",children:e.jsx(re,{value:"https://caldav.icloud.com",disabled:!0})}):null,e.jsx(q,{label:"Account email or username",children:e.jsx(re,{value:r.username,onChange:i=>t({username:i.target.value}),placeholder:"operator@example.com"})}),e.jsx(q,{label:r.provider==="apple"?"App-specific password":"Password or app password",children:e.jsx(re,{type:"password",value:r.password,onChange:i=>t({password:i.target.value}),placeholder:"Password"})})]})}const br=[{title:"Before you connect anything",description:"Forge mirrors provider events into Forge. Writable providers can also publish work blocks plus owned timeboxes into one shared Forge write target, while Exchange Online stays read-only for now.",bullets:["Google uses a localhost Authorization Code + PKCE flow. Each user signs in with their own Google account on the same machine running Forge, while Forge stores that user's refresh token on the server for background sync.","Calendars On This Mac uses EventKit to access the calendars already configured in Calendar.app on the host machine, including iCloud, Google, Exchange, and other accounts the Mac is already syncing.","Apple Calendar starts from https://caldav.icloud.com and autodiscovers the real principal plus calendar collections for you.","Exchange Online uses Microsoft Graph with a guided local public-client Microsoft sign-in flow and mirrors the calendars you select into Forge.","Custom CalDAV uses one account-level base URL, then Forge discovers the writable calendars before you choose what to mirror.","Read-only .ics feeds are not enough for writable-provider flows because Forge needs write access for work blocks and task timeboxes."],icon:Re,links:[]},{title:"Calendars On This Mac setup",description:"Use this path when the Mac already has the needed accounts connected in Calendar.app and Forge should sync them through EventKit instead of reconnecting each provider manually.",bullets:["Open Forge on the same Mac whose Calendar.app already contains the accounts you want to mirror.","Choose Calendars On This Mac in Forge settings.","Grant Calendar full access when macOS prompts for it, or re-enable it later in System Settings -> Privacy & Security -> Calendars.","Let Forge discover the available host calendar sources and pick the source account you want to sync.","Choose which calendars Forge should mirror. If Forge already has a write target on another writable connection, this new connection can reuse it instead of creating another Forge calendar.","If Forge already syncs the same account through Google, Apple, CalDAV, or Microsoft, the macOS-local connection replaces the older remote one instead of keeping two visible copies."],icon:Re,links:[]},{title:"Google Calendar setup",description:"Use one Google Cloud desktop-app OAuth client for local Forge, register the exact localhost callback URI, and let Forge complete the Authorization Code + PKCE exchange on the backend.",bullets:["Open Google Cloud credentials and create or reuse one OAuth client for Forge as a Desktop app.","Enable the Calendar API for the same project.","Register Forge's exact callback URI. In local Forge, the default callback is http://127.0.0.1:4317/api/v1/calendar/oauth/google/callback.","Open Forge on localhost on the same machine that is running Forge. If Forge is opened remotely from a phone or a Tailscale route while the callback is localhost, Google will redirect to localhost on that device and the flow will fail.","The user signs in with their own Google account and grants Forge access. They do not create their own Google OAuth client during this step.","Forge will discover the calendars, let you choose which calendars to mirror, and create or reuse Forge as the write calendar."],icon:$e,links:[{label:"Google Cloud credentials",href:"https://console.cloud.google.com/apis/credentials"},{label:"Calendar API quickstart",href:"https://developers.google.com/workspace/calendar/api/quickstart"}]},{title:"Apple Calendar setup",description:"Apple does not require you to paste raw calendar collection URLs into Forge. Start with your Apple ID email, an app-specific password, and the iCloud CalDAV base URL.",bullets:["Create an Apple app-specific password for third-party calendar access.","Open Forge settings and choose Apple Calendar.","Enter the Apple ID email and the app-specific password. Forge uses https://caldav.icloud.com for autodiscovery.","After discovery, choose which calendars Forge should mirror.","If a calendar named Forge already exists, Forge will preselect it as the write calendar. Otherwise you can ask Forge to create it for you."],icon:Tr,links:[{label:"Apple app-specific passwords",href:"https://support.apple.com/en-us/102654"},{label:"Use iCloud Calendar with third-party apps",href:"https://support.apple.com/guide/icloud/set-up-calendar-mmfc0f2442/icloud"}]},{title:"Exchange Online setup",description:"Use Microsoft Graph for Microsoft 365 or Exchange Online calendars. In self-hosted local Forge, the user first saves a Microsoft public client ID, tenant, and redirect URI in Settings -> Calendar, then completes a guided local sign-in flow with PKCE. The connection is still read-only in Forge today.",bullets:["Open Microsoft Entra App registrations and create or reuse an app for this local Forge instance.","Choose a supported account type that matches your self-hosted use case. Use a broad multi-account setup when Forge should work with normal personal or organizational Microsoft sign-ins.","Enable mobile and desktop or public client flow support for that app registration.","Add Forge's callback URI to the redirect URI list. The default local callback is http://127.0.0.1:4317/api/v1/calendar/oauth/microsoft/callback.","Add delegated Graph permissions for User.Read and Calendars.Read, then grant or request consent as required by the tenant.","Open Forge Settings -> Calendar and save the Microsoft client ID, tenant value, and redirect URI in the Exchange Online setup card.","Use Test Microsoft configuration to confirm Forge can launch the local sign-in flow.","Click Sign in with Microsoft, complete the popup flow, and then choose which Exchange Online calendars Forge should mirror."],icon:$e,links:[{label:"Microsoft Graph permissions",href:"https://learn.microsoft.com/en-us/graph/permissions-reference"},{label:"Microsoft identity platform",href:"https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow"},{label:"Microsoft Graph calendar overview",href:"https://learn.microsoft.com/en-us/graph/api/resources/calendar?view=graph-rest-1.0"}]},{title:"Custom CalDAV setup",description:"Use this path for Nextcloud, Fastmail, Baikal, DAViCal, and other CalDAV-compatible providers that expose an account-level base URL.",bullets:["Confirm the provider supports CalDAV, not just an .ics export.","Gather the account-level CalDAV server URL, username, and password or app password.","Open Forge settings and choose Custom CalDAV.","Forge discovers the available calendars from that base URL before anything is saved.","Choose which calendars to mirror and either select an existing Forge calendar or let Forge create one automatically."],icon:Re,links:[]}];function Ms(r){if(!r)return br;const t=r==="google"?"Google Calendar setup":r==="macos_local"?"Calendars On This Mac setup":r==="apple"?"Apple Calendar setup":r==="microsoft"?"Exchange Online setup":"Custom CalDAV setup";return br.filter(i=>i.title==="Before you connect anything"||i.title===t)}function Os({section:r,compact:t}){const i=r.icon;return e.jsxs(We,{className:t?"grid gap-3 rounded-[24px] border border-[var(--ui-border-subtle)] !bg-[var(--ui-surface-1)] p-4":"grid gap-4 rounded-[28px] border border-[var(--ui-border-subtle)] !bg-[var(--ui-surface-1)]",children:[e.jsxs("div",{className:"flex items-start gap-4",children:[e.jsx("div",{className:"rounded-[18px] bg-[var(--primary)]/14 p-3 text-[var(--primary)]",children:e.jsx(i,{className:t?"size-4":"size-5"})}),e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:t?"font-medium text-[var(--ui-ink-strong)]":"font-display text-[1.15rem] text-[var(--ui-ink-strong)]",children:r.title}),e.jsx("p",{className:t?"mt-1.5 text-sm leading-6 text-[var(--ui-ink-soft)]":"mt-2 max-w-3xl text-sm leading-6 text-[var(--ui-ink-soft)]",children:r.description})]})]}),e.jsx("div",{className:t?"grid gap-1.5":"grid gap-2",children:r.bullets.map(h=>e.jsx("div",{className:t?"rounded-[16px] bg-[var(--ui-surface-2)] px-3 py-2.5 text-sm leading-6 text-[var(--ui-ink-medium)]":"rounded-[18px] bg-[var(--ui-surface-2)] px-4 py-3 text-sm leading-6 text-[var(--ui-ink-medium)]",children:h},h))}),r.links.length>0?e.jsx("div",{className:"flex flex-wrap gap-2",children:r.links.map(h=>e.jsxs("a",{href:h.href,target:"_blank",rel:"noreferrer",className:"inline-flex min-h-10 items-center gap-2 rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-2 text-sm text-[var(--ui-ink-medium)] transition hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]",children:[e.jsx(ke,{className:"size-3.5"}),h.label]},h.href))}):null]})}function Gs({provider:r,compact:t=!1}){const i=Ms(r);return e.jsx("div",{className:"grid gap-4",children:i.map(h=>e.jsx(Os,{section:h,compact:t},h.title))})}const Se="rounded-[24px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)]",nr="rounded-[24px] border border-dashed border-[var(--ui-border-strong)] bg-[var(--ui-surface-1)]",Rs="rounded-[26px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)]",wr="rounded-[20px] bg-[var(--ui-surface-2)] px-4 py-3 text-sm text-[var(--ui-ink-soft)]",Ts="text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",me="text-sm leading-6 text-[var(--ui-ink-soft)]",K="font-medium text-[var(--ui-ink-strong)]",De="bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)]",Ps="bg-[var(--ui-info-soft)] text-[color-mix(in_srgb,var(--info)_76%,var(--ui-ink-strong)_24%)]",Ds="rounded-[20px] border border-[var(--ui-warning-soft)] bg-[var(--ui-warning-soft)] px-4 py-3 text-sm leading-6 text-[var(--ui-ink-strong)]",$s="rounded-[24px] border border-[var(--ui-info-soft)] bg-[var(--ui-info-soft)] p-4 text-sm leading-6 text-[var(--ui-ink-strong)]",zs="rounded-[24px] border border-[var(--ui-success-soft)] bg-[var(--ui-success-soft)] p-4 text-sm leading-6 text-[var(--ui-ink-strong)]",qs="border border-[color-mix(in_srgb,var(--primary)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-accent-soft)] text-[var(--primary)]",Ir="border border-[var(--ui-success-soft)] bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_74%,var(--ui-ink-strong)_26%)]",tr="border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] hover:bg-[var(--ui-surface-hover)]";function Bs({value:r,onProviderChange:t}){return e.jsxs("div",{className:"grid gap-5",children:[e.jsx(q,{label:"Provider",description:"Each setup path is guided. Forge discovers calendars before anything is saved.",children:e.jsx(qr,{value:r.provider,onChange:i=>t(i),options:[{value:"google",label:"Google Calendar",description:"Use Google sign-in with Authorization Code + PKCE, let Forge exchange the code on the backend, and store a per-user refresh token server-side."},{value:"apple",label:"Apple Calendar",description:"Start from https://caldav.icloud.com and autodiscover calendars with your app password."},{value:"microsoft",label:"Exchange Online",description:"Save the Microsoft app registration fields in Settings, then sign in with Microsoft and mirror selected Exchange Online calendars in read-only mode."},{value:"macos_local",label:"Calendars On This Mac",description:"Use EventKit to access the calendars already configured in Calendar.app on this host machine and avoid reconnecting those same accounts manually."},{value:"caldav",label:"Custom CalDAV",description:"Use a CalDAV base URL for Nextcloud, Fastmail, Baikal, and other compatible providers."}]})}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("div",{className:`${Se} p-4`,children:[e.jsxs("div",{className:"flex items-center gap-3 text-[var(--ui-ink-strong)]",children:[e.jsx(Pr,{className:"size-4 text-[var(--primary)]"}),e.jsx("div",{className:"font-medium",children:"Dedicated write calendar"})]}),e.jsx("p",{className:`mt-3 ${me}`,children:r.provider==="microsoft"?"Exchange Online is read-only for now. Forge mirrors selected calendars into Forge, but it does not publish work blocks or owned timeboxes back to Microsoft.":e.jsxs(e.Fragment,{children:["Forge writes work blocks and owned timeboxes into a dedicated calendar named ",e.jsx("span",{className:K,children:"Forge"}),"."]})})]}),e.jsxs("div",{className:`${Se} p-4`,children:[e.jsxs("div",{className:"flex items-center gap-3 text-[var(--ui-ink-strong)]",children:[e.jsx($e,{className:"size-4 text-[var(--primary)]"}),e.jsx("div",{className:"font-medium",children:"Discovery first"})]}),e.jsx("p",{className:`mt-3 ${me}`,children:r.provider==="google"?"Forge opens a Google sign-in popup, exchanges the authorization code on the backend, stores a per-user refresh token, and then discovers the writable calendars for that account.":r.provider==="macos_local"?"Forge asks macOS for Calendar access, discovers the host calendars grouped by account source, and replaces overlapping remote connections instead of keeping two copies.":r.provider==="microsoft"?"Forge starts a Microsoft sign-in popup, then discovers the calendars available to that account before you choose what to mirror.":"Forge discovers the actual calendar collections before you choose which ones to mirror and which one should receive owned timeboxes."})]})]}),e.jsxs("div",{className:`${Se} p-4`,children:[e.jsx("div",{className:Ts,children:"Setup guide"}),e.jsx("p",{className:`mt-2 ${me}`,children:"These are the exact setup steps for the selected provider. They stay inside this guided flow so Settings can stay focused on connection health and actions."}),e.jsx("div",{className:"mt-4",children:e.jsx(Gs,{provider:r.provider,compact:!0})})]})]})}function Ks({value:r,setValue:t,discovery:i,startGoogleFlow:h,startMicrosoftFlow:b,activeGoogleSetup:f,googlePairingAllowedFromCurrentOrigin:u,googleSession:A,microsoftValidation:j,hasUnsavedMicrosoftSettings:v,saveMicrosoftSettingsPending:E,microsoftSession:s,discoveryPending:m,runDiscovery:L,macosStatus:g,sharedForgeWriteTargetLabel:N}){return e.jsxs("div",{className:"grid gap-4",children:[e.jsx(Ws,{value:r,discovery:i,startGoogleFlow:h,startMicrosoftFlow:b,activeGoogleSetup:f,googlePairingAllowedFromCurrentOrigin:u,googleSession:A,microsoftValidation:j,hasUnsavedMicrosoftSettings:v,saveMicrosoftSettingsPending:E,microsoftSession:s,discoveryPending:m,runDiscovery:L,macosStatus:g}),i?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:`${Se} p-4 ${me}`,children:[r.provider==="macos_local"?"Discovered through the host calendar store":"Discovered through"," ",e.jsx("span",{className:K,children:i.serverUrl}),i.homeUrl?e.jsxs(e.Fragment,{children:[" ","· home set"," ",e.jsx("span",{className:K,children:i.homeUrl})]}):null]}),r.provider!=="microsoft"&&N?e.jsxs("div",{className:zs,children:["Forge already writes work blocks and owned timeboxes through"," ",e.jsx("span",{className:K,children:N}),". This connection only needs a mirror selection."]}):null,e.jsx("div",{className:"grid gap-3",children:i.calendars.map(p=>{const I=r.selectedCalendarUrls.includes(p.url),_=r.forgeCalendarUrl===p.url;return e.jsxs("div",{className:`${Se} p-4`,children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:K,children:Ve(p)}),e.jsxs("div",{className:"mt-1 break-all text-sm text-[var(--ui-ink-soft)]",children:[p.timezone||"No timezone exposed"," ·"," ",p.url]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[p.isForgeCandidate?e.jsx(k,{className:"bg-[var(--primary)]/14 text-[var(--primary)]",children:"Forge match"}):null,p.isPrimary?e.jsx(k,{className:De,children:"Primary"}):null]})]}),e.jsxs("div",{className:"mt-4 flex flex-wrap gap-2",children:[e.jsx("button",{type:"button",onClick:()=>t({selectedCalendarUrls:I?r.selectedCalendarUrls.filter(G=>G!==p.url):[...r.selectedCalendarUrls,p.url]}),className:`rounded-full px-3 py-2 text-sm transition ${I?qs:tr}`,children:I?"Mirrored":"Mirror into Forge"}),r.provider!=="microsoft"&&!N?e.jsx("button",{type:"button",onClick:()=>t({forgeCalendarUrl:p.url,createForgeCalendar:!1}),className:`rounded-full px-3 py-2 text-sm transition ${_?Ir:tr}`,children:_?"Forge writes here":"Use for Forge writes"}):e.jsx(k,{className:r.provider==="microsoft"?Ps:De,children:r.provider==="microsoft"?"Read only":"Shared target elsewhere"})]})]},p.url)})}),e.jsx(Vs,{value:r,setValue:t,sharedForgeWriteTargetLabel:N})]}):e.jsx(Qs,{value:r})]})}function Ws({value:r,discovery:t,startGoogleFlow:i,startMicrosoftFlow:h,activeGoogleSetup:b,googlePairingAllowedFromCurrentOrigin:f,googleSession:u,microsoftValidation:A,hasUnsavedMicrosoftSettings:j,saveMicrosoftSettingsPending:v,microsoftSession:E,discoveryPending:s,runDiscovery:m,macosStatus:L}){return r.provider==="google"?e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs(M,{type:"button",onClick:i,disabled:!b.isReadyForPairing||!f,pending:(u==null?void 0:u.status)==="pending",pendingLabel:"Waiting for Google",children:[e.jsx(ke,{className:"size-4"}),(u==null?void 0:u.status)==="authorized"?"Reconnect Google":"Sign in with Google"]}),t?e.jsxs(k,{className:De,children:[t.calendars.length," discovered"]}):null]}):r.provider==="microsoft"?e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs(M,{type:"button",onClick:h,disabled:!A.isValid||j||v,pending:(E==null?void 0:E.status)==="pending",pendingLabel:"Waiting for Microsoft",children:[e.jsx(ke,{className:"size-4"}),(E==null?void 0:E.status)==="authorized"?"Reconnect Microsoft":"Sign in with Microsoft"]}),t?e.jsxs(k,{className:De,children:[t.calendars.length," discovered"]}):null]}):e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs(M,{pending:s,pendingLabel:"Discovering",onClick:m,disabled:r.provider==="macos_local"&&L!=="full_access",children:[e.jsx(Qe,{className:"size-4"}),r.provider==="macos_local"?"Discover host calendars":"Discover calendars"]}),t?e.jsxs(k,{className:De,children:[t.calendars.length," discovered"]}):null]})}function Vs({value:r,setValue:t,sharedForgeWriteTargetLabel:i}){return r.provider!=="microsoft"&&!i?e.jsxs("div",{className:`${nr} p-4`,children:[e.jsx("div",{className:K,children:"No Forge calendar yet?"}),e.jsxs("p",{className:`mt-2 ${me}`,children:["If none of the discovered calendars should receive Forge-owned work blocks and timeboxes, let Forge create a dedicated calendar named"," ",e.jsx("span",{className:K,children:"Forge"}),"."]}),e.jsx("div",{className:"mt-4",children:e.jsx("button",{type:"button",onClick:()=>t({forgeCalendarUrl:null,createForgeCalendar:!r.createForgeCalendar}),className:`rounded-full px-3 py-2 text-sm transition ${r.createForgeCalendar?Ir:tr}`,children:r.createForgeCalendar?"Forge will create one":"Create a new Forge calendar"})})]}):r.provider==="microsoft"?e.jsx("div",{className:$s,children:"Exchange Online is connected through Microsoft Graph in read-only mode. Forge will mirror the calendars you select here, but it will keep work blocks and owned timeboxes local or publish them through another writable provider."}):e.jsxs("div",{className:`${nr} p-4 ${me}`,children:["Forge will keep"," ",e.jsx("span",{className:K,children:i})," ","as the canonical write target instead of creating another Forge calendar on this connection."]})}function Qs({value:r}){return e.jsx("div",{className:`${nr} px-4 py-6 ${me}`,children:r.provider==="google"?e.jsx(e.Fragment,{children:"Start the guided Google sign-in first. Forge will bring the discovered Google calendars back here as soon as the popup completes."}):r.provider==="microsoft"?e.jsx(e.Fragment,{children:"Start the guided Microsoft sign-in first. Forge will bring the discovered Exchange Online calendars back here as soon as the popup completes."}):e.jsx(e.Fragment,{children:r.provider==="macos_local"?"Grant macOS Calendar access and discover the host calendars first. If Calendar.app already aggregates Google, Exchange, or iCloud for this Mac, Forge will pick them up here without reconnecting those accounts.":e.jsxs(e.Fragment,{children:["Discover calendars after entering the credentials. For Apple, Forge starts from"," ",e.jsx("span",{className:K,children:"https://caldav.icloud.com"})," ","and resolves the principal plus calendar home automatically."]})})})}function Hs({value:r,macosDiscovery:t,existingConnections:i,sharedForgeWriteTargetLabel:h}){var b,f;return e.jsxs("div",{className:"grid gap-4",children:[r.provider==="macos_local"&&r.sourceId?e.jsxs("div",{className:`${Se} px-4 py-3 ${me}`,children:["Selected host source:"," ",e.jsx("span",{className:K,children:((b=t==null?void 0:t.sources.find(u=>u.sourceId===r.sourceId))==null?void 0:b.accountLabel)??((f=t==null?void 0:t.sources.find(u=>u.sourceId===r.sourceId))==null?void 0:f.sourceTitle)??r.sourceId})]}):null,e.jsxs("div",{className:`${Rs} p-5`,children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("div",{className:"rounded-[18px] bg-[var(--primary)]/14 p-3 text-[var(--primary)]",children:e.jsx(Re,{className:"size-4"})}),e.jsxs("div",{children:[e.jsx("div",{className:"font-display text-xl text-[var(--ui-ink-strong)]",children:ge(r.provider,r.label)}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-soft)]",children:r.provider==="google"?"Google Calendar":r.provider==="macos_local"?"Calendars On This Mac":r.provider==="apple"?"Apple Calendar":r.provider==="microsoft"?"Exchange Online":"Custom CalDAV"})]})]}),e.jsxs("div",{className:"mt-4 grid gap-3 md:grid-cols-2",children:[e.jsxs("div",{className:wr,children:["Mirrored calendars:"," ",e.jsx("span",{className:K,children:r.selectedCalendarUrls.length})]}),e.jsxs("div",{className:wr,children:["Forge writes:"," ",e.jsx("span",{className:K,children:r.provider==="microsoft"?"read only":r.forgeCalendarUrl?"existing calendar":r.createForgeCalendar?"new Forge calendar":h?`shared target via ${h}`:"not selected"})]})]}),r.replaceConnectionIds.length>0?e.jsxs("div",{className:`mt-4 ${Ds}`,children:["Forge will replace ",r.replaceConnectionIds.length," older overlapping connection",r.replaceConnectionIds.length===1?"":"s"," for this same calendar account so only one visible copy remains.",i.filter(u=>r.replaceConnectionIds.includes(u.id)).map(u=>u.label).join(", ")?` ${i.filter(u=>r.replaceConnectionIds.includes(u.id)).map(u=>u.label).join(", ")}.`:""]}):null]})]})}function Ys({open:r,onOpenChange:t,initialProvider:i="google",initialStepId:h,googleSetup:b,microsoftSetup:f,onCalendarSettingsChanged:u,existingConnections:A=[],onSubmit:j,pending:v=!1}){const E=Fr(),[s,m]=c.useState(()=>Ye(i)),[L,g]=c.useState(null),[N,p]=c.useState(null),[I,_]=c.useState("not_determined"),[G,P]=c.useState(null),[F,U]=c.useState(null),[S,W]=c.useState(null),[w,ie]=c.useState(b),[B,H]=c.useState(()=>Ge(b)),[V,se]=c.useState(()=>Ge(b)),[Ce,ae]=c.useState(!1),[Y,O]=c.useState(null),[D,le]=c.useState(f),[R,fe]=c.useState(()=>qe(f)),[ve,X]=c.useState(()=>qe(f)),[Ee,Q]=c.useState(null),T=c.useRef(null),ye=(a=[])=>{const o=new Set(a);return A.find(l=>{var y;return o.has(l.id)?!1:typeof((y=l.config)==null?void 0:y.forgeCalendarUrl)=="string"&&l.config.forgeCalendarUrl.trim().length>0})??null},$=c.useMemo(()=>s.provider==="microsoft"?null:ye(s.replaceConnectionIds),[s.provider,s.replaceConnectionIds,A]),J=$?$.accountLabel&&$.accountLabel.trim().length>0?`${$.label} · ${$.accountLabel}`:$.label:null,Ie=a=>(E.setQueryData(["forge-settings"],a),a.settings),n=()=>{U(null),T.current=null},d=()=>{W(null),T.current=null},x=a=>{p(a);const o=a.calendars.filter(y=>y.selectedByDefault).map(y=>y.url),l=a.calendars.find(y=>y.isForgeCandidate);m(y=>{const he=ye(y.replaceConnectionIds);return{...y,selectedCalendarUrls:y.selectedCalendarUrls.length>0?y.selectedCalendarUrls.filter(be=>a.calendars.some(Ae=>Ae.url===be)):o,forgeCalendarUrl:y.provider==="microsoft"||he?null:(l==null?void 0:l.url)??y.forgeCalendarUrl??null,createForgeCalendar:y.provider==="microsoft"||he?!1:y.createForgeCalendar&&!l}}),g(null)};c.useEffect(()=>{var a;if(!r){(a=T.current)==null||a.close(),T.current=null;return}g(null),p(null),m(Ye(i)),n(),d(),P(null),_("not_determined"),ae(!1),O(null),Q(null)},[i,r]),c.useEffect(()=>{!r||s.provider!=="macos_local"||z.mutateAsync()},[s.provider,r]),c.useEffect(()=>{if(!r||!N||s.provider==="microsoft"||$||s.forgeCalendarUrl||s.createForgeCalendar)return;const a=N.calendars.find(o=>o.isForgeCandidate);a&&m(o=>o.provider==="microsoft"||o.forgeCalendarUrl||o.createForgeCalendar||ye(o.replaceConnectionIds)?o:{...o,forgeCalendarUrl:a.url})},[N,s.createForgeCalendar,s.forgeCalendarUrl,s.provider,r,$]),c.useEffect(()=>{if(!r)return;ie(b);const a=Ge(b);H(a),se(a),ae(!1),O(null)},[b,r]),c.useEffect(()=>{if(!r)return;le(f);const a=qe(f);fe(a),X(a),Q(null)},[f,r]),c.useEffect(()=>{if(!r||!F||F.status!=="pending")return;const a=new URL(w.redirectUri).origin;let o=!1;const l=()=>{o||(o=!0,_r(F.sessionId).finally(()=>{o=!1}))},y=we=>{var Le,_e;we.origin===a&&(((Le=we.data)==null?void 0:Le.type)!=="forge:google-calendar-auth"||((_e=we.data)==null?void 0:_e.sessionId)!==F.sessionId||l())},he=()=>{l()},be=()=>{document.visibilityState==="visible"&&l()},Ae=window.setInterval(l,pr);return window.addEventListener("message",y),window.addEventListener("focus",he),document.addEventListener("visibilitychange",be),()=>{window.removeEventListener("message",y),window.removeEventListener("focus",he),document.removeEventListener("visibilitychange",be),window.clearInterval(Ae)}},[w.redirectUri,F,r]),c.useEffect(()=>{if(!r||!S||S.status!=="pending")return;const a=new URL(D.redirectUri).origin;let o=!1;const l=()=>{o||(o=!0,Mr(S.sessionId).finally(()=>{o=!1}))},y=we=>{var Le,_e;we.origin===a&&(((Le=we.data)==null?void 0:Le.type)!=="forge:microsoft-calendar-auth"||((_e=we.data)==null?void 0:_e.sessionId)!==S.sessionId||l())},he=()=>{l()},be=()=>{document.visibilityState==="visible"&&l()},Ae=window.setInterval(l,pr);return window.addEventListener("message",y),window.addEventListener("focus",he),document.addEventListener("visibilitychange",be),()=>{window.removeEventListener("message",y),window.removeEventListener("focus",he),document.removeEventListener("visibilitychange",be),window.clearInterval(Ae)}},[D.redirectUri,S,r]);const C=ee({mutationFn:()=>s.provider==="macos_local"?Kr().then(({discovery:a})=>{P(a),_(a.status);const o=a.sources.find(l=>l.sourceId===s.sourceId)??a.sources[0]??null;return o&&(x({provider:"macos_local",accountLabel:o.accountLabel,serverUrl:s.serverUrl,principalUrl:null,homeUrl:null,calendars:o.calendars}),m(l=>({...l,sourceId:o.sourceId}))),{discovery:null}}):s.provider==="apple"?dr({provider:"apple",username:s.username,password:s.password}):dr({provider:"caldav",serverUrl:s.serverUrl,username:s.username,password:s.password}),onSuccess:({discovery:a})=>{a&&x(a)},onError:a=>{p(null),g(a instanceof Error?a.message:"Forge could not discover calendars with these credentials.")}}),z=ee({mutationFn:Wr,onSuccess:({status:a})=>{_(a),a!=="full_access"&&(P(null),p(null))}}),ne=ee({mutationFn:Vr,onSuccess:({granted:a,status:o,message:l})=>{if(_(o),a){g(null);return}g(l??"Forge could not obtain Calendar access from macOS yet. Open System Settings > Privacy & Security > Calendars, allow Forge, then return here and click Check access.")},onError:a=>{g(a instanceof Error?a.message:"Forge could not request Calendar access from macOS.")}});c.useEffect(()=>{!r||s.provider!=="macos_local"||I!=="full_access"||G!==null||C.isPending||C.mutateAsync()},[C,s.provider,G,I,r]);const ce=ee({mutationFn:async a=>{const o=sr(a),l=await ur({calendarProviders:{microsoft:o}});return{normalized:o,settings:Ie(l)}},onSuccess:async({settings:a})=>{le(a.calendarProviders.microsoft);const o=qe(a.calendarProviders.microsoft);X(o),fe(o),Q("Microsoft settings saved. Start the guided Microsoft sign-in when you are ready."),u==null||u()},onError:a=>{Q(a instanceof Error?a.message:"Forge could not save the Microsoft settings.")}}),Z=ee({mutationFn:async a=>{const o=Sr(a),l=await ur({calendarProviders:{google:o}});return{normalized:o,settings:Ie(l)}},onSuccess:async({normalized:a,settings:o})=>{ie(o.calendarProviders.google);const l=Ge(o.calendarProviders.google);se(l),H(l),ae(!1),O(a.clientId||a.clientSecret?"Google OAuth credentials saved on the Forge server for this install.":"Google OAuth override cleared. Forge will use the packaged or environment default again."),u==null||u()},onError:a=>{O(a instanceof Error?a.message:"Forge could not save the Google OAuth credentials.")}}),te=ee({mutationFn:a=>{const o=sr(a);return Qr(o)},onSuccess:({result:a})=>{Q(a.message)},onError:a=>{Q(a instanceof Error?a.message:"Forge could not validate the Microsoft configuration.")}}),de=c.useMemo(()=>Cs(R),[R]),je=c.useMemo(()=>ws(B),[B]),ue=!bs(B,V),Ne=!ys(R,ve),xe=typeof window>"u"?"":window.location.origin,ir=c.useMemo(()=>{try{return new URL(w.redirectUri).origin}catch{return""}},[w.redirectUri]),ze=xe.length>0&&w.allowedOrigins.includes(xe)&&(!w.isLocalOnly||ar(new URL(xe).hostname)),Ue=xe&&!ze?Ns({currentOrigin:xe,appBaseUrl:w.appBaseUrl,redirectUri:w.redirectUri,allowedOrigins:w.allowedOrigins,isLocalOnly:w.isLocalOnly}):null,Ur=w.isReadyForPairing?null:xs(w.setupMessage)||mr(),Ar=Ue?fr(Ue,w.allowedOrigins):null,Lr=a=>{if(L)return L;if(s.provider==="google"&&(a==="credentials"||a==="discovery")){if(ue)return"Save the Google OAuth credential change before starting sign-in.";const o=[Ar,Ur].filter(l=>!!l);if(o.length>0)return o.join(`
4
4
 
@@ -1 +1 @@
1
- import{r as o,j as e,da as Y,db as V,cl as me,dc as Z,aQ as J,dd as xe,aD as ge,ca as pe}from"./vendor-BwL6m4SE.js";import{j as he,i as X,k}from"./state-Bpe5dF3T.js";import{a as ve,F as be,Q as ee}from"./question-flow-dialog-Ded2E85L.js";import{I as ae,k as u,S as fe,e as te,B as x,C as y,c as $,cY as je,cZ as ke,f as ye,c_ as we,c$ as Ne,d0 as Fe,d1 as Se,cU as Re,d2 as De}from"./index-FpGANF9S.js";import{S as Ce}from"./settings-section-nav-Lo-VKCfZ.js";import{P as Be}from"./page-hero-DvrM83_C.js";import{M as g}from"./metric-tile-boeHB1R1.js";import"./ui-B9TWEtCx.js";import"./motion-DcgUnXhY.js";import"./board-CuxQRKPJ.js";import"./forms-D1qJ3oOP.js";function A(t){if(!Number.isFinite(t)||t<=0)return"0 B";const l=["B","KB","MB","GB","TB"];let i=t,m=0;for(;i>=1024&&m<l.length-1;)i/=1024,m+=1;return`${i.toFixed(i>=100?0:i>=10?1:2)} ${l[m]}`}function _e(t,l){const i=URL.createObjectURL(t),m=document.createElement("a");m.href=i,m.download=l,m.click(),URL.revokeObjectURL(i)}function Me(t){return t?t===1?"Every hour":t===24?"Every day":t===168?"Every week":`Every ${t} hours`:"Off"}function se(t){switch(t){case"manual":return"Manual";case"automatic":return"Automatic";case"pre_restore":return"Safety backup before restore";case"pre_switch_root":return"Safety backup before folder change";default:return t}}function w(t,l="Unknown time"){if(!t)return l;const i=new Date(t);return Number.isNaN(i.getTime())?l:ye(t)}function Ae({tone:t,message:l}){return e.jsx("div",{className:$("rounded-[20px] border px-4 py-3 text-sm leading-6",t==="success"?"border-[color-mix(in_srgb,var(--success)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-success-soft)] text-[var(--success)]":t==="warning"?"border-[color-mix(in_srgb,var(--warning)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-warning-soft)] text-[var(--warning)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] text-[var(--ui-ink-soft)]"),children:l})}function z({label:t,value:l,icon:i}){return e.jsxs("div",{className:"min-w-0 overflow-hidden rounded-[24px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2 text-[11px] uppercase tracking-[0.16em] text-[var(--ui-ink-faint)]",children:[e.jsx(i,{className:"size-4"}),e.jsx("span",{className:"min-w-0 break-words",children:t})]}),e.jsx("div",{className:"mt-3 min-w-0 break-all text-sm leading-6 text-[var(--ui-ink-soft)] [overflow-wrap:anywhere]",children:l})]})}function Ie(){var G,W;const t=he(),[l,i]=o.useState(""),[m,T]=o.useState(""),[E,q]=o.useState(""),[U,O]=o.useState(!0),[b,re]=o.useState([]),[L,f]=o.useState(null),[ne,N]=o.useState(!1),[d,F]=o.useState({mode:"migrate_current",targetDataRoot:"",createSafetyBackup:!0}),[ie,j]=o.useState(null),[n,P]=o.useState(null),[K,H]=o.useState({createSafetyBackup:!0}),[oe,R]=o.useState(null),h=X({queryKey:["forge-operator-session"],queryFn:Re}),le=h.isSuccess,S=X({queryKey:["forge-data-management"],queryFn:De,enabled:le}),D=async()=>{await Promise.all([t.invalidateQueries({queryKey:["forge-operator-session"]}),t.invalidateQueries({queryKey:["forge-data-management"]})])},I=k({mutationFn:()=>we({backupDirectory:l,backupFrequencyHours:m==="off"?null:Number(m||"24"),backupRetentionDays:E==="forever"?null:Number(E||"30"),autoRepairEnabled:U}),onSuccess:async()=>{f({tone:"success",message:"Backup settings saved."}),await D()}}),C=k({mutationFn:()=>ke("Manual backup from Settings → Data"),onSuccess:async()=>{f({tone:"success",message:"Backup created."}),await D()}}),B=k({mutationFn:je,onSuccess:({candidates:a})=>{re(a),f({tone:a.some(c=>c.newerThanCurrent)?"warning":"neutral",message:a.length>0?`Found ${a.length} Forge ${a.length===1?"copy":"copies"} on disk.`:"No other Forge data copies were found in the scanned folders."})}}),_=k({mutationFn:a=>Fe({targetDataRoot:a.targetDataRoot,mode:a.mode,createSafetyBackup:a.createSafetyBackup}),onSuccess:async()=>{f({tone:"success",message:"Forge is now using the selected data folder."}),N(!1),await D()}}),M=k({mutationFn:({backupId:a,createSafetyBackup:c})=>Se(a,c),onSuccess:async()=>{f({tone:"success",message:"Backup restored. Forge is now running from that restored state."}),P(null),await D()}}),Q=k({mutationFn:async a=>{const c=await Ne(a);return _e(c.blob,c.fileName??`forge-export.${a}`),a},onSuccess:a=>{f({tone:"neutral",message:`Started download for ${a}.`})}}),s=(G=S.data)==null?void 0:G.data;o.useEffect(()=>{s&&(i(a=>a||s.settings.backupDirectory),T(a=>a||(s.settings.backupFrequencyHours?String(s.settings.backupFrequencyHours):"off")),O(s.settings.autoRepairEnabled),q(a=>a||(s.settings.backupRetentionDays?String(s.settings.backupRetentionDays):"forever")),F(a=>({...a,targetDataRoot:a.targetDataRoot||s.current.dataRoot})))},[s]);const ce=o.useMemo(()=>b.find(a=>a.newerThanCurrent),[b]),p=o.useMemo(()=>b.find(a=>a.dataRoot===d.targetDataRoot.trim()),[d.targetDataRoot,b]),de=[{id:"mode",eyebrow:"Step 1",title:"What do you want Forge to do?",description:"Choose whether Forge should move the current data into a new folder or switch to a folder that already contains the right Forge data.",render:(a,c)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(ve,{value:a.mode,onChange:v=>c({mode:v}),options:[{value:"migrate_current",label:"Move the current data",description:"Copy the live database and local secrets key into a new folder, then switch Forge to it."},{value:"adopt_existing",label:"Use an existing data folder",description:"Keep the target folder as it is and point Forge at that existing database directly."}]}),e.jsxs("label",{className:"flex items-start gap-3 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-4 py-3",children:[e.jsx("input",{type:"checkbox",className:"mt-1",checked:a.createSafetyBackup,onChange:v=>c({createSafetyBackup:v.target.checked})}),e.jsx("span",{className:"text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Create one safety backup first."})]})]})},{id:"folder",eyebrow:"Step 2",title:d.mode==="migrate_current"?"Choose the new data folder":"Choose the data folder to use",description:d.mode==="migrate_current"?"Pick an empty folder for the moved Forge data.":"Pick the folder that already contains the Forge data you trust.",render:(a,c)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(be,{label:"Data folder",description:"Forge will place or read the database and backups from here.",children:e.jsx(ae,{value:a.targetDataRoot,onChange:v=>c({targetDataRoot:v.target.value}),placeholder:"/absolute/path/to/forge-data"})}),p?e.jsxs("div",{className:"rounded-[22px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4 text-sm leading-6 text-[var(--ui-ink-soft)]",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:"Found on this machine"}),e.jsx("div",{className:"mt-2 break-all",children:p.databasePath}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx(u,{tone:"meta",children:p.sourceHint}),e.jsxs(u,{tone:"meta",children:[p.counts.notes," notes"]}),e.jsxs(u,{tone:"meta",children:[p.counts.tasks," tasks"]}),p.newerThanCurrent?e.jsx(u,{className:"bg-[var(--ui-warning-soft)] text-[var(--warning)]",children:"Newer than the current copy"}):null]})]}):e.jsx("div",{className:"rounded-[22px] border border-dashed border-[var(--ui-border-subtle)] px-4 py-4 text-sm leading-6 text-[var(--ui-ink-soft)]",children:d.mode==="migrate_current"?"Forge will copy the current data into this folder and then switch over.":"If this folder already holds a Forge database, Forge will start using it after you confirm."})]})}],ue=[{id:"review",eyebrow:"Step 1",title:"Review the backup you want to restore",description:"Restoring replaces the current database with the selected backup.",render:(a,c)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"rounded-[22px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4 text-sm leading-6 text-[var(--ui-ink-soft)]",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:n?w(n.createdAt):"Selected backup"}),e.jsx("div",{className:"mt-2",children:(n==null?void 0:n.note)||"Forge backup archive"}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx(u,{tone:"meta",children:n?se(n.mode):"Backup"}),e.jsx(u,{tone:"meta",children:n?A(n.sizeBytes):"0 B"}),n!=null&&n.includesWiki?e.jsx(u,{tone:"meta",children:"Includes wiki"}):null]})]}),e.jsxs("label",{className:"flex items-start gap-3 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-4 py-3",children:[e.jsx("input",{type:"checkbox",className:"mt-1",checked:a.createSafetyBackup,onChange:v=>c({createSafetyBackup:v.target.checked})}),e.jsx("span",{className:"text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Create one safety backup of the current state first."})]})]})},{id:"confirm",eyebrow:"Step 2",title:"Confirm the restore",description:"Use this only when you are confident this backup is the state you want back.",render:()=>e.jsx("div",{className:"rounded-[22px] border border-[color-mix(in_srgb,var(--warning)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-warning-soft)] p-4 text-sm leading-6 text-[var(--warning)]",children:"Forge will replace the live database with this backup, then reopen the restored copy."})}];if(h.isLoading||S.isLoading)return e.jsx(fe,{eyebrow:"Data",title:"Loading data controls",description:"Checking the live data folder, backup plan, and recovery tools.",columns:3,blocks:6});if(h.isError)return e.jsx(te,{eyebrow:"Data",error:h.error,onRetry:()=>void h.refetch()});if(S.isError||!s)return e.jsx(te,{eyebrow:"Data",error:S.error??new Error("Forge returned an empty data payload."),onRetry:()=>void S.refetch()});const r=s.current;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"mx-auto grid w-full max-w-[1480px] gap-5",children:[e.jsx(Be,{eyebrow:"Data, backups, recovery",title:"Data",description:"See where Forge is saving the live data, keep it protected with backups, look for a newer copy on disk if something goes wrong, and download the database or its structure when you need it.",badge:`${r.integrityOk?"Healthy":"Needs attention"} · ${A(r.databaseSizeBytes)}`,actions:e.jsxs(e.Fragment,{children:[e.jsxs(x,{variant:"secondary",pending:B.isPending,pendingLabel:"Scanning",onClick:()=>void B.mutateAsync(),children:[e.jsx(Y,{className:"size-4"}),"Look for other Forge copies"]}),e.jsxs(x,{pending:C.isPending,pendingLabel:"Creating backup",onClick:()=>void C.mutateAsync(),children:[e.jsx(V,{className:"size-4"}),"Create backup now"]})]})}),e.jsx(Ce,{}),(W=h.data)!=null&&W.session?e.jsxs("div",{className:"rounded-[20px] border border-[color-mix(in_srgb,var(--success)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-success-soft)] px-4 py-3 text-sm text-[var(--ui-ink-medium)]",children:["You are managing Forge data as"," ",e.jsx("span",{className:"font-medium text-[var(--ui-ink-strong)]",children:h.data.session.actorLabel}),"."]}):null,L?e.jsx(Ae,{tone:L.tone,message:L.message}):null,e.jsxs("div",{className:"grid gap-5 xl:grid-cols-[minmax(0,1.15fr)_minmax(0,0.85fr)]",children:[e.jsxs(y,{className:"grid gap-5",children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Live data folder"}),e.jsx("div",{className:"mt-2 min-w-0 break-all text-xl font-semibold text-[var(--ui-ink-strong)] [overflow-wrap:anywhere]",children:r.dataRoot}),e.jsx("div",{className:"mt-2 max-w-3xl text-sm leading-6 text-[var(--ui-ink-soft)]",children:"This is the folder Forge is reading and writing right now."})]}),e.jsx(u,{className:$(r.integrityOk?"bg-[var(--ui-success-soft)] text-[var(--success)]":"bg-[var(--ui-warning-soft)] text-[var(--warning)]"),children:r.integrityMessage})]}),e.jsxs("div",{className:"grid min-w-0 gap-3 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(z,{label:"Database file",value:r.databasePath,icon:me}),e.jsx(z,{label:"Folder layout",value:r.layout,icon:Z}),e.jsx(z,{label:"Last database change",value:r.databaseLastModifiedAt?w(r.databaseLastModifiedAt):"Unknown",icon:J})]}),e.jsxs("div",{className:"grid min-w-0 gap-3 md:grid-cols-3 xl:grid-cols-6",children:[e.jsx(g,{label:"Notes",value:r.counts.notes}),e.jsx(g,{label:"Goals",value:r.counts.goals}),e.jsx(g,{label:"Projects",value:r.counts.projects}),e.jsx(g,{label:"Tasks",value:r.counts.tasks}),e.jsx(g,{label:"Runs",value:r.counts.taskRuns}),e.jsx(g,{label:"Tags",value:r.counts.tags})]})]}),e.jsxs(y,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"flex size-11 items-center justify-center rounded-2xl border border-[color-mix(in_srgb,var(--success)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-success-soft)]",children:e.jsx(xe,{className:"size-5 text-[var(--success)]"})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:"Protection plan"}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Choose where backups go, how often Forge creates them, and whether scans should call out newer copies found elsewhere on disk."})]})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-3",children:[e.jsx(g,{label:"Automatic backup",value:Me(s.settings.backupFrequencyHours),detail:s.settings.lastAutoBackupAt?`Last run ${w(s.settings.lastAutoBackupAt)}`:"No automatic backup recorded yet"}),e.jsx(g,{label:"Manual backup",value:s.settings.lastManualBackupAt?w(s.settings.lastManualBackupAt):"None yet",detail:`${s.backups.length} backup${s.backups.length===1?"":"s"} saved`}),e.jsx(g,{label:"Retention",value:s.settings.backupRetentionDays?`${s.settings.backupRetentionDays} days`:"Keep forever",detail:"Automatic backups only"})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Backup folder"}),e.jsx(ae,{value:l,onChange:a=>i(a.target.value)})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Automatic backup"}),e.jsxs("select",{className:"h-11 rounded-[16px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-3 text-sm text-[var(--ui-ink-strong)] outline-none transition focus:border-[var(--primary)]",value:m||"24",onChange:a=>T(a.target.value),children:[e.jsx("option",{value:"off",children:"Off"}),e.jsx("option",{value:"1",children:"Every hour"}),e.jsx("option",{value:"6",children:"Every 6 hours"}),e.jsx("option",{value:"24",children:"Every day"}),e.jsx("option",{value:"168",children:"Every week"})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Keep automatic backups"}),e.jsxs("select",{className:"h-11 rounded-[16px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-3 text-sm text-[var(--ui-ink-strong)] outline-none transition focus:border-[var(--primary)]",value:E||"30",onChange:a=>q(a.target.value),children:[e.jsx("option",{value:"7",children:"7 days"}),e.jsx("option",{value:"14",children:"14 days"}),e.jsx("option",{value:"30",children:"30 days"}),e.jsx("option",{value:"90",children:"90 days"}),e.jsx("option",{value:"365",children:"1 year"}),e.jsx("option",{value:"forever",children:"Keep forever"})]})]}),e.jsxs("label",{className:"flex items-start gap-3 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-4 py-3",children:[e.jsx("input",{type:"checkbox",className:"mt-1",checked:U,onChange:a=>O(a.target.checked)}),e.jsx("span",{className:"text-sm leading-6 text-[var(--ui-ink-soft)]",children:"When I scan, point out Forge copies that look newer than the one I am using now."})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(x,{pending:I.isPending,pendingLabel:"Saving",onClick:()=>void I.mutateAsync(),children:"Save backup settings"}),e.jsx(x,{variant:"secondary",pending:C.isPending,pendingLabel:"Creating backup",onClick:()=>void C.mutateAsync(),children:"Create backup now"})]})]})]})]}),e.jsxs("div",{className:"grid gap-5 xl:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)]",children:[e.jsxs(y,{className:"grid gap-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Change data folder"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Move today’s Forge data into a new folder, or switch to another folder that already contains the right Forge database."})]}),e.jsxs("div",{className:"rounded-[22px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4 text-sm leading-6 text-[var(--ui-ink-soft)]",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:"Current folder"}),e.jsx("div",{className:"mt-2 break-all",children:r.dataRoot}),p?e.jsxs("div",{className:"mt-3 text-sm text-[var(--ui-ink-soft)]",children:["Selected scanned copy: ",p.dataRoot]}):null]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsxs(x,{onClick:()=>{F(a=>({...a,mode:"migrate_current",targetDataRoot:a.targetDataRoot||r.dataRoot})),j(null),N(!0)},children:[e.jsx(Z,{className:"size-4"}),"Move current data"]}),e.jsxs(x,{variant:"secondary",onClick:()=>{F(a=>({...a,mode:"adopt_existing",targetDataRoot:a.targetDataRoot||r.dataRoot})),j(null),N(!0)},children:[e.jsx(J,{className:"size-4"}),"Use existing data folder"]})]})]}),e.jsxs(y,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Downloads"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Download the live database itself, or export a structure and table snapshot in other formats."})]}),e.jsx(ge,{className:"size-5 text-[var(--ui-ink-faint)]"})]}),e.jsx("div",{className:"grid gap-3",children:s.exportOptions.map(a=>e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:a.label}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-[var(--ui-ink-soft)]",children:a.description})]}),e.jsx(x,{variant:"secondary",pending:Q.isPending,pendingLabel:"Preparing",onClick:()=>void Q.mutateAsync(a.format),children:"Download"})]},a.format))})]})]}),e.jsxs("div",{className:"grid gap-5 xl:grid-cols-[minmax(0,1.05fr)_minmax(0,0.95fr)]",children:[e.jsxs(y,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Backup history"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Go back to an older saved state if you need to undo a bad change."})]}),e.jsx(V,{className:"size-5 text-[var(--ui-ink-faint)]"})]}),e.jsx("div",{className:"grid gap-3",children:s.backups.length===0?e.jsx("div",{className:"rounded-[20px] border border-dashed border-[var(--ui-border-subtle)] px-4 py-6 text-sm text-[var(--ui-ink-soft)]",children:"No backups yet. Create one now so you have a safe restore point."}):s.backups.map(a=>e.jsxs("div",{className:"rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:w(a.createdAt)}),e.jsx(u,{tone:"meta",children:se(a.mode)})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:a.note||"Forge backup archive"})]}),e.jsx(x,{variant:"secondary",onClick:()=>{H({createSafetyBackup:!0}),R(null),P(a)},children:"Restore"})]}),e.jsxs("div",{className:"mt-3 grid gap-2 text-xs text-[var(--ui-ink-faint)] md:grid-cols-2",children:[e.jsx("div",{className:"break-all",children:a.archivePath}),e.jsx("div",{children:A(a.sizeBytes)})]})]},a.id))})]}),e.jsxs(y,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Find other Forge copies"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Search common folders on this machine for other Forge databases. Use this when Forge opened the wrong copy or when you think a newer copy exists somewhere else."})]}),e.jsxs(x,{variant:"secondary",pending:B.isPending,pendingLabel:"Scanning",onClick:()=>void B.mutateAsync(),children:[e.jsx(Y,{className:"size-4"}),"Scan now"]})]}),e.jsx("div",{className:"grid gap-3",children:b.length===0?e.jsx("div",{className:"rounded-[20px] border border-dashed border-[var(--ui-border-subtle)] px-4 py-6 text-sm text-[var(--ui-ink-soft)]",children:"No scan results yet. Run a scan to compare the live data folder with other Forge copies on disk."}):b.map(a=>e.jsxs("div",{className:$("rounded-[22px] border p-4",a.sameAsCurrent?"border-[color-mix(in_srgb,var(--success)_24%,var(--ui-border-subtle)_76%)] bg-[var(--ui-success-soft)]":a.newerThanCurrent?"border-[color-mix(in_srgb,var(--warning)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-warning-soft)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)]"),children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:a.dataRoot}),e.jsx(u,{tone:"meta",children:a.sourceHint}),a.newerThanCurrent?e.jsx(u,{className:"bg-[var(--ui-warning-soft)] text-[var(--warning)]",children:"Newer than current"}):null,a.sameAsCurrent?e.jsx(u,{className:"bg-[var(--ui-success-soft)] text-[var(--success)]",children:"Current copy"}):null]}),e.jsx("div",{className:"mt-2 break-all text-sm text-[var(--ui-ink-soft)]",children:a.databasePath})]}),a.sameAsCurrent?null:e.jsx(x,{variant:"secondary",onClick:()=>{F({mode:"adopt_existing",targetDataRoot:a.dataRoot,createSafetyBackup:!0}),j(null),N(!0)},children:"Use this folder"})]}),e.jsxs("div",{className:"mt-4 grid gap-2 text-xs text-[var(--ui-ink-faint)] md:grid-cols-5",children:[e.jsx("div",{children:a.integrityMessage}),e.jsx("div",{children:w(a.databaseLastModifiedAt??new Date().toISOString())}),e.jsx("div",{children:A(a.databaseSizeBytes)}),e.jsxs("div",{children:[a.counts.notes," notes"]}),e.jsxs("div",{children:[a.counts.tasks," tasks"]})]})]},a.id))}),ce?e.jsxs("div",{className:"flex items-start gap-3 rounded-[20px] border border-[color-mix(in_srgb,var(--warning)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-warning-soft)] px-4 py-3 text-sm text-[var(--warning)]",children:[e.jsx(pe,{className:"mt-0.5 size-4 shrink-0"}),e.jsx("div",{children:"Forge found a copy on disk that looks newer than the one you are using now. Review it carefully before switching."})]}):null]})]})]}),e.jsx(ee,{open:ne,onOpenChange:a=>{N(a),a||j(null)},eyebrow:"Data folder",title:d.mode==="migrate_current"?"Move Forge data":"Use an existing Forge data folder",description:"This guided flow keeps the folder change explicit and gives you a safety backup option first.",value:d,onChange:F,draftPersistenceKey:`settings.data.root.${d.mode}`,steps:de,pending:_.isPending,pendingLabel:d.mode==="migrate_current"?"Moving data":"Switching folder",submitLabel:d.mode==="migrate_current"?"Move and switch":"Use this folder",error:ie??(_.error instanceof Error?_.error.message:null),onSubmit:async()=>{if(!d.targetDataRoot.trim()){j("Choose a data folder first.");return}j(null),await _.mutateAsync(d)}}),e.jsx(ee,{open:n!==null,onOpenChange:a=>{a||(P(null),R(null))},eyebrow:"Restore backup",title:"Restore Forge backup",description:"This flow replaces the live data with an older saved state.",value:K,onChange:H,draftPersistenceKey:n?`settings.data.restore.${n.id}`:"settings.data.restore",steps:ue,pending:M.isPending,pendingLabel:"Restoring",submitLabel:"Restore this backup",error:oe??(M.error instanceof Error?M.error.message:null),onSubmit:async()=>{if(!n){R("Choose a backup first.");return}R(null),await M.mutateAsync({backupId:n.id,createSafetyBackup:K.createSafetyBackup})}})]})}export{Ie as SettingsDataPage};
1
+ import{r as o,j as e,da as Y,db as V,cl as me,dc as Z,aQ as J,dd as xe,aD as ge,ca as pe}from"./vendor-BwL6m4SE.js";import{j as he,i as X,k}from"./state-Bpe5dF3T.js";import{a as ve,F as be,Q as ee}from"./question-flow-dialog-D-_EvoAt.js";import{I as ae,k as u,S as fe,e as te,B as x,C as y,c as $,cY as je,cZ as ke,f as ye,c_ as we,c$ as Ne,d0 as Fe,d1 as Se,cU as Re,d2 as De}from"./index-izRKx6JK.js";import{S as Ce}from"./settings-section-nav-CMeU19Rx.js";import{P as Be}from"./page-hero-BLhM8FF3.js";import{M as g}from"./metric-tile-Bkx2btO2.js";import"./ui-B9TWEtCx.js";import"./motion-DcgUnXhY.js";import"./board-CuxQRKPJ.js";import"./forms-D1qJ3oOP.js";function A(t){if(!Number.isFinite(t)||t<=0)return"0 B";const l=["B","KB","MB","GB","TB"];let i=t,m=0;for(;i>=1024&&m<l.length-1;)i/=1024,m+=1;return`${i.toFixed(i>=100?0:i>=10?1:2)} ${l[m]}`}function _e(t,l){const i=URL.createObjectURL(t),m=document.createElement("a");m.href=i,m.download=l,m.click(),URL.revokeObjectURL(i)}function Me(t){return t?t===1?"Every hour":t===24?"Every day":t===168?"Every week":`Every ${t} hours`:"Off"}function se(t){switch(t){case"manual":return"Manual";case"automatic":return"Automatic";case"pre_restore":return"Safety backup before restore";case"pre_switch_root":return"Safety backup before folder change";default:return t}}function w(t,l="Unknown time"){if(!t)return l;const i=new Date(t);return Number.isNaN(i.getTime())?l:ye(t)}function Ae({tone:t,message:l}){return e.jsx("div",{className:$("rounded-[20px] border px-4 py-3 text-sm leading-6",t==="success"?"border-[color-mix(in_srgb,var(--success)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-success-soft)] text-[var(--success)]":t==="warning"?"border-[color-mix(in_srgb,var(--warning)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-warning-soft)] text-[var(--warning)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] text-[var(--ui-ink-soft)]"),children:l})}function z({label:t,value:l,icon:i}){return e.jsxs("div",{className:"min-w-0 overflow-hidden rounded-[24px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4",children:[e.jsxs("div",{className:"flex min-w-0 items-center gap-2 text-[11px] uppercase tracking-[0.16em] text-[var(--ui-ink-faint)]",children:[e.jsx(i,{className:"size-4"}),e.jsx("span",{className:"min-w-0 break-words",children:t})]}),e.jsx("div",{className:"mt-3 min-w-0 break-all text-sm leading-6 text-[var(--ui-ink-soft)] [overflow-wrap:anywhere]",children:l})]})}function Ie(){var G,W;const t=he(),[l,i]=o.useState(""),[m,T]=o.useState(""),[E,q]=o.useState(""),[U,O]=o.useState(!0),[b,re]=o.useState([]),[L,f]=o.useState(null),[ne,N]=o.useState(!1),[d,F]=o.useState({mode:"migrate_current",targetDataRoot:"",createSafetyBackup:!0}),[ie,j]=o.useState(null),[n,P]=o.useState(null),[K,H]=o.useState({createSafetyBackup:!0}),[oe,R]=o.useState(null),h=X({queryKey:["forge-operator-session"],queryFn:Re}),le=h.isSuccess,S=X({queryKey:["forge-data-management"],queryFn:De,enabled:le}),D=async()=>{await Promise.all([t.invalidateQueries({queryKey:["forge-operator-session"]}),t.invalidateQueries({queryKey:["forge-data-management"]})])},I=k({mutationFn:()=>we({backupDirectory:l,backupFrequencyHours:m==="off"?null:Number(m||"24"),backupRetentionDays:E==="forever"?null:Number(E||"30"),autoRepairEnabled:U}),onSuccess:async()=>{f({tone:"success",message:"Backup settings saved."}),await D()}}),C=k({mutationFn:()=>ke("Manual backup from Settings → Data"),onSuccess:async()=>{f({tone:"success",message:"Backup created."}),await D()}}),B=k({mutationFn:je,onSuccess:({candidates:a})=>{re(a),f({tone:a.some(c=>c.newerThanCurrent)?"warning":"neutral",message:a.length>0?`Found ${a.length} Forge ${a.length===1?"copy":"copies"} on disk.`:"No other Forge data copies were found in the scanned folders."})}}),_=k({mutationFn:a=>Fe({targetDataRoot:a.targetDataRoot,mode:a.mode,createSafetyBackup:a.createSafetyBackup}),onSuccess:async()=>{f({tone:"success",message:"Forge is now using the selected data folder."}),N(!1),await D()}}),M=k({mutationFn:({backupId:a,createSafetyBackup:c})=>Se(a,c),onSuccess:async()=>{f({tone:"success",message:"Backup restored. Forge is now running from that restored state."}),P(null),await D()}}),Q=k({mutationFn:async a=>{const c=await Ne(a);return _e(c.blob,c.fileName??`forge-export.${a}`),a},onSuccess:a=>{f({tone:"neutral",message:`Started download for ${a}.`})}}),s=(G=S.data)==null?void 0:G.data;o.useEffect(()=>{s&&(i(a=>a||s.settings.backupDirectory),T(a=>a||(s.settings.backupFrequencyHours?String(s.settings.backupFrequencyHours):"off")),O(s.settings.autoRepairEnabled),q(a=>a||(s.settings.backupRetentionDays?String(s.settings.backupRetentionDays):"forever")),F(a=>({...a,targetDataRoot:a.targetDataRoot||s.current.dataRoot})))},[s]);const ce=o.useMemo(()=>b.find(a=>a.newerThanCurrent),[b]),p=o.useMemo(()=>b.find(a=>a.dataRoot===d.targetDataRoot.trim()),[d.targetDataRoot,b]),de=[{id:"mode",eyebrow:"Step 1",title:"What do you want Forge to do?",description:"Choose whether Forge should move the current data into a new folder or switch to a folder that already contains the right Forge data.",render:(a,c)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(ve,{value:a.mode,onChange:v=>c({mode:v}),options:[{value:"migrate_current",label:"Move the current data",description:"Copy the live database and local secrets key into a new folder, then switch Forge to it."},{value:"adopt_existing",label:"Use an existing data folder",description:"Keep the target folder as it is and point Forge at that existing database directly."}]}),e.jsxs("label",{className:"flex items-start gap-3 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-4 py-3",children:[e.jsx("input",{type:"checkbox",className:"mt-1",checked:a.createSafetyBackup,onChange:v=>c({createSafetyBackup:v.target.checked})}),e.jsx("span",{className:"text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Create one safety backup first."})]})]})},{id:"folder",eyebrow:"Step 2",title:d.mode==="migrate_current"?"Choose the new data folder":"Choose the data folder to use",description:d.mode==="migrate_current"?"Pick an empty folder for the moved Forge data.":"Pick the folder that already contains the Forge data you trust.",render:(a,c)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(be,{label:"Data folder",description:"Forge will place or read the database and backups from here.",children:e.jsx(ae,{value:a.targetDataRoot,onChange:v=>c({targetDataRoot:v.target.value}),placeholder:"/absolute/path/to/forge-data"})}),p?e.jsxs("div",{className:"rounded-[22px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4 text-sm leading-6 text-[var(--ui-ink-soft)]",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:"Found on this machine"}),e.jsx("div",{className:"mt-2 break-all",children:p.databasePath}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx(u,{tone:"meta",children:p.sourceHint}),e.jsxs(u,{tone:"meta",children:[p.counts.notes," notes"]}),e.jsxs(u,{tone:"meta",children:[p.counts.tasks," tasks"]}),p.newerThanCurrent?e.jsx(u,{className:"bg-[var(--ui-warning-soft)] text-[var(--warning)]",children:"Newer than the current copy"}):null]})]}):e.jsx("div",{className:"rounded-[22px] border border-dashed border-[var(--ui-border-subtle)] px-4 py-4 text-sm leading-6 text-[var(--ui-ink-soft)]",children:d.mode==="migrate_current"?"Forge will copy the current data into this folder and then switch over.":"If this folder already holds a Forge database, Forge will start using it after you confirm."})]})}],ue=[{id:"review",eyebrow:"Step 1",title:"Review the backup you want to restore",description:"Restoring replaces the current database with the selected backup.",render:(a,c)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"rounded-[22px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4 text-sm leading-6 text-[var(--ui-ink-soft)]",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:n?w(n.createdAt):"Selected backup"}),e.jsx("div",{className:"mt-2",children:(n==null?void 0:n.note)||"Forge backup archive"}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx(u,{tone:"meta",children:n?se(n.mode):"Backup"}),e.jsx(u,{tone:"meta",children:n?A(n.sizeBytes):"0 B"}),n!=null&&n.includesWiki?e.jsx(u,{tone:"meta",children:"Includes wiki"}):null]})]}),e.jsxs("label",{className:"flex items-start gap-3 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-4 py-3",children:[e.jsx("input",{type:"checkbox",className:"mt-1",checked:a.createSafetyBackup,onChange:v=>c({createSafetyBackup:v.target.checked})}),e.jsx("span",{className:"text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Create one safety backup of the current state first."})]})]})},{id:"confirm",eyebrow:"Step 2",title:"Confirm the restore",description:"Use this only when you are confident this backup is the state you want back.",render:()=>e.jsx("div",{className:"rounded-[22px] border border-[color-mix(in_srgb,var(--warning)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-warning-soft)] p-4 text-sm leading-6 text-[var(--warning)]",children:"Forge will replace the live database with this backup, then reopen the restored copy."})}];if(h.isLoading||S.isLoading)return e.jsx(fe,{eyebrow:"Data",title:"Loading data controls",description:"Checking the live data folder, backup plan, and recovery tools.",columns:3,blocks:6});if(h.isError)return e.jsx(te,{eyebrow:"Data",error:h.error,onRetry:()=>void h.refetch()});if(S.isError||!s)return e.jsx(te,{eyebrow:"Data",error:S.error??new Error("Forge returned an empty data payload."),onRetry:()=>void S.refetch()});const r=s.current;return e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"mx-auto grid w-full max-w-[1480px] gap-5",children:[e.jsx(Be,{eyebrow:"Data, backups, recovery",title:"Data",description:"See where Forge is saving the live data, keep it protected with backups, look for a newer copy on disk if something goes wrong, and download the database or its structure when you need it.",badge:`${r.integrityOk?"Healthy":"Needs attention"} · ${A(r.databaseSizeBytes)}`,actions:e.jsxs(e.Fragment,{children:[e.jsxs(x,{variant:"secondary",pending:B.isPending,pendingLabel:"Scanning",onClick:()=>void B.mutateAsync(),children:[e.jsx(Y,{className:"size-4"}),"Look for other Forge copies"]}),e.jsxs(x,{pending:C.isPending,pendingLabel:"Creating backup",onClick:()=>void C.mutateAsync(),children:[e.jsx(V,{className:"size-4"}),"Create backup now"]})]})}),e.jsx(Ce,{}),(W=h.data)!=null&&W.session?e.jsxs("div",{className:"rounded-[20px] border border-[color-mix(in_srgb,var(--success)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-success-soft)] px-4 py-3 text-sm text-[var(--ui-ink-medium)]",children:["You are managing Forge data as"," ",e.jsx("span",{className:"font-medium text-[var(--ui-ink-strong)]",children:h.data.session.actorLabel}),"."]}):null,L?e.jsx(Ae,{tone:L.tone,message:L.message}):null,e.jsxs("div",{className:"grid gap-5 xl:grid-cols-[minmax(0,1.15fr)_minmax(0,0.85fr)]",children:[e.jsxs(y,{className:"grid gap-5",children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Live data folder"}),e.jsx("div",{className:"mt-2 min-w-0 break-all text-xl font-semibold text-[var(--ui-ink-strong)] [overflow-wrap:anywhere]",children:r.dataRoot}),e.jsx("div",{className:"mt-2 max-w-3xl text-sm leading-6 text-[var(--ui-ink-soft)]",children:"This is the folder Forge is reading and writing right now."})]}),e.jsx(u,{className:$(r.integrityOk?"bg-[var(--ui-success-soft)] text-[var(--success)]":"bg-[var(--ui-warning-soft)] text-[var(--warning)]"),children:r.integrityMessage})]}),e.jsxs("div",{className:"grid min-w-0 gap-3 md:grid-cols-2 xl:grid-cols-3",children:[e.jsx(z,{label:"Database file",value:r.databasePath,icon:me}),e.jsx(z,{label:"Folder layout",value:r.layout,icon:Z}),e.jsx(z,{label:"Last database change",value:r.databaseLastModifiedAt?w(r.databaseLastModifiedAt):"Unknown",icon:J})]}),e.jsxs("div",{className:"grid min-w-0 gap-3 md:grid-cols-3 xl:grid-cols-6",children:[e.jsx(g,{label:"Notes",value:r.counts.notes}),e.jsx(g,{label:"Goals",value:r.counts.goals}),e.jsx(g,{label:"Projects",value:r.counts.projects}),e.jsx(g,{label:"Tasks",value:r.counts.tasks}),e.jsx(g,{label:"Runs",value:r.counts.taskRuns}),e.jsx(g,{label:"Tags",value:r.counts.tags})]})]}),e.jsxs(y,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("div",{className:"flex size-11 items-center justify-center rounded-2xl border border-[color-mix(in_srgb,var(--success)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-success-soft)]",children:e.jsx(xe,{className:"size-5 text-[var(--success)]"})}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:"Protection plan"}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Choose where backups go, how often Forge creates them, and whether scans should call out newer copies found elsewhere on disk."})]})]}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-3",children:[e.jsx(g,{label:"Automatic backup",value:Me(s.settings.backupFrequencyHours),detail:s.settings.lastAutoBackupAt?`Last run ${w(s.settings.lastAutoBackupAt)}`:"No automatic backup recorded yet"}),e.jsx(g,{label:"Manual backup",value:s.settings.lastManualBackupAt?w(s.settings.lastManualBackupAt):"None yet",detail:`${s.backups.length} backup${s.backups.length===1?"":"s"} saved`}),e.jsx(g,{label:"Retention",value:s.settings.backupRetentionDays?`${s.settings.backupRetentionDays} days`:"Keep forever",detail:"Automatic backups only"})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Backup folder"}),e.jsx(ae,{value:l,onChange:a=>i(a.target.value)})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Automatic backup"}),e.jsxs("select",{className:"h-11 rounded-[16px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-3 text-sm text-[var(--ui-ink-strong)] outline-none transition focus:border-[var(--primary)]",value:m||"24",onChange:a=>T(a.target.value),children:[e.jsx("option",{value:"off",children:"Off"}),e.jsx("option",{value:"1",children:"Every hour"}),e.jsx("option",{value:"6",children:"Every 6 hours"}),e.jsx("option",{value:"24",children:"Every day"}),e.jsx("option",{value:"168",children:"Every week"})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Keep automatic backups"}),e.jsxs("select",{className:"h-11 rounded-[16px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-3 text-sm text-[var(--ui-ink-strong)] outline-none transition focus:border-[var(--primary)]",value:E||"30",onChange:a=>q(a.target.value),children:[e.jsx("option",{value:"7",children:"7 days"}),e.jsx("option",{value:"14",children:"14 days"}),e.jsx("option",{value:"30",children:"30 days"}),e.jsx("option",{value:"90",children:"90 days"}),e.jsx("option",{value:"365",children:"1 year"}),e.jsx("option",{value:"forever",children:"Keep forever"})]})]}),e.jsxs("label",{className:"flex items-start gap-3 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-4 py-3",children:[e.jsx("input",{type:"checkbox",className:"mt-1",checked:U,onChange:a=>O(a.target.checked)}),e.jsx("span",{className:"text-sm leading-6 text-[var(--ui-ink-soft)]",children:"When I scan, point out Forge copies that look newer than the one I am using now."})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(x,{pending:I.isPending,pendingLabel:"Saving",onClick:()=>void I.mutateAsync(),children:"Save backup settings"}),e.jsx(x,{variant:"secondary",pending:C.isPending,pendingLabel:"Creating backup",onClick:()=>void C.mutateAsync(),children:"Create backup now"})]})]})]})]}),e.jsxs("div",{className:"grid gap-5 xl:grid-cols-[minmax(0,0.9fr)_minmax(0,1.1fr)]",children:[e.jsxs(y,{className:"grid gap-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Change data folder"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Move today’s Forge data into a new folder, or switch to another folder that already contains the right Forge database."})]}),e.jsxs("div",{className:"rounded-[22px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4 text-sm leading-6 text-[var(--ui-ink-soft)]",children:[e.jsx("div",{className:"font-medium text-[var(--ui-ink-strong)]",children:"Current folder"}),e.jsx("div",{className:"mt-2 break-all",children:r.dataRoot}),p?e.jsxs("div",{className:"mt-3 text-sm text-[var(--ui-ink-soft)]",children:["Selected scanned copy: ",p.dataRoot]}):null]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsxs(x,{onClick:()=>{F(a=>({...a,mode:"migrate_current",targetDataRoot:a.targetDataRoot||r.dataRoot})),j(null),N(!0)},children:[e.jsx(Z,{className:"size-4"}),"Move current data"]}),e.jsxs(x,{variant:"secondary",onClick:()=>{F(a=>({...a,mode:"adopt_existing",targetDataRoot:a.targetDataRoot||r.dataRoot})),j(null),N(!0)},children:[e.jsx(J,{className:"size-4"}),"Use existing data folder"]})]})]}),e.jsxs(y,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Downloads"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Download the live database itself, or export a structure and table snapshot in other formats."})]}),e.jsx(ge,{className:"size-5 text-[var(--ui-ink-faint)]"})]}),e.jsx("div",{className:"grid gap-3",children:s.exportOptions.map(a=>e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:a.label}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-[var(--ui-ink-soft)]",children:a.description})]}),e.jsx(x,{variant:"secondary",pending:Q.isPending,pendingLabel:"Preparing",onClick:()=>void Q.mutateAsync(a.format),children:"Download"})]},a.format))})]})]}),e.jsxs("div",{className:"grid gap-5 xl:grid-cols-[minmax(0,1.05fr)_minmax(0,0.95fr)]",children:[e.jsxs(y,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Backup history"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Go back to an older saved state if you need to undo a bad change."})]}),e.jsx(V,{className:"size-5 text-[var(--ui-ink-faint)]"})]}),e.jsx("div",{className:"grid gap-3",children:s.backups.length===0?e.jsx("div",{className:"rounded-[20px] border border-dashed border-[var(--ui-border-subtle)] px-4 py-6 text-sm text-[var(--ui-ink-soft)]",children:"No backups yet. Create one now so you have a safe restore point."}):s.backups.map(a=>e.jsxs("div",{className:"rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:w(a.createdAt)}),e.jsx(u,{tone:"meta",children:se(a.mode)})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:a.note||"Forge backup archive"})]}),e.jsx(x,{variant:"secondary",onClick:()=>{H({createSafetyBackup:!0}),R(null),P(a)},children:"Restore"})]}),e.jsxs("div",{className:"mt-3 grid gap-2 text-xs text-[var(--ui-ink-faint)] md:grid-cols-2",children:[e.jsx("div",{className:"break-all",children:a.archivePath}),e.jsx("div",{children:A(a.sizeBytes)})]})]},a.id))})]}),e.jsxs(y,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Find other Forge copies"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-[var(--ui-ink-soft)]",children:"Search common folders on this machine for other Forge databases. Use this when Forge opened the wrong copy or when you think a newer copy exists somewhere else."})]}),e.jsxs(x,{variant:"secondary",pending:B.isPending,pendingLabel:"Scanning",onClick:()=>void B.mutateAsync(),children:[e.jsx(Y,{className:"size-4"}),"Scan now"]})]}),e.jsx("div",{className:"grid gap-3",children:b.length===0?e.jsx("div",{className:"rounded-[20px] border border-dashed border-[var(--ui-border-subtle)] px-4 py-6 text-sm text-[var(--ui-ink-soft)]",children:"No scan results yet. Run a scan to compare the live data folder with other Forge copies on disk."}):b.map(a=>e.jsxs("div",{className:$("rounded-[22px] border p-4",a.sameAsCurrent?"border-[color-mix(in_srgb,var(--success)_24%,var(--ui-border-subtle)_76%)] bg-[var(--ui-success-soft)]":a.newerThanCurrent?"border-[color-mix(in_srgb,var(--warning)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-warning-soft)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)]"),children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:a.dataRoot}),e.jsx(u,{tone:"meta",children:a.sourceHint}),a.newerThanCurrent?e.jsx(u,{className:"bg-[var(--ui-warning-soft)] text-[var(--warning)]",children:"Newer than current"}):null,a.sameAsCurrent?e.jsx(u,{className:"bg-[var(--ui-success-soft)] text-[var(--success)]",children:"Current copy"}):null]}),e.jsx("div",{className:"mt-2 break-all text-sm text-[var(--ui-ink-soft)]",children:a.databasePath})]}),a.sameAsCurrent?null:e.jsx(x,{variant:"secondary",onClick:()=>{F({mode:"adopt_existing",targetDataRoot:a.dataRoot,createSafetyBackup:!0}),j(null),N(!0)},children:"Use this folder"})]}),e.jsxs("div",{className:"mt-4 grid gap-2 text-xs text-[var(--ui-ink-faint)] md:grid-cols-5",children:[e.jsx("div",{children:a.integrityMessage}),e.jsx("div",{children:w(a.databaseLastModifiedAt??new Date().toISOString())}),e.jsx("div",{children:A(a.databaseSizeBytes)}),e.jsxs("div",{children:[a.counts.notes," notes"]}),e.jsxs("div",{children:[a.counts.tasks," tasks"]})]})]},a.id))}),ce?e.jsxs("div",{className:"flex items-start gap-3 rounded-[20px] border border-[color-mix(in_srgb,var(--warning)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-warning-soft)] px-4 py-3 text-sm text-[var(--warning)]",children:[e.jsx(pe,{className:"mt-0.5 size-4 shrink-0"}),e.jsx("div",{children:"Forge found a copy on disk that looks newer than the one you are using now. Review it carefully before switching."})]}):null]})]})]}),e.jsx(ee,{open:ne,onOpenChange:a=>{N(a),a||j(null)},eyebrow:"Data folder",title:d.mode==="migrate_current"?"Move Forge data":"Use an existing Forge data folder",description:"This guided flow keeps the folder change explicit and gives you a safety backup option first.",value:d,onChange:F,draftPersistenceKey:`settings.data.root.${d.mode}`,steps:de,pending:_.isPending,pendingLabel:d.mode==="migrate_current"?"Moving data":"Switching folder",submitLabel:d.mode==="migrate_current"?"Move and switch":"Use this folder",error:ie??(_.error instanceof Error?_.error.message:null),onSubmit:async()=>{if(!d.targetDataRoot.trim()){j("Choose a data folder first.");return}j(null),await _.mutateAsync(d)}}),e.jsx(ee,{open:n!==null,onOpenChange:a=>{a||(P(null),R(null))},eyebrow:"Restore backup",title:"Restore Forge backup",description:"This flow replaces the live data with an older saved state.",value:K,onChange:H,draftPersistenceKey:n?`settings.data.restore.${n.id}`:"settings.data.restore",steps:ue,pending:M.isPending,pendingLabel:"Restoring",submitLabel:"Restore this backup",error:oe??(M.error instanceof Error?M.error.message:null),onSubmit:async()=>{if(!n){R("Choose a backup first.");return}R(null),await M.mutateAsync({backupId:n.id,createSafetyBackup:K.createSafetyBackup})}})]})}export{Ie as SettingsDataPage};