specrails-desktop 2.57.0 → 2.58.0

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 (336) hide show
  1. package/README.md +1 -1
  2. package/cli/dist/args.js +10 -4
  3. package/cli/dist/help.js +1 -1
  4. package/client/dist/assets/{ActivityFeedPage-DdMNmVBk.js → ActivityFeedPage-BQGppIR0.js} +1 -1
  5. package/client/dist/assets/{AgentBrowserCapture-CeerUf--.js → AgentBrowserCapture-PI-cxyxi.js} +1 -1
  6. package/client/dist/assets/{AgentModeAnalyticsPane-BjGb-8rh.js → AgentModeAnalyticsPane-mQsOqdXx.js} +2 -2
  7. package/client/dist/assets/{AgentModeCodePane-8XRkQEo_.js → AgentModeCodePane-BL-vpmlY.js} +2 -2
  8. package/client/dist/assets/{AgentModeJobsPane-BN3dgJOA.js → AgentModeJobsPane-DR_06oqH.js} +1 -1
  9. package/client/dist/assets/AgentsPage-BKIKjm_1.js +118 -0
  10. package/client/dist/assets/{AnalyticsPage-CyfhYiBn.js → AnalyticsPage-069npRVo.js} +1 -1
  11. package/client/dist/assets/{CodePage-C2Nf-Q5W.js → CodePage-Alitorrv.js} +2 -2
  12. package/client/dist/assets/DesktopAnalyticsPage-qtWAPM47.js +1 -0
  13. package/client/dist/assets/{DocsDialog-Br3bczCp.js → DocsDialog-DwL6rgcT.js} +1 -1
  14. package/client/dist/assets/{DocsPage-BcDr2cBm.js → DocsPage-BA1hiJZ-.js} +1 -1
  15. package/client/dist/assets/{ExportDropdown-BVGKEgkd.js → ExportDropdown-BcMpvV89.js} +1 -1
  16. package/client/dist/assets/InteractiveJobComposer-B3H1YHr6.js +19 -0
  17. package/client/dist/assets/JobDetailModal-XZQ9eAAy.js +1 -0
  18. package/client/dist/assets/{JobDetailPage-vBbNeRuz.js → JobDetailPage-B-SIaq_q.js} +1 -1
  19. package/client/dist/assets/{JobsPage-CJCtPhIz.js → JobsPage-iQXAv2mx.js} +1 -1
  20. package/client/dist/assets/LoopBuilderPage-B_gbFAHn.js +1 -0
  21. package/client/dist/assets/LoopPreviewModal-je5pSCf-.js +1 -0
  22. package/client/dist/assets/LoopsPage-BZwcY5cu.js +2 -0
  23. package/client/dist/assets/{MinimizedChatsContext-D3QzgV0B.js → MinimizedChatsContext-CNx_0bZu.js} +1 -1
  24. package/client/dist/assets/{PluginsPage-DOpTV75p.js → PluginsPage-DFocnoHX.js} +2 -2
  25. package/client/dist/assets/{ProjectSettingsDialog-Dkwrn0z1.js → ProjectSettingsDialog-Bh3S6EBB.js} +1 -1
  26. package/client/dist/assets/{RepositoryDeliveries-Du2UCf1a.js → RepositoryDeliveries-BiwJuS8r.js} +1 -1
  27. package/client/dist/assets/{RepositoryScopeSelector-hPGZNRBm.js → RepositoryScopeSelector-C2mvWBQ6.js} +1 -1
  28. package/client/dist/assets/{ReviewPacketPage-DcOq-UTA.js → ReviewPacketPage-CrAf-WDy.js} +2 -2
  29. package/client/dist/assets/TemplatePreviewModal-C7DordpN.js +1 -0
  30. package/client/dist/assets/{TicketDetailModalContext-DAK-NoK6.js → TicketDetailModalContext-B-DySpKL.js} +1 -1
  31. package/client/dist/assets/{Trans-DEbgkuAY.js → Trans-D3AfDylf.js} +1 -1
  32. package/client/dist/assets/agentRuntime-BeUb3g9g.js +1 -0
  33. package/client/dist/assets/agentRuntime-Bg9tbmqm.js +1 -0
  34. package/client/dist/assets/agentRuntime-D-GJVGkj.js +1 -0
  35. package/client/dist/assets/agentRuntime-D2__CVI_.js +1 -0
  36. package/client/dist/assets/agentRuntime-D35dGVOP.js +1 -0
  37. package/client/dist/assets/agentRuntime-DGz_IqKW.js +1 -0
  38. package/client/dist/assets/agentRuntime-O1liDt6G.js +1 -0
  39. package/client/dist/assets/agentRuntime-hInH9Fzj.js +1 -0
  40. package/client/dist/assets/agentstudio-B2CTtQgZ.js +1 -0
  41. package/client/dist/assets/agentstudio-BWAKeGgB.js +1 -0
  42. package/client/dist/assets/{agentstudio-DR7doNBV.js → agentstudio-Cja8Sjcp.js} +1 -1
  43. package/client/dist/assets/agentstudio-DtfPcr99.js +1 -0
  44. package/client/dist/assets/agentstudio-QdAJIDef.js +1 -0
  45. package/client/dist/assets/agentstudio-X70BKf6u.js +1 -0
  46. package/client/dist/assets/agentstudio-fLXpRGIi.js +1 -0
  47. package/client/dist/assets/agentstudio-qXKqVnWS.js +1 -0
  48. package/client/dist/assets/{analytics-jzCkOec3.js → analytics-B1DIQd4m.js} +1 -1
  49. package/client/dist/assets/{analytics-CoEzWPx4.js → analytics-BAIZ9vE_.js} +1 -1
  50. package/client/dist/assets/{analytics-DjLlE7jS.js → analytics-BTqgmgBd.js} +1 -1
  51. package/client/dist/assets/analytics-BWynXPEm.js +1 -0
  52. package/client/dist/assets/{analytics-nZIjjtCc.js → analytics-DGcUsQ44.js} +1 -1
  53. package/client/dist/assets/{analytics-BNgZ1Nj7.js → analytics-GnSnpJ4W.js} +1 -1
  54. package/client/dist/assets/{analytics-DFh5lSOl.js → analytics-TWgYaoO0.js} +1 -1
  55. package/client/dist/assets/{analytics-DZp-DS2U.js → analytics-kJy6Tuko.js} +1 -1
  56. package/client/dist/assets/builder-C0FyvM83.js +1 -0
  57. package/client/dist/assets/builder-C1neIYGR.js +1 -0
  58. package/client/dist/assets/builder-CvnFm0im.js +1 -0
  59. package/client/dist/assets/builder-CzW5ovyI.js +1 -0
  60. package/client/dist/assets/builder-D06L7iPy.js +1 -0
  61. package/client/dist/assets/builder-DGETbtZj.js +1 -0
  62. package/client/dist/assets/builder-DXEJUlC0.js +1 -0
  63. package/client/dist/assets/builder-DyQperXU.js +1 -0
  64. package/client/dist/assets/common-BCK7c9Pv.js +1 -0
  65. package/client/dist/assets/common-C0BOdeNi.js +1 -0
  66. package/client/dist/assets/common-C4Yvvhp6.js +1 -0
  67. package/client/dist/assets/{common-BrlwEnL7.js → common-DmsclwjP.js} +1 -1
  68. package/client/dist/assets/common-DpLWwgI1.js +1 -0
  69. package/client/dist/assets/common-OCvl3c8t.js +1 -0
  70. package/client/dist/assets/common-c0aujEZC.js +1 -0
  71. package/client/dist/assets/common-od8WThlf.js +1 -0
  72. package/client/dist/assets/dashboard-B1ndRHuC.js +1 -0
  73. package/client/dist/assets/dashboard-BX7KXiqA.js +1 -0
  74. package/client/dist/assets/dashboard-B_BSNxcN.js +1 -0
  75. package/client/dist/assets/dashboard-CCeFN7-V.js +1 -0
  76. package/client/dist/assets/dashboard-CRl0WtFJ.js +1 -0
  77. package/client/dist/assets/dashboard-XGdQ5mjw.js +1 -0
  78. package/client/dist/assets/dashboard-_oltA6Jd.js +1 -0
  79. package/client/dist/assets/dashboard-bAuf5KVk.js +1 -0
  80. package/client/dist/assets/{formatDistanceToNow-Cc2u5FwQ.js → formatDistanceToNow-aBss1Nai.js} +1 -1
  81. package/client/dist/assets/{getTimezoneOffsetInMilliseconds-BHm2U-w1.js → getTimezoneOffsetInMilliseconds-DOGj1Mfz.js} +1 -1
  82. package/client/dist/assets/index-BS7KCWkV.css +2 -0
  83. package/client/dist/assets/{index-Cxb288Rj.js → index-C4Mv6tV6.js} +32 -32
  84. package/client/dist/assets/{jira-api-DrGxiD9p.js → jira-api-BYbEPlkr.js} +1 -1
  85. package/client/dist/assets/{jobs-DSp9DoD_.js → jobs-6_-r75yC.js} +1 -1
  86. package/client/dist/assets/{jobs-C6qmvUAi.js → jobs-B1yqyId5.js} +1 -1
  87. package/client/dist/assets/{jobs-DoFaEl9g.js → jobs-BFuV7ttH.js} +1 -1
  88. package/client/dist/assets/{jobs-DTQO08nJ.js → jobs-BKa8LuwA.js} +1 -1
  89. package/client/dist/assets/{jobs-DrF8Do8s.js → jobs-BKiK-ZWh.js} +1 -1
  90. package/client/dist/assets/{jobs-DLHdDkHc.js → jobs-DmKV7b7d.js} +1 -1
  91. package/client/dist/assets/{jobs-C9j2PuwW.js → jobs-KG4Sn12X.js} +1 -1
  92. package/client/dist/assets/{jobs-Dpw6AEOP.js → jobs-pPv4KWjb.js} +1 -1
  93. package/client/dist/assets/loop-layout-BF8xMiNv.js +7 -0
  94. package/client/dist/assets/loops-B4_D-nbg.js +1 -0
  95. package/client/dist/assets/loops-BJDY9FTh.js +1 -0
  96. package/client/dist/assets/loops-BO3V8244.js +1 -0
  97. package/client/dist/assets/loops-C-hZK8pf.js +1 -0
  98. package/client/dist/assets/loops-CDOWZ0ci.js +1 -0
  99. package/client/dist/assets/loops-Dv849ckF.js +1 -0
  100. package/client/dist/assets/loops-Q9LIgGkq.js +1 -0
  101. package/client/dist/assets/loops-eUnCfLjC.js +1 -0
  102. package/client/dist/assets/{project-repositories-9Wzs0coQ.js → project-repositories-CSnfzUpg.js} +1 -1
  103. package/client/dist/assets/settings-3o4Ntzi5.js +1 -0
  104. package/client/dist/assets/settings-B97jlkwD.js +1 -0
  105. package/client/dist/assets/settings-BTaT_bsS.js +1 -0
  106. package/client/dist/assets/settings-CT8w7WiC.js +1 -0
  107. package/client/dist/assets/settings-Cvr8_tvh.js +1 -0
  108. package/client/dist/assets/settings-Dn1qgAC8.js +1 -0
  109. package/client/dist/assets/settings-EShDdg4J.js +1 -0
  110. package/client/dist/assets/settings-tfLhQZRN.js +1 -0
  111. package/client/dist/assets/{setup-Dwzt5nO1.js → setup-CBMu3tqH.js} +1 -1
  112. package/client/dist/assets/{setup-B5FHuxvB.js → setup-CPh-e6J2.js} +1 -1
  113. package/client/dist/assets/{setup-DpqzaEEA.js → setup-CRKLp_ke.js} +1 -1
  114. package/client/dist/assets/{setup-CROyqD5N.js → setup-Cy302v4J.js} +1 -1
  115. package/client/dist/assets/{setup-C9Fy9PKQ.js → setup-D681vTPf.js} +1 -1
  116. package/client/dist/assets/{setup-BihzXadx.js → setup-DYK0VBkE.js} +1 -1
  117. package/client/dist/assets/{setup-BtC6Hg4K.js → setup-KAuiIiVs.js} +1 -1
  118. package/client/dist/assets/{setup-zLEDnG7N.js → setup-OGX-oCfI.js} +1 -1
  119. package/client/dist/assets/{spending-T5GM7wpn.js → spending-HBSk-6jv.js} +1 -1
  120. package/client/dist/assets/{useDesktop-QogiN0zR.js → useDesktop-0unHDBJJ.js} +1 -1
  121. package/client/dist/assets/useRuntimeRuns-BN1rhyEm.js +1 -0
  122. package/client/dist/assets/{useSharedWebSocket-Dz-HI6De.js → useSharedWebSocket-BZMrX4jr.js} +2 -2
  123. package/client/dist/index.html +25 -25
  124. package/docs/agent-live-steering.md +16 -0
  125. package/docs/cli.md +7 -7
  126. package/docs/codex.md +2 -2
  127. package/docs/customizing.md +1 -1
  128. package/docs/gemini.md +1 -1
  129. package/docs/getting-started.md +1 -1
  130. package/docs/guide/de/integrations/7-local-engines.md +1 -1
  131. package/docs/guide/de/pipeline/1-rails-and-jobs.md +8 -6
  132. package/docs/guide/de/pipeline/2-the-job-detail-view.md +11 -2
  133. package/docs/guide/de/pipeline/4-picking-an-engine-per-rail.md +2 -2
  134. package/docs/guide/de/pipeline/5-the-loop-builder.md +24 -5
  135. package/docs/guide/en/integrations/7-local-engines.md +1 -1
  136. package/docs/guide/en/pipeline/1-rails-and-jobs.md +8 -6
  137. package/docs/guide/en/pipeline/2-the-job-detail-view.md +11 -2
  138. package/docs/guide/en/pipeline/4-picking-an-engine-per-rail.md +2 -2
  139. package/docs/guide/en/pipeline/5-the-loop-builder.md +34 -5
  140. package/docs/guide/en/settings/3-pipeline-telemetry-and-diagnostics.md +1 -1
  141. package/docs/guide/es/integrations/7-local-engines.md +1 -1
  142. package/docs/guide/es/pipeline/1-rails-and-jobs.md +8 -6
  143. package/docs/guide/es/pipeline/2-the-job-detail-view.md +11 -2
  144. package/docs/guide/es/pipeline/4-picking-an-engine-per-rail.md +2 -2
  145. package/docs/guide/es/pipeline/5-the-loop-builder.md +30 -5
  146. package/docs/guide/es/settings/3-pipeline-telemetry-and-diagnostics.md +1 -2
  147. package/docs/guide/fr/integrations/7-local-engines.md +1 -1
  148. package/docs/guide/fr/pipeline/1-rails-and-jobs.md +8 -6
  149. package/docs/guide/fr/pipeline/2-the-job-detail-view.md +11 -2
  150. package/docs/guide/fr/pipeline/4-picking-an-engine-per-rail.md +2 -2
  151. package/docs/guide/fr/pipeline/5-the-loop-builder.md +24 -5
  152. package/docs/guide/it/integrations/7-local-engines.md +1 -1
  153. package/docs/guide/it/pipeline/1-rails-and-jobs.md +8 -6
  154. package/docs/guide/it/pipeline/2-the-job-detail-view.md +11 -2
  155. package/docs/guide/it/pipeline/4-picking-an-engine-per-rail.md +2 -2
  156. package/docs/guide/it/pipeline/5-the-loop-builder.md +24 -5
  157. package/docs/guide/ja/integrations/7-local-engines.md +1 -1
  158. package/docs/guide/ja/pipeline/1-rails-and-jobs.md +8 -6
  159. package/docs/guide/ja/pipeline/2-the-job-detail-view.md +11 -2
  160. package/docs/guide/ja/pipeline/4-picking-an-engine-per-rail.md +2 -2
  161. package/docs/guide/ja/pipeline/5-the-loop-builder.md +24 -5
  162. package/docs/guide/pt/integrations/7-local-engines.md +1 -1
  163. package/docs/guide/pt/pipeline/1-rails-and-jobs.md +8 -6
  164. package/docs/guide/pt/pipeline/2-the-job-detail-view.md +11 -2
  165. package/docs/guide/pt/pipeline/4-picking-an-engine-per-rail.md +2 -2
  166. package/docs/guide/pt/pipeline/5-the-loop-builder.md +24 -5
  167. package/docs/guide/zh/integrations/7-local-engines.md +1 -1
  168. package/docs/guide/zh/pipeline/1-rails-and-jobs.md +8 -6
  169. package/docs/guide/zh/pipeline/2-the-job-detail-view.md +11 -2
  170. package/docs/guide/zh/pipeline/4-picking-an-engine-per-rail.md +2 -2
  171. package/docs/guide/zh/pipeline/5-the-loop-builder.md +24 -5
  172. package/docs/internals/api-reference.md +2 -2
  173. package/docs/internals/ci-performance.md +71 -0
  174. package/docs/internals/companion-rails-as-loops-contract.md +4 -3
  175. package/docs/internals/configuration.md +3 -3
  176. package/docs/internals/core-runtime-updates.md +3 -2
  177. package/docs/internals/interactive-jobs.md +2 -2
  178. package/docs/internals/loop-step-log-explorer.md +42 -0
  179. package/docs/internals/mission-rail-cards.md +1 -1
  180. package/docs/internals/operations-runbook.md +22 -0
  181. package/docs/internals/programmatic-agent-runtime.md +130 -7
  182. package/docs/internals/project-builder.md +35 -16
  183. package/docs/internals/source-map.md +48 -2
  184. package/docs/kimi.md +2 -2
  185. package/docs/local-providers.md +1 -1
  186. package/docs/running-pipelines.md +26 -18
  187. package/docs/tracking-cost.md +10 -1
  188. package/package.json +2 -1
  189. package/server/dist/core-compat.js +8 -3
  190. package/server/dist/core-execution.js +49 -3
  191. package/server/dist/db/migrations.js +101 -0
  192. package/server/dist/desktop-db.js +28 -0
  193. package/server/dist/desktop-router.js +2 -0
  194. package/server/dist/mcp/guide.js +6 -3
  195. package/server/dist/mcp/tools/jobs.js +14 -1
  196. package/server/dist/mcp/tools/loops.js +17 -8
  197. package/server/dist/mcp/tools/rails.js +3 -3
  198. package/server/dist/modules/agent-runtime/runtime/agent-runtime-bridge.js +313 -9
  199. package/server/dist/modules/agent-runtime/runtime/agent-runtime-controls-router.js +34 -1
  200. package/server/dist/modules/agent-runtime/runtime/agent-runtime-controls.js +203 -21
  201. package/server/dist/modules/agent-runtime/runtime/agent-runtime-effective-config.js +46 -1
  202. package/server/dist/modules/agent-runtime/runtime/agent-runtime-engines.js +10 -0
  203. package/server/dist/modules/agent-runtime/runtime/agent-runtime-loader.js +68 -3
  204. package/server/dist/modules/agent-runtime/runtime/agent-runtime-metrics.js +16 -8
  205. package/server/dist/modules/agent-runtime/runtime/agent-runtime-package-gc.js +81 -0
  206. package/server/dist/modules/agent-runtime/runtime/agent-runtime-package-lock.js +37 -0
  207. package/server/dist/modules/agent-runtime/runtime/agent-runtime-package.js +30 -24
  208. package/server/dist/modules/agent-runtime/runtime/agent-runtime-retention-host.js +87 -0
  209. package/server/dist/modules/agent-runtime/runtime/agent-runtime-retention-quarantine.js +231 -0
  210. package/server/dist/modules/agent-runtime/runtime/agent-runtime-retention-records.js +32 -0
  211. package/server/dist/modules/agent-runtime/runtime/agent-runtime-retention.js +102 -0
  212. package/server/dist/modules/agent-runtime/runtime/agent-runtime-settings-router.js +12 -7
  213. package/server/dist/modules/agent-runtime/runtime/agent-runtime-settings.js +57 -13
  214. package/server/dist/modules/agents/runtime/agent-catalog.js +32 -0
  215. package/server/dist/modules/agents/runtime/agent-refine-manager.js +12 -0
  216. package/server/dist/modules/agents/runtime/agent-role-descriptor.js +64 -0
  217. package/server/dist/modules/agents/runtime/profiles-router.js +26 -34
  218. package/server/dist/modules/builder/runtime/milestone-chain.js +121 -73
  219. package/server/dist/modules/delivery/runtime/definition-fork.js +158 -0
  220. package/server/dist/modules/delivery/runtime/delivery-evidence.js +56 -10
  221. package/server/dist/modules/delivery/runtime/isolated-settlement-reconstruction.js +99 -0
  222. package/server/dist/modules/delivery/runtime/isolated-settlement-store.js +53 -0
  223. package/server/dist/modules/delivery/runtime/multi-repo-execution-store.js +3 -1
  224. package/server/dist/modules/delivery/runtime/rail-isolated-launch.js +388 -203
  225. package/server/dist/modules/delivery/runtime/rail-launch-parser.js +3 -2
  226. package/server/dist/modules/delivery/runtime/rail-pr-store.js +6 -1
  227. package/server/dist/modules/delivery/runtime/rails-router.js +66 -10
  228. package/server/dist/modules/execution/runtime/queue-manager.js +11 -2
  229. package/server/dist/modules/loops/runtime/builtin-loops.js +70 -0
  230. package/server/dist/modules/loops/runtime/definition-cancellation.js +31 -0
  231. package/server/dist/modules/loops/runtime/legacy-launch-telemetry.js +78 -0
  232. package/server/dist/modules/loops/runtime/loop-command-catalog.js +13 -12
  233. package/server/dist/modules/loops/runtime/loop-compat.js +219 -0
  234. package/server/dist/modules/loops/runtime/loop-core-factory.js +42 -0
  235. package/server/dist/modules/loops/runtime/loop-definition-controls.js +48 -0
  236. package/server/dist/modules/loops/runtime/loop-definition-events.js +145 -0
  237. package/server/dist/modules/loops/runtime/loop-definition-recovery.js +106 -0
  238. package/server/dist/modules/loops/runtime/loop-definition-run.js +36 -0
  239. package/server/dist/modules/loops/runtime/loop-definition.js +246 -0
  240. package/server/dist/modules/loops/runtime/loop-effect.js +10 -1
  241. package/server/dist/modules/loops/runtime/loop-executors.js +63 -3
  242. package/server/dist/modules/loops/runtime/loop-factory.js +35 -15
  243. package/server/dist/modules/loops/runtime/loop-graph.js +84 -8
  244. package/server/dist/modules/loops/runtime/loop-migration.js +36 -0
  245. package/server/dist/modules/loops/runtime/loop-preview.js +10 -0
  246. package/server/dist/modules/loops/runtime/loop-run-manager.js +206 -13
  247. package/server/dist/modules/loops/runtime/loop-runs-store.js +271 -7
  248. package/server/dist/modules/loops/runtime/loop-templates.js +205 -45
  249. package/server/dist/modules/loops/runtime/loops-router.js +246 -29
  250. package/server/dist/modules/loops/runtime/loops-store.js +140 -20
  251. package/server/dist/modules/missions/runtime/agent-operator-prompt.js +14 -11
  252. package/server/dist/modules/specs/runtime/spec-addenda.js +28 -0
  253. package/server/dist/project-registry.js +87 -51
  254. package/server/dist/project-router-jobs.js +17 -6
  255. package/server/dist/project-router-loop-runs.js +200 -0
  256. package/server/dist/project-router-spending.js +17 -0
  257. package/server/dist/project-router.js +8 -6
  258. package/server/dist/schemas/agent-runtime.schema.json +93 -1
  259. package/server/dist/schemas/workflow-definition.schema.json +312 -0
  260. package/server/dist/vitest-setup.js +22 -0
  261. package/server/dist/worktree-overlay.js +1 -1
  262. package/client/dist/assets/AgentsPage-DfHWgP_x.js +0 -87
  263. package/client/dist/assets/DesktopAnalyticsPage-tc0p4jJW.js +0 -1
  264. package/client/dist/assets/InteractiveJobComposer-DFPpdg2D.js +0 -19
  265. package/client/dist/assets/JobDetailModal-BdOv-l-M.js +0 -1
  266. package/client/dist/assets/LoopBuilderPage-BemvUOxy.js +0 -7
  267. package/client/dist/assets/LoopPreviewModal-C6hNAeYN.js +0 -1
  268. package/client/dist/assets/LoopsPage-BZr0quvh.js +0 -1
  269. package/client/dist/assets/TemplatePreviewModal-Cejcquah.js +0 -1
  270. package/client/dist/assets/agentRuntime-BUimiX__.js +0 -1
  271. package/client/dist/assets/agentRuntime-BcN97sAB.js +0 -1
  272. package/client/dist/assets/agentRuntime-Ckyg-ahT.js +0 -1
  273. package/client/dist/assets/agentRuntime-DJCwyX4t.js +0 -1
  274. package/client/dist/assets/agentRuntime-DVzPJOl0.js +0 -1
  275. package/client/dist/assets/agentRuntime-V9AZTG3c.js +0 -1
  276. package/client/dist/assets/agentRuntime-bAAjw1vw.js +0 -1
  277. package/client/dist/assets/agentRuntime-v4qKAYH-.js +0 -1
  278. package/client/dist/assets/agentstudio-BNUth0uj.js +0 -1
  279. package/client/dist/assets/agentstudio-BNdB5hkr.js +0 -1
  280. package/client/dist/assets/agentstudio-C7-bt8FO.js +0 -1
  281. package/client/dist/assets/agentstudio-C8uNchpV.js +0 -1
  282. package/client/dist/assets/agentstudio-CKabyMlg.js +0 -1
  283. package/client/dist/assets/agentstudio-CN2pokQu.js +0 -1
  284. package/client/dist/assets/agentstudio-y2dVDXeM.js +0 -1
  285. package/client/dist/assets/analytics-BlypLLR6.js +0 -1
  286. package/client/dist/assets/builder-765NeYTp.js +0 -1
  287. package/client/dist/assets/builder-8MG3V6ea.js +0 -1
  288. package/client/dist/assets/builder-B-1UBs5K.js +0 -1
  289. package/client/dist/assets/builder-BTiGnPT0.js +0 -1
  290. package/client/dist/assets/builder-Cx9Rz-7u.js +0 -1
  291. package/client/dist/assets/builder-DKFMELBl.js +0 -1
  292. package/client/dist/assets/builder-OcmKrC0h.js +0 -1
  293. package/client/dist/assets/builder-P9qVBXFZ.js +0 -1
  294. package/client/dist/assets/common-B5AZNYMH.js +0 -1
  295. package/client/dist/assets/common-BFZ0c_vN.js +0 -1
  296. package/client/dist/assets/common-BttQx3z4.js +0 -1
  297. package/client/dist/assets/common-CM65k_-e.js +0 -1
  298. package/client/dist/assets/common-D4mvFFlu.js +0 -1
  299. package/client/dist/assets/common-TZ9Ny96S.js +0 -1
  300. package/client/dist/assets/common-nFpSF4GC.js +0 -1
  301. package/client/dist/assets/dashboard-B9uWNGO2.js +0 -1
  302. package/client/dist/assets/dashboard-BIwmO9wc.js +0 -1
  303. package/client/dist/assets/dashboard-BV4vOZkR.js +0 -1
  304. package/client/dist/assets/dashboard-Bf6MPVsM.js +0 -1
  305. package/client/dist/assets/dashboard-C8klWVvZ.js +0 -1
  306. package/client/dist/assets/dashboard-D1ORhPF0.js +0 -1
  307. package/client/dist/assets/dashboard-DSubvs9x.js +0 -1
  308. package/client/dist/assets/dashboard-px_vlRx_.js +0 -1
  309. package/client/dist/assets/index-C51x61Bz.css +0 -2
  310. package/client/dist/assets/loops-B7YpGizO.js +0 -1
  311. package/client/dist/assets/loops-BomD2J-h.js +0 -1
  312. package/client/dist/assets/loops-BrQHSQw3.js +0 -1
  313. package/client/dist/assets/loops-BvBwvTPA.js +0 -1
  314. package/client/dist/assets/loops-CODk6Slz.js +0 -1
  315. package/client/dist/assets/loops-DC6k-Ym-.js +0 -1
  316. package/client/dist/assets/loops-DSEg8-uY.js +0 -1
  317. package/client/dist/assets/loops-DhCoXD_v.js +0 -1
  318. package/client/dist/assets/settings-BsehKpty.js +0 -1
  319. package/client/dist/assets/settings-CQWob3SB.js +0 -1
  320. package/client/dist/assets/settings-CgCl0hzy.js +0 -1
  321. package/client/dist/assets/settings-DLRLd22L.js +0 -1
  322. package/client/dist/assets/settings-Dn5prAFl.js +0 -1
  323. package/client/dist/assets/settings-HZSu-K4l.js +0 -1
  324. package/client/dist/assets/settings-p4OVIyRh.js +0 -1
  325. package/client/dist/assets/settings-rddaldUp.js +0 -1
  326. package/client/dist/assets/useRuntimeRuns-Dqmz9fS9.js +0 -1
  327. package/docs/guide/de/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  328. package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +0 -126
  329. package/docs/guide/es/pipeline/3-batch-implement-and-multi-feature.md +0 -114
  330. package/docs/guide/fr/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  331. package/docs/guide/it/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  332. package/docs/guide/ja/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  333. package/docs/guide/pt/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  334. package/docs/guide/zh/pipeline/3-batch-implement-and-multi-feature.md +0 -84
  335. package/server/dist/modules/loops/runtime/loop-templates-ported.js +0 -675
  336. /package/client/dist/assets/{LoopBuilderPage-DtxX27Jz.css → loop-layout-DtxX27Jz.css} +0 -0
@@ -1 +1 @@
1
- var e={title:`プロジェクトを追加`,description:`プロジェクトディレクトリを登録して Specrails から管理します。`,noProviderDetected:`AI CLI が見つかりません。まず Claude Code、Codex CLI、Gemini CLI、Kimi Code のいずれかをインストールしてください。`,pathLabel:`プロジェクトパス`,pathPlaceholder:`/Users/me/my-project`,pathHint:`プロジェクトルートへの絶対パス`,browseForFolder:`フォルダを参照`,selectProjectFolder:`プロジェクトフォルダを選択`,nameLabel:`表示名`,optional:`(任意)`,namePlaceholder:`マイプロジェクト`,nameHint:`デフォルトはディレクトリ名`,adding:`追加中…`,submit:`プロジェクトを追加`,toolsRequired_one:`プロジェクトの追加には {{tools}} が必要です`,toolsRequired_other:`プロジェクトの追加には {{tools}} が必要です`,errors:{pathRequired:`プロジェクトパスは必須です`,addFailed:`プロジェクトの追加に失敗しました`},toasts:{registered:`プロジェクト「{{name}}」を登録しました`},chooser:{description:`既存のリポジトリを取り込むか、アイデアから新しいプロジェクトを作りましょう。`,existingTitle:`既存プロジェクト`,existingDescription:`ディスク上に既にあるリポジトリを登録します。`,newTitle:`新規プロジェクト`,newDescription:`アイデアを伝えると、マイルストーン1のバックログ付きでリポジトリが用意されます。`}},t={corruptedBundle:`バンドル破損 — アプリを再インストールしてください`,notInstalled:`未インストール`,failedToExecute:`見つかりましたが実行できませんでした`,failedToExecuteAt:`{{path}} に見つかりましたが実行できませんでした`,failedToExecuteWithError:`見つかりましたが実行できませんでした({{error}})`,failedToExecuteAtWithError:`{{path}} に見つかりましたが実行できませんでした({{error}})`,needsMinimum:`{{version}} が見つかりました — {{minVersion}} 以上が必要です`,unknownVersion:`不明`,installedLabel:`インストール済み`,verifyError:`開発者ツールをローカルで検証できませんでした — インストール時に検証されます。`,allDetected:`必要なツールはすべて検出されました`,bundleCorruptedTitle:`アプリバンドルが破損しています`,toolsRequired_one:`{{count}} 個の開発者ツールが必要です`,toolsRequired_other:`{{count}} 個の開発者ツールが必要です`,reinstallHint:`Specrails アプリを再インストールしてバンドルツールを復元してください。`,installMissingHint:`続行するには不足しているツールをインストールしてください。`,moreInfo:`詳細`,bundledBadge:`バンドル`,optional:`任意`,ghNoAuth:"未ログイン — `gh auth login` を実行してください"},n={title:`開発者ツールをインストール`,description:`SpecRails には PATH 上の Node.js、npm、npx、Git が必要です。お使いの OS のスニペットを選んで実行し、「インストールしました。再チェック」をクリックしてください。`,darwin:{intro:`Homebrew なら1行で両方のツールをインストールできます。brew がない場合は公式ダウンロードを利用してください。`,installNodeGit:`Homebrew で Node.js と Git をインストール`},win32:{intro:`Winget は Windows 11 および最近の Windows 10 に同梱されています。PowerShell またはターミナルを開いて実行してください:`,installNode:`Node.js LTS をインストール`,installGit:`Git をインストール`,note:`インストール後、Windows が PATH を更新するように Specrails を再起動してください。`},linux:{intro:`ディストリビューションのパッケージマネージャーを使用してください:`,debian:`Debian / Ubuntu`,fedora:`Fedora / RHEL`},links:{nodeOfficial:`Node.js(公式)`,gitOfficial:`Git(公式)`,gitWindows:`Git for Windows(公式)`},showOtherPlatforms:`他のプラットフォームを表示`,hideOtherPlatforms:`他のプラットフォームを非表示`,recheck:`インストールしました。再チェック`,diagnostics:{copy:`診断情報をコピー`,copied:`診断情報をコピーしました`,failed:`コピーに失敗しました`},corrupted:{title:`アプリバンドルが破損しています`,description:`バンドルされたツール(Node.js、Git)の一部を検証できませんでした。`,body:`このツールは Specrails アプリにバンドルされており、個別にインストールできません。このメッセージが表示される場合、アプリバンドルが破損している可能性があります。Specrails を再インストールしてください。`}},r={title:`<spec>spec</spec><rails>rails</rails> へようこそ`,description:`Specrails は複数のプロジェクトを単一のインターフェースで管理します。最初のプロジェクトを追加して始めましょう。`,addFirstProject:`最初のプロジェクトを追加`,jiraHint:`各プロジェクトを専用の Jira ボードに接続 — スペックは双方向で同期され続けます。`,mcpHint:`安全なローカル MCP サーバー経由で外部の AI ツールを Specrails に接続します。既定でオン、設定 → MCP で管理します。`,agentChatHint:`チャットで Specrails を操作 — 内蔵エージェントがローカル MCP を通じて specs・rails・分析をあなたの代わりに処理します。バブルから、または ⌘⇧A で開けます。`,localEnginesHint:`ローカルモデルしかない場合は、設定 → Specrails Agents で OpenAI 互換のエンドポイントを追加してください。レール、チャット、ミッションなどすべての画面が既定でそれを使います。`},i=JSON.parse(`{"productTour":"プロダクトツアー","stepCount":"ステップ {{current}} / {{total}}","goToStep":"ステップ {{step}} へ移動: {{label}}","stepLabel":"ステップ {{step}}","dontShowAgain":"今後表示しない","skipTour":"ツアーをスキップ","getStarted":"始める","flow":{"architect":"アーキテクト","developer":"デベロッパー","reviewer":"レビュアー","describe":"記述","specs":"スペック","rails":"レール","review":"レビューとマージ","yourReview":"あなたのレビュー","blueprint":"ブループリント","approve":"承認","m1Specs":"マイルストーン1のスペック","milestones":"マイルストーン"},"language":{"nav":"言語","title":"言語を選ぶ","subtitle":"Specrailsはあなたの言語に対応","intro":"インターフェースで使いたい言語を選んでください。即座に適用されます — このツアーも含めて。","note":"設定 → 言語でいつでも変更できます。"},"theme":{"nav":"テーマ","title":"好みの見た目を選ぶ","subtitle":"内蔵テーマを即座に適用","intro":"Specrailsの見た目を選びましょう — テーマはクリックした瞬間に適用されます。","note":"設定 → 外観でいつでも変更できます。"},"welcome":{"nav":"ようこそ","title":"Specrails へようこそ","subtitle":"AI エージェントでソフトウェアを届けるローカルのコックピット","intro":"Specrails はアイデアをリリース済みのコードに変え、すべてのステップを<b>見て、導き、信頼</b>できるようにします。欲しいものを記述し、正確なスペックを得て、Claude Code・Codex・Gemini・Kimi でレール上に実行し、何をマージするかを決めます。あなたなしでは何もマージされません。","coreLoopLabel":"中心のループ","flowCaption":"<b>記述 → スペック → レール → レビューとマージ</b>。各ステップはライブで流れ、各結果はあなたの判断を待ちます。","missionLabel":"ミッションモード:既定","missionBody":"ひとつの会話がアプリ全体を動かします。エージェントがスペックを書き、レールを起動し、コストを確認し、決定カードを差し出します。<b>あなたが話し、エージェントが動く。</b>","boardLabel":"ボードモード:スイッチひとつ","boardBody":"従来のダッシュボード:スペックボード、レール、ジョブ、分析。左サイドバーのスイッチで切り替えます。<b>同じプロジェクト、同じデータ</b>です。","localNote":"<b>100% ローカル · シングルユーザー · アカウント不要。</b>すべてあなたのマシンで動きます。<i>あなた</i>がエージェントを実行しない限り、コードはノート PC を離れません。","tourNote":"このクイックツアーではアプリでできることをひと通り紹介します。約 2 分です。"},"mission":{"nav":"ミッションモード","title":"話すだけ、エージェントが動く","subtitle":"ミッションモードが既定の画面です","intro":"<b>ミッションモード</b>では、ウィンドウ全体が、Specrails を自身の <b>MCP ツール</b>で操作するエージェントとの会話になります。「優先度上位 3 件のスペックを起動して」「今週いくら使った?」「ダークモードのスペックを書いて」。すべてライブで、作業中にレール・スペック・カードが更新されます。","missionsLabel":"ミッションとプロジェクト","missionsBody":"各会話はプロジェクト(または全体を表すホーム)にピン留めされたミッションです。ヘッダーでミッションを切り替え、ターン中でもメッセージを送れます。キューに入り順番に実行されます。","levelsLabel":"手綱はあなたの手に","levelsBody":"ライブのレベル、<b>観察 → 編集 → 操作 → 自律</b>を <shift>Shift</shift> <tab>Tab</tab> で切り替え、どこまで動けるかを制限します。設定したレベルを超えて行動することはありません。","cardsLabel":"決定カード","cardsBody":"起動はコンポーザー上部にピン留めされたライブカードとして表示されます。レールの進捗、その後 PR 作成 / ローカル統合 / 破棄と、平易な言葉のレビュー。返答内のスペック番号・ジョブ・ループはクリック可能です。","workspaceLabel":"すぐ横のワークスペース","workspaceBody":"右サイドバーから、会話の隣にブループリント、ジョブ、分析、内蔵ブラウザ、ターミナル、コードエクスプローラーを開けます。コンテキストの切り替えは不要です。","mcpLabel":"ローカル MCP 上で動作","mcpBody":"エージェントは Specrails 内蔵の MCP サーバーを通じて動きます。<b>既定でオン</b>、ループバックのみ。同じサーバーで自分のツール(Claude Desktop、Cursor など)から Specrails を操作できます。設定 → MCP で管理します。"},"builder":{"nav":"新規プロジェクト","title":"アイデアからプロジェクトを始める","subtitle":"ビルダー:コードを 1 行も書く前にブループリント、スペック、マイルストーンを","intro":"プロジェクトを追加 → <b>新規</b>で、エージェントが<b>プロジェクトビルダー</b>になります。アイデアを記述すると、短いインタビュー(またはワンクリックで全決定)のうえ、製品・コアフロー・プラットフォーム・スタック・マイルストーンを提案し、あなたが承認または調整します。","flowLabel":"アイデアからバックログへ","flowCaption":"コミットでリポジトリ、ワークスペース、マイルストーン1のバックログが作られます。任意でプライベートな GitHub リポジトリも。","cardsLabel":"ワンクリックの決定","cardsBody":"「おまかせ」と「承認してスペックを生成」はスレッド内のカードとして表示され、下した決定は記録としてそこに固定されます。","specsLabel":"プレミアムなスペックを正直に監査","specsBody":"マイルストーン1のスペックは 2 件ずつ完全に書かれ、その後バッチ全体を監査します(課題、解決策、範囲、技術的考慮、6 件以上の受け入れ基準)。決定的なゲートが薄い内容を止めます。","milestonesLabel":"レール上のマイルストーン","milestonesBody":"マイルストーン1を起動すると、最大 3 スペックのレールとして実行され、それぞれ前のブランチに積み上がります。<b>ウェーブのチェックポイント</b>が次のレールごとに確認します。自動続行も選べます。","progressLabel":"ライブの進捗","progressBody":"ブループリントパネルは実数(納品済み、レビュー中、完了)を表示し、未マージのものがある限り「完了」とは言いません。以降のマイルストーンは実際のリポジトリに対して生成されます。"},"authorSpecs":{"nav":"スペックを書く","title":"アイデアをスペックに","subtitle":"作りたいものを正確に捉える 6 つの方法","intro":"<b>スペック</b>はやってほしい作業の記述です。その時に合う方法で書きましょう。一行のメモから、エージェントに調査させるまで。","agentLabel":"エージェントに頼む","agentBody":"ミッションモードで変更内容を記述するだけ。エージェントは先に実際のコードを読み、ライブカードとしてスーパースペックを起草し、あなたの合図で保存します。","exploreLabel":"Explore:対話で","exploreBody":"チャットで要望を記述すると、ライブの下書きが毎ターン組み直されます。プリセットのスライダーで AI に見せるプロジェクトの文脈量を調整できます。メッセージのみから、コードベース全体+MCP サーバーまで。","quickLabel":"Quick:一発で","quickBody":"欲しいものが決まっているなら、1 ターンで完全なスペックを生成。任意でコントラクト層を追加:正確な名前、データ構造、不変条件、対象ファイル一覧で、エージェントに再発明させません。","websiteLabel":"Web サイトから","websiteBody":"内蔵ブラウザを開き、要素をホバー選択するか矩形をドラッグ。スクリーンショット、DOM、適用 CSS が添付になります。","smashLabel":"大きなエピックを SMASH","smashBody":"大きなスペックをワンクリックで小さなサブスペックの一群に分解。各子カードに短い要約が付きます。","draftsLabel":"ドラフトと編集の再開","draftsBody":"進行中の探索をドラフトチケットとして保留し、後で再開。どのスペックも Explore で開き直して磨き続けられます。"},"rails":{"nav":"レールとレビュー","title":"レール上でパイプラインを実行","subtitle":"隔離されたレーンと、本当に読めるレビュー","intro":"<b>レール</b>は実行レーンです。最大 12 本、必要に応じて作成。スペックをレールに置いて <play>▶ 再生</play>、または空いているレールを<b>すべて起動</b>して並列実行。各ランは専用の git worktree で動き、あなたのチェックアウトには触れません。","jobLabel":"各ランがすること","flowCaption":"各フェーズはライブで流れます。終了時、作業はブランチに残り、アプリが次の行動を尋ねます。Specrails は PR を作るだけで、自分ではマージしません。","reviewLabel":"先に尋ねる PR レビュー","reviewBody":"完了したスペックは<b>レビュー中</b>に留まります。選ぶのはあなた:ドラフト PR の作成、ローカル統合(リモート不要)、または破棄。マージで完了になります。","packetLabel":"レビューパケット","packetBody":"納品ごとの平易なページ:何を依頼したか、何が変わったか、AI の報告とアプリが検証した事実、コスト。受け入れ / 変更を依頼 / 破棄 が付きます。","steerLabel":"実行中に舵を取る","steerBody":"Claude のランは対話式です。作業中に質問や方向転換ができ、生ログではなくナレーション付きの進捗を追えます。","loopsLabel":"独自のループを作る","loopsBody":"<b>Loops</b> はビジュアルビルダーです。AI ステップ、シェルコマンド、目標達成まで繰り返す<b>ループデサイダー</b>をつなげます。Implement、Batch、Freestyle はすぐ使えます。","profilesLabel":"エージェントプロファイルと既定値","profilesBody":"どのエージェントを動かし、それぞれどのモデルを使うかを決めます。プロジェクトのプロファイル単位、レール単位、または設定 → Specrails エージェントでマシン全体に一度だけ。","isolationLabel":"多くのプロジェクトを隔離","isolationBody":"各プロジェクトは専用のデータベースとキューを持ちます。Specrails は自身のファイルをホームフォルダー下に置くため、リポジトリは手つかずのままです。"},"providers":{"nav":"あなたのエージェント","title":"自分のエージェントを持ち込む","subtitle":"Claude Code、Codex、Gemini、Kimi をファーストクラスのエンジンに","intro":"<b>Claude Code</b>、<b>Codex CLI</b>、<b>Gemini CLI</b>、<b>Kimi Code</b> はひとつの契約の下で入れ替え可能なエンジンです。このマシンにインストールされサインイン済みのものは自動検出され、どこでも使えます。プロジェクトごとの設定は不要です。","calloutLabel":"複数インストールされている場合","calloutBody":"エンジンは<b>スペック、レール、ミッション、ターミナル起動ごと</b>に選べます。アプリはプロジェクトごとに最後の選択を記憶します。推定コストは <mono>~</mono> 付き。Kimi はトークンもコストも報告しません。","table":{"capability":"機能","streamingResume":"ストリーミングとセッション再開","native":"ネイティブ","costReporting":"コストレポート","providerBilled":"プロバイダー請求額","estimated":"推定(~)","unavailable":"利用不可","telemetry":"テレメトリ(OTEL)","synthesized":"合成","agentProfiles":"エージェントプロファイル"}},"cost":{"nav":"コスト追跡","title":"1セント単位で追跡","subtitle":"課金対象のすべての呼び出しを記録・可視化","intro":"すべての AI 呼び出しでライフサイクルとプロバイダーを記録します。Kimi のように使用量やコストを報告しない場合、それらは利用不可のままです。","analyticsLabel":"分析ページ","analyticsBody":"バーンレートのヒーロー表示、日次タイムライン、トップチケット、モデル別内訳、コスト対ターン数の散布図。期間(7日 / 30日 / 90日 / 全期間)とサーフェスでフィルタできます。","perTicketLabel":"チケット別の支出","perTicketBody":"各スペックの詳細にはコストと所要ターン数が表示され、そのチケットでフィルタした分析ページへディープリンクします。","honestLabel":"正直な数字","honestBody":"Claude のコストはプロバイダー報告値、Codex と Gemini は推定の場合 <mono>~</mono> が付きます。Kimi のトークンと USD コストは 0 ではなく利用不可です。","budgetsLabel":"予算とアラート","budgetsBody":"日次予算とジョブ単位のコストアラートを設定でき、上限を超えるとアプリが自動でキューを一時停止します。すべて CSV または JSON にエクスポートできます。"},"workspace":{"nav":"ワークスペース","title":"自分のワークスペースに","subtitle":"ウィンドウを離れずに必要なものすべて","terminalLabel":"ターミナルパネル","terminalBody":"下部に VS Code 風の本物のターミナル(<mod>{{mod}}</mod> <j>J</j>)。WebGL 描画、検索、インライン画像、パスのドラッグ&ドロップ、シェル統合。プロジェクトごとに最大 10 セッション。","codeLabel":"コードエクスプローラー","codeBody":"読み取り専用のファイルツリーと Monaco ビューアー。平易な AI 要約と、ファイルごとの構築ストーリー(どのスペックが、いつ、なぜ触れたか)を表示します。","browserLabel":"内蔵ブラウザ","browserBody":"リンク、PR、開発サーバーをアプリ内で開けます。デスクトップ版ではネイティブのブラウザペインで、ポップアップも OAuth ログインを維持します。","integrationsLabel":"連携と MCP","integrationsBody":"プロジェクトごとの MCP 連携マーケットプレイス(Serena のセマンティックナビゲーションを同梱)と、アプリを自分の AI ツールへ公開する Specrails MCP サーバー。","themesLabel":"テーマとエフェクト","themesBody":"6 つの内蔵テーマ(specrails、dracula、aurora-light、obsidian-dark、code-rain、galaxy)を UI 描画前に適用。設定 → エフェクトで、エージェントの思考ハローなどの演出を切り替えられます。","chatsLabel":"最小化できるチャット","chatsBody":"Explore や AI 編集のセッションをドックのチップに退避し、後で再開。リロードやプロジェクト切り替えでも失われません。","compareLabel":"並べて比較","compareBody":"スペックを画面端へドラッグすると他のスペックのピッカーが現れ、タブレットのように 2 件を並べてレビューできます。","desktopLabel":"デスクトップかブラウザか","desktopBody":"ブラウザで Specrails を使うか、署名済みデスクトップアプリ(macOS・Windows)を入手。サーバー、Node、git、GitHub CLI を同梱しています。"},"companion":{"nav":"モバイルコンパニオン","title":"Specrails を持ち歩く","subtitle":"Specrails Companion — あなたのパイプラインを、スマートフォンで","intro":"<b>Specrails Companion</b> は specrails.dev/companion-app で使える Web アプリです — スマートフォンで開く(またはホーム画面に追加する)だけで、スペックボードの閲覧、レールの起動と停止、ジョブログのライブ追跡、分析のチェックができます。インストール不要、アプリストアも不要。","localLabel":"ほかのすべてと同じく 100% ローカル","localBody":"スマートフォンはこのコンピュータに直接接続します — ピアツーピアで暗号化(WebRTC)。クラウド中継なし、アカウント不要、コードがあなたのデバイスの外に出ることはありません。","downloadLabel":"スマートフォンで開く","downloadHint":"スマートフォンのカメラでコードをスキャンするか、ブラウザで specrails.dev/companion-app を開いてください。","open":"Specrails Companion を開く","pairLabel":"ペアリングは10秒で完了","pairBody":"スマートフォンで specrails.dev/companion-app を開き、こちらで 設定 → モバイルコンパニオン → Web コンパニオンをペアリング と進んで、画面の手順に従ってください。"},"moveFast":{"nav":"素早く動く","title":"思考の速さで動く","subtitle":"キーボードファースト、どこでも","paletteLabel":"コマンドパレット","paletteShortcut":"<f>どこでも</f> <mod>{{mod}}</mod> <m>+</m> <k>K</k> <m>を押す</m>","paletteBody":"プロジェクト切り替え、スペックコマンドの実行、任意のページへの移動、最近のジョブ検索をあいまい検索で。","agentLabel":"エージェント","agentBody":"<mod>{{mod}}</mod> <shift>Shift</shift> <a>A</a> でエージェントを表示/非表示。<shift>Shift</shift> <tab>Tab</tab> でレベルを切り替え。","terminalLabel":"ターミナルパネル","terminalBody":"<mod>{{mod}}</mod> <j>J</j> で切り替え。","shortcutsLabel":"すべてのショートカット","shortcutsBody":"<q>?</q> を押すと一覧が表示されます。","chatLabel":"右サイドバー","chatBody":"<mod>{{mod}}</mod> <bkey>B</bkey> で右サイドバーを切り替え。","projectsLabel":"プロジェクトサイドバー","projectsBody":"<alt>{{alt}}</alt> <mod>{{mod}}</mod> <bkey>B</bkey> で左の Arc サイドバーを切り替え。","pagesLabel":"番号でページとプロジェクトへ","pagesBody":"<mod>{{mod}}</mod> <n>1–9</n> でページに移動、<alt>{{alt}}</alt> <mod>{{mod}}</mod> <n>1–9</n> でプロジェクトを切り替え。","outro":"<b>ツアーは以上です。</b>ミッションのコンポーザーに作りたいものを入力するか、左サイドバーからプロジェクトを追加してください。このツアーは設定からいつでも再表示できます。"},"jira":{"label":"Jira 連携","body":"任意のプロジェクトを <b>Jira ボード</b> で裏付けます — 各スペックは Jira の課題になり、双方向で同期されます。ステータスは rail に追従し、job 完了時にコメントが投稿されます。追加時にプロジェクトごとに設定するか、いつでも設定から構成できます。"}}`),a={addProject:e,prerequisites:t,instructions:n,welcome:r,onboarding:i};export{e as addProject,a as default,n as instructions,i as onboarding,t as prerequisites,r as welcome};
1
+ var e={title:`プロジェクトを追加`,description:`プロジェクトディレクトリを登録して Specrails から管理します。`,noProviderDetected:`AI CLI が見つかりません。まず Claude Code、Codex CLI、Gemini CLI、Kimi Code のいずれかをインストールしてください。`,pathLabel:`プロジェクトパス`,pathPlaceholder:`/Users/me/my-project`,pathHint:`プロジェクトルートへの絶対パス`,browseForFolder:`フォルダを参照`,selectProjectFolder:`プロジェクトフォルダを選択`,nameLabel:`表示名`,optional:`(任意)`,namePlaceholder:`マイプロジェクト`,nameHint:`デフォルトはディレクトリ名`,adding:`追加中…`,submit:`プロジェクトを追加`,toolsRequired_one:`プロジェクトの追加には {{tools}} が必要です`,toolsRequired_other:`プロジェクトの追加には {{tools}} が必要です`,errors:{pathRequired:`プロジェクトパスは必須です`,addFailed:`プロジェクトの追加に失敗しました`},toasts:{registered:`プロジェクト「{{name}}」を登録しました`},chooser:{description:`既存のリポジトリを取り込むか、アイデアから新しいプロジェクトを作りましょう。`,existingTitle:`既存プロジェクト`,existingDescription:`ディスク上に既にあるリポジトリを登録します。`,newTitle:`新規プロジェクト`,newDescription:`アイデアを伝えると、マイルストーン1のバックログ付きでリポジトリが用意されます。`}},t={corruptedBundle:`バンドル破損 — アプリを再インストールしてください`,notInstalled:`未インストール`,failedToExecute:`見つかりましたが実行できませんでした`,failedToExecuteAt:`{{path}} に見つかりましたが実行できませんでした`,failedToExecuteWithError:`見つかりましたが実行できませんでした({{error}})`,failedToExecuteAtWithError:`{{path}} に見つかりましたが実行できませんでした({{error}})`,needsMinimum:`{{version}} が見つかりました — {{minVersion}} 以上が必要です`,unknownVersion:`不明`,installedLabel:`インストール済み`,verifyError:`開発者ツールをローカルで検証できませんでした — インストール時に検証されます。`,allDetected:`必要なツールはすべて検出されました`,bundleCorruptedTitle:`アプリバンドルが破損しています`,toolsRequired_one:`{{count}} 個の開発者ツールが必要です`,toolsRequired_other:`{{count}} 個の開発者ツールが必要です`,reinstallHint:`Specrails アプリを再インストールしてバンドルツールを復元してください。`,installMissingHint:`続行するには不足しているツールをインストールしてください。`,moreInfo:`詳細`,bundledBadge:`バンドル`,optional:`任意`,ghNoAuth:"未ログイン — `gh auth login` を実行してください"},n={title:`開発者ツールをインストール`,description:`SpecRails には PATH 上の Node.js、npm、npx、Git が必要です。お使いの OS のスニペットを選んで実行し、「インストールしました。再チェック」をクリックしてください。`,darwin:{intro:`Homebrew なら1行で両方のツールをインストールできます。brew がない場合は公式ダウンロードを利用してください。`,installNodeGit:`Homebrew で Node.js と Git をインストール`},win32:{intro:`Winget は Windows 11 および最近の Windows 10 に同梱されています。PowerShell またはターミナルを開いて実行してください:`,installNode:`Node.js LTS をインストール`,installGit:`Git をインストール`,note:`インストール後、Windows が PATH を更新するように Specrails を再起動してください。`},linux:{intro:`ディストリビューションのパッケージマネージャーを使用してください:`,debian:`Debian / Ubuntu`,fedora:`Fedora / RHEL`},links:{nodeOfficial:`Node.js(公式)`,gitOfficial:`Git(公式)`,gitWindows:`Git for Windows(公式)`},showOtherPlatforms:`他のプラットフォームを表示`,hideOtherPlatforms:`他のプラットフォームを非表示`,recheck:`インストールしました。再チェック`,diagnostics:{copy:`診断情報をコピー`,copied:`診断情報をコピーしました`,failed:`コピーに失敗しました`},corrupted:{title:`アプリバンドルが破損しています`,description:`バンドルされたツール(Node.js、Git)の一部を検証できませんでした。`,body:`このツールは Specrails アプリにバンドルされており、個別にインストールできません。このメッセージが表示される場合、アプリバンドルが破損している可能性があります。Specrails を再インストールしてください。`}},r={title:`<spec>spec</spec><rails>rails</rails> へようこそ`,description:`Specrails は複数のプロジェクトを単一のインターフェースで管理します。最初のプロジェクトを追加して始めましょう。`,addFirstProject:`最初のプロジェクトを追加`,jiraHint:`各プロジェクトを専用の Jira ボードに接続 — スペックは双方向で同期され続けます。`,mcpHint:`安全なローカル MCP サーバー経由で外部の AI ツールを Specrails に接続します。既定でオン、設定 → MCP で管理します。`,agentChatHint:`チャットで Specrails を操作 — 内蔵エージェントがローカル MCP を通じて specs・rails・分析をあなたの代わりに処理します。バブルから、または ⌘⇧A で開けます。`,localEnginesHint:`ローカルモデルしかない場合は、設定 → Specrails Agents で OpenAI 互換のエンドポイントを追加してください。レール、チャット、ミッションなどすべての画面が既定でそれを使います。`},i=JSON.parse(`{"productTour":"プロダクトツアー","stepCount":"ステップ {{current}} / {{total}}","goToStep":"ステップ {{step}} へ移動: {{label}}","stepLabel":"ステップ {{step}}","dontShowAgain":"今後表示しない","skipTour":"ツアーをスキップ","getStarted":"始める","flow":{"architect":"アーキテクト","developer":"デベロッパー","reviewer":"レビュアー","describe":"記述","specs":"スペック","rails":"レール","review":"レビューとマージ","yourReview":"あなたのレビュー","blueprint":"ブループリント","approve":"承認","m1Specs":"マイルストーン1のスペック","milestones":"マイルストーン"},"language":{"nav":"言語","title":"言語を選ぶ","subtitle":"Specrailsはあなたの言語に対応","intro":"インターフェースで使いたい言語を選んでください。即座に適用されます — このツアーも含めて。","note":"設定 → 言語でいつでも変更できます。"},"theme":{"nav":"テーマ","title":"好みの見た目を選ぶ","subtitle":"内蔵テーマを即座に適用","intro":"Specrailsの見た目を選びましょう — テーマはクリックした瞬間に適用されます。","note":"設定 → 外観でいつでも変更できます。"},"welcome":{"nav":"ようこそ","title":"Specrails へようこそ","subtitle":"AI エージェントでソフトウェアを届けるローカルのコックピット","intro":"Specrails はアイデアをリリース済みのコードに変え、すべてのステップを<b>見て、導き、信頼</b>できるようにします。欲しいものを記述し、正確なスペックを得て、Claude Code・Codex・Gemini・Kimi でレール上に実行し、何をマージするかを決めます。あなたなしでは何もマージされません。","coreLoopLabel":"中心のループ","flowCaption":"<b>記述 → スペック → レール → レビューとマージ</b>。各ステップはライブで流れ、各結果はあなたの判断を待ちます。","missionLabel":"ミッションモード:既定","missionBody":"ひとつの会話がアプリ全体を動かします。エージェントがスペックを書き、レールを起動し、コストを確認し、決定カードを差し出します。<b>あなたが話し、エージェントが動く。</b>","boardLabel":"ボードモード:スイッチひとつ","boardBody":"従来のダッシュボード:スペックボード、レール、ジョブ、分析。左サイドバーのスイッチで切り替えます。<b>同じプロジェクト、同じデータ</b>です。","localNote":"<b>100% ローカル · シングルユーザー · アカウント不要。</b>すべてあなたのマシンで動きます。<i>あなた</i>がエージェントを実行しない限り、コードはノート PC を離れません。","tourNote":"このクイックツアーではアプリでできることをひと通り紹介します。約 2 分です。"},"mission":{"nav":"ミッションモード","title":"話すだけ、エージェントが動く","subtitle":"ミッションモードが既定の画面です","intro":"<b>ミッションモード</b>では、ウィンドウ全体が、Specrails を自身の <b>MCP ツール</b>で操作するエージェントとの会話になります。「優先度上位 3 件のスペックを起動して」「今週いくら使った?」「ダークモードのスペックを書いて」。すべてライブで、作業中にレール・スペック・カードが更新されます。","missionsLabel":"ミッションとプロジェクト","missionsBody":"各会話はプロジェクト(または全体を表すホーム)にピン留めされたミッションです。ヘッダーでミッションを切り替え、ターン中でもメッセージを送れます。キューに入り順番に実行されます。","levelsLabel":"手綱はあなたの手に","levelsBody":"ライブのレベル、<b>観察 → 編集 → 操作 → 自律</b>を <shift>Shift</shift> <tab>Tab</tab> で切り替え、どこまで動けるかを制限します。設定したレベルを超えて行動することはありません。","cardsLabel":"決定カード","cardsBody":"起動はコンポーザー上部にピン留めされたライブカードとして表示されます。レールの進捗、その後 PR 作成 / ローカル統合 / 破棄と、平易な言葉のレビュー。返答内のスペック番号・ジョブ・ループはクリック可能です。","workspaceLabel":"すぐ横のワークスペース","workspaceBody":"右サイドバーから、会話の隣にブループリント、ジョブ、分析、内蔵ブラウザ、ターミナル、コードエクスプローラーを開けます。コンテキストの切り替えは不要です。","mcpLabel":"ローカル MCP 上で動作","mcpBody":"エージェントは Specrails 内蔵の MCP サーバーを通じて動きます。<b>既定でオン</b>、ループバックのみ。同じサーバーで自分のツール(Claude Desktop、Cursor など)から Specrails を操作できます。設定 → MCP で管理します。"},"builder":{"nav":"新規プロジェクト","title":"アイデアからプロジェクトを始める","subtitle":"ビルダー:コードを 1 行も書く前にブループリント、スペック、マイルストーンを","intro":"プロジェクトを追加 → <b>新規</b>で、エージェントが<b>プロジェクトビルダー</b>になります。アイデアを記述すると、短いインタビュー(またはワンクリックで全決定)のうえ、製品・コアフロー・プラットフォーム・スタック・マイルストーンを提案し、あなたが承認または調整します。","flowLabel":"アイデアからバックログへ","flowCaption":"コミットでリポジトリ、ワークスペース、マイルストーン1のバックログが作られます。任意でプライベートな GitHub リポジトリも。","cardsLabel":"ワンクリックの決定","cardsBody":"「おまかせ」と「承認してスペックを生成」はスレッド内のカードとして表示され、下した決定は記録としてそこに固定されます。","specsLabel":"プレミアムなスペックを正直に監査","specsBody":"マイルストーン1のスペックは 2 件ずつ完全に書かれ、その後バッチ全体を監査します(課題、解決策、範囲、技術的考慮、6 件以上の受け入れ基準)。決定的なゲートが薄い内容を止めます。","milestonesLabel":"レール上のマイルストーン","milestonesBody":"マイルストーン1を起動すると、最大 3 スペックのレールとして実行され、それぞれ前のブランチに積み上がります。<b>ウェーブのチェックポイント</b>が次のレールごとに確認します。自動続行も選べます。","progressLabel":"ライブの進捗","progressBody":"ブループリントパネルは実数(納品済み、レビュー中、完了)を表示し、未マージのものがある限り「完了」とは言いません。以降のマイルストーンは実際のリポジトリに対して生成されます。"},"authorSpecs":{"nav":"スペックを書く","title":"アイデアをスペックに","subtitle":"作りたいものを正確に捉える 6 つの方法","intro":"<b>スペック</b>はやってほしい作業の記述です。その時に合う方法で書きましょう。一行のメモから、エージェントに調査させるまで。","agentLabel":"エージェントに頼む","agentBody":"ミッションモードで変更内容を記述するだけ。エージェントは先に実際のコードを読み、ライブカードとしてスーパースペックを起草し、あなたの合図で保存します。","exploreLabel":"Explore:対話で","exploreBody":"チャットで要望を記述すると、ライブの下書きが毎ターン組み直されます。プリセットのスライダーで AI に見せるプロジェクトの文脈量を調整できます。メッセージのみから、コードベース全体+MCP サーバーまで。","quickLabel":"Quick:一発で","quickBody":"欲しいものが決まっているなら、1 ターンで完全なスペックを生成。任意でコントラクト層を追加:正確な名前、データ構造、不変条件、対象ファイル一覧で、エージェントに再発明させません。","websiteLabel":"Web サイトから","websiteBody":"内蔵ブラウザを開き、要素をホバー選択するか矩形をドラッグ。スクリーンショット、DOM、適用 CSS が添付になります。","smashLabel":"大きなエピックを SMASH","smashBody":"大きなスペックをワンクリックで小さなサブスペックの一群に分解。各子カードに短い要約が付きます。","draftsLabel":"ドラフトと編集の再開","draftsBody":"進行中の探索をドラフトチケットとして保留し、後で再開。どのスペックも Explore で開き直して磨き続けられます。"},"rails":{"nav":"レールとレビュー","title":"レール上でパイプラインを実行","subtitle":"隔離されたレーンと、本当に読めるレビュー","intro":"<b>レール</b>は実行レーンです。最大 12 本、必要に応じて作成。スペックをレールに置いて <play>▶ 再生</play>、または空いているレールを<b>すべて起動</b>して並列実行。各ランは専用の git worktree で動き、あなたのチェックアウトには触れません。","jobLabel":"各ランがすること","flowCaption":"各フェーズはライブで流れます。終了時、作業はブランチに残り、アプリが次の行動を尋ねます。Specrails は PR を作るだけで、自分ではマージしません。","reviewLabel":"先に尋ねる PR レビュー","reviewBody":"完了したスペックは<b>レビュー中</b>に留まります。選ぶのはあなた:ドラフト PR の作成、ローカル統合(リモート不要)、または破棄。マージで完了になります。","packetLabel":"レビューパケット","packetBody":"納品ごとの平易なページ:何を依頼したか、何が変わったか、AI の報告とアプリが検証した事実、コスト。受け入れ / 変更を依頼 / 破棄 が付きます。","steerLabel":"実行中に舵を取る","steerBody":"Claude のランは対話式です。作業中に質問や方向転換ができ、生ログではなくナレーション付きの進捗を追えます。","loopsLabel":"独自のループを作る","loopsBody":"<b>Loops</b> はビジュアルビルダーです。AI ステップ、シェルコマンド、目標達成まで繰り返す<b>ループデサイダー</b>をつなげます。Implement、Freestyle はすぐ使えます。","profilesLabel":"エージェントプロファイルと既定値","profilesBody":"どのエージェントを動かし、それぞれどのモデルを使うかを決めます。プロジェクトのプロファイル単位、レール単位、または設定 → Specrails エージェントでマシン全体に一度だけ。","isolationLabel":"多くのプロジェクトを隔離","isolationBody":"各プロジェクトは専用のデータベースとキューを持ちます。Specrails は自身のファイルをホームフォルダー下に置くため、リポジトリは手つかずのままです。"},"providers":{"nav":"あなたのエージェント","title":"自分のエージェントを持ち込む","subtitle":"Claude Code、Codex、Gemini、Kimi をファーストクラスのエンジンに","intro":"<b>Claude Code</b>、<b>Codex CLI</b>、<b>Gemini CLI</b>、<b>Kimi Code</b> はひとつの契約の下で入れ替え可能なエンジンです。このマシンにインストールされサインイン済みのものは自動検出され、どこでも使えます。プロジェクトごとの設定は不要です。","calloutLabel":"複数インストールされている場合","calloutBody":"エンジンは<b>スペック、レール、ミッション、ターミナル起動ごと</b>に選べます。アプリはプロジェクトごとに最後の選択を記憶します。推定コストは <mono>~</mono> 付き。Kimi はトークンもコストも報告しません。","table":{"capability":"機能","streamingResume":"ストリーミングとセッション再開","native":"ネイティブ","costReporting":"コストレポート","providerBilled":"プロバイダー請求額","estimated":"推定(~)","unavailable":"利用不可","telemetry":"テレメトリ(OTEL)","synthesized":"合成","agentProfiles":"エージェントプロファイル"}},"cost":{"nav":"コスト追跡","title":"1セント単位で追跡","subtitle":"課金対象のすべての呼び出しを記録・可視化","intro":"すべての AI 呼び出しでライフサイクルとプロバイダーを記録します。Kimi のように使用量やコストを報告しない場合、それらは利用不可のままです。","analyticsLabel":"分析ページ","analyticsBody":"バーンレートのヒーロー表示、日次タイムライン、トップチケット、モデル別内訳、コスト対ターン数の散布図。期間(7日 / 30日 / 90日 / 全期間)とサーフェスでフィルタできます。","perTicketLabel":"チケット別の支出","perTicketBody":"各スペックの詳細にはコストと所要ターン数が表示され、そのチケットでフィルタした分析ページへディープリンクします。","honestLabel":"正直な数字","honestBody":"Claude のコストはプロバイダー報告値、Codex と Gemini は推定の場合 <mono>~</mono> が付きます。Kimi のトークンと USD コストは 0 ではなく利用不可です。","budgetsLabel":"予算とアラート","budgetsBody":"日次予算とジョブ単位のコストアラートを設定でき、上限を超えるとアプリが自動でキューを一時停止します。すべて CSV または JSON にエクスポートできます。"},"workspace":{"nav":"ワークスペース","title":"自分のワークスペースに","subtitle":"ウィンドウを離れずに必要なものすべて","terminalLabel":"ターミナルパネル","terminalBody":"下部に VS Code 風の本物のターミナル(<mod>{{mod}}</mod> <j>J</j>)。WebGL 描画、検索、インライン画像、パスのドラッグ&ドロップ、シェル統合。プロジェクトごとに最大 10 セッション。","codeLabel":"コードエクスプローラー","codeBody":"読み取り専用のファイルツリーと Monaco ビューアー。平易な AI 要約と、ファイルごとの構築ストーリー(どのスペックが、いつ、なぜ触れたか)を表示します。","browserLabel":"内蔵ブラウザ","browserBody":"リンク、PR、開発サーバーをアプリ内で開けます。デスクトップ版ではネイティブのブラウザペインで、ポップアップも OAuth ログインを維持します。","integrationsLabel":"連携と MCP","integrationsBody":"プロジェクトごとの MCP 連携マーケットプレイス(Serena のセマンティックナビゲーションを同梱)と、アプリを自分の AI ツールへ公開する Specrails MCP サーバー。","themesLabel":"テーマとエフェクト","themesBody":"6 つの内蔵テーマ(specrails、dracula、aurora-light、obsidian-dark、code-rain、galaxy)を UI 描画前に適用。設定 → エフェクトで、エージェントの思考ハローなどの演出を切り替えられます。","chatsLabel":"最小化できるチャット","chatsBody":"Explore や AI 編集のセッションをドックのチップに退避し、後で再開。リロードやプロジェクト切り替えでも失われません。","compareLabel":"並べて比較","compareBody":"スペックを画面端へドラッグすると他のスペックのピッカーが現れ、タブレットのように 2 件を並べてレビューできます。","desktopLabel":"デスクトップかブラウザか","desktopBody":"ブラウザで Specrails を使うか、署名済みデスクトップアプリ(macOS・Windows)を入手。サーバー、Node、git、GitHub CLI を同梱しています。"},"companion":{"nav":"モバイルコンパニオン","title":"Specrails を持ち歩く","subtitle":"Specrails Companion — あなたのパイプラインを、スマートフォンで","intro":"<b>Specrails Companion</b> は specrails.dev/companion-app で使える Web アプリです — スマートフォンで開く(またはホーム画面に追加する)だけで、スペックボードの閲覧、レールの起動と停止、ジョブログのライブ追跡、分析のチェックができます。インストール不要、アプリストアも不要。","localLabel":"ほかのすべてと同じく 100% ローカル","localBody":"スマートフォンはこのコンピュータに直接接続します — ピアツーピアで暗号化(WebRTC)。クラウド中継なし、アカウント不要、コードがあなたのデバイスの外に出ることはありません。","downloadLabel":"スマートフォンで開く","downloadHint":"スマートフォンのカメラでコードをスキャンするか、ブラウザで specrails.dev/companion-app を開いてください。","open":"Specrails Companion を開く","pairLabel":"ペアリングは10秒で完了","pairBody":"スマートフォンで specrails.dev/companion-app を開き、こちらで 設定 → モバイルコンパニオン → Web コンパニオンをペアリング と進んで、画面の手順に従ってください。"},"moveFast":{"nav":"素早く動く","title":"思考の速さで動く","subtitle":"キーボードファースト、どこでも","paletteLabel":"コマンドパレット","paletteShortcut":"<f>どこでも</f> <mod>{{mod}}</mod> <m>+</m> <k>K</k> <m>を押す</m>","paletteBody":"プロジェクト切り替え、スペックコマンドの実行、任意のページへの移動、最近のジョブ検索をあいまい検索で。","agentLabel":"エージェント","agentBody":"<mod>{{mod}}</mod> <shift>Shift</shift> <a>A</a> でエージェントを表示/非表示。<shift>Shift</shift> <tab>Tab</tab> でレベルを切り替え。","terminalLabel":"ターミナルパネル","terminalBody":"<mod>{{mod}}</mod> <j>J</j> で切り替え。","shortcutsLabel":"すべてのショートカット","shortcutsBody":"<q>?</q> を押すと一覧が表示されます。","chatLabel":"右サイドバー","chatBody":"<mod>{{mod}}</mod> <bkey>B</bkey> で右サイドバーを切り替え。","projectsLabel":"プロジェクトサイドバー","projectsBody":"<alt>{{alt}}</alt> <mod>{{mod}}</mod> <bkey>B</bkey> で左の Arc サイドバーを切り替え。","pagesLabel":"番号でページとプロジェクトへ","pagesBody":"<mod>{{mod}}</mod> <n>1–9</n> でページに移動、<alt>{{alt}}</alt> <mod>{{mod}}</mod> <n>1–9</n> でプロジェクトを切り替え。","outro":"<b>ツアーは以上です。</b>ミッションのコンポーザーに作りたいものを入力するか、左サイドバーからプロジェクトを追加してください。このツアーは設定からいつでも再表示できます。"},"jira":{"label":"Jira 連携","body":"任意のプロジェクトを <b>Jira ボード</b> で裏付けます — 各スペックは Jira の課題になり、双方向で同期されます。ステータスは rail に追従し、job 完了時にコメントが投稿されます。追加時にプロジェクトごとに設定するか、いつでも設定から構成できます。"}}`),a={addProject:e,prerequisites:t,instructions:n,welcome:r,onboarding:i};export{e as addProject,a as default,n as instructions,i as onboarding,t as prerequisites,r as welcome};
@@ -1 +1 @@
1
- var e={title:`Añadir proyecto`,description:`Registra un directorio de proyecto para gestionarlo desde Specrails.`,noProviderDetected:`No se ha detectado ningún CLI de IA. Instala primero Claude Code, Codex CLI, Gemini CLI o Kimi Code.`,pathLabel:`Ruta del proyecto`,pathPlaceholder:`/Users/yo/mi-proyecto`,pathHint:`Ruta absoluta a la raíz del proyecto`,browseForFolder:`Buscar carpeta`,selectProjectFolder:`Seleccionar carpeta del proyecto`,nameLabel:`Nombre para mostrar`,optional:`(opcional)`,namePlaceholder:`Mi proyecto`,nameHint:`Por defecto, el nombre del directorio`,adding:`Añadiendo...`,submit:`Añadir proyecto`,toolsRequired_one:`Se necesita {{tools}} para añadir un proyecto`,toolsRequired_other:`Se necesitan {{tools}} para añadir un proyecto`,errors:{pathRequired:`La ruta del proyecto es obligatoria`,addFailed:`No se pudo añadir el proyecto`},toasts:{registered:`Proyecto "{{name}}" registrado`},chooser:{description:`Trae un repositorio existente o construye un proyecto nuevo desde una idea.`,existingTitle:`Proyecto existente`,existingDescription:`Registra un repositorio que ya existe en disco.`,newTitle:`Proyecto nuevo`,newDescription:`Describe una idea y recibe un repo inicializado con un backlog del Hito 1.`}},t={corruptedBundle:`bundle dañado — reinstala la app`,notInstalled:`no instalado`,failedToExecute:`encontrado pero no se pudo ejecutar`,failedToExecuteAt:`encontrado en {{path}} pero no se pudo ejecutar`,failedToExecuteWithError:`encontrado pero no se pudo ejecutar ({{error}})`,failedToExecuteAtWithError:`encontrado en {{path}} pero no se pudo ejecutar ({{error}})`,needsMinimum:`{{version}} encontrada — se necesita {{minVersion}}+`,unknownVersion:`desconocida`,installedLabel:`instalado`,verifyError:`No se pudieron verificar las herramientas de desarrollo en local — la instalación lo validará.`,allDetected:`Todas las herramientas necesarias detectadas`,bundleCorruptedTitle:`Bundle de la app dañado`,toolsRequired_one:`{{count}} herramienta de desarrollo necesaria`,toolsRequired_other:`{{count}} herramientas de desarrollo necesarias`,reinstallHint:`Reinstala la app Specrails para restaurar las herramientas incluidas.`,installMissingHint:`Instala las herramientas que faltan para continuar.`,moreInfo:`Más información`,bundledBadge:`incluida`,optional:`opcional`,ghNoAuth:"Sin sesión — ejecuta `gh auth login`"},n={title:`Instalar herramientas de desarrollo`,description:`SpecRails necesita Node.js, npm, npx y Git en el PATH. Elige el snippet de tu SO, ejecútalo y pulsa "Ya lo he instalado, volver a comprobar".`,darwin:{intro:`Homebrew te da ambas herramientas en una línea. Si no tienes brew, usa las descargas oficiales.`,installNodeGit:`Instalar Node.js y Git con Homebrew`},win32:{intro:`Winget viene incluido en Windows 11 y en las versiones recientes de Windows 10. Abre PowerShell o Terminal y ejecuta:`,installNode:`Instalar Node.js LTS`,installGit:`Instalar Git`,note:`Tras la instalación, reinicia Specrails para que Windows actualice el PATH.`},linux:{intro:`Usa el gestor de paquetes de tu distro:`,debian:`Debian / Ubuntu`,fedora:`Fedora / RHEL`},links:{nodeOfficial:`Node.js (oficial)`,gitOfficial:`Git (oficial)`,gitWindows:`Git para Windows (oficial)`},showOtherPlatforms:`Mostrar otras plataformas`,hideOtherPlatforms:`Ocultar otras plataformas`,recheck:`Ya lo he instalado, volver a comprobar`,diagnostics:{copy:`Copiar diagnóstico`,copied:`Diagnóstico copiado`,failed:`Error al copiar`},corrupted:{title:`Bundle de la app dañado`,description:`No se pudieron verificar una o más herramientas incluidas (Node.js, Git).`,body:`Esta herramienta viene incluida con la app Specrails y no puede instalarse por separado. Si ves este mensaje, el bundle de la app puede estar dañado. Reinstala Specrails.`}},r={title:`Bienvenido a <spec>spec</spec><rails>rails</rails>`,description:`Specrails gestiona varios proyectos desde una única interfaz. Añade tu primer proyecto para empezar.`,addFirstProject:`Añade tu primer proyecto`,jiraHint:`Conecta cada proyecto a su propio tablero de Jira — las specs se sincronizan en ambos sentidos.`,mcpHint:`Conecta herramientas de IA externas a Specrails mediante un servidor MCP local seguro: activado por defecto, gestiónalo en Ajustes → MCP.`,agentChatHint:`Opera Specrails conversando — un agente integrado gestiona specs, rails y analíticas por ti a través del MCP local. Ábrelo desde la burbuja o con ⌘⇧A.`,localEnginesHint:`¿Solo un modelo local? Añade un endpoint compatible con OpenAI en Ajustes → Specrails Agents y todas las superficies — rails, chat, misiones — lo usarán por defecto.`},i=JSON.parse(`{"productTour":"Tour del producto","stepCount":"Paso {{current}} de {{total}}","goToStep":"Ir al paso {{step}}: {{label}}","stepLabel":"Paso {{step}}","dontShowAgain":"No volver a mostrar","skipTour":"Saltar el tour","getStarted":"Empezar","flow":{"architect":"Arquitecto","developer":"Desarrollador","reviewer":"Revisor","describe":"Describe","specs":"Specs","rails":"Rails","review":"Revisa y fusiona","yourReview":"Tu revisión","blueprint":"Blueprint","approve":"Aprobar","m1Specs":"Specs del Hito 1","milestones":"Hitos"},"language":{"nav":"Idioma","title":"Elige tu idioma","subtitle":"Specrails habla tu idioma","intro":"Selecciona el idioma en el que quieres la interfaz. Se aplica al instante — este tour incluido.","note":"Puedes cambiarlo cuando quieras en Ajustes → Idioma."},"theme":{"nav":"Tema","title":"Elige tu estilo","subtitle":"Temas integrados, aplicados al instante","intro":"Decide qué aspecto tendrá Specrails — el tema se aplica en cuanto haces clic.","note":"Puedes cambiarlo cuando quieras en Ajustes → Apariencia."},"welcome":{"nav":"Bienvenida","title":"Bienvenido a Specrails","subtitle":"Tu cabina local para entregar software con agentes de IA","intro":"Specrails convierte una idea en código entregado, y te deja <b>ver, dirigir y confiar</b> en cada paso. Describe lo que quieres, obtén specs precisas, ejecútalas en rails con Claude Code, Codex, Gemini o Kimi y decide qué fusionar. Nada se fusiona sin ti.","coreLoopLabel":"El bucle central","flowCaption":"<b>Describe → Specs → Rails → Revisa y fusiona</b>. Cada paso se transmite en vivo y cada resultado espera tu decisión.","missionLabel":"Modo Misión: el predeterminado","missionBody":"Una conversación gobierna toda la app: el agente redacta specs, lanza rails, consulta el gasto y te entrega tarjetas de decisión. <b>Tú hablas, él opera.</b>","boardLabel":"Modo Tablero: a un clic","boardBody":"El panel clásico: tablero de specs, rails, jobs, analítica. Cambia entre ambos con el interruptor de la barra lateral izquierda: <b>mismos proyectos, mismos datos</b>.","localNote":"<b>100 % local · un solo usuario · sin cuentas.</b> Todo corre en tu máquina. Tu código nunca sale del portátil a menos que <i>tú</i> lances un agente sobre él.","tourNote":"Este recorrido rápido repasa todo lo que puede hacer la app: unos dos minutos."},"mission":{"nav":"Modo Misión","title":"Habla; el agente opera","subtitle":"El modo Misión es la superficie predeterminada","intro":"En el <b>modo Misión</b> toda la ventana es una conversación con un agente que maneja Specrails a través de sus propias <b>herramientas MCP</b>: «lanza las tres specs de mayor prioridad», «¿cuánto gasté esta semana?», «escríbeme una spec para el modo oscuro». Todo lo que hace es en vivo: rails, specs y tarjetas se actualizan mientras trabaja.","missionsLabel":"Misiones y proyectos","missionsBody":"Cada conversación es una misión anclada a un proyecto (o a Inicio para todo). Cambia de misión desde la cabecera y envía mensajes a mitad de turno: se encolan y se ejecutan en orden.","levelsLabel":"Tú llevas la correa","levelsBody":"Un nivel en vivo, <b>Observar → Editar → Operar → Autónomo</b>, que se recorre con <shift>Shift</shift> <tab>Tab</tab>, limita hasta dónde puede llegar. Nunca actúa por encima del nivel que fijes.","cardsLabel":"Tarjetas de decisión","cardsBody":"Los lanzamientos aparecen como tarjetas en vivo fijadas sobre el composer: progreso del rail y luego Crear PR / Integrar en local / Descartar, con una Revisión en lenguaje llano. Los números de spec, jobs y loops de las respuestas son clicables.","workspaceLabel":"Un workspace al lado","workspaceBody":"La barra lateral derecha abre Blueprint, Jobs, Analítica, un navegador integrado, la terminal y el explorador de código junto a la conversación, sin cambiar de contexto.","mcpLabel":"Funciona sobre el MCP local","mcpBody":"El agente trabaja a través del servidor MCP embebido de Specrails, <b>activado por defecto</b> y solo en loopback. Ese mismo servidor permite que tus propias herramientas (Claude Desktop, Cursor…) manejen Specrails; gestiónalo en Ajustes → MCP."},"builder":{"nav":"Proyecto nuevo","title":"Arranca un proyecto desde una idea","subtitle":"El Constructor: blueprint, specs e hitos antes de que exista una línea de código","intro":"Añadir proyecto → <b>Nuevo</b> convierte al agente en el <b>Constructor de proyectos</b>. Describe la idea; te entrevista brevemente (o lo decide todo con un clic), propone producto, flujo principal, plataforma, stack e hitos, y tú apruebas o retocas.","flowLabel":"De la idea al backlog","flowCaption":"El commit crea el repositorio, el workspace y el backlog del Hito 1; opcionalmente también un repo privado en GitHub.","cardsLabel":"Decisiones de un clic","cardsBody":"«Sorpréndeme» y «Aprobar y generar specs» aparecen como tarjetas en el hilo; cada decisión que tomas queda fija ahí como registro.","specsLabel":"Specs premium, auditadas con honestidad","specsBody":"Las specs del Hito 1 se escriben al completo de dos en dos y luego se audita todo el lote (problema, solución, alcance, consideraciones técnicas, seis o más criterios de aceptación) y una puerta determinista bloquea cualquier spec pobre.","milestonesLabel":"Hitos sobre rails","milestonesBody":"Lanza el Hito 1 y corre como rails de hasta tres specs, cada uno apilado sobre la rama del anterior. Los <b>puntos de control por oleada</b> preguntan antes de cada rail siguiente, o activa continuar automáticamente.","progressLabel":"Progreso en vivo","progressBody":"El panel Blueprint muestra recuentos reales (entregadas, en revisión, hechas), nunca «completo» mientras algo esté sin fusionar. Los hitos posteriores se generan contra el repositorio real."},"authorSpecs":{"nav":"Redactar specs","title":"Convierte ideas en specs","subtitle":"Seis formas de capturar exactamente lo que quieres construir","intro":"Una <b>spec</b> es la descripción de un trabajo que quieres hecho. Redáctala como convenga al momento: desde una línea hasta que el agente investigue por ti.","agentLabel":"Pídesela al agente","agentBody":"En modo Misión, describe el cambio. El agente lee primero el código real, redacta una super spec como tarjeta en vivo y la guarda cuando tú lo digas.","exploreLabel":"Explorar: conversa","exploreBody":"Describe lo que quieres en un chat; un borrador en vivo se reconstruye en cada turno. Un selector de presets ajusta cuánto contexto del proyecto ve la IA: desde solo tu mensaje hasta todo el código más tus servidores MCP.","quickLabel":"Rápida: de una vez","quickBody":"¿Ya sabes lo que quieres? Genera una spec completa en un solo turno. Opcionalmente enriquécela con una Capa de Contrato: nombres exactos, formas de datos, invariantes y lista de archivos para que los agentes no reinventen nada.","websiteLabel":"Desde una web","websiteBody":"Abre un navegador integrado. Selecciona un elemento o dibuja un rectángulo, y la captura, el DOM y el CSS aplicado se convierten en adjuntos.","smashLabel":"SMASH a una épica","smashBody":"Explota una spec grande en una familia de sub-specs más pequeñas con un clic; cada hija lleva un resumen breve en su tarjeta.","draftsLabel":"Borradores y seguir editando","draftsBody":"Aparca una exploración en curso como ticket borrador y retómala después; reabre cualquier spec en Explorar para seguir refinándola."},"rails":{"nav":"Rails y revisión","title":"Ejecuta la pipeline sobre rails","subtitle":"Carriles aislados y una revisión que de verdad se puede leer","intro":"Los <b>rails</b> son carriles de ejecución: hasta doce, creados bajo demanda. Suelta specs en un rail y pulsa <play>▶ Play</play>, o <b>Lanzar todo</b> los rails libres en paralelo. Cada run trabaja en su propio worktree de git, nunca en tu checkout.","jobLabel":"Qué hace cada run","flowCaption":"Cada fase se transmite en vivo. Al final el trabajo se queda en su rama y la app te pregunta qué hacer: Specrails produce PRs, nunca fusiona por su cuenta.","reviewLabel":"Revisión de PR que pregunta primero","reviewBody":"Las specs terminadas quedan <b>En revisión</b>. Tú eliges: crear un PR en borrador, integrar en local (sin remoto) o descartar. Fusionar las pasa a Hecho.","packetLabel":"Paquete de revisión","packetBody":"Una página en lenguaje llano por entrega: qué se pidió, qué cambió, qué informa la IA frente a lo que la app verificó, el coste, con Aceptar / Pedir cambios / Descartar.","steerLabel":"Dirige a mitad de run","steerBody":"Los runs de Claude son interactivos: pregunta o redirige mientras trabajan, y sigue un progreso narrado en lugar de logs en crudo.","loopsLabel":"Construye tus propios loops","loopsBody":"<b>Loops</b> es un constructor visual: encadena pasos de IA, comandos de shell y un <b>Loop Decider</b> que repite hasta cumplir el objetivo. Implement, Batch y Freestyle vienen listos para usar.","profilesLabel":"Perfiles de agente y defaults","profilesBody":"Decide qué agentes corren y qué modelo usa cada uno: por perfil de proyecto, por rail, o una vez para toda la máquina en Ajustes → Agentes de Specrails.","isolationLabel":"Muchos proyectos, aislados","isolationBody":"Cada proyecto tiene su propia base de datos y su cola; tu repositorio queda intacto porque Specrails guarda sus archivos bajo tu carpeta de usuario."},"providers":{"nav":"Tu agente","title":"Trae tu propio agente","subtitle":"Claude Code, Codex, Gemini y Kimi como motores de primera clase","intro":"<b>Claude Code</b>, <b>Codex CLI</b>, <b>Gemini CLI</b> y <b>Kimi Code</b> son motores intercambiables tras un mismo contrato. Lo que esté instalado y con sesión iniciada en esta máquina se detecta automáticamente y se ofrece en todas partes; nada que configurar por proyecto.","calloutLabel":"Cuando hay varios instalados","calloutBody":"Elige el motor <b>por spec, por rail, por misión o por lanzamiento de terminal</b>; la app recuerda tu última elección por proyecto. Los costes estimados se marcan con <mono>~</mono>; Kimi no informa tokens ni coste.","table":{"capability":"Capacidad","streamingResume":"Streaming y reanudación de sesión","native":"Nativo","costReporting":"Informe de costes","providerBilled":"Facturado por el proveedor","estimated":"Estimado (~)","unavailable":"No disponible","telemetry":"Telemetría (OTEL)","synthesized":"Sintetizada","agentProfiles":"Perfiles de agentes"}},"cost":{"nav":"Controla el coste","title":"Controla cada céntimo","subtitle":"Cada invocación facturable, registrada y visualizada","intro":"Cada invocación de IA — en rails, Quick, Explore, ediciones con IA, SMASH y resúmenes de archivos — registra su ciclo de vida y proveedor. El uso y el coste quedan no disponibles cuando el proveedor, como Kimi, no los informa.","analyticsLabel":"Página de analítica","analyticsBody":"Un hero de burn-rate, línea temporal diaria, top de tickets, desglose por modelo y un scatter de coste frente a turnos. Filtra por periodo (7d / 30d / 90d / Todo) y por superficie.","perTicketLabel":"Gasto por ticket","perTicketBody":"El detalle de cada spec muestra cuánto costó y cuántos turnos llevó, con enlace directo a la analítica filtrada por ese ticket.","honestLabel":"Números honestos","honestBody":"El coste de Claude es el facturado por el proveedor; Codex y Gemini pueden estimarse y se marcan con <mono>~</mono>. Kimi no informa de tokens ni coste USD nativo, así que esos campos aparecen como no disponibles, no como cero.","budgetsLabel":"Presupuestos y alertas","budgetsBody":"Define un presupuesto diario y una alerta de coste por job; la aplicación pausa la cola automáticamente cuando cruzas la línea. Exporta lo que quieras a CSV o JSON."},"workspace":{"nav":"Workspace","title":"Hazlo tu workspace","subtitle":"Todo lo que necesitas sin salir de la ventana","terminalLabel":"Panel de terminal","terminalBody":"Una terminal real estilo VS Code abajo (<mod>{{mod}}</mod> <j>J</j>): renderizado WebGL, búsqueda, imágenes en línea, rutas por arrastre e integración con la shell. Hasta 10 sesiones por proyecto.","codeLabel":"Explorador de código","codeBody":"Árbol de archivos de solo lectura y visor Monaco con resúmenes de IA en lenguaje llano y una historia de construcción por archivo: qué spec lo tocó, cuándo y por qué.","browserLabel":"Navegador integrado","browserBody":"Abre enlaces, PRs y tu servidor de desarrollo dentro de la app: un panel de navegador nativo en la versión de escritorio, con popups que mantienen los inicios de sesión OAuth.","integrationsLabel":"Integraciones y MCP","integrationsBody":"Un marketplace por proyecto de integraciones MCP (la navegación semántica de Serena viene incluida), más el servidor MCP de Specrails que expone la app a tus propias herramientas de IA.","themesLabel":"Temas y efectos","themesBody":"Seis temas integrados (specrails, dracula, aurora-light, obsidian-dark, code-rain y galaxy) aplicados antes de pintar la interfaz. Ajustes → Efectos activa detalles visuales como el halo de pensamiento del agente.","chatsLabel":"Chats minimizables","chatsBody":"Aparca una sesión de Explorar o de Edición con IA en un chip del dock y retómala después; nunca se pierde entre recargas o cambios de proyecto.","compareLabel":"Compara lado a lado","compareBody":"Arrastra una spec al borde de la pantalla y aparece un selector con tus otras specs: revisa dos juntas, al estilo tableta.","desktopLabel":"Escritorio o navegador","desktopBody":"Usa Specrails en tu navegador o descarga la app de escritorio firmada (macOS y Windows), que incluye su propio servidor, Node, git y la CLI de GitHub."},"companion":{"nav":"Compañera móvil","title":"Llévate Specrails contigo","subtitle":"Specrails Companion — tus pipelines, en tu teléfono","intro":"<b>Specrails Companion</b> es una app web en specrails.dev/companion-app — ábrela en tu teléfono (o añádela a tu pantalla de inicio) para navegar por el tablero de specs, lanzar y detener rails, seguir los logs de los jobs en directo y echar un vistazo a la analítica. Sin instalación, sin tienda de apps.","localLabel":"100 % local, como todo lo demás","localBody":"Tu teléfono se conecta directamente a este ordenador — peer-to-peer y cifrado (WebRTC). Sin servidores intermedios en la nube, sin cuentas, y tu código nunca sale de tus dispositivos.","downloadLabel":"Ábrela en tu teléfono","downloadHint":"Escanea el código con la cámara de tu teléfono o abre specrails.dev/companion-app en su navegador.","open":"Abrir Specrails Companion","pairLabel":"Emparejar lleva diez segundos","pairBody":"En tu teléfono abre specrails.dev/companion-app y luego, aquí, ve a Ajustes → Compañera móvil → Emparejar compañera web y sigue los pasos en pantalla."},"moveFast":{"nav":"Ve rápido","title":"Muévete a la velocidad del pensamiento","subtitle":"Teclado primero, en todas partes","paletteLabel":"Paleta de comandos","paletteShortcut":"<f>Pulsa</f> <mod>{{mod}}</mod> <m>+</m> <k>K</k> <m>en cualquier sitio</m>","paletteBody":"Cambia de proyecto, ejecuta comandos de spec, salta a cualquier página y encuentra jobs recientes, todo con búsqueda difusa.","agentLabel":"Agente","agentBody":"Muestra u oculta el agente con <mod>{{mod}}</mod> <shift>Shift</shift> <a>A</a>; recorre su nivel con <shift>Shift</shift> <tab>Tab</tab>.","terminalLabel":"Panel de terminal","terminalBody":"Alterna con <mod>{{mod}}</mod> <j>J</j>.","shortcutsLabel":"Todos los atajos","shortcutsBody":"Pulsa <q>?</q> para ver la chuleta completa.","chatLabel":"Barra lateral derecha","chatBody":"Alterna la barra lateral derecha con <mod>{{mod}}</mod> <bkey>B</bkey>.","projectsLabel":"Barra de proyectos","projectsBody":"Alterna la barra Arc izquierda con <alt>{{alt}}</alt> <mod>{{mod}}</mod> <bkey>B</bkey>.","pagesLabel":"Páginas y proyectos por número","pagesBody":"<mod>{{mod}}</mod> <n>1–9</n> salta a una página; <alt>{{alt}}</alt> <mod>{{mod}}</mod> <n>1–9</n> cambia de proyecto.","outro":"<b>Fin del recorrido.</b> Escribe lo que quieres construir en el composer de la misión o añade un proyecto desde la barra izquierda. Puedes reabrir este recorrido cuando quieras desde Ajustes."},"jira":{"label":"Integración con Jira","body":"Respalda cualquier proyecto con un <b>tablero de Jira</b> — cada spec es un issue de Jira, sincronizado en ambos sentidos: el estado sigue al rail y se publica un comentario al terminar un job. Configúralo por proyecto al añadirlo, o cuando quieras en Ajustes."}}`),a={addProject:e,prerequisites:t,instructions:n,welcome:r,onboarding:i};export{e as addProject,a as default,n as instructions,i as onboarding,t as prerequisites,r as welcome};
1
+ var e={title:`Añadir proyecto`,description:`Registra un directorio de proyecto para gestionarlo desde Specrails.`,noProviderDetected:`No se ha detectado ningún CLI de IA. Instala primero Claude Code, Codex CLI, Gemini CLI o Kimi Code.`,pathLabel:`Ruta del proyecto`,pathPlaceholder:`/Users/yo/mi-proyecto`,pathHint:`Ruta absoluta a la raíz del proyecto`,browseForFolder:`Buscar carpeta`,selectProjectFolder:`Seleccionar carpeta del proyecto`,nameLabel:`Nombre para mostrar`,optional:`(opcional)`,namePlaceholder:`Mi proyecto`,nameHint:`Por defecto, el nombre del directorio`,adding:`Añadiendo...`,submit:`Añadir proyecto`,toolsRequired_one:`Se necesita {{tools}} para añadir un proyecto`,toolsRequired_other:`Se necesitan {{tools}} para añadir un proyecto`,errors:{pathRequired:`La ruta del proyecto es obligatoria`,addFailed:`No se pudo añadir el proyecto`},toasts:{registered:`Proyecto "{{name}}" registrado`},chooser:{description:`Trae un repositorio existente o construye un proyecto nuevo desde una idea.`,existingTitle:`Proyecto existente`,existingDescription:`Registra un repositorio que ya existe en disco.`,newTitle:`Proyecto nuevo`,newDescription:`Describe una idea y recibe un repo inicializado con un backlog del Hito 1.`}},t={corruptedBundle:`bundle dañado — reinstala la app`,notInstalled:`no instalado`,failedToExecute:`encontrado pero no se pudo ejecutar`,failedToExecuteAt:`encontrado en {{path}} pero no se pudo ejecutar`,failedToExecuteWithError:`encontrado pero no se pudo ejecutar ({{error}})`,failedToExecuteAtWithError:`encontrado en {{path}} pero no se pudo ejecutar ({{error}})`,needsMinimum:`{{version}} encontrada — se necesita {{minVersion}}+`,unknownVersion:`desconocida`,installedLabel:`instalado`,verifyError:`No se pudieron verificar las herramientas de desarrollo en local — la instalación lo validará.`,allDetected:`Todas las herramientas necesarias detectadas`,bundleCorruptedTitle:`Bundle de la app dañado`,toolsRequired_one:`{{count}} herramienta de desarrollo necesaria`,toolsRequired_other:`{{count}} herramientas de desarrollo necesarias`,reinstallHint:`Reinstala la app Specrails para restaurar las herramientas incluidas.`,installMissingHint:`Instala las herramientas que faltan para continuar.`,moreInfo:`Más información`,bundledBadge:`incluida`,optional:`opcional`,ghNoAuth:"Sin sesión — ejecuta `gh auth login`"},n={title:`Instalar herramientas de desarrollo`,description:`SpecRails necesita Node.js, npm, npx y Git en el PATH. Elige el snippet de tu SO, ejecútalo y pulsa "Ya lo he instalado, volver a comprobar".`,darwin:{intro:`Homebrew te da ambas herramientas en una línea. Si no tienes brew, usa las descargas oficiales.`,installNodeGit:`Instalar Node.js y Git con Homebrew`},win32:{intro:`Winget viene incluido en Windows 11 y en las versiones recientes de Windows 10. Abre PowerShell o Terminal y ejecuta:`,installNode:`Instalar Node.js LTS`,installGit:`Instalar Git`,note:`Tras la instalación, reinicia Specrails para que Windows actualice el PATH.`},linux:{intro:`Usa el gestor de paquetes de tu distro:`,debian:`Debian / Ubuntu`,fedora:`Fedora / RHEL`},links:{nodeOfficial:`Node.js (oficial)`,gitOfficial:`Git (oficial)`,gitWindows:`Git para Windows (oficial)`},showOtherPlatforms:`Mostrar otras plataformas`,hideOtherPlatforms:`Ocultar otras plataformas`,recheck:`Ya lo he instalado, volver a comprobar`,diagnostics:{copy:`Copiar diagnóstico`,copied:`Diagnóstico copiado`,failed:`Error al copiar`},corrupted:{title:`Bundle de la app dañado`,description:`No se pudieron verificar una o más herramientas incluidas (Node.js, Git).`,body:`Esta herramienta viene incluida con la app Specrails y no puede instalarse por separado. Si ves este mensaje, el bundle de la app puede estar dañado. Reinstala Specrails.`}},r={title:`Bienvenido a <spec>spec</spec><rails>rails</rails>`,description:`Specrails gestiona varios proyectos desde una única interfaz. Añade tu primer proyecto para empezar.`,addFirstProject:`Añade tu primer proyecto`,jiraHint:`Conecta cada proyecto a su propio tablero de Jira — las specs se sincronizan en ambos sentidos.`,mcpHint:`Conecta herramientas de IA externas a Specrails mediante un servidor MCP local seguro: activado por defecto, gestiónalo en Ajustes → MCP.`,agentChatHint:`Opera Specrails conversando — un agente integrado gestiona specs, rails y analíticas por ti a través del MCP local. Ábrelo desde la burbuja o con ⌘⇧A.`,localEnginesHint:`¿Solo un modelo local? Añade un endpoint compatible con OpenAI en Ajustes → Specrails Agents y todas las superficies — rails, chat, misiones — lo usarán por defecto.`},i=JSON.parse(`{"productTour":"Tour del producto","stepCount":"Paso {{current}} de {{total}}","goToStep":"Ir al paso {{step}}: {{label}}","stepLabel":"Paso {{step}}","dontShowAgain":"No volver a mostrar","skipTour":"Saltar el tour","getStarted":"Empezar","flow":{"architect":"Arquitecto","developer":"Desarrollador","reviewer":"Revisor","describe":"Describe","specs":"Specs","rails":"Rails","review":"Revisa y fusiona","yourReview":"Tu revisión","blueprint":"Blueprint","approve":"Aprobar","m1Specs":"Specs del Hito 1","milestones":"Hitos"},"language":{"nav":"Idioma","title":"Elige tu idioma","subtitle":"Specrails habla tu idioma","intro":"Selecciona el idioma en el que quieres la interfaz. Se aplica al instante — este tour incluido.","note":"Puedes cambiarlo cuando quieras en Ajustes → Idioma."},"theme":{"nav":"Tema","title":"Elige tu estilo","subtitle":"Temas integrados, aplicados al instante","intro":"Decide qué aspecto tendrá Specrails — el tema se aplica en cuanto haces clic.","note":"Puedes cambiarlo cuando quieras en Ajustes → Apariencia."},"welcome":{"nav":"Bienvenida","title":"Bienvenido a Specrails","subtitle":"Tu cabina local para entregar software con agentes de IA","intro":"Specrails convierte una idea en código entregado, y te deja <b>ver, dirigir y confiar</b> en cada paso. Describe lo que quieres, obtén specs precisas, ejecútalas en rails con Claude Code, Codex, Gemini o Kimi y decide qué fusionar. Nada se fusiona sin ti.","coreLoopLabel":"El bucle central","flowCaption":"<b>Describe → Specs → Rails → Revisa y fusiona</b>. Cada paso se transmite en vivo y cada resultado espera tu decisión.","missionLabel":"Modo Misión: el predeterminado","missionBody":"Una conversación gobierna toda la app: el agente redacta specs, lanza rails, consulta el gasto y te entrega tarjetas de decisión. <b>Tú hablas, él opera.</b>","boardLabel":"Modo Tablero: a un clic","boardBody":"El panel clásico: tablero de specs, rails, jobs, analítica. Cambia entre ambos con el interruptor de la barra lateral izquierda: <b>mismos proyectos, mismos datos</b>.","localNote":"<b>100 % local · un solo usuario · sin cuentas.</b> Todo corre en tu máquina. Tu código nunca sale del portátil a menos que <i>tú</i> lances un agente sobre él.","tourNote":"Este recorrido rápido repasa todo lo que puede hacer la app: unos dos minutos."},"mission":{"nav":"Modo Misión","title":"Habla; el agente opera","subtitle":"El modo Misión es la superficie predeterminada","intro":"En el <b>modo Misión</b> toda la ventana es una conversación con un agente que maneja Specrails a través de sus propias <b>herramientas MCP</b>: «lanza las tres specs de mayor prioridad», «¿cuánto gasté esta semana?», «escríbeme una spec para el modo oscuro». Todo lo que hace es en vivo: rails, specs y tarjetas se actualizan mientras trabaja.","missionsLabel":"Misiones y proyectos","missionsBody":"Cada conversación es una misión anclada a un proyecto (o a Inicio para todo). Cambia de misión desde la cabecera y envía mensajes a mitad de turno: se encolan y se ejecutan en orden.","levelsLabel":"Tú llevas la correa","levelsBody":"Un nivel en vivo, <b>Observar → Editar → Operar → Autónomo</b>, que se recorre con <shift>Shift</shift> <tab>Tab</tab>, limita hasta dónde puede llegar. Nunca actúa por encima del nivel que fijes.","cardsLabel":"Tarjetas de decisión","cardsBody":"Los lanzamientos aparecen como tarjetas en vivo fijadas sobre el composer: progreso del rail y luego Crear PR / Integrar en local / Descartar, con una Revisión en lenguaje llano. Los números de spec, jobs y loops de las respuestas son clicables.","workspaceLabel":"Un workspace al lado","workspaceBody":"La barra lateral derecha abre Blueprint, Jobs, Analítica, un navegador integrado, la terminal y el explorador de código junto a la conversación, sin cambiar de contexto.","mcpLabel":"Funciona sobre el MCP local","mcpBody":"El agente trabaja a través del servidor MCP embebido de Specrails, <b>activado por defecto</b> y solo en loopback. Ese mismo servidor permite que tus propias herramientas (Claude Desktop, Cursor…) manejen Specrails; gestiónalo en Ajustes → MCP."},"builder":{"nav":"Proyecto nuevo","title":"Arranca un proyecto desde una idea","subtitle":"El Constructor: blueprint, specs e hitos antes de que exista una línea de código","intro":"Añadir proyecto → <b>Nuevo</b> convierte al agente en el <b>Constructor de proyectos</b>. Describe la idea; te entrevista brevemente (o lo decide todo con un clic), propone producto, flujo principal, plataforma, stack e hitos, y tú apruebas o retocas.","flowLabel":"De la idea al backlog","flowCaption":"El commit crea el repositorio, el workspace y el backlog del Hito 1; opcionalmente también un repo privado en GitHub.","cardsLabel":"Decisiones de un clic","cardsBody":"«Sorpréndeme» y «Aprobar y generar specs» aparecen como tarjetas en el hilo; cada decisión que tomas queda fija ahí como registro.","specsLabel":"Specs premium, auditadas con honestidad","specsBody":"Las specs del Hito 1 se escriben al completo de dos en dos y luego se audita todo el lote (problema, solución, alcance, consideraciones técnicas, seis o más criterios de aceptación) y una puerta determinista bloquea cualquier spec pobre.","milestonesLabel":"Hitos sobre rails","milestonesBody":"Lanza el Hito 1 y corre como rails de hasta tres specs, cada uno apilado sobre la rama del anterior. Los <b>puntos de control por oleada</b> preguntan antes de cada rail siguiente, o activa continuar automáticamente.","progressLabel":"Progreso en vivo","progressBody":"El panel Blueprint muestra recuentos reales (entregadas, en revisión, hechas), nunca «completo» mientras algo esté sin fusionar. Los hitos posteriores se generan contra el repositorio real."},"authorSpecs":{"nav":"Redactar specs","title":"Convierte ideas en specs","subtitle":"Seis formas de capturar exactamente lo que quieres construir","intro":"Una <b>spec</b> es la descripción de un trabajo que quieres hecho. Redáctala como convenga al momento: desde una línea hasta que el agente investigue por ti.","agentLabel":"Pídesela al agente","agentBody":"En modo Misión, describe el cambio. El agente lee primero el código real, redacta una super spec como tarjeta en vivo y la guarda cuando tú lo digas.","exploreLabel":"Explorar: conversa","exploreBody":"Describe lo que quieres en un chat; un borrador en vivo se reconstruye en cada turno. Un selector de presets ajusta cuánto contexto del proyecto ve la IA: desde solo tu mensaje hasta todo el código más tus servidores MCP.","quickLabel":"Rápida: de una vez","quickBody":"¿Ya sabes lo que quieres? Genera una spec completa en un solo turno. Opcionalmente enriquécela con una Capa de Contrato: nombres exactos, formas de datos, invariantes y lista de archivos para que los agentes no reinventen nada.","websiteLabel":"Desde una web","websiteBody":"Abre un navegador integrado. Selecciona un elemento o dibuja un rectángulo, y la captura, el DOM y el CSS aplicado se convierten en adjuntos.","smashLabel":"SMASH a una épica","smashBody":"Explota una spec grande en una familia de sub-specs más pequeñas con un clic; cada hija lleva un resumen breve en su tarjeta.","draftsLabel":"Borradores y seguir editando","draftsBody":"Aparca una exploración en curso como ticket borrador y retómala después; reabre cualquier spec en Explorar para seguir refinándola."},"rails":{"nav":"Rails y revisión","title":"Ejecuta la pipeline sobre rails","subtitle":"Carriles aislados y una revisión que de verdad se puede leer","intro":"Los <b>rails</b> son carriles de ejecución: hasta doce, creados bajo demanda. Suelta specs en un rail y pulsa <play>▶ Play</play>, o <b>Lanzar todo</b> los rails libres en paralelo. Cada run trabaja en su propio worktree de git, nunca en tu checkout.","jobLabel":"Qué hace cada run","flowCaption":"Cada fase se transmite en vivo. Al final el trabajo se queda en su rama y la app te pregunta qué hacer: Specrails produce PRs, nunca fusiona por su cuenta.","reviewLabel":"Revisión de PR que pregunta primero","reviewBody":"Las specs terminadas quedan <b>En revisión</b>. Tú eliges: crear un PR en borrador, integrar en local (sin remoto) o descartar. Fusionar las pasa a Hecho.","packetLabel":"Paquete de revisión","packetBody":"Una página en lenguaje llano por entrega: qué se pidió, qué cambió, qué informa la IA frente a lo que la app verificó, el coste, con Aceptar / Pedir cambios / Descartar.","steerLabel":"Dirige a mitad de run","steerBody":"Los runs de Claude son interactivos: pregunta o redirige mientras trabajan, y sigue un progreso narrado en lugar de logs en crudo.","loopsLabel":"Construye tus propios loops","loopsBody":"<b>Loops</b> es un constructor visual: encadena pasos de IA, comandos de shell y un <b>Loop Decider</b> que repite hasta cumplir el objetivo. Implement y Freestyle vienen listos para usar.","profilesLabel":"Perfiles de agente y defaults","profilesBody":"Decide qué agentes corren y qué modelo usa cada uno: por perfil de proyecto, por rail, o una vez para toda la máquina en Ajustes → Agentes de Specrails.","isolationLabel":"Muchos proyectos, aislados","isolationBody":"Cada proyecto tiene su propia base de datos y su cola; tu repositorio queda intacto porque Specrails guarda sus archivos bajo tu carpeta de usuario."},"providers":{"nav":"Tu agente","title":"Trae tu propio agente","subtitle":"Claude Code, Codex, Gemini y Kimi como motores de primera clase","intro":"<b>Claude Code</b>, <b>Codex CLI</b>, <b>Gemini CLI</b> y <b>Kimi Code</b> son motores intercambiables tras un mismo contrato. Lo que esté instalado y con sesión iniciada en esta máquina se detecta automáticamente y se ofrece en todas partes; nada que configurar por proyecto.","calloutLabel":"Cuando hay varios instalados","calloutBody":"Elige el motor <b>por spec, por rail, por misión o por lanzamiento de terminal</b>; la app recuerda tu última elección por proyecto. Los costes estimados se marcan con <mono>~</mono>; Kimi no informa tokens ni coste.","table":{"capability":"Capacidad","streamingResume":"Streaming y reanudación de sesión","native":"Nativo","costReporting":"Informe de costes","providerBilled":"Facturado por el proveedor","estimated":"Estimado (~)","unavailable":"No disponible","telemetry":"Telemetría (OTEL)","synthesized":"Sintetizada","agentProfiles":"Perfiles de agentes"}},"cost":{"nav":"Controla el coste","title":"Controla cada céntimo","subtitle":"Cada invocación facturable, registrada y visualizada","intro":"Cada invocación de IA — en rails, Quick, Explore, ediciones con IA, SMASH y resúmenes de archivos — registra su ciclo de vida y proveedor. El uso y el coste quedan no disponibles cuando el proveedor, como Kimi, no los informa.","analyticsLabel":"Página de analítica","analyticsBody":"Un hero de burn-rate, línea temporal diaria, top de tickets, desglose por modelo y un scatter de coste frente a turnos. Filtra por periodo (7d / 30d / 90d / Todo) y por superficie.","perTicketLabel":"Gasto por ticket","perTicketBody":"El detalle de cada spec muestra cuánto costó y cuántos turnos llevó, con enlace directo a la analítica filtrada por ese ticket.","honestLabel":"Números honestos","honestBody":"El coste de Claude es el facturado por el proveedor; Codex y Gemini pueden estimarse y se marcan con <mono>~</mono>. Kimi no informa de tokens ni coste USD nativo, así que esos campos aparecen como no disponibles, no como cero.","budgetsLabel":"Presupuestos y alertas","budgetsBody":"Define un presupuesto diario y una alerta de coste por job; la aplicación pausa la cola automáticamente cuando cruzas la línea. Exporta lo que quieras a CSV o JSON."},"workspace":{"nav":"Workspace","title":"Hazlo tu workspace","subtitle":"Todo lo que necesitas sin salir de la ventana","terminalLabel":"Panel de terminal","terminalBody":"Una terminal real estilo VS Code abajo (<mod>{{mod}}</mod> <j>J</j>): renderizado WebGL, búsqueda, imágenes en línea, rutas por arrastre e integración con la shell. Hasta 10 sesiones por proyecto.","codeLabel":"Explorador de código","codeBody":"Árbol de archivos de solo lectura y visor Monaco con resúmenes de IA en lenguaje llano y una historia de construcción por archivo: qué spec lo tocó, cuándo y por qué.","browserLabel":"Navegador integrado","browserBody":"Abre enlaces, PRs y tu servidor de desarrollo dentro de la app: un panel de navegador nativo en la versión de escritorio, con popups que mantienen los inicios de sesión OAuth.","integrationsLabel":"Integraciones y MCP","integrationsBody":"Un marketplace por proyecto de integraciones MCP (la navegación semántica de Serena viene incluida), más el servidor MCP de Specrails que expone la app a tus propias herramientas de IA.","themesLabel":"Temas y efectos","themesBody":"Seis temas integrados (specrails, dracula, aurora-light, obsidian-dark, code-rain y galaxy) aplicados antes de pintar la interfaz. Ajustes → Efectos activa detalles visuales como el halo de pensamiento del agente.","chatsLabel":"Chats minimizables","chatsBody":"Aparca una sesión de Explorar o de Edición con IA en un chip del dock y retómala después; nunca se pierde entre recargas o cambios de proyecto.","compareLabel":"Compara lado a lado","compareBody":"Arrastra una spec al borde de la pantalla y aparece un selector con tus otras specs: revisa dos juntas, al estilo tableta.","desktopLabel":"Escritorio o navegador","desktopBody":"Usa Specrails en tu navegador o descarga la app de escritorio firmada (macOS y Windows), que incluye su propio servidor, Node, git y la CLI de GitHub."},"companion":{"nav":"Compañera móvil","title":"Llévate Specrails contigo","subtitle":"Specrails Companion — tus pipelines, en tu teléfono","intro":"<b>Specrails Companion</b> es una app web en specrails.dev/companion-app — ábrela en tu teléfono (o añádela a tu pantalla de inicio) para navegar por el tablero de specs, lanzar y detener rails, seguir los logs de los jobs en directo y echar un vistazo a la analítica. Sin instalación, sin tienda de apps.","localLabel":"100 % local, como todo lo demás","localBody":"Tu teléfono se conecta directamente a este ordenador — peer-to-peer y cifrado (WebRTC). Sin servidores intermedios en la nube, sin cuentas, y tu código nunca sale de tus dispositivos.","downloadLabel":"Ábrela en tu teléfono","downloadHint":"Escanea el código con la cámara de tu teléfono o abre specrails.dev/companion-app en su navegador.","open":"Abrir Specrails Companion","pairLabel":"Emparejar lleva diez segundos","pairBody":"En tu teléfono abre specrails.dev/companion-app y luego, aquí, ve a Ajustes → Compañera móvil → Emparejar compañera web y sigue los pasos en pantalla."},"moveFast":{"nav":"Ve rápido","title":"Muévete a la velocidad del pensamiento","subtitle":"Teclado primero, en todas partes","paletteLabel":"Paleta de comandos","paletteShortcut":"<f>Pulsa</f> <mod>{{mod}}</mod> <m>+</m> <k>K</k> <m>en cualquier sitio</m>","paletteBody":"Cambia de proyecto, ejecuta comandos de spec, salta a cualquier página y encuentra jobs recientes, todo con búsqueda difusa.","agentLabel":"Agente","agentBody":"Muestra u oculta el agente con <mod>{{mod}}</mod> <shift>Shift</shift> <a>A</a>; recorre su nivel con <shift>Shift</shift> <tab>Tab</tab>.","terminalLabel":"Panel de terminal","terminalBody":"Alterna con <mod>{{mod}}</mod> <j>J</j>.","shortcutsLabel":"Todos los atajos","shortcutsBody":"Pulsa <q>?</q> para ver la chuleta completa.","chatLabel":"Barra lateral derecha","chatBody":"Alterna la barra lateral derecha con <mod>{{mod}}</mod> <bkey>B</bkey>.","projectsLabel":"Barra de proyectos","projectsBody":"Alterna la barra Arc izquierda con <alt>{{alt}}</alt> <mod>{{mod}}</mod> <bkey>B</bkey>.","pagesLabel":"Páginas y proyectos por número","pagesBody":"<mod>{{mod}}</mod> <n>1–9</n> salta a una página; <alt>{{alt}}</alt> <mod>{{mod}}</mod> <n>1–9</n> cambia de proyecto.","outro":"<b>Fin del recorrido.</b> Escribe lo que quieres construir en el composer de la misión o añade un proyecto desde la barra izquierda. Puedes reabrir este recorrido cuando quieras desde Ajustes."},"jira":{"label":"Integración con Jira","body":"Respalda cualquier proyecto con un <b>tablero de Jira</b> — cada spec es un issue de Jira, sincronizado en ambos sentidos: el estado sigue al rail y se publica un comentario al terminar un job. Configúralo por proyecto al añadirlo, o cuando quieras en Ajustes."}}`),a={addProject:e,prerequisites:t,instructions:n,welcome:r,onboarding:i};export{e as addProject,a as default,n as instructions,i as onboarding,t as prerequisites,r as welcome};
@@ -1 +1 @@
1
- import{h as e}from"./useSharedWebSocket-Dz-HI6De.js";import{t}from"./createLucideIcon-Bjbbp_KS.js";var n=t(`arrow-up-right`,[[`path`,{d:`M7 7h10v10`,key:`1tivn9`}],[`path`,{d:`M7 17 17 7`,key:`1vkiza`}]]),r={job:`analytics:surfaces.job`,"quick-spec":`analytics:surfaces.quickSpec`,"explore-spec":`analytics:surfaces.exploreSpec`,"ai-edit":`analytics:surfaces.aiEdit`,smash:`analytics:surfaces.smash`,"file-summary":`analytics:surfaces.fileSummary`,loop:`analytics:surfaces.loop`,"chat-sidebar":`analytics:surfaces.chatSidebar`,"spec-launcher":`analytics:surfaces.specLauncher`,proposal:`analytics:surfaces.proposal`,"agent-studio":`analytics:surfaces.agentStudio`,setup:`analytics:surfaces.setup`},i={bg:`bg-muted/40`,text:`text-muted-foreground`,ring:`ring-border/40`,dot:`bg-muted-foreground`},a={job:{bg:`bg-accent-info/15`,text:`text-accent-info`,ring:`ring-accent-info/40`,dot:`bg-accent-info`},"quick-spec":{bg:`bg-accent-secondary/15`,text:`text-accent-secondary`,ring:`ring-accent-secondary/40`,dot:`bg-accent-secondary`},"explore-spec":{bg:`bg-accent-highlight/15`,text:`text-accent-highlight`,ring:`ring-accent-highlight/40`,dot:`bg-accent-highlight`},"ai-edit":{bg:`bg-accent-success/15`,text:`text-accent-success`,ring:`ring-accent-success/40`,dot:`bg-accent-success`},smash:{bg:`bg-accent-highlight/15`,text:`text-accent-highlight`,ring:`ring-accent-highlight/40`,dot:`bg-accent-highlight`},"file-summary":{bg:`bg-accent-warning/15`,text:`text-accent-warning`,ring:`ring-accent-warning/40`,dot:`bg-accent-warning`},loop:{bg:`bg-accent-primary/15`,text:`text-accent-primary`,ring:`ring-accent-primary/40`,dot:`bg-accent-primary`},"chat-sidebar":{bg:`bg-accent-info/15`,text:`text-accent-info`,ring:`ring-accent-info/40`,dot:`bg-accent-info`},"spec-launcher":{bg:`bg-accent-secondary/15`,text:`text-accent-secondary`,ring:`ring-accent-secondary/40`,dot:`bg-accent-secondary`},proposal:{bg:`bg-accent-highlight/15`,text:`text-accent-highlight`,ring:`ring-accent-highlight/40`,dot:`bg-accent-highlight`},"agent-studio":{bg:`bg-accent-success/15`,text:`text-accent-success`,ring:`ring-accent-success/40`,dot:`bg-accent-success`},setup:{bg:`bg-accent-primary/15`,text:`text-accent-primary`,ring:`ring-accent-primary/40`,dot:`bg-accent-primary`}};function o(e,t){return new Proxy(e,{get(e,n,r){return typeof n==`string`&&!(n in e)?t(n):Reflect.get(e,n,r)}})}var s=o(Object.defineProperties({},Object.fromEntries(Object.keys(r).map(t=>[t,{get:()=>e.t(r[t]),enumerable:!0}]))),e=>e),c=o(a,()=>i);export{s as n,n as r,c as t};
1
+ import{h as e}from"./useSharedWebSocket-BZMrX4jr.js";import{t}from"./createLucideIcon-Bjbbp_KS.js";var n=t(`arrow-up-right`,[[`path`,{d:`M7 7h10v10`,key:`1tivn9`}],[`path`,{d:`M7 17 17 7`,key:`1vkiza`}]]),r={job:`analytics:surfaces.job`,"quick-spec":`analytics:surfaces.quickSpec`,"explore-spec":`analytics:surfaces.exploreSpec`,"ai-edit":`analytics:surfaces.aiEdit`,smash:`analytics:surfaces.smash`,"file-summary":`analytics:surfaces.fileSummary`,loop:`analytics:surfaces.loop`,"chat-sidebar":`analytics:surfaces.chatSidebar`,"spec-launcher":`analytics:surfaces.specLauncher`,proposal:`analytics:surfaces.proposal`,"agent-studio":`analytics:surfaces.agentStudio`,setup:`analytics:surfaces.setup`},i={bg:`bg-muted/40`,text:`text-muted-foreground`,ring:`ring-border/40`,dot:`bg-muted-foreground`},a={job:{bg:`bg-accent-info/15`,text:`text-accent-info`,ring:`ring-accent-info/40`,dot:`bg-accent-info`},"quick-spec":{bg:`bg-accent-secondary/15`,text:`text-accent-secondary`,ring:`ring-accent-secondary/40`,dot:`bg-accent-secondary`},"explore-spec":{bg:`bg-accent-highlight/15`,text:`text-accent-highlight`,ring:`ring-accent-highlight/40`,dot:`bg-accent-highlight`},"ai-edit":{bg:`bg-accent-success/15`,text:`text-accent-success`,ring:`ring-accent-success/40`,dot:`bg-accent-success`},smash:{bg:`bg-accent-highlight/15`,text:`text-accent-highlight`,ring:`ring-accent-highlight/40`,dot:`bg-accent-highlight`},"file-summary":{bg:`bg-accent-warning/15`,text:`text-accent-warning`,ring:`ring-accent-warning/40`,dot:`bg-accent-warning`},loop:{bg:`bg-accent-primary/15`,text:`text-accent-primary`,ring:`ring-accent-primary/40`,dot:`bg-accent-primary`},"chat-sidebar":{bg:`bg-accent-info/15`,text:`text-accent-info`,ring:`ring-accent-info/40`,dot:`bg-accent-info`},"spec-launcher":{bg:`bg-accent-secondary/15`,text:`text-accent-secondary`,ring:`ring-accent-secondary/40`,dot:`bg-accent-secondary`},proposal:{bg:`bg-accent-highlight/15`,text:`text-accent-highlight`,ring:`ring-accent-highlight/40`,dot:`bg-accent-highlight`},"agent-studio":{bg:`bg-accent-success/15`,text:`text-accent-success`,ring:`ring-accent-success/40`,dot:`bg-accent-success`},setup:{bg:`bg-accent-primary/15`,text:`text-accent-primary`,ring:`ring-accent-primary/40`,dot:`bg-accent-primary`}};function o(e,t){return new Proxy(e,{get(e,n,r){return typeof n==`string`&&!(n in e)?t(n):Reflect.get(e,n,r)}})}var s=o(Object.defineProperties({},Object.fromEntries(Object.keys(r).map(t=>[t,{get:()=>e.t(r[t]),enumerable:!0}]))),e=>e),c=o(a,()=>i);export{s as n,n as r,c as t};
@@ -1 +1 @@
1
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{t as r}from"./react-dom-DiWzBDP9.js";import{h as i,l as a,r as o}from"./useSharedWebSocket-Dz-HI6De.js";var s=e(t(),1),c=e(r(),1);function l(e){if(!e||typeof document>`u`)return;let t=document.head||document.getElementsByTagName(`head`)[0],n=document.createElement(`style`);n.type=`text/css`,t.appendChild(n),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(document.createTextNode(e))}var u=e=>{switch(e){case`success`:return p;case`info`:return h;case`warning`:return m;case`error`:return g;default:return null}},d=Array(12).fill(0),f=({visible:e,className:t})=>s.createElement(`div`,{className:[`sonner-loading-wrapper`,t].filter(Boolean).join(` `),"data-visible":e},s.createElement(`div`,{className:`sonner-spinner`},d.map((e,t)=>s.createElement(`div`,{className:`sonner-loading-bar`,key:`spinner-bar-${t}`})))),p=s.createElement(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 20 20`,fill:`currentColor`,height:`20`,width:`20`},s.createElement(`path`,{fillRule:`evenodd`,d:`M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z`,clipRule:`evenodd`})),m=s.createElement(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 24 24`,fill:`currentColor`,height:`20`,width:`20`},s.createElement(`path`,{fillRule:`evenodd`,d:`M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z`,clipRule:`evenodd`})),h=s.createElement(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 20 20`,fill:`currentColor`,height:`20`,width:`20`},s.createElement(`path`,{fillRule:`evenodd`,d:`M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z`,clipRule:`evenodd`})),g=s.createElement(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 20 20`,fill:`currentColor`,height:`20`,width:`20`},s.createElement(`path`,{fillRule:`evenodd`,d:`M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z`,clipRule:`evenodd`})),_=s.createElement(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`12`,height:`12`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`},s.createElement(`line`,{x1:`18`,y1:`6`,x2:`6`,y2:`18`}),s.createElement(`line`,{x1:`6`,y1:`6`,x2:`18`,y2:`18`})),v=()=>{let[e,t]=s.useState(document.hidden);return s.useEffect(()=>{let e=()=>{t(document.hidden)};return document.addEventListener(`visibilitychange`,e),()=>window.removeEventListener(`visibilitychange`,e)},[]),e},y=1,b=new class{constructor(){this.subscribe=e=>(this.subscribers.push(e),()=>{let t=this.subscribers.indexOf(e);this.subscribers.splice(t,1)}),this.publish=e=>{this.subscribers.forEach(t=>t(e))},this.addToast=e=>{this.publish(e),this.toasts=[...this.toasts,e]},this.create=e=>{let{message:t,...n}=e,r=typeof e?.id==`number`||e.id?.length>0?e.id:y++,i=this.toasts.find(e=>e.id===r),a=e.dismissible===void 0||e.dismissible;return this.dismissedToasts.has(r)&&this.dismissedToasts.delete(r),i?this.toasts=this.toasts.map(n=>n.id===r?(this.publish({...n,...e,id:r,title:t}),{...n,...e,id:r,dismissible:a,title:t}):n):this.addToast({title:t,...n,dismissible:a,id:r}),r},this.dismiss=e=>(e?(this.dismissedToasts.add(e),requestAnimationFrame(()=>this.subscribers.forEach(t=>t({id:e,dismiss:!0})))):this.toasts.forEach(e=>{this.subscribers.forEach(t=>t({id:e.id,dismiss:!0}))}),e),this.message=(e,t)=>this.create({...t,message:e}),this.error=(e,t)=>this.create({...t,message:e,type:`error`}),this.success=(e,t)=>this.create({...t,type:`success`,message:e}),this.info=(e,t)=>this.create({...t,type:`info`,message:e}),this.warning=(e,t)=>this.create({...t,type:`warning`,message:e}),this.loading=(e,t)=>this.create({...t,type:`loading`,message:e}),this.promise=(e,t)=>{if(!t)return;let n;t.loading!==void 0&&(n=this.create({...t,promise:e,type:`loading`,message:t.loading,description:typeof t.description==`function`?void 0:t.description}));let r=Promise.resolve(e instanceof Function?e():e),i=n!==void 0,a,o=r.then(async e=>{if(a=[`resolve`,e],s.isValidElement(e))i=!1,this.create({id:n,type:`default`,message:e});else if(S(e)&&!e.ok){i=!1;let r=typeof t.error==`function`?await t.error(`HTTP error! status: ${e.status}`):t.error,a=typeof t.description==`function`?await t.description(`HTTP error! status: ${e.status}`):t.description,o=typeof r==`object`&&!s.isValidElement(r)?r:{message:r};this.create({id:n,type:`error`,description:a,...o})}else if(e instanceof Error){i=!1;let r=typeof t.error==`function`?await t.error(e):t.error,a=typeof t.description==`function`?await t.description(e):t.description,o=typeof r==`object`&&!s.isValidElement(r)?r:{message:r};this.create({id:n,type:`error`,description:a,...o})}else if(t.success!==void 0){i=!1;let r=typeof t.success==`function`?await t.success(e):t.success,a=typeof t.description==`function`?await t.description(e):t.description,o=typeof r==`object`&&!s.isValidElement(r)?r:{message:r};this.create({id:n,type:`success`,description:a,...o})}}).catch(async e=>{if(a=[`reject`,e],t.error!==void 0){i=!1;let r=typeof t.error==`function`?await t.error(e):t.error,a=typeof t.description==`function`?await t.description(e):t.description,o=typeof r==`object`&&!s.isValidElement(r)?r:{message:r};this.create({id:n,type:`error`,description:a,...o})}}).finally(()=>{i&&(this.dismiss(n),n=void 0),t.finally==null||t.finally.call(t)}),c=()=>new Promise((e,t)=>o.then(()=>a[0]===`reject`?t(a[1]):e(a[1])).catch(t));return typeof n!=`string`&&typeof n!=`number`?{unwrap:c}:Object.assign(n,{unwrap:c})},this.custom=(e,t)=>{let n=t?.id||y++;return this.create({jsx:e(n),id:n,...t}),n},this.getActiveToasts=()=>this.toasts.filter(e=>!this.dismissedToasts.has(e.id)),this.subscribers=[],this.toasts=[],this.dismissedToasts=new Set}},x=(e,t)=>{let n=t?.id||y++;return b.addToast({title:e,...t,id:n}),n},S=e=>e&&typeof e==`object`&&`ok`in e&&typeof e.ok==`boolean`&&`status`in e&&typeof e.status==`number`,C=Object.assign(x,{success:b.success,info:b.info,warning:b.warning,error:b.error,custom:b.custom,message:b.message,promise:b.promise,dismiss:b.dismiss,loading:b.loading},{getHistory:()=>b.toasts,getToasts:()=>b.getActiveToasts()});l(`[data-sonner-toaster][dir=ltr],html[dir=ltr]{--toast-icon-margin-start:-3px;--toast-icon-margin-end:4px;--toast-svg-margin-start:-1px;--toast-svg-margin-end:0px;--toast-button-margin-start:auto;--toast-button-margin-end:0;--toast-close-button-start:0;--toast-close-button-end:unset;--toast-close-button-transform:translate(-35%, -35%)}[data-sonner-toaster][dir=rtl],html[dir=rtl]{--toast-icon-margin-start:4px;--toast-icon-margin-end:-3px;--toast-svg-margin-start:0px;--toast-svg-margin-end:-1px;--toast-button-margin-start:0;--toast-button-margin-end:auto;--toast-close-button-start:unset;--toast-close-button-end:0;--toast-close-button-transform:translate(35%, -35%)}[data-sonner-toaster]{position:fixed;width:var(--width);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;--gray1:hsl(0, 0%, 99%);--gray2:hsl(0, 0%, 97.3%);--gray3:hsl(0, 0%, 95.1%);--gray4:hsl(0, 0%, 93%);--gray5:hsl(0, 0%, 90.9%);--gray6:hsl(0, 0%, 88.7%);--gray7:hsl(0, 0%, 85.8%);--gray8:hsl(0, 0%, 78%);--gray9:hsl(0, 0%, 56.1%);--gray10:hsl(0, 0%, 52.3%);--gray11:hsl(0, 0%, 43.5%);--gray12:hsl(0, 0%, 9%);--border-radius:8px;box-sizing:border-box;padding:0;margin:0;list-style:none;outline:0;z-index:999999999;transition:transform .4s ease}@media (hover:none) and (pointer:coarse){[data-sonner-toaster][data-lifted=true]{transform:none}}[data-sonner-toaster][data-x-position=right]{right:var(--offset-right)}[data-sonner-toaster][data-x-position=left]{left:var(--offset-left)}[data-sonner-toaster][data-x-position=center]{left:50%;transform:translateX(-50%)}[data-sonner-toaster][data-y-position=top]{top:var(--offset-top)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--offset-bottom)}[data-sonner-toast]{--y:translateY(100%);--lift-amount:calc(var(--lift) * var(--gap));z-index:var(--z-index);position:absolute;opacity:0;transform:var(--y);touch-action:none;transition:transform .4s,opacity .4s,height .4s,box-shadow .2s;box-sizing:border-box;outline:0;overflow-wrap:anywhere}[data-sonner-toast][data-styled=true]{padding:16px;background:var(--normal-bg);border:1px solid var(--normal-border);color:var(--normal-text);border-radius:var(--border-radius);box-shadow:0 4px 12px rgba(0,0,0,.1);width:var(--width);font-size:13px;display:flex;align-items:center;gap:6px}[data-sonner-toast]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-y-position=top]{top:0;--y:translateY(-100%);--lift:1;--lift-amount:calc(1 * var(--gap))}[data-sonner-toast][data-y-position=bottom]{bottom:0;--y:translateY(100%);--lift:-1;--lift-amount:calc(var(--lift) * var(--gap))}[data-sonner-toast][data-styled=true] [data-description]{font-weight:400;line-height:1.4;color:#3f3f3f}[data-rich-colors=true][data-sonner-toast][data-styled=true] [data-description]{color:inherit}[data-sonner-toaster][data-sonner-theme=dark] [data-description]{color:#e8e8e8}[data-sonner-toast][data-styled=true] [data-title]{font-weight:500;line-height:1.5;color:inherit}[data-sonner-toast][data-styled=true] [data-icon]{display:flex;height:16px;width:16px;position:relative;justify-content:flex-start;align-items:center;flex-shrink:0;margin-left:var(--toast-icon-margin-start);margin-right:var(--toast-icon-margin-end)}[data-sonner-toast][data-promise=true] [data-icon]>svg{opacity:0;transform:scale(.8);transform-origin:center;animation:sonner-fade-in .3s ease forwards}[data-sonner-toast][data-styled=true] [data-icon]>*{flex-shrink:0}[data-sonner-toast][data-styled=true] [data-icon] svg{margin-left:var(--toast-svg-margin-start);margin-right:var(--toast-svg-margin-end)}[data-sonner-toast][data-styled=true] [data-content]{display:flex;flex-direction:column;gap:2px}[data-sonner-toast][data-styled=true] [data-button]{border-radius:4px;padding-left:8px;padding-right:8px;height:24px;font-size:12px;color:var(--normal-bg);background:var(--normal-text);margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end);border:none;font-weight:500;cursor:pointer;outline:0;display:flex;align-items:center;flex-shrink:0;transition:opacity .4s,box-shadow .2s}[data-sonner-toast][data-styled=true] [data-button]:focus-visible{box-shadow:0 0 0 2px rgba(0,0,0,.4)}[data-sonner-toast][data-styled=true] [data-button]:first-of-type{margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end)}[data-sonner-toast][data-styled=true] [data-cancel]{color:var(--normal-text);background:rgba(0,0,0,.08)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-styled=true] [data-cancel]{background:rgba(255,255,255,.3)}[data-sonner-toast][data-styled=true] [data-close-button]{position:absolute;left:var(--toast-close-button-start);right:var(--toast-close-button-end);top:0;height:20px;width:20px;display:flex;justify-content:center;align-items:center;padding:0;color:var(--gray12);background:var(--normal-bg);border:1px solid var(--gray4);transform:var(--toast-close-button-transform);border-radius:50%;cursor:pointer;z-index:1;transition:opacity .1s,background .2s,border-color .2s}[data-sonner-toast][data-styled=true] [data-close-button]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-styled=true] [data-disabled=true]{cursor:not-allowed}[data-sonner-toast][data-styled=true]:hover [data-close-button]:hover{background:var(--gray2);border-color:var(--gray5)}[data-sonner-toast][data-swiping=true]::before{content:'';position:absolute;left:-100%;right:-100%;height:100%;z-index:-1}[data-sonner-toast][data-y-position=top][data-swiping=true]::before{bottom:50%;transform:scaleY(3) translateY(50%)}[data-sonner-toast][data-y-position=bottom][data-swiping=true]::before{top:50%;transform:scaleY(3) translateY(-50%)}[data-sonner-toast][data-swiping=false][data-removed=true]::before{content:'';position:absolute;inset:0;transform:scaleY(2)}[data-sonner-toast][data-expanded=true]::after{content:'';position:absolute;left:0;height:calc(var(--gap) + 1px);bottom:100%;width:100%}[data-sonner-toast][data-mounted=true]{--y:translateY(0);opacity:1}[data-sonner-toast][data-expanded=false][data-front=false]{--scale:var(--toasts-before) * 0.05 + 1;--y:translateY(calc(var(--lift-amount) * var(--toasts-before))) scale(calc(-1 * var(--scale)));height:var(--front-toast-height)}[data-sonner-toast]>*{transition:opacity .4s}[data-sonner-toast][data-x-position=right]{right:0}[data-sonner-toast][data-x-position=left]{left:0}[data-sonner-toast][data-expanded=false][data-front=false][data-styled=true]>*{opacity:0}[data-sonner-toast][data-visible=false]{opacity:0;pointer-events:none}[data-sonner-toast][data-mounted=true][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset)));height:var(--initial-height)}[data-sonner-toast][data-removed=true][data-front=true][data-swipe-out=false]{--y:translateY(calc(var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset) + var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=false]{--y:translateY(40%);opacity:0;transition:transform .5s,opacity .2s}[data-sonner-toast][data-removed=true][data-front=false]::before{height:calc(var(--initial-height) + 20%)}[data-sonner-toast][data-swiping=true]{transform:var(--y) translateY(var(--swipe-amount-y,0)) translateX(var(--swipe-amount-x,0));transition:none}[data-sonner-toast][data-swiped=true]{user-select:none}[data-sonner-toast][data-swipe-out=true][data-y-position=bottom],[data-sonner-toast][data-swipe-out=true][data-y-position=top]{animation-duration:.2s;animation-timing-function:ease-out;animation-fill-mode:forwards}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=left]{animation-name:swipe-out-left}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=right]{animation-name:swipe-out-right}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=up]{animation-name:swipe-out-up}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=down]{animation-name:swipe-out-down}@keyframes swipe-out-left{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) - 100%));opacity:0}}@keyframes swipe-out-right{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) + 100%));opacity:0}}@keyframes swipe-out-up{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) - 100%));opacity:0}}@keyframes swipe-out-down{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) + 100%));opacity:0}}@media (max-width:600px){[data-sonner-toaster]{position:fixed;right:var(--mobile-offset-right);left:var(--mobile-offset-left);width:100%}[data-sonner-toaster][dir=rtl]{left:calc(var(--mobile-offset-left) * -1)}[data-sonner-toaster] [data-sonner-toast]{left:0;right:0;width:calc(100% - var(--mobile-offset-left) * 2)}[data-sonner-toaster][data-x-position=left]{left:var(--mobile-offset-left)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--mobile-offset-bottom)}[data-sonner-toaster][data-y-position=top]{top:var(--mobile-offset-top)}[data-sonner-toaster][data-x-position=center]{left:var(--mobile-offset-left);right:var(--mobile-offset-right);transform:none}}[data-sonner-toaster][data-sonner-theme=light]{--normal-bg:#fff;--normal-border:var(--gray4);--normal-text:var(--gray12);--success-bg:hsl(143, 85%, 96%);--success-border:hsl(145, 92%, 87%);--success-text:hsl(140, 100%, 27%);--info-bg:hsl(208, 100%, 97%);--info-border:hsl(221, 91%, 93%);--info-text:hsl(210, 92%, 45%);--warning-bg:hsl(49, 100%, 97%);--warning-border:hsl(49, 91%, 84%);--warning-text:hsl(31, 92%, 45%);--error-bg:hsl(359, 100%, 97%);--error-border:hsl(359, 100%, 94%);--error-text:hsl(360, 100%, 45%)}[data-sonner-toaster][data-sonner-theme=light] [data-sonner-toast][data-invert=true]{--normal-bg:#000;--normal-border:hsl(0, 0%, 20%);--normal-text:var(--gray1)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-invert=true]{--normal-bg:#fff;--normal-border:var(--gray3);--normal-text:var(--gray12)}[data-sonner-toaster][data-sonner-theme=dark]{--normal-bg:#000;--normal-bg-hover:hsl(0, 0%, 12%);--normal-border:hsl(0, 0%, 20%);--normal-border-hover:hsl(0, 0%, 25%);--normal-text:var(--gray1);--success-bg:hsl(150, 100%, 6%);--success-border:hsl(147, 100%, 12%);--success-text:hsl(150, 86%, 65%);--info-bg:hsl(215, 100%, 6%);--info-border:hsl(223, 43%, 17%);--info-text:hsl(216, 87%, 65%);--warning-bg:hsl(64, 100%, 6%);--warning-border:hsl(60, 100%, 9%);--warning-text:hsl(46, 87%, 65%);--error-bg:hsl(358, 76%, 10%);--error-border:hsl(357, 89%, 16%);--error-text:hsl(358, 100%, 81%)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]{background:var(--normal-bg);border-color:var(--normal-border);color:var(--normal-text)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]:hover{background:var(--normal-bg-hover);border-color:var(--normal-border-hover)}[data-rich-colors=true][data-sonner-toast][data-type=success]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=success] [data-close-button]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=info]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=info] [data-close-button]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning] [data-close-button]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=error]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}[data-rich-colors=true][data-sonner-toast][data-type=error] [data-close-button]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}.sonner-loading-wrapper{--size:16px;height:var(--size);width:var(--size);position:absolute;inset:0;z-index:10}.sonner-loading-wrapper[data-visible=false]{transform-origin:center;animation:sonner-fade-out .2s ease forwards}.sonner-spinner{position:relative;top:50%;left:50%;height:var(--size);width:var(--size)}.sonner-loading-bar{animation:sonner-spin 1.2s linear infinite;background:var(--gray11);border-radius:6px;height:8%;left:-10%;position:absolute;top:-3.9%;width:24%}.sonner-loading-bar:first-child{animation-delay:-1.2s;transform:rotate(.0001deg) translate(146%)}.sonner-loading-bar:nth-child(2){animation-delay:-1.1s;transform:rotate(30deg) translate(146%)}.sonner-loading-bar:nth-child(3){animation-delay:-1s;transform:rotate(60deg) translate(146%)}.sonner-loading-bar:nth-child(4){animation-delay:-.9s;transform:rotate(90deg) translate(146%)}.sonner-loading-bar:nth-child(5){animation-delay:-.8s;transform:rotate(120deg) translate(146%)}.sonner-loading-bar:nth-child(6){animation-delay:-.7s;transform:rotate(150deg) translate(146%)}.sonner-loading-bar:nth-child(7){animation-delay:-.6s;transform:rotate(180deg) translate(146%)}.sonner-loading-bar:nth-child(8){animation-delay:-.5s;transform:rotate(210deg) translate(146%)}.sonner-loading-bar:nth-child(9){animation-delay:-.4s;transform:rotate(240deg) translate(146%)}.sonner-loading-bar:nth-child(10){animation-delay:-.3s;transform:rotate(270deg) translate(146%)}.sonner-loading-bar:nth-child(11){animation-delay:-.2s;transform:rotate(300deg) translate(146%)}.sonner-loading-bar:nth-child(12){animation-delay:-.1s;transform:rotate(330deg) translate(146%)}@keyframes sonner-fade-in{0%{opacity:0;transform:scale(.8)}100%{opacity:1;transform:scale(1)}}@keyframes sonner-fade-out{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.8)}}@keyframes sonner-spin{0%{opacity:1}100%{opacity:.15}}@media (prefers-reduced-motion){.sonner-loading-bar,[data-sonner-toast],[data-sonner-toast]>*{transition:none!important;animation:none!important}}.sonner-loader{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;transition:opacity .2s,transform .2s}.sonner-loader[data-visible=false]{opacity:0;transform:scale(.8) translate(-50%,-50%)}`);function w(e){return e.label!==void 0}var T=3,E=`24px`,D=`16px`,O=4e3,k=356,A=14,j=45,ee=200;function M(...e){return e.filter(Boolean).join(` `)}function N(e){let[t,n]=e.split(`-`),r=[];return t&&r.push(t),n&&r.push(n),r}var P=e=>{let{invert:t,toast:n,unstyled:r,interacting:i,setHeights:a,visibleToasts:o,heights:c,index:l,toasts:d,expanded:p,removeToast:m,defaultRichColors:h,closeButton:g,style:y,cancelButtonStyle:b,actionButtonStyle:x,className:S=``,descriptionClassName:C=``,duration:T,position:E,gap:D,expandByDefault:k,classNames:A,icons:P,closeButtonAriaLabel:te=`Close toast`}=e,[F,I]=s.useState(null),[L,R]=s.useState(null),[z,B]=s.useState(!1),[V,H]=s.useState(!1),[U,W]=s.useState(!1),[ne,re]=s.useState(!1),[ie,G]=s.useState(!1),[ae,K]=s.useState(0),[oe,se]=s.useState(0),q=s.useRef(n.duration||T||O),ce=s.useRef(null),J=s.useRef(null),le=l===0,ue=l+1<=o,Y=n.type,X=n.dismissible!==!1,de=n.className||``,fe=n.descriptionClassName||``,pe=s.useMemo(()=>c.findIndex(e=>e.toastId===n.id)||0,[c,n.id]),me=s.useMemo(()=>n.closeButton??g,[n.closeButton,g]),he=s.useMemo(()=>n.duration||T||O,[n.duration,T]),ge=s.useRef(0),Z=s.useRef(0),_e=s.useRef(0),Q=s.useRef(null),[ve,ye]=E.split(`-`),be=s.useMemo(()=>c.reduce((e,t,n)=>n>=pe?e:e+t.height,0),[c,pe]),xe=v(),Se=n.invert||t,Ce=Y===`loading`;Z.current=s.useMemo(()=>pe*D+be,[pe,be]),s.useEffect(()=>{q.current=he},[he]),s.useEffect(()=>{B(!0)},[]),s.useEffect(()=>{let e=J.current;if(e){let t=e.getBoundingClientRect().height;return se(t),a(e=>[{toastId:n.id,height:t,position:n.position},...e]),()=>a(e=>e.filter(e=>e.toastId!==n.id))}},[a,n.id]),s.useLayoutEffect(()=>{if(!z)return;let e=J.current,t=e.style.height;e.style.height=`auto`;let r=e.getBoundingClientRect().height;e.style.height=t,se(r),a(e=>e.find(e=>e.toastId===n.id)?e.map(e=>e.toastId===n.id?{...e,height:r}:e):[{toastId:n.id,height:r,position:n.position},...e])},[z,n.title,n.description,a,n.id,n.jsx,n.action,n.cancel]);let $=s.useCallback(()=>{H(!0),K(Z.current),a(e=>e.filter(e=>e.toastId!==n.id)),setTimeout(()=>{m(n)},ee)},[n,m,a,Z]);s.useEffect(()=>{if(n.promise&&Y===`loading`||n.duration===1/0||n.type===`loading`)return;let e;return p||i||xe?(()=>{if(_e.current<ge.current){let e=new Date().getTime()-ge.current;q.current-=e}_e.current=new Date().getTime()})():q.current!==1/0&&(ge.current=new Date().getTime(),e=setTimeout(()=>{n.onAutoClose==null||n.onAutoClose.call(n,n),$()},q.current)),()=>clearTimeout(e)},[p,i,n,Y,xe,$]),s.useEffect(()=>{n.delete&&($(),n.onDismiss==null||n.onDismiss.call(n,n))},[$,n.delete]);function we(){return P?.loading?s.createElement(`div`,{className:M(A?.loader,n?.classNames?.loader,`sonner-loader`),"data-visible":Y===`loading`},P.loading):s.createElement(f,{className:M(A?.loader,n?.classNames?.loader),visible:Y===`loading`})}let Te=n.icon||P?.[Y]||u(Y);return s.createElement(`li`,{tabIndex:0,ref:J,className:M(S,de,A?.toast,n?.classNames?.toast,A?.default,A?.[Y],n?.classNames?.[Y]),"data-sonner-toast":``,"data-rich-colors":n.richColors??h,"data-styled":!(n.jsx||n.unstyled||r),"data-mounted":z,"data-promise":!!n.promise,"data-swiped":ie,"data-removed":V,"data-visible":ue,"data-y-position":ve,"data-x-position":ye,"data-index":l,"data-front":le,"data-swiping":U,"data-dismissible":X,"data-type":Y,"data-invert":Se,"data-swipe-out":ne,"data-swipe-direction":L,"data-expanded":!!(p||k&&z),"data-testid":n.testId,style:{"--index":l,"--toasts-before":l,"--z-index":d.length-l,"--offset":`${V?ae:Z.current}px`,"--initial-height":k?`auto`:`${oe}px`,...y,...n.style},onDragEnd:()=>{W(!1),I(null),Q.current=null},onPointerDown:e=>{e.button!==2&&(Ce||!X||(ce.current=new Date,K(Z.current),e.target.setPointerCapture(e.pointerId),e.target.tagName!==`BUTTON`&&(W(!0),Q.current={x:e.clientX,y:e.clientY})))},onPointerUp:()=>{if(ne||!X)return;Q.current=null;let e=Number(J.current?.style.getPropertyValue(`--swipe-amount-x`).replace(`px`,``)||0),t=Number(J.current?.style.getPropertyValue(`--swipe-amount-y`).replace(`px`,``)||0),r=new Date().getTime()-ce.current?.getTime(),i=F===`x`?e:t,a=Math.abs(i)/r;if(Math.abs(i)>=j||a>.11){K(Z.current),n.onDismiss==null||n.onDismiss.call(n,n),R(F===`x`?e>0?`right`:`left`:t>0?`down`:`up`),$(),re(!0);return}else{var o,s;(o=J.current)==null||o.style.setProperty(`--swipe-amount-x`,`0px`),(s=J.current)==null||s.style.setProperty(`--swipe-amount-y`,`0px`)}G(!1),W(!1),I(null)},onPointerMove:t=>{var n,r;if(!Q.current||!X||window.getSelection()?.toString().length>0)return;let i=t.clientY-Q.current.y,a=t.clientX-Q.current.x,o=e.swipeDirections??N(E);!F&&(Math.abs(a)>1||Math.abs(i)>1)&&I(Math.abs(a)>Math.abs(i)?`x`:`y`);let s={x:0,y:0},c=e=>1/(1.5+Math.abs(e)/20);if(F===`y`){if(o.includes(`top`)||o.includes(`bottom`))if(o.includes(`top`)&&i<0||o.includes(`bottom`)&&i>0)s.y=i;else{let e=i*c(i);s.y=Math.abs(e)<Math.abs(i)?e:i}}else if(F===`x`&&(o.includes(`left`)||o.includes(`right`)))if(o.includes(`left`)&&a<0||o.includes(`right`)&&a>0)s.x=a;else{let e=a*c(a);s.x=Math.abs(e)<Math.abs(a)?e:a}(Math.abs(s.x)>0||Math.abs(s.y)>0)&&G(!0),(n=J.current)==null||n.style.setProperty(`--swipe-amount-x`,`${s.x}px`),(r=J.current)==null||r.style.setProperty(`--swipe-amount-y`,`${s.y}px`)}},me&&!n.jsx&&Y!==`loading`?s.createElement(`button`,{"aria-label":te,"data-disabled":Ce,"data-close-button":!0,onClick:Ce||!X?()=>{}:()=>{$(),n.onDismiss==null||n.onDismiss.call(n,n)},className:M(A?.closeButton,n?.classNames?.closeButton)},P?.close??_):null,(Y||n.icon||n.promise)&&n.icon!==null&&(P?.[Y]!==null||n.icon)?s.createElement(`div`,{"data-icon":``,className:M(A?.icon,n?.classNames?.icon)},n.promise||n.type===`loading`&&!n.icon?n.icon||we():null,n.type===`loading`?null:Te):null,s.createElement(`div`,{"data-content":``,className:M(A?.content,n?.classNames?.content)},s.createElement(`div`,{"data-title":``,className:M(A?.title,n?.classNames?.title)},n.jsx?n.jsx:typeof n.title==`function`?n.title():n.title),n.description?s.createElement(`div`,{"data-description":``,className:M(C,fe,A?.description,n?.classNames?.description)},typeof n.description==`function`?n.description():n.description):null),s.isValidElement(n.cancel)?n.cancel:n.cancel&&w(n.cancel)?s.createElement(`button`,{"data-button":!0,"data-cancel":!0,style:n.cancelButtonStyle||b,onClick:e=>{w(n.cancel)&&X&&(n.cancel.onClick==null||n.cancel.onClick.call(n.cancel,e),$())},className:M(A?.cancelButton,n?.classNames?.cancelButton)},n.cancel.label):null,s.isValidElement(n.action)?n.action:n.action&&w(n.action)?s.createElement(`button`,{"data-button":!0,"data-action":!0,style:n.actionButtonStyle||x,onClick:e=>{w(n.action)&&(n.action.onClick==null||n.action.onClick.call(n.action,e),!e.defaultPrevented&&$())},className:M(A?.actionButton,n?.classNames?.actionButton)},n.action.label):null)};function te(){if(typeof window>`u`||typeof document>`u`)return`ltr`;let e=document.documentElement.getAttribute(`dir`);return e===`auto`||!e?window.getComputedStyle(document.documentElement).direction:e}function F(e,t){let n={};return[e,t].forEach((e,t)=>{let r=t===1,i=r?`--mobile-offset`:`--offset`,a=r?D:E;function o(e){[`top`,`right`,`bottom`,`left`].forEach(t=>{n[`${i}-${t}`]=typeof e==`number`?`${e}px`:e})}typeof e==`number`||typeof e==`string`?o(e):typeof e==`object`?[`top`,`right`,`bottom`,`left`].forEach(t=>{e[t]===void 0?n[`${i}-${t}`]=a:n[`${i}-${t}`]=typeof e[t]==`number`?`${e[t]}px`:e[t]}):o(a)}),n}var I=s.forwardRef(function(e,t){let{id:n,invert:r,position:i=`bottom-right`,hotkey:a=[`altKey`,`KeyT`],expand:o,closeButton:l,className:u,offset:d,mobileOffset:f,theme:p=`light`,richColors:m,duration:h,style:g,visibleToasts:_=T,toastOptions:v,dir:y=te(),gap:x=A,icons:S,containerAriaLabel:C=`Notifications`}=e,[w,E]=s.useState([]),D=s.useMemo(()=>n?w.filter(e=>e.toasterId===n):w.filter(e=>!e.toasterId),[w,n]),O=s.useMemo(()=>Array.from(new Set([i].concat(D.filter(e=>e.position).map(e=>e.position)))),[D,i]),[j,ee]=s.useState([]),[M,N]=s.useState(!1),[I,L]=s.useState(!1),[R,z]=s.useState(p===`system`?typeof window<`u`&&window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`:p),B=s.useRef(null),V=a.join(`+`).replace(/Key/g,``).replace(/Digit/g,``),H=s.useRef(null),U=s.useRef(!1),W=s.useCallback(e=>{E(t=>(t.find(t=>t.id===e.id)?.delete||b.dismiss(e.id),t.filter(({id:t})=>t!==e.id)))},[]);return s.useEffect(()=>b.subscribe(e=>{if(e.dismiss){requestAnimationFrame(()=>{E(t=>t.map(t=>t.id===e.id?{...t,delete:!0}:t))});return}setTimeout(()=>{c.flushSync(()=>{E(t=>{let n=t.findIndex(t=>t.id===e.id);return n===-1?[e,...t]:[...t.slice(0,n),{...t[n],...e},...t.slice(n+1)]})})})}),[w]),s.useEffect(()=>{if(p!==`system`){z(p);return}if(p===`system`&&(window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches?z(`dark`):z(`light`)),typeof window>`u`)return;let e=window.matchMedia(`(prefers-color-scheme: dark)`);try{e.addEventListener(`change`,({matches:e})=>{z(e?`dark`:`light`)})}catch{e.addListener(({matches:e})=>{try{z(e?`dark`:`light`)}catch(e){console.error(e)}})}},[p]),s.useEffect(()=>{w.length<=1&&N(!1)},[w]),s.useEffect(()=>{let e=e=>{if(a.every(t=>e[t]||e.code===t)){var t;N(!0),(t=B.current)==null||t.focus()}e.code===`Escape`&&(document.activeElement===B.current||B.current?.contains(document.activeElement))&&N(!1)};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[a]),s.useEffect(()=>{if(B.current)return()=>{H.current&&(H.current.focus({preventScroll:!0}),H.current=null,U.current=!1)}},[B.current]),s.createElement(`section`,{ref:t,"aria-label":`${C} ${V}`,tabIndex:-1,"aria-live":`polite`,"aria-relevant":`additions text`,"aria-atomic":`false`,suppressHydrationWarning:!0},O.map((t,n)=>{let[i,a]=t.split(`-`);return D.length?s.createElement(`ol`,{key:t,dir:y===`auto`?te():y,tabIndex:-1,ref:B,className:u,"data-sonner-toaster":!0,"data-sonner-theme":R,"data-y-position":i,"data-x-position":a,style:{"--front-toast-height":`${j[0]?.height||0}px`,"--width":`${k}px`,"--gap":`${x}px`,...g,...F(d,f)},onBlur:e=>{U.current&&!e.currentTarget.contains(e.relatedTarget)&&(U.current=!1,H.current&&=(H.current.focus({preventScroll:!0}),null))},onFocus:e=>{e.target instanceof HTMLElement&&e.target.dataset.dismissible===`false`||U.current||(U.current=!0,H.current=e.relatedTarget)},onMouseEnter:()=>N(!0),onMouseMove:()=>N(!0),onMouseLeave:()=>{I||N(!1)},onDragEnd:()=>N(!1),onPointerDown:e=>{e.target instanceof HTMLElement&&e.target.dataset.dismissible===`false`||L(!0)},onPointerUp:()=>L(!1)},D.filter(e=>!e.position&&n===0||e.position===t).map((n,i)=>s.createElement(P,{key:n.id,icons:S,index:i,toast:n,defaultRichColors:m,duration:v?.duration??h,className:v?.className,descriptionClassName:v?.descriptionClassName,invert:r,visibleToasts:_,closeButton:v?.closeButton??l,interacting:I,position:t,style:v?.style,unstyled:v?.unstyled,classNames:v?.classNames,cancelButtonStyle:v?.cancelButtonStyle,actionButtonStyle:v?.actionButtonStyle,closeButtonAriaLabel:v?.closeButtonAriaLabel,removeToast:W,toasts:D.filter(e=>e.position==n.position),heights:j.filter(e=>e.position==n.position),setHeights:ee,expandByDefault:o,gap:x,expanded:M,swipeDirections:e.swipeDirections}))):null}))}),L=null;function R(e){L=e}function z(){if(!L)throw Error(`getApiBase called with no active project — call setActiveProjectId first`);return`${a}/api/projects/${L}`}var B=new Map;function V(e,t){return`${e}:${t}`}function H(e){return(e instanceof Error?e.message:e==null?``:String(e)).trim()||`Request failed`}function U(e){if(!e)return;let t=`${e}:`;for(let e of B.keys())e.startsWith(t)&&B.delete(e)}function W({namespace:e,projectId:t,initialValue:n,fetcher:r,pollInterval:i=0}){let a=t?V(t,e):null,[o,c]=(0,s.useState)(()=>a&&B.has(a)?B.get(a):n),[l,u]=(0,s.useState)(()=>!a||!B.has(a)),[d,f]=(0,s.useState)(l),[p,m]=(0,s.useState)(null),h=(0,s.useRef)(r);h.current=r;let g=(0,s.useRef)(n);g.current=n;let _=(0,s.useRef)(a);_.current=a;let v=(0,s.useRef)(0),y=(0,s.useRef)(null),b=(0,s.useCallback)(async(e,t,n)=>{let r=++v.current;y.current?.abort();let i=new AbortController;y.current=i,n&&_.current===e&&(f(!0),m(null));try{let n=await h.current({projectId:t,signal:i.signal});if(i.signal.aborted||r!==v.current)return;B.set(e,n),_.current===e&&(c(n),m(null))}catch(t){if(i.signal.aborted||r!==v.current)return;_.current===e&&m(H(t))}finally{r===v.current&&(y.current===i&&(y.current=null),_.current===e&&(f(!1),u(!1)))}},[]);return(0,s.useEffect)(()=>{if(v.current+=1,y.current?.abort(),y.current=null,m(null),!a||!t){c(g.current),u(!0),f(!1);return}let e=B.has(a);e?(c(B.get(a)),u(!1),f(!1)):(c(g.current),u(!0),f(!0)),b(a,t,!e);let n;return i>0&&(n=setInterval(()=>{b(a,t,!1)},i)),()=>{v.current+=1,y.current?.abort(),y.current=null,n&&clearInterval(n)}},[a,t,i,b]),{data:o,isLoading:d,isFirstLoad:l,error:p,refresh:(0,s.useCallback)(async()=>{!a||!t||await b(a,t,!0)},[a,t,b])}}var ne=n();function re(e){return e.providers&&e.providers.length>0?e.providers:[e.provider]}var ie=(0,s.createContext)(null),G=`specrails-desktop:activeProjectId`;function ae(e){try{e?localStorage.setItem(G,e):localStorage.removeItem(G)}catch{}}function K(){try{return localStorage.getItem(G)}catch{return null}}function oe({children:e,isolated:t=!1}){let n=(0,s.useCallback)(e=>{t||ae(e)},[t]),[r,c]=(0,s.useState)([]),[l,u]=(0,s.useState)(null),[d,f]=(0,s.useState)(!0),[p,m]=(0,s.useState)(!1),h=(0,s.useRef)(null),g=(0,s.useRef)(new Set),_=(0,s.useRef)(!1),v=(0,s.useRef)(0),y=(0,s.useRef)(null),b=(0,s.useRef)(null),x=(0,s.useRef)(0),S=(0,s.useCallback)(e=>{n(e),R(e),u(t=>(t!==null&&t!==e&&(h.current&&clearTimeout(h.current),m(!0),h.current=setTimeout(()=>m(!1),400)),e))},[n]),{registerHandler:w,unregisterHandler:T,connectionStatus:E}=o(),D=(0,s.useCallback)(async function e(){if(!_.current||y.current)return;b.current&&clearTimeout(b.current);let r=new AbortController;y.current=r;let i=v.current,o=setTimeout(()=>r.abort(),8e3);try{let e=await fetch(`${a}/api/projects`,{signal:r.signal});if(!e.ok)throw Error(`HTTP ${e.status}`);let o=await e.json();if(!Array.isArray(o.projects))throw Error(`Invalid project snapshot`);if(!_.current||r.signal.aborted||i!==v.current)return;c(o.projects);let s=o.projects;u(e=>{if(e&&s.some(t=>t.id===e))return e;let r=t?null:K(),i=r&&s.some(e=>e.id===r)?r:null;return n(i),R(i),i}),x.current=0,f(!1)}catch{if(_.current&&i===v.current){let t=Math.min(500*2**Math.min(x.current++,5),1e4);b.current=setTimeout(()=>{e()},t)}}finally{clearTimeout(o),y.current===r&&(y.current=null)}},[t,n]);(0,s.useEffect)(()=>{_.current=!0,D();let e=()=>{D()};return window.addEventListener(`online`,e),window.addEventListener(`focus`,e),()=>{_.current=!1,v.current++,y.current?.abort(),y.current=null,b.current&&clearTimeout(b.current),h.current&&clearTimeout(h.current),window.removeEventListener(`online`,e),window.removeEventListener(`focus`,e)}},[D]);let O=(0,s.useRef)(E),k=(0,s.useRef)(E===`connected`);(0,s.useEffect)(()=>{E===`connected`&&(k.current&&O.current!==`connected`&&D(),k.current=!0),O.current=E},[E,D]);let A=(0,s.useCallback)(e=>{if(!e||typeof e!=`object`)return;let r=e;if(typeof r.type==`string`){if(r.type===`desktop.projects`){if(!Array.isArray(r.projects))return;v.current++,x.current=0,b.current&&clearTimeout(b.current);let e=r.projects;c(e),u(r=>{let i;if(r&&e.find(e=>e.id===r))i=r;else{let n=t?null:K();i=n&&e.find(e=>e.id===n)?n:!t&&e.length>0?e[0].id:null}return n(i),R(i),i}),f(!1)}else if(r.type===`desktop.project_added`){let e=r.project;if(!e||typeof e.id!=`string`)return;v.current++,c(t=>t.find(t=>t.id===e.id)?t:[...t,e]),g.current.has(e.id)?g.current.delete(e.id):t||(C.success(i.t(`nav:projects.added`,{name:e.name})),S(e.id))}else if(r.type===`providers.detected_changed`)D();else if(r.type===`desktop.project_removed`){let e=r.projectId;if(typeof e!=`string`)return;v.current++,t||C.success(i.t(`nav:projects.removed`)),U(e),c(t=>t.filter(t=>t.id!==e)),u(t=>t===e?(n(null),R(null),null):t)}}},[D,S,t,n]);(0,s.useLayoutEffect)(()=>(w(`desktop`,A),()=>T(`desktop`)),[A,w,T]);let j=(0,s.useRef)(0);(0,s.useEffect)(()=>{let e=()=>{let e=Date.now();e-j.current<6e4||(j.current=e,fetch(`${a}/api/providers/detected?refresh=1`).catch(()=>{}))};return window.addEventListener(`focus`,e),()=>window.removeEventListener(`focus`,e)},[]);let ee=(0,s.useCallback)(async(e,t,n,r)=>{try{let i={path:e};n&&n.length>0&&(i.providers=n),t&&(i.name=t),r?.length&&(i.repositories=r);let a=await fetch(`/api/projects`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)});if(!a.ok){let e=await a.json();throw Error(e.error??`HTTP ${a.status}`)}let o=await a.json();return g.current.add(o.project.id),v.current++,c(e=>e.find(e=>e.id===o.project.id)?e:[...e,o.project]),S(o.project.id),o}catch(e){throw console.error(`[useDesktop] addProject error:`,e),e}},[S]),M=(0,s.useCallback)(async e=>{try{let t=await fetch(`${a}/api/projects/${e}`,{method:`DELETE`});if(!t.ok){let e=await t.json();throw Error(e.error??`HTTP ${t.status}`)}U(e),v.current++,c(t=>t.filter(t=>t.id!==e)),u(t=>t===e?(n(null),R(null),null):t)}catch(e){throw console.error(`[useDesktop] removeProject error:`,e),e}},[n]),N=(0,s.useMemo)(()=>({projects:r,activeProjectId:l,setActiveProjectId:S,addProject:ee,removeProject:M,refreshProjects:D,isLoading:d,isSwitchingProject:p}),[r,l,S,ee,M,D,d,p]);return(0,ne.jsx)(ie.Provider,{value:N,children:e})}var se={projects:[],activeProjectId:null,setActiveProjectId:()=>{},addProject:async()=>null,removeProject:async()=>{},refreshProjects:async()=>{},isLoading:!1,isSwitchingProject:!1};function q(){return(0,s.useContext)(ie)??se}export{z as a,W as i,re as n,I as o,q as r,C as s,oe as t};
1
+ import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{t as r}from"./react-dom-DiWzBDP9.js";import{h as i,l as a,r as o}from"./useSharedWebSocket-BZMrX4jr.js";var s=e(t(),1),c=e(r(),1);function l(e){if(!e||typeof document>`u`)return;let t=document.head||document.getElementsByTagName(`head`)[0],n=document.createElement(`style`);n.type=`text/css`,t.appendChild(n),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(document.createTextNode(e))}var u=e=>{switch(e){case`success`:return p;case`info`:return h;case`warning`:return m;case`error`:return g;default:return null}},d=Array(12).fill(0),f=({visible:e,className:t})=>s.createElement(`div`,{className:[`sonner-loading-wrapper`,t].filter(Boolean).join(` `),"data-visible":e},s.createElement(`div`,{className:`sonner-spinner`},d.map((e,t)=>s.createElement(`div`,{className:`sonner-loading-bar`,key:`spinner-bar-${t}`})))),p=s.createElement(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 20 20`,fill:`currentColor`,height:`20`,width:`20`},s.createElement(`path`,{fillRule:`evenodd`,d:`M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z`,clipRule:`evenodd`})),m=s.createElement(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 24 24`,fill:`currentColor`,height:`20`,width:`20`},s.createElement(`path`,{fillRule:`evenodd`,d:`M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z`,clipRule:`evenodd`})),h=s.createElement(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 20 20`,fill:`currentColor`,height:`20`,width:`20`},s.createElement(`path`,{fillRule:`evenodd`,d:`M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z`,clipRule:`evenodd`})),g=s.createElement(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 20 20`,fill:`currentColor`,height:`20`,width:`20`},s.createElement(`path`,{fillRule:`evenodd`,d:`M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z`,clipRule:`evenodd`})),_=s.createElement(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`12`,height:`12`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`},s.createElement(`line`,{x1:`18`,y1:`6`,x2:`6`,y2:`18`}),s.createElement(`line`,{x1:`6`,y1:`6`,x2:`18`,y2:`18`})),v=()=>{let[e,t]=s.useState(document.hidden);return s.useEffect(()=>{let e=()=>{t(document.hidden)};return document.addEventListener(`visibilitychange`,e),()=>window.removeEventListener(`visibilitychange`,e)},[]),e},y=1,b=new class{constructor(){this.subscribe=e=>(this.subscribers.push(e),()=>{let t=this.subscribers.indexOf(e);this.subscribers.splice(t,1)}),this.publish=e=>{this.subscribers.forEach(t=>t(e))},this.addToast=e=>{this.publish(e),this.toasts=[...this.toasts,e]},this.create=e=>{let{message:t,...n}=e,r=typeof e?.id==`number`||e.id?.length>0?e.id:y++,i=this.toasts.find(e=>e.id===r),a=e.dismissible===void 0||e.dismissible;return this.dismissedToasts.has(r)&&this.dismissedToasts.delete(r),i?this.toasts=this.toasts.map(n=>n.id===r?(this.publish({...n,...e,id:r,title:t}),{...n,...e,id:r,dismissible:a,title:t}):n):this.addToast({title:t,...n,dismissible:a,id:r}),r},this.dismiss=e=>(e?(this.dismissedToasts.add(e),requestAnimationFrame(()=>this.subscribers.forEach(t=>t({id:e,dismiss:!0})))):this.toasts.forEach(e=>{this.subscribers.forEach(t=>t({id:e.id,dismiss:!0}))}),e),this.message=(e,t)=>this.create({...t,message:e}),this.error=(e,t)=>this.create({...t,message:e,type:`error`}),this.success=(e,t)=>this.create({...t,type:`success`,message:e}),this.info=(e,t)=>this.create({...t,type:`info`,message:e}),this.warning=(e,t)=>this.create({...t,type:`warning`,message:e}),this.loading=(e,t)=>this.create({...t,type:`loading`,message:e}),this.promise=(e,t)=>{if(!t)return;let n;t.loading!==void 0&&(n=this.create({...t,promise:e,type:`loading`,message:t.loading,description:typeof t.description==`function`?void 0:t.description}));let r=Promise.resolve(e instanceof Function?e():e),i=n!==void 0,a,o=r.then(async e=>{if(a=[`resolve`,e],s.isValidElement(e))i=!1,this.create({id:n,type:`default`,message:e});else if(S(e)&&!e.ok){i=!1;let r=typeof t.error==`function`?await t.error(`HTTP error! status: ${e.status}`):t.error,a=typeof t.description==`function`?await t.description(`HTTP error! status: ${e.status}`):t.description,o=typeof r==`object`&&!s.isValidElement(r)?r:{message:r};this.create({id:n,type:`error`,description:a,...o})}else if(e instanceof Error){i=!1;let r=typeof t.error==`function`?await t.error(e):t.error,a=typeof t.description==`function`?await t.description(e):t.description,o=typeof r==`object`&&!s.isValidElement(r)?r:{message:r};this.create({id:n,type:`error`,description:a,...o})}else if(t.success!==void 0){i=!1;let r=typeof t.success==`function`?await t.success(e):t.success,a=typeof t.description==`function`?await t.description(e):t.description,o=typeof r==`object`&&!s.isValidElement(r)?r:{message:r};this.create({id:n,type:`success`,description:a,...o})}}).catch(async e=>{if(a=[`reject`,e],t.error!==void 0){i=!1;let r=typeof t.error==`function`?await t.error(e):t.error,a=typeof t.description==`function`?await t.description(e):t.description,o=typeof r==`object`&&!s.isValidElement(r)?r:{message:r};this.create({id:n,type:`error`,description:a,...o})}}).finally(()=>{i&&(this.dismiss(n),n=void 0),t.finally==null||t.finally.call(t)}),c=()=>new Promise((e,t)=>o.then(()=>a[0]===`reject`?t(a[1]):e(a[1])).catch(t));return typeof n!=`string`&&typeof n!=`number`?{unwrap:c}:Object.assign(n,{unwrap:c})},this.custom=(e,t)=>{let n=t?.id||y++;return this.create({jsx:e(n),id:n,...t}),n},this.getActiveToasts=()=>this.toasts.filter(e=>!this.dismissedToasts.has(e.id)),this.subscribers=[],this.toasts=[],this.dismissedToasts=new Set}},x=(e,t)=>{let n=t?.id||y++;return b.addToast({title:e,...t,id:n}),n},S=e=>e&&typeof e==`object`&&`ok`in e&&typeof e.ok==`boolean`&&`status`in e&&typeof e.status==`number`,C=Object.assign(x,{success:b.success,info:b.info,warning:b.warning,error:b.error,custom:b.custom,message:b.message,promise:b.promise,dismiss:b.dismiss,loading:b.loading},{getHistory:()=>b.toasts,getToasts:()=>b.getActiveToasts()});l(`[data-sonner-toaster][dir=ltr],html[dir=ltr]{--toast-icon-margin-start:-3px;--toast-icon-margin-end:4px;--toast-svg-margin-start:-1px;--toast-svg-margin-end:0px;--toast-button-margin-start:auto;--toast-button-margin-end:0;--toast-close-button-start:0;--toast-close-button-end:unset;--toast-close-button-transform:translate(-35%, -35%)}[data-sonner-toaster][dir=rtl],html[dir=rtl]{--toast-icon-margin-start:4px;--toast-icon-margin-end:-3px;--toast-svg-margin-start:0px;--toast-svg-margin-end:-1px;--toast-button-margin-start:0;--toast-button-margin-end:auto;--toast-close-button-start:unset;--toast-close-button-end:0;--toast-close-button-transform:translate(35%, -35%)}[data-sonner-toaster]{position:fixed;width:var(--width);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;--gray1:hsl(0, 0%, 99%);--gray2:hsl(0, 0%, 97.3%);--gray3:hsl(0, 0%, 95.1%);--gray4:hsl(0, 0%, 93%);--gray5:hsl(0, 0%, 90.9%);--gray6:hsl(0, 0%, 88.7%);--gray7:hsl(0, 0%, 85.8%);--gray8:hsl(0, 0%, 78%);--gray9:hsl(0, 0%, 56.1%);--gray10:hsl(0, 0%, 52.3%);--gray11:hsl(0, 0%, 43.5%);--gray12:hsl(0, 0%, 9%);--border-radius:8px;box-sizing:border-box;padding:0;margin:0;list-style:none;outline:0;z-index:999999999;transition:transform .4s ease}@media (hover:none) and (pointer:coarse){[data-sonner-toaster][data-lifted=true]{transform:none}}[data-sonner-toaster][data-x-position=right]{right:var(--offset-right)}[data-sonner-toaster][data-x-position=left]{left:var(--offset-left)}[data-sonner-toaster][data-x-position=center]{left:50%;transform:translateX(-50%)}[data-sonner-toaster][data-y-position=top]{top:var(--offset-top)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--offset-bottom)}[data-sonner-toast]{--y:translateY(100%);--lift-amount:calc(var(--lift) * var(--gap));z-index:var(--z-index);position:absolute;opacity:0;transform:var(--y);touch-action:none;transition:transform .4s,opacity .4s,height .4s,box-shadow .2s;box-sizing:border-box;outline:0;overflow-wrap:anywhere}[data-sonner-toast][data-styled=true]{padding:16px;background:var(--normal-bg);border:1px solid var(--normal-border);color:var(--normal-text);border-radius:var(--border-radius);box-shadow:0 4px 12px rgba(0,0,0,.1);width:var(--width);font-size:13px;display:flex;align-items:center;gap:6px}[data-sonner-toast]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-y-position=top]{top:0;--y:translateY(-100%);--lift:1;--lift-amount:calc(1 * var(--gap))}[data-sonner-toast][data-y-position=bottom]{bottom:0;--y:translateY(100%);--lift:-1;--lift-amount:calc(var(--lift) * var(--gap))}[data-sonner-toast][data-styled=true] [data-description]{font-weight:400;line-height:1.4;color:#3f3f3f}[data-rich-colors=true][data-sonner-toast][data-styled=true] [data-description]{color:inherit}[data-sonner-toaster][data-sonner-theme=dark] [data-description]{color:#e8e8e8}[data-sonner-toast][data-styled=true] [data-title]{font-weight:500;line-height:1.5;color:inherit}[data-sonner-toast][data-styled=true] [data-icon]{display:flex;height:16px;width:16px;position:relative;justify-content:flex-start;align-items:center;flex-shrink:0;margin-left:var(--toast-icon-margin-start);margin-right:var(--toast-icon-margin-end)}[data-sonner-toast][data-promise=true] [data-icon]>svg{opacity:0;transform:scale(.8);transform-origin:center;animation:sonner-fade-in .3s ease forwards}[data-sonner-toast][data-styled=true] [data-icon]>*{flex-shrink:0}[data-sonner-toast][data-styled=true] [data-icon] svg{margin-left:var(--toast-svg-margin-start);margin-right:var(--toast-svg-margin-end)}[data-sonner-toast][data-styled=true] [data-content]{display:flex;flex-direction:column;gap:2px}[data-sonner-toast][data-styled=true] [data-button]{border-radius:4px;padding-left:8px;padding-right:8px;height:24px;font-size:12px;color:var(--normal-bg);background:var(--normal-text);margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end);border:none;font-weight:500;cursor:pointer;outline:0;display:flex;align-items:center;flex-shrink:0;transition:opacity .4s,box-shadow .2s}[data-sonner-toast][data-styled=true] [data-button]:focus-visible{box-shadow:0 0 0 2px rgba(0,0,0,.4)}[data-sonner-toast][data-styled=true] [data-button]:first-of-type{margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end)}[data-sonner-toast][data-styled=true] [data-cancel]{color:var(--normal-text);background:rgba(0,0,0,.08)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-styled=true] [data-cancel]{background:rgba(255,255,255,.3)}[data-sonner-toast][data-styled=true] [data-close-button]{position:absolute;left:var(--toast-close-button-start);right:var(--toast-close-button-end);top:0;height:20px;width:20px;display:flex;justify-content:center;align-items:center;padding:0;color:var(--gray12);background:var(--normal-bg);border:1px solid var(--gray4);transform:var(--toast-close-button-transform);border-radius:50%;cursor:pointer;z-index:1;transition:opacity .1s,background .2s,border-color .2s}[data-sonner-toast][data-styled=true] [data-close-button]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-styled=true] [data-disabled=true]{cursor:not-allowed}[data-sonner-toast][data-styled=true]:hover [data-close-button]:hover{background:var(--gray2);border-color:var(--gray5)}[data-sonner-toast][data-swiping=true]::before{content:'';position:absolute;left:-100%;right:-100%;height:100%;z-index:-1}[data-sonner-toast][data-y-position=top][data-swiping=true]::before{bottom:50%;transform:scaleY(3) translateY(50%)}[data-sonner-toast][data-y-position=bottom][data-swiping=true]::before{top:50%;transform:scaleY(3) translateY(-50%)}[data-sonner-toast][data-swiping=false][data-removed=true]::before{content:'';position:absolute;inset:0;transform:scaleY(2)}[data-sonner-toast][data-expanded=true]::after{content:'';position:absolute;left:0;height:calc(var(--gap) + 1px);bottom:100%;width:100%}[data-sonner-toast][data-mounted=true]{--y:translateY(0);opacity:1}[data-sonner-toast][data-expanded=false][data-front=false]{--scale:var(--toasts-before) * 0.05 + 1;--y:translateY(calc(var(--lift-amount) * var(--toasts-before))) scale(calc(-1 * var(--scale)));height:var(--front-toast-height)}[data-sonner-toast]>*{transition:opacity .4s}[data-sonner-toast][data-x-position=right]{right:0}[data-sonner-toast][data-x-position=left]{left:0}[data-sonner-toast][data-expanded=false][data-front=false][data-styled=true]>*{opacity:0}[data-sonner-toast][data-visible=false]{opacity:0;pointer-events:none}[data-sonner-toast][data-mounted=true][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset)));height:var(--initial-height)}[data-sonner-toast][data-removed=true][data-front=true][data-swipe-out=false]{--y:translateY(calc(var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset) + var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=false]{--y:translateY(40%);opacity:0;transition:transform .5s,opacity .2s}[data-sonner-toast][data-removed=true][data-front=false]::before{height:calc(var(--initial-height) + 20%)}[data-sonner-toast][data-swiping=true]{transform:var(--y) translateY(var(--swipe-amount-y,0)) translateX(var(--swipe-amount-x,0));transition:none}[data-sonner-toast][data-swiped=true]{user-select:none}[data-sonner-toast][data-swipe-out=true][data-y-position=bottom],[data-sonner-toast][data-swipe-out=true][data-y-position=top]{animation-duration:.2s;animation-timing-function:ease-out;animation-fill-mode:forwards}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=left]{animation-name:swipe-out-left}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=right]{animation-name:swipe-out-right}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=up]{animation-name:swipe-out-up}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=down]{animation-name:swipe-out-down}@keyframes swipe-out-left{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) - 100%));opacity:0}}@keyframes swipe-out-right{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) + 100%));opacity:0}}@keyframes swipe-out-up{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) - 100%));opacity:0}}@keyframes swipe-out-down{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) + 100%));opacity:0}}@media (max-width:600px){[data-sonner-toaster]{position:fixed;right:var(--mobile-offset-right);left:var(--mobile-offset-left);width:100%}[data-sonner-toaster][dir=rtl]{left:calc(var(--mobile-offset-left) * -1)}[data-sonner-toaster] [data-sonner-toast]{left:0;right:0;width:calc(100% - var(--mobile-offset-left) * 2)}[data-sonner-toaster][data-x-position=left]{left:var(--mobile-offset-left)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--mobile-offset-bottom)}[data-sonner-toaster][data-y-position=top]{top:var(--mobile-offset-top)}[data-sonner-toaster][data-x-position=center]{left:var(--mobile-offset-left);right:var(--mobile-offset-right);transform:none}}[data-sonner-toaster][data-sonner-theme=light]{--normal-bg:#fff;--normal-border:var(--gray4);--normal-text:var(--gray12);--success-bg:hsl(143, 85%, 96%);--success-border:hsl(145, 92%, 87%);--success-text:hsl(140, 100%, 27%);--info-bg:hsl(208, 100%, 97%);--info-border:hsl(221, 91%, 93%);--info-text:hsl(210, 92%, 45%);--warning-bg:hsl(49, 100%, 97%);--warning-border:hsl(49, 91%, 84%);--warning-text:hsl(31, 92%, 45%);--error-bg:hsl(359, 100%, 97%);--error-border:hsl(359, 100%, 94%);--error-text:hsl(360, 100%, 45%)}[data-sonner-toaster][data-sonner-theme=light] [data-sonner-toast][data-invert=true]{--normal-bg:#000;--normal-border:hsl(0, 0%, 20%);--normal-text:var(--gray1)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-invert=true]{--normal-bg:#fff;--normal-border:var(--gray3);--normal-text:var(--gray12)}[data-sonner-toaster][data-sonner-theme=dark]{--normal-bg:#000;--normal-bg-hover:hsl(0, 0%, 12%);--normal-border:hsl(0, 0%, 20%);--normal-border-hover:hsl(0, 0%, 25%);--normal-text:var(--gray1);--success-bg:hsl(150, 100%, 6%);--success-border:hsl(147, 100%, 12%);--success-text:hsl(150, 86%, 65%);--info-bg:hsl(215, 100%, 6%);--info-border:hsl(223, 43%, 17%);--info-text:hsl(216, 87%, 65%);--warning-bg:hsl(64, 100%, 6%);--warning-border:hsl(60, 100%, 9%);--warning-text:hsl(46, 87%, 65%);--error-bg:hsl(358, 76%, 10%);--error-border:hsl(357, 89%, 16%);--error-text:hsl(358, 100%, 81%)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]{background:var(--normal-bg);border-color:var(--normal-border);color:var(--normal-text)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]:hover{background:var(--normal-bg-hover);border-color:var(--normal-border-hover)}[data-rich-colors=true][data-sonner-toast][data-type=success]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=success] [data-close-button]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=info]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=info] [data-close-button]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning] [data-close-button]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=error]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}[data-rich-colors=true][data-sonner-toast][data-type=error] [data-close-button]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}.sonner-loading-wrapper{--size:16px;height:var(--size);width:var(--size);position:absolute;inset:0;z-index:10}.sonner-loading-wrapper[data-visible=false]{transform-origin:center;animation:sonner-fade-out .2s ease forwards}.sonner-spinner{position:relative;top:50%;left:50%;height:var(--size);width:var(--size)}.sonner-loading-bar{animation:sonner-spin 1.2s linear infinite;background:var(--gray11);border-radius:6px;height:8%;left:-10%;position:absolute;top:-3.9%;width:24%}.sonner-loading-bar:first-child{animation-delay:-1.2s;transform:rotate(.0001deg) translate(146%)}.sonner-loading-bar:nth-child(2){animation-delay:-1.1s;transform:rotate(30deg) translate(146%)}.sonner-loading-bar:nth-child(3){animation-delay:-1s;transform:rotate(60deg) translate(146%)}.sonner-loading-bar:nth-child(4){animation-delay:-.9s;transform:rotate(90deg) translate(146%)}.sonner-loading-bar:nth-child(5){animation-delay:-.8s;transform:rotate(120deg) translate(146%)}.sonner-loading-bar:nth-child(6){animation-delay:-.7s;transform:rotate(150deg) translate(146%)}.sonner-loading-bar:nth-child(7){animation-delay:-.6s;transform:rotate(180deg) translate(146%)}.sonner-loading-bar:nth-child(8){animation-delay:-.5s;transform:rotate(210deg) translate(146%)}.sonner-loading-bar:nth-child(9){animation-delay:-.4s;transform:rotate(240deg) translate(146%)}.sonner-loading-bar:nth-child(10){animation-delay:-.3s;transform:rotate(270deg) translate(146%)}.sonner-loading-bar:nth-child(11){animation-delay:-.2s;transform:rotate(300deg) translate(146%)}.sonner-loading-bar:nth-child(12){animation-delay:-.1s;transform:rotate(330deg) translate(146%)}@keyframes sonner-fade-in{0%{opacity:0;transform:scale(.8)}100%{opacity:1;transform:scale(1)}}@keyframes sonner-fade-out{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.8)}}@keyframes sonner-spin{0%{opacity:1}100%{opacity:.15}}@media (prefers-reduced-motion){.sonner-loading-bar,[data-sonner-toast],[data-sonner-toast]>*{transition:none!important;animation:none!important}}.sonner-loader{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;transition:opacity .2s,transform .2s}.sonner-loader[data-visible=false]{opacity:0;transform:scale(.8) translate(-50%,-50%)}`);function w(e){return e.label!==void 0}var T=3,E=`24px`,D=`16px`,O=4e3,k=356,A=14,j=45,ee=200;function M(...e){return e.filter(Boolean).join(` `)}function N(e){let[t,n]=e.split(`-`),r=[];return t&&r.push(t),n&&r.push(n),r}var P=e=>{let{invert:t,toast:n,unstyled:r,interacting:i,setHeights:a,visibleToasts:o,heights:c,index:l,toasts:d,expanded:p,removeToast:m,defaultRichColors:h,closeButton:g,style:y,cancelButtonStyle:b,actionButtonStyle:x,className:S=``,descriptionClassName:C=``,duration:T,position:E,gap:D,expandByDefault:k,classNames:A,icons:P,closeButtonAriaLabel:te=`Close toast`}=e,[F,I]=s.useState(null),[L,R]=s.useState(null),[z,B]=s.useState(!1),[V,H]=s.useState(!1),[U,W]=s.useState(!1),[ne,re]=s.useState(!1),[ie,G]=s.useState(!1),[ae,K]=s.useState(0),[oe,se]=s.useState(0),q=s.useRef(n.duration||T||O),ce=s.useRef(null),J=s.useRef(null),le=l===0,ue=l+1<=o,Y=n.type,X=n.dismissible!==!1,de=n.className||``,fe=n.descriptionClassName||``,pe=s.useMemo(()=>c.findIndex(e=>e.toastId===n.id)||0,[c,n.id]),me=s.useMemo(()=>n.closeButton??g,[n.closeButton,g]),he=s.useMemo(()=>n.duration||T||O,[n.duration,T]),ge=s.useRef(0),Z=s.useRef(0),_e=s.useRef(0),Q=s.useRef(null),[ve,ye]=E.split(`-`),be=s.useMemo(()=>c.reduce((e,t,n)=>n>=pe?e:e+t.height,0),[c,pe]),xe=v(),Se=n.invert||t,Ce=Y===`loading`;Z.current=s.useMemo(()=>pe*D+be,[pe,be]),s.useEffect(()=>{q.current=he},[he]),s.useEffect(()=>{B(!0)},[]),s.useEffect(()=>{let e=J.current;if(e){let t=e.getBoundingClientRect().height;return se(t),a(e=>[{toastId:n.id,height:t,position:n.position},...e]),()=>a(e=>e.filter(e=>e.toastId!==n.id))}},[a,n.id]),s.useLayoutEffect(()=>{if(!z)return;let e=J.current,t=e.style.height;e.style.height=`auto`;let r=e.getBoundingClientRect().height;e.style.height=t,se(r),a(e=>e.find(e=>e.toastId===n.id)?e.map(e=>e.toastId===n.id?{...e,height:r}:e):[{toastId:n.id,height:r,position:n.position},...e])},[z,n.title,n.description,a,n.id,n.jsx,n.action,n.cancel]);let $=s.useCallback(()=>{H(!0),K(Z.current),a(e=>e.filter(e=>e.toastId!==n.id)),setTimeout(()=>{m(n)},ee)},[n,m,a,Z]);s.useEffect(()=>{if(n.promise&&Y===`loading`||n.duration===1/0||n.type===`loading`)return;let e;return p||i||xe?(()=>{if(_e.current<ge.current){let e=new Date().getTime()-ge.current;q.current-=e}_e.current=new Date().getTime()})():q.current!==1/0&&(ge.current=new Date().getTime(),e=setTimeout(()=>{n.onAutoClose==null||n.onAutoClose.call(n,n),$()},q.current)),()=>clearTimeout(e)},[p,i,n,Y,xe,$]),s.useEffect(()=>{n.delete&&($(),n.onDismiss==null||n.onDismiss.call(n,n))},[$,n.delete]);function we(){return P?.loading?s.createElement(`div`,{className:M(A?.loader,n?.classNames?.loader,`sonner-loader`),"data-visible":Y===`loading`},P.loading):s.createElement(f,{className:M(A?.loader,n?.classNames?.loader),visible:Y===`loading`})}let Te=n.icon||P?.[Y]||u(Y);return s.createElement(`li`,{tabIndex:0,ref:J,className:M(S,de,A?.toast,n?.classNames?.toast,A?.default,A?.[Y],n?.classNames?.[Y]),"data-sonner-toast":``,"data-rich-colors":n.richColors??h,"data-styled":!(n.jsx||n.unstyled||r),"data-mounted":z,"data-promise":!!n.promise,"data-swiped":ie,"data-removed":V,"data-visible":ue,"data-y-position":ve,"data-x-position":ye,"data-index":l,"data-front":le,"data-swiping":U,"data-dismissible":X,"data-type":Y,"data-invert":Se,"data-swipe-out":ne,"data-swipe-direction":L,"data-expanded":!!(p||k&&z),"data-testid":n.testId,style:{"--index":l,"--toasts-before":l,"--z-index":d.length-l,"--offset":`${V?ae:Z.current}px`,"--initial-height":k?`auto`:`${oe}px`,...y,...n.style},onDragEnd:()=>{W(!1),I(null),Q.current=null},onPointerDown:e=>{e.button!==2&&(Ce||!X||(ce.current=new Date,K(Z.current),e.target.setPointerCapture(e.pointerId),e.target.tagName!==`BUTTON`&&(W(!0),Q.current={x:e.clientX,y:e.clientY})))},onPointerUp:()=>{if(ne||!X)return;Q.current=null;let e=Number(J.current?.style.getPropertyValue(`--swipe-amount-x`).replace(`px`,``)||0),t=Number(J.current?.style.getPropertyValue(`--swipe-amount-y`).replace(`px`,``)||0),r=new Date().getTime()-ce.current?.getTime(),i=F===`x`?e:t,a=Math.abs(i)/r;if(Math.abs(i)>=j||a>.11){K(Z.current),n.onDismiss==null||n.onDismiss.call(n,n),R(F===`x`?e>0?`right`:`left`:t>0?`down`:`up`),$(),re(!0);return}else{var o,s;(o=J.current)==null||o.style.setProperty(`--swipe-amount-x`,`0px`),(s=J.current)==null||s.style.setProperty(`--swipe-amount-y`,`0px`)}G(!1),W(!1),I(null)},onPointerMove:t=>{var n,r;if(!Q.current||!X||window.getSelection()?.toString().length>0)return;let i=t.clientY-Q.current.y,a=t.clientX-Q.current.x,o=e.swipeDirections??N(E);!F&&(Math.abs(a)>1||Math.abs(i)>1)&&I(Math.abs(a)>Math.abs(i)?`x`:`y`);let s={x:0,y:0},c=e=>1/(1.5+Math.abs(e)/20);if(F===`y`){if(o.includes(`top`)||o.includes(`bottom`))if(o.includes(`top`)&&i<0||o.includes(`bottom`)&&i>0)s.y=i;else{let e=i*c(i);s.y=Math.abs(e)<Math.abs(i)?e:i}}else if(F===`x`&&(o.includes(`left`)||o.includes(`right`)))if(o.includes(`left`)&&a<0||o.includes(`right`)&&a>0)s.x=a;else{let e=a*c(a);s.x=Math.abs(e)<Math.abs(a)?e:a}(Math.abs(s.x)>0||Math.abs(s.y)>0)&&G(!0),(n=J.current)==null||n.style.setProperty(`--swipe-amount-x`,`${s.x}px`),(r=J.current)==null||r.style.setProperty(`--swipe-amount-y`,`${s.y}px`)}},me&&!n.jsx&&Y!==`loading`?s.createElement(`button`,{"aria-label":te,"data-disabled":Ce,"data-close-button":!0,onClick:Ce||!X?()=>{}:()=>{$(),n.onDismiss==null||n.onDismiss.call(n,n)},className:M(A?.closeButton,n?.classNames?.closeButton)},P?.close??_):null,(Y||n.icon||n.promise)&&n.icon!==null&&(P?.[Y]!==null||n.icon)?s.createElement(`div`,{"data-icon":``,className:M(A?.icon,n?.classNames?.icon)},n.promise||n.type===`loading`&&!n.icon?n.icon||we():null,n.type===`loading`?null:Te):null,s.createElement(`div`,{"data-content":``,className:M(A?.content,n?.classNames?.content)},s.createElement(`div`,{"data-title":``,className:M(A?.title,n?.classNames?.title)},n.jsx?n.jsx:typeof n.title==`function`?n.title():n.title),n.description?s.createElement(`div`,{"data-description":``,className:M(C,fe,A?.description,n?.classNames?.description)},typeof n.description==`function`?n.description():n.description):null),s.isValidElement(n.cancel)?n.cancel:n.cancel&&w(n.cancel)?s.createElement(`button`,{"data-button":!0,"data-cancel":!0,style:n.cancelButtonStyle||b,onClick:e=>{w(n.cancel)&&X&&(n.cancel.onClick==null||n.cancel.onClick.call(n.cancel,e),$())},className:M(A?.cancelButton,n?.classNames?.cancelButton)},n.cancel.label):null,s.isValidElement(n.action)?n.action:n.action&&w(n.action)?s.createElement(`button`,{"data-button":!0,"data-action":!0,style:n.actionButtonStyle||x,onClick:e=>{w(n.action)&&(n.action.onClick==null||n.action.onClick.call(n.action,e),!e.defaultPrevented&&$())},className:M(A?.actionButton,n?.classNames?.actionButton)},n.action.label):null)};function te(){if(typeof window>`u`||typeof document>`u`)return`ltr`;let e=document.documentElement.getAttribute(`dir`);return e===`auto`||!e?window.getComputedStyle(document.documentElement).direction:e}function F(e,t){let n={};return[e,t].forEach((e,t)=>{let r=t===1,i=r?`--mobile-offset`:`--offset`,a=r?D:E;function o(e){[`top`,`right`,`bottom`,`left`].forEach(t=>{n[`${i}-${t}`]=typeof e==`number`?`${e}px`:e})}typeof e==`number`||typeof e==`string`?o(e):typeof e==`object`?[`top`,`right`,`bottom`,`left`].forEach(t=>{e[t]===void 0?n[`${i}-${t}`]=a:n[`${i}-${t}`]=typeof e[t]==`number`?`${e[t]}px`:e[t]}):o(a)}),n}var I=s.forwardRef(function(e,t){let{id:n,invert:r,position:i=`bottom-right`,hotkey:a=[`altKey`,`KeyT`],expand:o,closeButton:l,className:u,offset:d,mobileOffset:f,theme:p=`light`,richColors:m,duration:h,style:g,visibleToasts:_=T,toastOptions:v,dir:y=te(),gap:x=A,icons:S,containerAriaLabel:C=`Notifications`}=e,[w,E]=s.useState([]),D=s.useMemo(()=>n?w.filter(e=>e.toasterId===n):w.filter(e=>!e.toasterId),[w,n]),O=s.useMemo(()=>Array.from(new Set([i].concat(D.filter(e=>e.position).map(e=>e.position)))),[D,i]),[j,ee]=s.useState([]),[M,N]=s.useState(!1),[I,L]=s.useState(!1),[R,z]=s.useState(p===`system`?typeof window<`u`&&window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`:p),B=s.useRef(null),V=a.join(`+`).replace(/Key/g,``).replace(/Digit/g,``),H=s.useRef(null),U=s.useRef(!1),W=s.useCallback(e=>{E(t=>(t.find(t=>t.id===e.id)?.delete||b.dismiss(e.id),t.filter(({id:t})=>t!==e.id)))},[]);return s.useEffect(()=>b.subscribe(e=>{if(e.dismiss){requestAnimationFrame(()=>{E(t=>t.map(t=>t.id===e.id?{...t,delete:!0}:t))});return}setTimeout(()=>{c.flushSync(()=>{E(t=>{let n=t.findIndex(t=>t.id===e.id);return n===-1?[e,...t]:[...t.slice(0,n),{...t[n],...e},...t.slice(n+1)]})})})}),[w]),s.useEffect(()=>{if(p!==`system`){z(p);return}if(p===`system`&&(window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches?z(`dark`):z(`light`)),typeof window>`u`)return;let e=window.matchMedia(`(prefers-color-scheme: dark)`);try{e.addEventListener(`change`,({matches:e})=>{z(e?`dark`:`light`)})}catch{e.addListener(({matches:e})=>{try{z(e?`dark`:`light`)}catch(e){console.error(e)}})}},[p]),s.useEffect(()=>{w.length<=1&&N(!1)},[w]),s.useEffect(()=>{let e=e=>{if(a.every(t=>e[t]||e.code===t)){var t;N(!0),(t=B.current)==null||t.focus()}e.code===`Escape`&&(document.activeElement===B.current||B.current?.contains(document.activeElement))&&N(!1)};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[a]),s.useEffect(()=>{if(B.current)return()=>{H.current&&(H.current.focus({preventScroll:!0}),H.current=null,U.current=!1)}},[B.current]),s.createElement(`section`,{ref:t,"aria-label":`${C} ${V}`,tabIndex:-1,"aria-live":`polite`,"aria-relevant":`additions text`,"aria-atomic":`false`,suppressHydrationWarning:!0},O.map((t,n)=>{let[i,a]=t.split(`-`);return D.length?s.createElement(`ol`,{key:t,dir:y===`auto`?te():y,tabIndex:-1,ref:B,className:u,"data-sonner-toaster":!0,"data-sonner-theme":R,"data-y-position":i,"data-x-position":a,style:{"--front-toast-height":`${j[0]?.height||0}px`,"--width":`${k}px`,"--gap":`${x}px`,...g,...F(d,f)},onBlur:e=>{U.current&&!e.currentTarget.contains(e.relatedTarget)&&(U.current=!1,H.current&&=(H.current.focus({preventScroll:!0}),null))},onFocus:e=>{e.target instanceof HTMLElement&&e.target.dataset.dismissible===`false`||U.current||(U.current=!0,H.current=e.relatedTarget)},onMouseEnter:()=>N(!0),onMouseMove:()=>N(!0),onMouseLeave:()=>{I||N(!1)},onDragEnd:()=>N(!1),onPointerDown:e=>{e.target instanceof HTMLElement&&e.target.dataset.dismissible===`false`||L(!0)},onPointerUp:()=>L(!1)},D.filter(e=>!e.position&&n===0||e.position===t).map((n,i)=>s.createElement(P,{key:n.id,icons:S,index:i,toast:n,defaultRichColors:m,duration:v?.duration??h,className:v?.className,descriptionClassName:v?.descriptionClassName,invert:r,visibleToasts:_,closeButton:v?.closeButton??l,interacting:I,position:t,style:v?.style,unstyled:v?.unstyled,classNames:v?.classNames,cancelButtonStyle:v?.cancelButtonStyle,actionButtonStyle:v?.actionButtonStyle,closeButtonAriaLabel:v?.closeButtonAriaLabel,removeToast:W,toasts:D.filter(e=>e.position==n.position),heights:j.filter(e=>e.position==n.position),setHeights:ee,expandByDefault:o,gap:x,expanded:M,swipeDirections:e.swipeDirections}))):null}))}),L=null;function R(e){L=e}function z(){if(!L)throw Error(`getApiBase called with no active project — call setActiveProjectId first`);return`${a}/api/projects/${L}`}var B=new Map;function V(e,t){return`${e}:${t}`}function H(e){return(e instanceof Error?e.message:e==null?``:String(e)).trim()||`Request failed`}function U(e){if(!e)return;let t=`${e}:`;for(let e of B.keys())e.startsWith(t)&&B.delete(e)}function W({namespace:e,projectId:t,initialValue:n,fetcher:r,pollInterval:i=0}){let a=t?V(t,e):null,[o,c]=(0,s.useState)(()=>a&&B.has(a)?B.get(a):n),[l,u]=(0,s.useState)(()=>!a||!B.has(a)),[d,f]=(0,s.useState)(l),[p,m]=(0,s.useState)(null),h=(0,s.useRef)(r);h.current=r;let g=(0,s.useRef)(n);g.current=n;let _=(0,s.useRef)(a);_.current=a;let v=(0,s.useRef)(0),y=(0,s.useRef)(null),b=(0,s.useCallback)(async(e,t,n)=>{let r=++v.current;y.current?.abort();let i=new AbortController;y.current=i,n&&_.current===e&&(f(!0),m(null));try{let n=await h.current({projectId:t,signal:i.signal});if(i.signal.aborted||r!==v.current)return;B.set(e,n),_.current===e&&(c(n),m(null))}catch(t){if(i.signal.aborted||r!==v.current)return;_.current===e&&m(H(t))}finally{r===v.current&&(y.current===i&&(y.current=null),_.current===e&&(f(!1),u(!1)))}},[]);return(0,s.useEffect)(()=>{if(v.current+=1,y.current?.abort(),y.current=null,m(null),!a||!t){c(g.current),u(!0),f(!1);return}let e=B.has(a);e?(c(B.get(a)),u(!1),f(!1)):(c(g.current),u(!0),f(!0)),b(a,t,!e);let n;return i>0&&(n=setInterval(()=>{b(a,t,!1)},i)),()=>{v.current+=1,y.current?.abort(),y.current=null,n&&clearInterval(n)}},[a,t,i,b]),{data:o,isLoading:d,isFirstLoad:l,error:p,refresh:(0,s.useCallback)(async()=>{!a||!t||await b(a,t,!0)},[a,t,b])}}var ne=n();function re(e){return e.providers&&e.providers.length>0?e.providers:[e.provider]}var ie=(0,s.createContext)(null),G=`specrails-desktop:activeProjectId`;function ae(e){try{e?localStorage.setItem(G,e):localStorage.removeItem(G)}catch{}}function K(){try{return localStorage.getItem(G)}catch{return null}}function oe({children:e,isolated:t=!1}){let n=(0,s.useCallback)(e=>{t||ae(e)},[t]),[r,c]=(0,s.useState)([]),[l,u]=(0,s.useState)(null),[d,f]=(0,s.useState)(!0),[p,m]=(0,s.useState)(!1),h=(0,s.useRef)(null),g=(0,s.useRef)(new Set),_=(0,s.useRef)(!1),v=(0,s.useRef)(0),y=(0,s.useRef)(null),b=(0,s.useRef)(null),x=(0,s.useRef)(0),S=(0,s.useCallback)(e=>{n(e),R(e),u(t=>(t!==null&&t!==e&&(h.current&&clearTimeout(h.current),m(!0),h.current=setTimeout(()=>m(!1),400)),e))},[n]),{registerHandler:w,unregisterHandler:T,connectionStatus:E}=o(),D=(0,s.useCallback)(async function e(){if(!_.current||y.current)return;b.current&&clearTimeout(b.current);let r=new AbortController;y.current=r;let i=v.current,o=setTimeout(()=>r.abort(),8e3);try{let e=await fetch(`${a}/api/projects`,{signal:r.signal});if(!e.ok)throw Error(`HTTP ${e.status}`);let o=await e.json();if(!Array.isArray(o.projects))throw Error(`Invalid project snapshot`);if(!_.current||r.signal.aborted||i!==v.current)return;c(o.projects);let s=o.projects;u(e=>{if(e&&s.some(t=>t.id===e))return e;let r=t?null:K(),i=r&&s.some(e=>e.id===r)?r:null;return n(i),R(i),i}),x.current=0,f(!1)}catch{if(_.current&&i===v.current){let t=Math.min(500*2**Math.min(x.current++,5),1e4);b.current=setTimeout(()=>{e()},t)}}finally{clearTimeout(o),y.current===r&&(y.current=null)}},[t,n]);(0,s.useEffect)(()=>{_.current=!0,D();let e=()=>{D()};return window.addEventListener(`online`,e),window.addEventListener(`focus`,e),()=>{_.current=!1,v.current++,y.current?.abort(),y.current=null,b.current&&clearTimeout(b.current),h.current&&clearTimeout(h.current),window.removeEventListener(`online`,e),window.removeEventListener(`focus`,e)}},[D]);let O=(0,s.useRef)(E),k=(0,s.useRef)(E===`connected`);(0,s.useEffect)(()=>{E===`connected`&&(k.current&&O.current!==`connected`&&D(),k.current=!0),O.current=E},[E,D]);let A=(0,s.useCallback)(e=>{if(!e||typeof e!=`object`)return;let r=e;if(typeof r.type==`string`){if(r.type===`desktop.projects`){if(!Array.isArray(r.projects))return;v.current++,x.current=0,b.current&&clearTimeout(b.current);let e=r.projects;c(e),u(r=>{let i;if(r&&e.find(e=>e.id===r))i=r;else{let n=t?null:K();i=n&&e.find(e=>e.id===n)?n:!t&&e.length>0?e[0].id:null}return n(i),R(i),i}),f(!1)}else if(r.type===`desktop.project_added`){let e=r.project;if(!e||typeof e.id!=`string`)return;v.current++,c(t=>t.find(t=>t.id===e.id)?t:[...t,e]),g.current.has(e.id)?g.current.delete(e.id):t||(C.success(i.t(`nav:projects.added`,{name:e.name})),S(e.id))}else if(r.type===`providers.detected_changed`)D();else if(r.type===`desktop.project_removed`){let e=r.projectId;if(typeof e!=`string`)return;v.current++,t||C.success(i.t(`nav:projects.removed`)),U(e),c(t=>t.filter(t=>t.id!==e)),u(t=>t===e?(n(null),R(null),null):t)}}},[D,S,t,n]);(0,s.useLayoutEffect)(()=>(w(`desktop`,A),()=>T(`desktop`)),[A,w,T]);let j=(0,s.useRef)(0);(0,s.useEffect)(()=>{let e=()=>{let e=Date.now();e-j.current<6e4||(j.current=e,fetch(`${a}/api/providers/detected?refresh=1`).catch(()=>{}))};return window.addEventListener(`focus`,e),()=>window.removeEventListener(`focus`,e)},[]);let ee=(0,s.useCallback)(async(e,t,n,r)=>{try{let i={path:e};n&&n.length>0&&(i.providers=n),t&&(i.name=t),r?.length&&(i.repositories=r);let a=await fetch(`/api/projects`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)});if(!a.ok){let e=await a.json();throw Error(e.error??`HTTP ${a.status}`)}let o=await a.json();return g.current.add(o.project.id),v.current++,c(e=>e.find(e=>e.id===o.project.id)?e:[...e,o.project]),S(o.project.id),o}catch(e){throw console.error(`[useDesktop] addProject error:`,e),e}},[S]),M=(0,s.useCallback)(async e=>{try{let t=await fetch(`${a}/api/projects/${e}`,{method:`DELETE`});if(!t.ok){let e=await t.json();throw Error(e.error??`HTTP ${t.status}`)}U(e),v.current++,c(t=>t.filter(t=>t.id!==e)),u(t=>t===e?(n(null),R(null),null):t)}catch(e){throw console.error(`[useDesktop] removeProject error:`,e),e}},[n]),N=(0,s.useMemo)(()=>({projects:r,activeProjectId:l,setActiveProjectId:S,addProject:ee,removeProject:M,refreshProjects:D,isLoading:d,isSwitchingProject:p}),[r,l,S,ee,M,D,d,p]);return(0,ne.jsx)(ie.Provider,{value:N,children:e})}var se={projects:[],activeProjectId:null,setActiveProjectId:()=>{},addProject:async()=>null,removeProject:async()=>{},refreshProjects:async()=>{},isLoading:!1,isSwitchingProject:!1};function q(){return(0,s.useContext)(ie)??se}export{z as a,W as i,re as n,I as o,q as r,C as s,oe as t};
@@ -0,0 +1 @@
1
+ import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t}from"./jsx-runtime-zu2_FqZY.js";import{n}from"./createLucideIcon-Bjbbp_KS.js";import{n as r}from"./project-repositories-CSnfzUpg.js";function i(e){if(!Number.isFinite(e)||e<0)return`0s`;let t=Math.round(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60),r=t%60;return n<60?`${n}m ${r}s`:`${Math.floor(n/60)}h ${n%60}m`}var a=e(t(),1);function o(e,t={}){let{jobId:i,railIndex:o,enabled:s=!0}=t,{t:c}=n(`agentRuntime`),[l,u]=(0,a.useState)([]),[d,f]=(0,a.useState)(``),[p,m]=(0,a.useState)(null),[h,g]=(0,a.useState)(0),[_,v]=(0,a.useState)({}),y=(0,a.useRef)(!0),b=s&&!!e,x=e?`${r(e)}/agent-runtime/runs`:``,S=(0,a.useRef)(x);S.current=x;let C=(0,a.useRef)(new Set);(0,a.useEffect)(()=>{m(null),v({})},[x]);let w=i?`${x}/${encodeURIComponent(i)}`:o===void 0?x:`${x}?railIndex=${o}`;(0,a.useEffect)(()=>{if(y.current=!0,!b)return u([]),f(``),()=>{y.current=!1};let e=!1,t;async function n(){try{let t=await fetch(w,{cache:`no-store`});if(!t.ok)throw Error();let n=await t.json();if(!Array.isArray(n.runs))throw Error();e||(u(n.runs),f(``))}catch{e||f(c(`runs.loadFailed`))}finally{e||(t=setTimeout(()=>void n(),1e4))}}return n(),()=>{e=!0,y.current=!1,clearTimeout(t)}},[b,w,h,c]);let T=(0,a.useCallback)(async(t,n,i)=>{let a=`${x}:${t.runId}`;if(!e||C.current.has(a))return;C.current.add(a);let o=()=>y.current&&S.current===x;m(t.runId),f(``);try{let a=n===`approve`?{approve:[t.pendingApproval.stepId]}:n===`recover`?{recover:i??t.recoverableSteps}:n===`answer`?{answer:(_[t.runId]??``).trim(),...t.engineVersion===2&&t.pendingQuestion?{interruptId:t.pendingQuestion.stepId}:{}}:{},s=n===`cancel`?`cancel`:n===`settle`?`settle`:n===`dismiss`?`dismiss`:`resume`,l=t.engineVersion===2&&(s===`resume`||s===`settle`),u=l||t.engineVersion===2&&s===`cancel`?`${r(e)}/loop-runs`:x,d=await fetch(`${u}/${encodeURIComponent(t.runId)}/${l?`resume`:s}`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(a)});if(!d.ok){let e=await d.json();throw Error(e.message??e.detail??c(`runs.actionFailed`))}o()&&(n===`answer`&&v(e=>({...e,[t.runId]:``})),g(e=>e+1))}catch(e){o()&&f(e instanceof Error?e.message:c(`runs.actionFailed`))}finally{C.current.delete(a),o()&&m(null)}},[_,x,e,c]);return{runs:l,error:d,busy:p,answers:_,setAnswer:(0,a.useCallback)((e,t)=>{v(n=>({...n,[e]:t}))},[]),act:T,refresh:(0,a.useCallback)(()=>g(e=>e+1),[])}}export{i as n,o as t};