specrails-desktop 2.25.0 → 2.26.1

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 (140) hide show
  1. package/client/dist/assets/{ActivityFeedPage-BGRTOOhT.js → ActivityFeedPage-C1LftFSE.js} +1 -1
  2. package/client/dist/assets/{AgentBrowserCapture-DvDLxsUy.js → AgentBrowserCapture-B5prW-V0.js} +1 -1
  3. package/client/dist/assets/{AgentModeCodePane-DfwctjzN.js → AgentModeCodePane-b6UmdjwB.js} +2 -2
  4. package/client/dist/assets/{AgentModeJobsPane-G3WrS-sE.js → AgentModeJobsPane-DW3Wj5oi.js} +1 -1
  5. package/client/dist/assets/{AgentsPage-DGFFijMC.js → AgentsPage-DBMnhdlq.js} +3 -3
  6. package/client/dist/assets/{AnalyticsPage-hoJmlEpk.js → AnalyticsPage-DjFf1OxU.js} +1 -1
  7. package/client/dist/assets/{BarChart-BEhAXVK-.js → BarChart-nmDbbUiR.js} +1 -1
  8. package/client/dist/assets/{CodePage-B4zB9DVC.js → CodePage-DHd46Sm7.js} +1 -1
  9. package/client/dist/assets/{DesktopAnalyticsPage-CBX-Qpxd.js → DesktopAnalyticsPage-ee0bpk-F.js} +1 -1
  10. package/client/dist/assets/{DocsDialog-lTsnNdAM.js → DocsDialog-CGUzB1zX.js} +1 -1
  11. package/client/dist/assets/{DocsPage-CkvdGroT.js → DocsPage-96iws84I.js} +1 -1
  12. package/client/dist/assets/{ExportDropdown-Da98gR-P.js → ExportDropdown-Dzk2Lkxw.js} +1 -1
  13. package/client/dist/assets/{IntegrationsPage-Cf9o4eZq.js → IntegrationsPage-Bta2lAhq.js} +1 -1
  14. package/client/dist/assets/{InteractiveJobComposer-C8N-Bbnn.js → InteractiveJobComposer-B9S_ZGJS.js} +5 -5
  15. package/client/dist/assets/{JobDetailModal-BZVwIIEx.js → JobDetailModal-DhrwU2z0.js} +1 -1
  16. package/client/dist/assets/{JobDetailPage-CQewQ1zy.js → JobDetailPage-BnhoXkql.js} +1 -1
  17. package/client/dist/assets/{JobsPage-CB4wOxmE.js → JobsPage-BBT9fyhg.js} +1 -1
  18. package/client/dist/assets/{LoopBuilderPage-B9Y5gt08.js → LoopBuilderPage-5ucN9Hq9.js} +2 -2
  19. package/client/dist/assets/{LoopPreviewModal-kxQ5kV1t.js → LoopPreviewModal-wKAts-Wf.js} +1 -1
  20. package/client/dist/assets/{LoopsPage-RysW-6sC.js → LoopsPage-COyxf6Pa.js} +1 -1
  21. package/client/dist/assets/{ProjectSettingsDialog-BHN5qsGT.js → ProjectSettingsDialog-CcToBI-Z.js} +1 -1
  22. package/client/dist/assets/{TemplatePreviewModal-DW6lZCIs.js → TemplatePreviewModal-_Dy6ceXg.js} +1 -1
  23. package/client/dist/assets/agent-BmH52J4j.js +1 -0
  24. package/client/dist/assets/agent-Bxb9RRNW.js +1 -0
  25. package/client/dist/assets/agent-Cg49-TGZ.js +1 -0
  26. package/client/dist/assets/agent-DgDtg-0Y2.js +1 -0
  27. package/client/dist/assets/agent-DolxzTol.js +1 -0
  28. package/client/dist/assets/agent-DwDR2Exf2.js +1 -0
  29. package/client/dist/assets/agent-_tfCgFUk.js +1 -0
  30. package/client/dist/assets/agent-gFi-qvxO2.js +1 -0
  31. package/client/dist/assets/{brain-B9dkGuAN.js → brain-BJ2Gd98j.js} +1 -1
  32. package/client/dist/assets/code-CwnBPPyA.js +1 -0
  33. package/client/dist/assets/dashboard-90r0QcUc2.js +1 -0
  34. package/client/dist/assets/dashboard-B0C6mJP-.js +1 -0
  35. package/client/dist/assets/dashboard-BOx0FR1L2.js +1 -0
  36. package/client/dist/assets/dashboard-BcjUOLJr.js +1 -0
  37. package/client/dist/assets/dashboard-C27kNpjn.js +1 -0
  38. package/client/dist/assets/dashboard-DJAj2EbH.js +1 -0
  39. package/client/dist/assets/dashboard-DNd1Gobs.js +1 -0
  40. package/client/dist/assets/dashboard-DZWrDAYm2.js +1 -0
  41. package/client/dist/assets/{dist-js-Bbd7Wzdw.js → dist-js-CXAsO0Z8.js} +1 -1
  42. package/client/dist/assets/{dist-js-BW5-IZTP.js → dist-js-D7smLA35.js} +1 -1
  43. package/client/dist/assets/index-B3ejvKSt.js +156 -0
  44. package/client/dist/assets/index-C695aPdV.css +2 -0
  45. package/client/dist/assets/{lib-EIkIPf26.js → lib-BIHmUkcn.js} +1 -1
  46. package/client/dist/assets/{loops-YYV2bwjd.js → loops-Brnx4Fji.js} +1 -1
  47. package/client/dist/assets/{loops-hXgncEpF2.js → loops-BvqQ-bHR2.js} +1 -1
  48. package/client/dist/assets/{loops-BvEenWBy.js → loops-CvOWsi5r.js} +1 -1
  49. package/client/dist/assets/{loops-DjOtVXRo.js → loops-D6D3XHjj.js} +1 -1
  50. package/client/dist/assets/{loops-HTHf-xu32.js → loops-DJNhp17p2.js} +1 -1
  51. package/client/dist/assets/{loops-kYbydDyN.js → loops-K5_HXfJa.js} +1 -1
  52. package/client/dist/assets/loops-LIgO_-eM.js +1 -0
  53. package/client/dist/assets/{loops-DNGiYKll2.js → loops-vhJdbcz92.js} +1 -1
  54. package/client/dist/assets/{settings-BsJMsWGc.js → settings-BHdPchJP.js} +1 -1
  55. package/client/dist/assets/{settings-lFoaYT-s2.js → settings-BeCczBFS2.js} +1 -1
  56. package/client/dist/assets/{settings-DZJeXoRV.js → settings-BlLi719f.js} +1 -1
  57. package/client/dist/assets/{settings-BOHOmHkb.js → settings-C_nY14Yz.js} +1 -1
  58. package/client/dist/assets/{settings-D6qY9_UI.js → settings-CaZ26a0S.js} +1 -1
  59. package/client/dist/assets/{settings-BlEA_7h02.js → settings-D54_cgl12.js} +1 -1
  60. package/client/dist/assets/settings-D9bDDe2O.js +1 -0
  61. package/client/dist/assets/{settings-TNga5gIF2.js → settings-cn0tbve62.js} +1 -1
  62. package/client/dist/assets/{setup-iY8vH8pB.js → setup-7J8TjG4O.js} +1 -1
  63. package/client/dist/assets/{setup-D674kWQH.js → setup-BXpw07r-.js} +1 -1
  64. package/client/dist/assets/{setup-B590KsTX.js → setup-BiduSX9d.js} +1 -1
  65. package/client/dist/assets/{setup-CmU6bTCV2.js → setup-BuQNKztt2.js} +1 -1
  66. package/client/dist/assets/{setup-CEj6uY3-2.js → setup-BwMovM9z2.js} +1 -1
  67. package/client/dist/assets/{setup-BkyGoby6.js → setup-D84y3wx-.js} +1 -1
  68. package/client/dist/assets/{setup-CbIerFGf2.js → setup-DU0ULX8q2.js} +1 -1
  69. package/client/dist/assets/{setup-VNqXyB6Y.js → setup-RiUHzq7E.js} +1 -1
  70. package/client/dist/assets/{upload-BCMl-nCg.js → upload-xdQuJvXN.js} +1 -1
  71. package/client/dist/assets/{value-CG-amSq1.js → value-Bk2f9AUg.js} +1 -1
  72. package/client/dist/index.html +22 -9
  73. package/docs/agy-cli-provider-study.md +1 -1
  74. package/docs/codex.md +2 -2
  75. package/docs/gemini-cli-provider-study.md +2 -2
  76. package/docs/guide/de/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  77. package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  78. package/docs/guide/es/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  79. package/docs/guide/fr/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  80. package/docs/guide/it/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  81. package/docs/guide/ja/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  82. package/docs/guide/pt/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  83. package/docs/guide/pt/pipeline/5-the-loop-builder.md +1 -1
  84. package/docs/guide/zh/pipeline/3-batch-implement-and-multi-feature.md +1 -1
  85. package/docs/internals/api-reference.md +3 -3
  86. package/docs/internals/companion-rails-as-loops-contract.md +6 -6
  87. package/docs/internals/configuration.md +1 -1
  88. package/docs/internals/interactive-jobs.md +3 -3
  89. package/docs/internals/safe-pr-review-flow.md +1 -1
  90. package/docs/internals/visual-design-audit.md +2 -2
  91. package/docs/running-pipelines.md +1 -1
  92. package/package.json +1 -1
  93. package/server/dist/agent-chat-manager.js +16 -2
  94. package/server/dist/agent-chat-router.js +66 -1
  95. package/server/dist/agent-context-resolver.js +301 -0
  96. package/server/dist/agent-operator-prompt.js +58 -11
  97. package/server/dist/agent-store.js +24 -12
  98. package/server/dist/db.js +17 -17
  99. package/server/dist/desktop-db.js +6 -0
  100. package/server/dist/desktop-router.js +9 -2
  101. package/server/dist/feature-flags.js +2 -2
  102. package/server/dist/index.js +1 -1
  103. package/server/dist/interactive-job-session.js +3 -3
  104. package/server/dist/loop-command-catalog.js +11 -11
  105. package/server/dist/loop-factory.js +7 -7
  106. package/server/dist/loop-graph.js +2 -2
  107. package/server/dist/loop-run-manager.js +1 -1
  108. package/server/dist/mcp/guide.js +41 -10
  109. package/server/dist/mcp/tools/app-settings.js +18 -2
  110. package/server/dist/mcp/tools/catalog.js +2 -0
  111. package/server/dist/mcp/tools/rails.js +29 -9
  112. package/server/dist/mcp/tools/support.js +324 -0
  113. package/server/dist/mobile/mobile-router.js +1 -1
  114. package/server/dist/project-router-jobs.js +1 -1
  115. package/server/dist/project-router-loop-runs.js +1 -1
  116. package/server/dist/project-router-settings.js +5 -5
  117. package/server/dist/queue-manager.js +27 -27
  118. package/server/dist/rail-isolated-launch.js +5 -1
  119. package/server/dist/rails-router.js +76 -27
  120. package/client/dist/assets/agent-4ARs0uac2.js +0 -1
  121. package/client/dist/assets/agent-C55wwsUX.js +0 -1
  122. package/client/dist/assets/agent-C_kqyrXo.js +0 -1
  123. package/client/dist/assets/agent-Df3lnHMu.js +0 -1
  124. package/client/dist/assets/agent-G6Zn2gpr.js +0 -1
  125. package/client/dist/assets/agent-MQhun7cv.js +0 -1
  126. package/client/dist/assets/agent-NqlER4Yh2.js +0 -1
  127. package/client/dist/assets/agent-OTGI6t7e2.js +0 -1
  128. package/client/dist/assets/code-CqCcRThR.js +0 -1
  129. package/client/dist/assets/dashboard-4WX7agHF2.js +0 -1
  130. package/client/dist/assets/dashboard-5Z_esXIB.js +0 -1
  131. package/client/dist/assets/dashboard-DQ-po1MG2.js +0 -1
  132. package/client/dist/assets/dashboard-IbEztmJ52.js +0 -1
  133. package/client/dist/assets/dashboard-nc-Raovv.js +0 -1
  134. package/client/dist/assets/dashboard-ojWdDq6S.js +0 -1
  135. package/client/dist/assets/dashboard-oqS7VRrK.js +0 -1
  136. package/client/dist/assets/dashboard-zfoJcdFW.js +0 -1
  137. package/client/dist/assets/index-BtAks9nm.css +0 -2
  138. package/client/dist/assets/index-DC-REAcL.js +0 -155
  139. package/client/dist/assets/loops-CBiWd9Hf.js +0 -1
  140. package/client/dist/assets/settings-Mr7MnJbf.js +0 -1
@@ -1 +1 @@
1
- var e={configureAgents:`Configura gli agenti {{provider}}`,configureSubtitle:`Scegli quali agenti installare e come eseguirli.`,tabs:{agents:`Agenti`,models:`Modelli`},skipForNow:`Salta per ora`,install:`Installa`,nextProvider:`Avanti: {{provider}}`,installingProvider:`Installazione di {{provider}}…`,installingSpecrails:`Installazione di specrails...`,installingFromTemplates:`Installazione degli agenti dai template`,waitingForOutput:`In attesa dell'output...`,checkpoints:{baseInstall:`Installazione di base`,agentSelection:`Selezione degli agenti`,agentGeneration:`Generazione degli agenti`},steps:{configure:`Configura`},summary:{agents:`Agenti`,agentSkills:`Skill degli agenti`,skills:`Skill`,openspecSkills:`Skill OpenSpec`,legacyRemoved_one:`Rimosso {{count}} comando legacy <code>/specrails:*</code>`,legacyRemoved_other:`Rimossi {{count}} comandi legacy <code>/specrails:*</code>`},complete:{welcome:`Benvenuto in <spec>spec</spec><rails>rails</rails>`,configured:`<strong>{{projectName}}</strong> è ora configurato con workflow di sviluppo basati sull'IA. I tuoi agenti specializzati e i comandi sono pronti all'uso.`,installedForEngines_one:`Installato per {{count}} engine`,installedForEngines_other:`Installato per {{count}} engine`,installed:`Installato`,installFailed:`Installazione non riuscita`,learnMore:`Scopri come ottenere il massimo da specrails:`,continueToProject:`Continua al progetto`,jira:{title:`Collega una board Jira`,subtitle:`Facoltativo — appoggia le spec di questo progetto a una board Jira. Puoi farlo anche più tardi nelle Impostazioni.`,configure:`Configura Jira`,optional:`facoltativo`},mcpHint:`Collega strumenti di IA esterni a Specrails tramite un server MCP locale sicuro — attivalo nelle Impostazioni.`,agentChatHint:`Gestisci Specrails chattando — l'agente integrato guida l'intera app per te. Aprilo dalla bolla o con ⌘⇧A.`},error:{title:`Setup non riuscito`,skipSetup:`Salta il setup`,prereqMissing:`Il setup di SpecRails richiede Node.js, npm, npx e Git disponibili sul PATH prima di poter installare questo progetto.`,prereqRetryHint:`Installa gli strumenti mancanti, riavvia Specrails e poi riprova il setup.`}},t={title:`Aggiungi progetto`,description:`Registra una directory di progetto per gestirla da Specrails.`,noProviderDetected:`Nessuna CLI IA rilevata. Installa prima Claude Code o Codex CLI.`,pathLabel:`Percorso del progetto`,pathPlaceholder:`/Users/me/my-project`,pathHint:`Percorso assoluto alla root del progetto`,browseForFolder:`Sfoglia cartelle`,selectProjectFolder:`Seleziona la cartella del progetto`,nameLabel:`Nome visualizzato`,optional:`(facoltativo)`,namePlaceholder:`Il mio progetto`,nameHint:`Per impostazione predefinita usa il nome della directory`,providersLabel:`Provider IA`,notFound:`non trovato`,multiProviderHint:`Verranno configurati entrambi gli engine. Il primo è il predefinito del progetto. Non modificabile dopo la creazione.`,singleProviderHint:`Non modificabile dopo la creazione del progetto.`,adding:`Aggiunta in corso...`,submit:`Aggiungi progetto`,toolsRequired_one:`{{tools}} è richiesto per aggiungere un progetto`,toolsRequired_other:`{{tools}} sono richiesti per aggiungere un progetto`,errors:{pathRequired:`Il percorso del progetto è obbligatorio`,selectProvider:`Seleziona almeno un provider IA`,addFailed:`Aggiunta del progetto non riuscita`},toasts:{registered:`Progetto "{{name}}" registrato`}},n={corruptedBundle:`bundle corrotto — reinstalla l'app`,notInstalled:`non installato`,failedToExecute:`trovato ma esecuzione non riuscita`,failedToExecuteAt:`trovato in {{path}} ma esecuzione non riuscita`,failedToExecuteWithError:`trovato ma esecuzione non riuscita ({{error}})`,failedToExecuteAtWithError:`trovato in {{path}} ma esecuzione non riuscita ({{error}})`,needsMinimum:`{{version}} trovata — serve {{minVersion}}+`,unknownVersion:`sconosciuta`,installedLabel:`installato`,verifyError:`Impossibile verificare localmente gli strumenti di sviluppo — l'installazione li convaliderà.`,allDetected:`Tutti gli strumenti richiesti rilevati`,bundleCorruptedTitle:`Bundle dell'app corrotto`,toolsRequired_one:`{{count}} strumento di sviluppo richiesto`,toolsRequired_other:`{{count}} strumenti di sviluppo richiesti`,reinstallHint:`Reinstalla l'app Specrails per ripristinare gli strumenti inclusi.`,installMissingHint:`Installa gli strumenti mancanti per continuare.`,moreInfo:`Maggiori informazioni`,bundledBadge:`incluso`,optional:`opzionale`,ghNoAuth:"Non connesso — esegui `gh auth login`"},r={title:`Installa gli strumenti di sviluppo`,description:`SpecRails richiede Node.js, npm, npx e Git sul PATH. Scegli lo snippet per il tuo sistema operativo, eseguilo e poi clicca "L'ho installato, ricontrolla".`,darwin:{intro:`Con Homebrew ottieni entrambi gli strumenti in una riga. Se non hai brew, usa i download ufficiali.`,installNodeGit:`Installa Node.js e Git con Homebrew`},win32:{intro:`Winget è incluso in Windows 11 e nelle versioni recenti di Windows 10. Apri PowerShell o il Terminale ed esegui:`,installNode:`Installa Node.js LTS`,installGit:`Installa Git`,note:`Dopo l'installazione, riavvia Specrails così Windows aggiorna il PATH.`},linux:{intro:`Usa il package manager della tua distro:`,debian:`Debian / Ubuntu`,fedora:`Fedora / RHEL`},links:{nodeOfficial:`Node.js (ufficiale)`,gitOfficial:`Git (ufficiale)`,gitWindows:`Git per Windows (ufficiale)`},showOtherPlatforms:`Mostra altre piattaforme`,hideOtherPlatforms:`Nascondi altre piattaforme`,recheck:`L'ho installato, ricontrolla`,diagnostics:{copy:`Copia diagnostica`,copied:`Diagnostica copiata`,failed:`Copia non riuscita`},corrupted:{title:`Bundle dell'app corrotto`,description:`Non è stato possibile verificare uno o più strumenti inclusi (Node.js, Git).`,body:`Questo strumento è incluso nell'app Specrails e non può essere installato separatamente. Se vedi questo messaggio, il bundle dell'app potrebbe essere corrotto. Reinstalla Specrails.`}},i={title:`Avanzamento del setup`,progress:`{{done}} di {{total}} completati`,rawLog_one:`Log grezzo ({{count}} riga)`,rawLog_other:`Log grezzo ({{count}} righe)`},a={title:`Assistente di setup`,subtitle:`Rispondi ai prompt per configurare il progetto`,settingUp:`Configurazione del progetto in corso...`,placeholder:`Scrivi una risposta...`,keyboardHint:`Invio per inviare, Shift+Invio per andare a capo`},o={title:`Benvenuto in <spec>spec</spec><rails>rails</rails>`,description:`Specrails gestisce più progetti da un'unica interfaccia. Aggiungi il tuo primo progetto per iniziare.`,addFirstProject:`Aggiungi il tuo primo progetto`,jiraHint:`Collega ogni progetto alla sua board Jira — le spec restano sincronizzate in entrambe le direzioni.`,mcpHint:`Collega strumenti di IA esterni a Specrails tramite un server MCP locale sicuro — attivalo nelle Impostazioni.`,agentChatHint:`Gestisci Specrails chattando — un agente integrato gestisce spec, rail e analisi per te tramite l'MCP locale. Aprilo dalla bolla o con ⌘⇧A.`},s=JSON.parse(`{"productTour":"Tour del prodotto","stepCount":"Passo {{current}} di {{total}}","goToStep":"Vai al passo {{step}}: {{label}}","stepLabel":"Passo {{step}}","dontShowAgain":"Non mostrare più","skipTour":"Salta il tour","getStarted":"Inizia","flow":{"addSpec":"Aggiungi Spec","dropInRail":"Trascina su un Rail","hitPlay":"Premi Play","ship":"Ship","architect":"Architetto","developer":"Developer","reviewer":"Reviewer"},"language":{"nav":"Lingua","title":"Scegli la tua lingua","subtitle":"Specrails parla la tua lingua","intro":"Seleziona la lingua in cui vuoi usare l'interfaccia. Si applica all'istante — questo tour incluso.","note":"Puoi cambiarla in qualsiasi momento da Impostazioni → Lingua."},"theme":{"nav":"Tema","title":"Scegli il tuo stile","subtitle":"Temi integrati, applicati all'istante","intro":"Scegli l'aspetto di Specrails — il tema si applica appena fai clic.","note":"Puoi cambiarlo in qualsiasi momento da Impostazioni → Aspetto."},"welcome":{"nav":"Benvenuto","title":"Benvenuto in Specrails","subtitle":"La tua cabina di pilotaggio locale per rilasciare software con agenti IA","intro":"Specrails trasforma un'idea in codice rilasciato — e ti permette di <b>vedere, guidare e verificare</b> ogni passo. Abbozza una spec parlando con un'IA, trascinala su un rail di esecuzione e premi Play. La pipeline gestisce architettura, implementazione, review e la pull request, trasmettendo il proprio lavoro in diretta per tutto il tempo.","coreLoopLabel":"Il ciclo fondamentale","flowCaption":"Ogni spec passa automaticamente per <b>Architect → Developer → Reviewer → Ship</b>.","localNote":"<b>100% locale · utente singolo · nessun account.</b> Tutto gira sulla tua macchina. Il tuo codice non lascia mai il laptop a meno che non sia <i>tu</i> a lanciarci sopra un agente.","tourNote":"Questo breve tour mostra tutto ciò che l'app sa fare — circa un minuto."},"authorSpecs":{"nav":"Scrivi le spec","title":"Trasforma le idee in spec","subtitle":"Sei modi per catturare esattamente cosa vuoi costruire","intro":"Una <b>spec</b> è una descrizione del lavoro che vuoi far svolgere. Scrivila come preferisci sul momento — da una riga veloce a una conversazione completa con l'IA.","exploreLabel":"Explore — conversa","exploreBody":"Descrivi cosa vuoi in una chat; una bozza live si ricostruisce a ogni turno. Uno slider di preset regola quanto contesto del progetto vede l'IA — dal solo tuo messaggio fino all'intero codebase più i tuoi server MCP.","quickLabel":"Quick — in un colpo solo","quickBody":"Sai già cosa vuoi? Genera una spec completa in un solo turno. Facoltativamente arricchiscila con un Contract Layer: nomi esatti, forme dei dati, invarianti e un elenco dei file da toccare, così gli agenti non reinventano nulla.","websiteLabel":"Da un sito web","websiteBody":"Apre un browser integrato. Seleziona un elemento al passaggio del mouse o trascina un rettangolo: screenshot, DOM e CSS applicato diventano allegati. La build desktop include il proprio Chromium, quindi funziona offline.","smashLabel":"SMASH su una grande epic","smashBody":"Esplodi una spec grande in una famiglia di sotto-spec più piccole con un clic — ogni figlia porta un breve riassunto sulla sua card.","draftsLabel":"Bozze e ripresa della modifica","draftsBody":"Parcheggia un'esplorazione in corso come ticket in bozza e riprendila più tardi; riapri qualsiasi spec in Explore per continuare a rifinirla.","compareLabel":"Confronta fianco a fianco","compareBody":"Trascina una spec verso il bordo dello schermo e scivola dentro un selettore delle altre spec — esaminane due insieme, in stile tablet."},"rails":{"nav":"Esegui sui rail","title":"Esegui la pipeline sui rail","subtitle":"Organizza le spec in corsie, poi lancia gli agenti","intro":"Il lato destro della Dashboard sono i tuoi <b>Rail</b> — corsie di esecuzione. Trascina una card spec su un rail e premi <play>▶ Play</play> per lanciare un job di implementazione.","jobLabel":"Cosa esegue ogni job","flowCaption":"Ogni fase trasmette i propri log in diretta mentre lavora.","modeLabel":"Scegli un Loop da eseguire","modeBody":"Ogni rail esegue un <b>Loop</b>. Scegline uno integrato — <b>Implement</b> (la pipeline strutturata completa), <b>Batch</b> (più spec contemporaneamente) o <b>Freestyle</b> (Claude lavora in autonomia, senza pipeline fissa) — oppure uno creato da te.","profilesLabel":"Profili agente","profilesBody":"Un catalogo dichiarativo per progetto che decide quali agenti girano e quale modello usa ciascuno — scelto per rail e congelato per job, così il lavoro concorrente resta isolato.","jobDetailLabel":"Dettaglio job in diretta","jobDetailBody":"Ogni job mostra un header con l'identità del ticket, un contatore di durata in tempo reale e conteggi correnti di turni e token, con il costo definitivo risolto alla chiusura.","isolationLabel":"Tanti progetti, isolati","isolationBody":"Ogni progetto ha il proprio database e la propria coda di job. Esegui progetti diversi contemporaneamente e passa dall'uno all'altro dalla sidebar sinistra — la tua posizione viene ricordata per progetto.","loopsLabel":"Crea i tuoi loop","loopsBody":"<b>Loops</b> è un costruttore visuale: concatena passaggi AI, comandi shell e un <b>Loop Decider</b> che ripete finché un obiettivo non è raggiunto — ad esempio verifica → correggi → verifica finché è tutto verde. Pubblica un loop e sceglilo su qualsiasi rail."},"agent":{"nav":"Chat dell'agente","title":"Gestisci l'app chattando","subtitle":"Un copilota che guida Specrails per te","intro":"La <b>chat dell'agente</b> integrata ti permette di usare Specrails chiedendo — creare spec, avviare rail, controllare le analisi — invece di cliccare qua e là. Funziona tramite gli strumenti <b>MCP</b> di Specrails e, poiché tutto è in tempo reale, vedi la board cambiare mentre lavora.","openLabel":"Sempre a portata di clic","openBody":"Aprila dalla bolla flottante in basso, oppure premi ⌘⇧A (Ctrl+Shift+A) da qualsiasi punto. Il pannello si sposta, si ridimensiona, si massimizza e ricorda dove l'hai lasciato.","operateLabel":"Guida l'intera app","operateBody":"Scegli un progetto (o Home per tutto) e un provider, poi chiedi semplicemente: “avvia i tre ticket a priorità più alta”, “quanto ho speso questa settimana?”.","levelsLabel":"Le redini sono tue","levelsBody":"Un livello in tempo reale — <b>Osserva → Modifica → Opera → Autonomo</b>, che scorri con Shift+Tab — decide fin dove può spingersi. Non agisce mai oltre il livello che imposti.","watchLabel":"Guardalo all'opera","watchBody":"Il pannello non è modale, quindi rail e spec compaiono sulla dashboard in tempo reale mentre l'agente lavora. Un chip di stato mostra cosa sta facendo in questo momento.","mcpLabel":"Funziona sull'MCP locale","mcpBody":"L'agente guida l'app tramite il server MCP integrato di Specrails. Se è spento, il pannello propone di attivarlo con un clic — non viene installato nulla."},"providers":{"nav":"Il tuo agente","title":"Porta il tuo agente","subtitle":"Claude Code, Codex e Gemini come motori di prima classe","intro":"L'app tratta <b>Claude Code</b>, <b>Codex CLI</b> e <b>Gemini CLI</b> come motori intercambiabili dietro un unico contratto. Un progetto può installarne uno o più — la scelta avviene all'installazione.","table":{"capability":"Capacità","streamingResume":"Streaming e ripresa della sessione","native":"Nativo","costReporting":"Report dei costi","providerBilled":"Fatturato dal provider","estimated":"Stimato (~)","telemetry":"Telemetria (OTEL)","synthesized":"Sintetizzata","agentProfiles":"Profili agente"},"calloutLabel":"Quando ne sono installati diversi","calloutBody":"Scegli l'engine <b>per spec, per rail o per avvio del terminale</b>. L'app ricorda la tua ultima scelta per progetto. Il costo di Codex è stimato da un tariffario locale e sempre contrassegnato con <mono>~</mono>."},"cost":{"nav":"Monitora i costi","title":"Traccia ogni centesimo","subtitle":"Ogni invocazione fatturabile, registrata e visualizzata","intro":"Ogni invocazione IA — su rail, Quick, Explore, modifiche AI, SMASH e riassunti dei file — viene registrata per <b>Claude e Codex</b>. Mai più tirare a indovinare quanto costano gli agenti.","analyticsLabel":"Pagina Analytics","analyticsBody":"Un hero con il burn-rate, timeline giornaliera, ticket principali, ripartizione per modello e uno scatter costo-vs-turni. Filtra per periodo (7d / 30d / 90d / Tutto) e per superficie.","perTicketLabel":"Spesa per ticket","perTicketBody":"Il dettaglio di ogni spec mostra quanto è costata e quanti turni ha richiesto, con un link diretto ad Analytics filtrato su quel ticket.","honestLabel":"Numeri onesti","honestBody":"Il costo di Claude è la cifra fatturata dal provider; quello di Codex è stimato e contrassegnato con <mono>~</mono>. I totali dei token includono i livelli di cache, quindi i conti tornano davvero.","budgetsLabel":"Budget e avvisi","budgetsBody":"Imposta un budget giornaliero e un avviso di costo per job; l'app mette in pausa automaticamente la coda quando superi la soglia. Esporta tutto in CSV o JSON."},"workspace":{"nav":"Workspace","title":"Rendilo il tuo workspace","subtitle":"Tutto ciò che ti serve senza lasciare la finestra","terminalLabel":"Pannello terminale","terminalBody":"Un vero terminale in stile VS Code in basso (<mod>{{mod}}</mod> <j>J</j>) — rendering WebGL, ricerca, immagini inline, trascinamento di percorsi e integrazione con la shell. Fino a 10 sessioni per progetto.","codeLabel":"Esploratore di codice","codeBody":"Un albero dei file in sola lettura e un visualizzatore Monaco con riassunti IA in linguaggio semplice e chip di provenienza “toccato dall'IA”, così chiunque può seguire cosa è cambiato e perché.","integrationsLabel":"Integrazioni","integrationsBody":"Un marketplace per progetto di integrazioni MCP — la navigazione semantica del codice di Serena è inclusa. Le installazioni sono additive: aggiungerne una non disturba mai le altre.","themesLabel":"Temi","themesBody":"Cinque temi integrati — specrails (predefinito), dracula, aurora-light, obsidian-dark e matrix — applicati prima che la UI venga disegnata, quindi nessun flash. Cambiali in Impostazioni → Aspetto.","chatsLabel":"Chat minimizzabili","chatsBody":"Parcheggia una sessione Explore o AI Edit in una chip del dock e riprendila più tardi — mai persa tra refresh o cambi di progetto.","desktopLabel":"Desktop o browser","desktopBody":"Esegui Specrails nel browser, oppure scarica l'app desktop firmata (macOS e Windows) che include il proprio server e i runtime."},"companion":{"nav":"Companion mobile","title":"Porta Specrails con te","subtitle":"Specrails Companion — le tue pipeline, sul tuo telefono","intro":"<b>Specrails Companion</b> è una web app su specrails.dev/companion-app — aprila sul tuo telefono (o aggiungila alla schermata Home) per sfogliare la board delle spec, lanciare e fermare i rail, seguire i log dei job in diretta e dare un'occhiata alle Analytics. Nessuna installazione, nessuno app store.","localLabel":"100% locale, come tutto il resto","localBody":"Il tuo telefono si connette direttamente a questo computer — peer-to-peer e cifrato (WebRTC). Nessun relay cloud, nessun account, e il tuo codice non lascia mai i tuoi dispositivi.","downloadLabel":"Aprila sul tuo telefono","downloadHint":"Scansiona il codice con la fotocamera del telefono, oppure apri specrails.dev/companion-app nel suo browser.","open":"Apri Specrails Companion","pairLabel":"L'associazione richiede dieci secondi","pairBody":"Sul tuo telefono apri specrails.dev/companion-app, poi qui vai su Impostazioni → Companion mobile → Associa companion web e segui i passaggi a schermo."},"moveFast":{"nav":"Vai veloce","title":"Muoviti alla velocità del pensiero","subtitle":"Keyboard-first, ovunque","paletteLabel":"Palette dei comandi","paletteShortcut":"<f>Premi</f> <mod>{{mod}}</mod> <m>+</m> <k>K</k> <m>ovunque</m>","paletteBody":"Cambia progetto, esegui comandi spec, salta a qualsiasi pagina e trova i job recenti — tutto con ricerca fuzzy.","terminalLabel":"Pannello terminale","terminalBody":"Attiva/disattiva con <mod>{{mod}}</mod> <j>J</j>.","shortcutsLabel":"Tutte le scorciatoie","shortcutsBody":"Premi <q>?</q> per vedere il cheat-sheet completo.","chatLabel":"Sidebar della chat","chatBody":"Attiva/disattiva la sidebar destra con <mod>{{mod}}</mod> <bkey>B</bkey>.","projectsLabel":"Sidebar dei progetti","projectsBody":"Attiva/disattiva la sidebar Arc sinistra con <alt>{{alt}}</alt> <mod>{{mod}}</mod> <bkey>B</bkey>.","outro":"<b>Il tour finisce qui.</b> Aggiungi un progetto dalla sidebar sinistra e rilascia la tua prima spec. Puoi riaprire questa guida in qualsiasi momento dalle Impostazioni."},"jira":{"label":"Integrazione Jira","body":"Appoggia qualsiasi progetto a una <b>board Jira</b> — ogni spec diventa un ticket Jira, sincronizzato in entrambe le direzioni: lo stato segue il rail e viene pubblicato un commento al termine di un job. Configuralo per progetto quando lo aggiungi, o in qualsiasi momento nelle Impostazioni."}}`),c={wizard:e,addProject:t,prerequisites:n,instructions:r,checkpoints:i,setupChat:a,welcome:o,onboarding:s};export{t as addProject,i as checkpoints,c as default,r as instructions,s as onboarding,n as prerequisites,a as setupChat,o as welcome,e as wizard};
1
+ var e={configureAgents:`Configura gli agenti {{provider}}`,configureSubtitle:`Scegli quali agenti installare e come eseguirli.`,tabs:{agents:`Agenti`,models:`Modelli`},skipForNow:`Salta per ora`,install:`Installa`,nextProvider:`Avanti: {{provider}}`,installingProvider:`Installazione di {{provider}}…`,installingSpecrails:`Installazione di specrails...`,installingFromTemplates:`Installazione degli agenti dai template`,waitingForOutput:`In attesa dell'output...`,checkpoints:{baseInstall:`Installazione di base`,agentSelection:`Selezione degli agenti`,agentGeneration:`Generazione degli agenti`},steps:{configure:`Configura`},summary:{agents:`Agenti`,agentSkills:`Skill degli agenti`,skills:`Skill`,openspecSkills:`Skill OpenSpec`,legacyRemoved_one:`Rimosso {{count}} comando legacy <code>/specrails:*</code>`,legacyRemoved_other:`Rimossi {{count}} comandi legacy <code>/specrails:*</code>`},complete:{welcome:`Benvenuto in <spec>spec</spec><rails>rails</rails>`,configured:`<strong>{{projectName}}</strong> è ora configurato con workflow di sviluppo basati sull'IA. I tuoi agenti specializzati e i comandi sono pronti all'uso.`,installedForEngines_one:`Installato per {{count}} engine`,installedForEngines_other:`Installato per {{count}} engine`,installed:`Installato`,installFailed:`Installazione non riuscita`,learnMore:`Scopri come ottenere il massimo da specrails:`,continueToProject:`Continua al progetto`,jira:{title:`Collega una board Jira`,subtitle:`Facoltativo — appoggia le spec di questo progetto a una board Jira. Puoi farlo anche più tardi nelle Impostazioni.`,configure:`Configura Jira`,optional:`facoltativo`},mcpHint:`Collega strumenti di IA esterni a Specrails tramite un server MCP locale sicuro — attivalo nelle Impostazioni.`,agentChatHint:`Gestisci Specrails chattando — l'agente integrato guida l'intera app per te. Aprilo dalla bolla o con ⌘⇧A.`},error:{title:`Setup non riuscito`,skipSetup:`Salta il setup`,prereqMissing:`Il setup di SpecRails richiede Node.js, npm, npx e Git disponibili sul PATH prima di poter installare questo progetto.`,prereqRetryHint:`Installa gli strumenti mancanti, riavvia Specrails e poi riprova il setup.`}},t={title:`Aggiungi progetto`,description:`Registra una directory di progetto per gestirla da Specrails.`,noProviderDetected:`Nessuna CLI IA rilevata. Installa prima Claude Code o Codex CLI.`,pathLabel:`Percorso del progetto`,pathPlaceholder:`/Users/me/my-project`,pathHint:`Percorso assoluto alla root del progetto`,browseForFolder:`Sfoglia cartelle`,selectProjectFolder:`Seleziona la cartella del progetto`,nameLabel:`Nome visualizzato`,optional:`(facoltativo)`,namePlaceholder:`Il mio progetto`,nameHint:`Per impostazione predefinita usa il nome della directory`,providersLabel:`Provider IA`,notFound:`non trovato`,multiProviderHint:`Verranno configurati entrambi gli engine. Il primo è il predefinito del progetto. Non modificabile dopo la creazione.`,singleProviderHint:`Non modificabile dopo la creazione del progetto.`,adding:`Aggiunta in corso...`,submit:`Aggiungi progetto`,toolsRequired_one:`{{tools}} è richiesto per aggiungere un progetto`,toolsRequired_other:`{{tools}} sono richiesti per aggiungere un progetto`,errors:{pathRequired:`Il percorso del progetto è obbligatorio`,selectProvider:`Seleziona almeno un provider IA`,addFailed:`Aggiunta del progetto non riuscita`},toasts:{registered:`Progetto "{{name}}" registrato`}},n={corruptedBundle:`bundle corrotto — reinstalla l'app`,notInstalled:`non installato`,failedToExecute:`trovato ma esecuzione non riuscita`,failedToExecuteAt:`trovato in {{path}} ma esecuzione non riuscita`,failedToExecuteWithError:`trovato ma esecuzione non riuscita ({{error}})`,failedToExecuteAtWithError:`trovato in {{path}} ma esecuzione non riuscita ({{error}})`,needsMinimum:`{{version}} trovata — serve {{minVersion}}+`,unknownVersion:`sconosciuta`,installedLabel:`installato`,verifyError:`Impossibile verificare localmente gli strumenti di sviluppo — l'installazione li convaliderà.`,allDetected:`Tutti gli strumenti richiesti rilevati`,bundleCorruptedTitle:`Bundle dell'app corrotto`,toolsRequired_one:`{{count}} strumento di sviluppo richiesto`,toolsRequired_other:`{{count}} strumenti di sviluppo richiesti`,reinstallHint:`Reinstalla l'app Specrails per ripristinare gli strumenti inclusi.`,installMissingHint:`Installa gli strumenti mancanti per continuare.`,moreInfo:`Maggiori informazioni`,bundledBadge:`incluso`,optional:`opzionale`,ghNoAuth:"Non connesso — esegui `gh auth login`"},r={title:`Installa gli strumenti di sviluppo`,description:`SpecRails richiede Node.js, npm, npx e Git sul PATH. Scegli lo snippet per il tuo sistema operativo, eseguilo e poi clicca "L'ho installato, ricontrolla".`,darwin:{intro:`Con Homebrew ottieni entrambi gli strumenti in una riga. Se non hai brew, usa i download ufficiali.`,installNodeGit:`Installa Node.js e Git con Homebrew`},win32:{intro:`Winget è incluso in Windows 11 e nelle versioni recenti di Windows 10. Apri PowerShell o il Terminale ed esegui:`,installNode:`Installa Node.js LTS`,installGit:`Installa Git`,note:`Dopo l'installazione, riavvia Specrails così Windows aggiorna il PATH.`},linux:{intro:`Usa il package manager della tua distro:`,debian:`Debian / Ubuntu`,fedora:`Fedora / RHEL`},links:{nodeOfficial:`Node.js (ufficiale)`,gitOfficial:`Git (ufficiale)`,gitWindows:`Git per Windows (ufficiale)`},showOtherPlatforms:`Mostra altre piattaforme`,hideOtherPlatforms:`Nascondi altre piattaforme`,recheck:`L'ho installato, ricontrolla`,diagnostics:{copy:`Copia diagnostica`,copied:`Diagnostica copiata`,failed:`Copia non riuscita`},corrupted:{title:`Bundle dell'app corrotto`,description:`Non è stato possibile verificare uno o più strumenti inclusi (Node.js, Git).`,body:`Questo strumento è incluso nell'app Specrails e non può essere installato separatamente. Se vedi questo messaggio, il bundle dell'app potrebbe essere corrotto. Reinstalla Specrails.`}},i={title:`Avanzamento del setup`,progress:`{{done}} di {{total}} completati`,rawLog_one:`Log grezzo ({{count}} riga)`,rawLog_other:`Log grezzo ({{count}} righe)`},a={title:`Assistente di setup`,subtitle:`Rispondi ai prompt per configurare il progetto`,settingUp:`Configurazione del progetto in corso...`,placeholder:`Scrivi una risposta...`,keyboardHint:`Invio per inviare, Shift+Invio per andare a capo`},o={title:`Benvenuto in <spec>spec</spec><rails>rails</rails>`,description:`Specrails gestisce più progetti da un'unica interfaccia. Aggiungi il tuo primo progetto per iniziare.`,addFirstProject:`Aggiungi il tuo primo progetto`,jiraHint:`Collega ogni progetto alla sua board Jira — le spec restano sincronizzate in entrambe le direzioni.`,mcpHint:`Collega strumenti di IA esterni a Specrails tramite un server MCP locale sicuro — attivalo nelle Impostazioni.`,agentChatHint:`Gestisci Specrails chattando — un agente integrato gestisce spec, rail e analisi per te tramite l'MCP locale. Aprilo dalla bolla o con ⌘⇧A.`},s=JSON.parse(`{"productTour":"Tour del prodotto","stepCount":"Passo {{current}} di {{total}}","goToStep":"Vai al passo {{step}}: {{label}}","stepLabel":"Passo {{step}}","dontShowAgain":"Non mostrare più","skipTour":"Salta il tour","getStarted":"Inizia","flow":{"addSpec":"Aggiungi Spec","dropInRail":"Trascina su un Rail","hitPlay":"Premi Play","ship":"Ship","architect":"Architetto","developer":"Developer","reviewer":"Reviewer"},"language":{"nav":"Lingua","title":"Scegli la tua lingua","subtitle":"Specrails parla la tua lingua","intro":"Seleziona la lingua in cui vuoi usare l'interfaccia. Si applica all'istante — questo tour incluso.","note":"Puoi cambiarla in qualsiasi momento da Impostazioni → Lingua."},"theme":{"nav":"Tema","title":"Scegli il tuo stile","subtitle":"Temi integrati, applicati all'istante","intro":"Scegli l'aspetto di Specrails — il tema si applica appena fai clic.","note":"Puoi cambiarlo in qualsiasi momento da Impostazioni → Aspetto."},"welcome":{"nav":"Benvenuto","title":"Benvenuto in Specrails","subtitle":"La tua cabina di pilotaggio locale per rilasciare software con agenti IA","intro":"Specrails trasforma un'idea in codice rilasciato — e ti permette di <b>vedere, guidare e verificare</b> ogni passo. Abbozza una spec parlando con un'IA, trascinala su un rail di esecuzione e premi Play. La pipeline gestisce architettura, implementazione, review e la pull request, trasmettendo il proprio lavoro in diretta per tutto il tempo.","coreLoopLabel":"Il ciclo fondamentale","flowCaption":"Ogni spec passa automaticamente per <b>Architect → Developer → Reviewer → Ship</b>.","localNote":"<b>100% locale · utente singolo · nessun account.</b> Tutto gira sulla tua macchina. Il tuo codice non lascia mai il laptop a meno che non sia <i>tu</i> a lanciarci sopra un agente.","tourNote":"Questo breve tour mostra tutto ciò che l'app sa fare — circa un minuto."},"authorSpecs":{"nav":"Scrivi le spec","title":"Trasforma le idee in spec","subtitle":"Sei modi per catturare esattamente cosa vuoi costruire","intro":"Una <b>spec</b> è una descrizione del lavoro che vuoi far svolgere. Scrivila come preferisci sul momento — da una riga veloce a una conversazione completa con l'IA.","exploreLabel":"Explore — conversa","exploreBody":"Descrivi cosa vuoi in una chat; una bozza live si ricostruisce a ogni turno. Uno slider di preset regola quanto contesto del progetto vede l'IA — dal solo tuo messaggio fino all'intero codebase più i tuoi server MCP.","quickLabel":"Quick — in un colpo solo","quickBody":"Sai già cosa vuoi? Genera una spec completa in un solo turno. Facoltativamente arricchiscila con un Contract Layer: nomi esatti, forme dei dati, invarianti e un elenco dei file da toccare, così gli agenti non reinventano nulla.","websiteLabel":"Da un sito web","websiteBody":"Apre un browser integrato. Seleziona un elemento al passaggio del mouse o trascina un rettangolo: screenshot, DOM e CSS applicato diventano allegati. La build desktop include il proprio Chromium, quindi funziona offline.","smashLabel":"SMASH su una grande epic","smashBody":"Esplodi una spec grande in una famiglia di sotto-spec più piccole con un clic — ogni figlia porta un breve riassunto sulla sua card.","draftsLabel":"Bozze e ripresa della modifica","draftsBody":"Parcheggia un'esplorazione in corso come ticket in bozza e riprendila più tardi; riapri qualsiasi spec in Explore per continuare a rifinirla.","compareLabel":"Confronta fianco a fianco","compareBody":"Trascina una spec verso il bordo dello schermo e scivola dentro un selettore delle altre spec — esaminane due insieme, in stile tablet."},"rails":{"nav":"Esegui sui rail","title":"Esegui la pipeline sui rail","subtitle":"Organizza le spec in corsie, poi lancia gli agenti","intro":"Il lato destro della Dashboard sono i tuoi <b>Rail</b> — corsie di esecuzione. Trascina una card spec su un rail e premi <play>▶ Play</play> per lanciare un job di implementazione.","jobLabel":"Cosa esegue ogni job","flowCaption":"Ogni fase trasmette i propri log in diretta mentre lavora.","modeLabel":"Scegli un Loop da eseguire","modeBody":"Ogni rail esegue un <b>Loop</b>. Scegline uno integrato — <b>Implement</b> (la pipeline strutturata completa), <b>Batch</b> (più spec contemporaneamente) o <b>Freestyle</b> (Claude lavora in autonomia, senza pipeline fissa) — oppure uno creato da te.","profilesLabel":"Profili agente","profilesBody":"Un catalogo dichiarativo per progetto che decide quali agenti girano e quale modello usa ciascuno — scelto per rail e congelato per job, così il lavoro concorrente resta isolato.","jobDetailLabel":"Dettaglio job in diretta","jobDetailBody":"Ogni job mostra un header con l'identità del ticket, un contatore di durata in tempo reale e conteggi correnti di turni e token, con il costo definitivo risolto alla chiusura.","isolationLabel":"Tanti progetti, isolati","isolationBody":"Ogni progetto ha il proprio database e la propria coda di job. Esegui progetti diversi contemporaneamente e passa dall'uno all'altro dalla sidebar sinistra — la tua posizione viene ricordata per progetto.","loopsLabel":"Crea i tuoi loop","loopsBody":"<b>Loops</b> è un costruttore visuale: concatena passaggi AI, comandi shell e un <b>Loop Decider</b> che ripete finché un obiettivo non è raggiunto — ad esempio verifica → correggi → verifica finché è tutto verde. Pubblica un loop e sceglilo su qualsiasi rail."},"agent":{"nav":"Chat dell'agente","title":"Gestisci l'app chattando","subtitle":"Un copilota che guida Specrails per te","intro":"La <b>chat dell'agente</b> integrata ti permette di usare Specrails chiedendo — creare spec, avviare rail, controllare le analisi — invece di cliccare qua e là. Funziona tramite gli strumenti <b>MCP</b> di Specrails e, poiché tutto è in tempo reale, vedi la board cambiare mentre lavora.","openLabel":"Sempre a portata di clic","openBody":"Aprila dalla bolla flottante in basso, oppure premi ⌘⇧A (Ctrl+Shift+A) da qualsiasi punto. Il pannello si sposta, si ridimensiona, si massimizza e ricorda dove l'hai lasciato.","operateLabel":"Guida l'intera app","operateBody":"Scegli un progetto (o Home per tutto) e un provider, poi chiedi semplicemente: “avvia i tre ticket a priorità più alta”, “quanto ho speso questa settimana?”.","levelsLabel":"Le redini sono tue","levelsBody":"Un livello in tempo reale — <b>Osserva → Modifica → Opera → Autonomo</b>, che scorri con Shift+Tab — decide fin dove può spingersi. Non agisce mai oltre il livello che imposti.","watchLabel":"Guardalo all'opera","watchBody":"Il pannello non è modale, quindi rail e spec compaiono sulla dashboard in tempo reale mentre l'agente lavora. Un chip di stato mostra cosa sta facendo in questo momento.","mcpLabel":"Funziona sull'MCP locale","mcpBody":"L'agente guida l'app tramite il server MCP integrato di Specrails. Se è spento, il pannello propone di attivarlo con un clic — non viene installato nulla."},"providers":{"nav":"Il tuo agente","title":"Porta il tuo agente","subtitle":"Claude Code, Codex e Gemini come motori di prima classe","intro":"L'app tratta <b>Claude Code</b>, <b>Codex CLI</b> e <b>Gemini CLI</b> come motori intercambiabili dietro un unico contratto. Un progetto può installarne uno o più — la scelta avviene all'installazione.","table":{"capability":"Capacità","streamingResume":"Streaming e ripresa della sessione","native":"Nativo","costReporting":"Report dei costi","providerBilled":"Fatturato dal provider","estimated":"Stimato (~)","telemetry":"Telemetria (OTEL)","synthesized":"Sintetizzata","agentProfiles":"Profili agente"},"calloutLabel":"Quando ne sono installati diversi","calloutBody":"Scegli l'engine <b>per spec, per rail o per avvio del terminale</b>. L'app ricorda la tua ultima scelta per progetto. Il costo di Codex è stimato da un tariffario locale e sempre contrassegnato con <mono>~</mono>."},"cost":{"nav":"Monitora i costi","title":"Traccia ogni centesimo","subtitle":"Ogni invocazione fatturabile, registrata e visualizzata","intro":"Ogni invocazione IA — su rail, Quick, Explore, modifiche AI, SMASH e riassunti dei file — viene registrata per <b>Claude e Codex</b>. Mai più tirare a indovinare quanto costano gli agenti.","analyticsLabel":"Pagina Analytics","analyticsBody":"Un hero con il burn-rate, timeline giornaliera, ticket principali, ripartizione per modello e uno scatter costo-vs-turni. Filtra per periodo (7d / 30d / 90d / Tutto) e per superficie.","perTicketLabel":"Spesa per ticket","perTicketBody":"Il dettaglio di ogni spec mostra quanto è costata e quanti turni ha richiesto, con un link diretto ad Analytics filtrato su quel ticket.","honestLabel":"Numeri onesti","honestBody":"Il costo di Claude è la cifra fatturata dal provider; quello di Codex è stimato e contrassegnato con <mono>~</mono>. I totali dei token includono i livelli di cache, quindi i conti tornano davvero.","budgetsLabel":"Budget e avvisi","budgetsBody":"Imposta un budget giornaliero e un avviso di costo per job; l'app mette in pausa automaticamente la coda quando superi la soglia. Esporta tutto in CSV o JSON."},"workspace":{"nav":"Workspace","title":"Rendilo il tuo workspace","subtitle":"Tutto ciò che ti serve senza lasciare la finestra","terminalLabel":"Pannello terminale","terminalBody":"Un vero terminale in stile VS Code in basso (<mod>{{mod}}</mod> <j>J</j>) — rendering WebGL, ricerca, immagini inline, trascinamento di percorsi e integrazione con la shell. Fino a 10 sessioni per progetto.","codeLabel":"Esploratore di codice","codeBody":"Un albero dei file in sola lettura e un visualizzatore Monaco con riassunti IA in linguaggio semplice e chip di provenienza “toccato dall'IA”, così chiunque può seguire cosa è cambiato e perché.","integrationsLabel":"Integrazioni","integrationsBody":"Un marketplace per progetto di integrazioni MCP — la navigazione semantica del codice di Serena è inclusa. Le installazioni sono additive: aggiungerne una non disturba mai le altre.","themesLabel":"Temi","themesBody":"Sei temi integrati — specrails (predefinito), dracula, aurora-light, obsidian-dark, code-rain e galaxy — applicati prima che la UI venga disegnata, quindi nessun flash. Cambiali in Impostazioni → Aspetto.","chatsLabel":"Chat minimizzabili","chatsBody":"Parcheggia una sessione Explore o AI Edit in una chip del dock e riprendila più tardi — mai persa tra refresh o cambi di progetto.","desktopLabel":"Desktop o browser","desktopBody":"Esegui Specrails nel browser, oppure scarica l'app desktop firmata (macOS e Windows) che include il proprio server e i runtime."},"companion":{"nav":"Companion mobile","title":"Porta Specrails con te","subtitle":"Specrails Companion — le tue pipeline, sul tuo telefono","intro":"<b>Specrails Companion</b> è una web app su specrails.dev/companion-app — aprila sul tuo telefono (o aggiungila alla schermata Home) per sfogliare la board delle spec, lanciare e fermare i rail, seguire i log dei job in diretta e dare un'occhiata alle Analytics. Nessuna installazione, nessuno app store.","localLabel":"100% locale, come tutto il resto","localBody":"Il tuo telefono si connette direttamente a questo computer — peer-to-peer e cifrato (WebRTC). Nessun relay cloud, nessun account, e il tuo codice non lascia mai i tuoi dispositivi.","downloadLabel":"Aprila sul tuo telefono","downloadHint":"Scansiona il codice con la fotocamera del telefono, oppure apri specrails.dev/companion-app nel suo browser.","open":"Apri Specrails Companion","pairLabel":"L'associazione richiede dieci secondi","pairBody":"Sul tuo telefono apri specrails.dev/companion-app, poi qui vai su Impostazioni → Companion mobile → Associa companion web e segui i passaggi a schermo."},"moveFast":{"nav":"Vai veloce","title":"Muoviti alla velocità del pensiero","subtitle":"Keyboard-first, ovunque","paletteLabel":"Palette dei comandi","paletteShortcut":"<f>Premi</f> <mod>{{mod}}</mod> <m>+</m> <k>K</k> <m>ovunque</m>","paletteBody":"Cambia progetto, esegui comandi spec, salta a qualsiasi pagina e trova i job recenti — tutto con ricerca fuzzy.","terminalLabel":"Pannello terminale","terminalBody":"Attiva/disattiva con <mod>{{mod}}</mod> <j>J</j>.","shortcutsLabel":"Tutte le scorciatoie","shortcutsBody":"Premi <q>?</q> per vedere il cheat-sheet completo.","chatLabel":"Sidebar della chat","chatBody":"Attiva/disattiva la sidebar destra con <mod>{{mod}}</mod> <bkey>B</bkey>.","projectsLabel":"Sidebar dei progetti","projectsBody":"Attiva/disattiva la sidebar Arc sinistra con <alt>{{alt}}</alt> <mod>{{mod}}</mod> <bkey>B</bkey>.","outro":"<b>Il tour finisce qui.</b> Aggiungi un progetto dalla sidebar sinistra e rilascia la tua prima spec. Puoi riaprire questa guida in qualsiasi momento dalle Impostazioni."},"jira":{"label":"Integrazione Jira","body":"Appoggia qualsiasi progetto a una <b>board Jira</b> — ogni spec diventa un ticket Jira, sincronizzato in entrambe le direzioni: lo stato segue il rail e viene pubblicato un commento al termine di un job. Configuralo per progetto quando lo aggiungi, o in qualsiasi momento nelle Impostazioni."}}`),c={wizard:e,addProject:t,prerequisites:n,instructions:r,checkpoints:i,setupChat:a,welcome:o,onboarding:s};export{t as addProject,i as checkpoints,c as default,r as instructions,s as onboarding,n as prerequisites,a as setupChat,o as welcome,e as wizard};
@@ -1 +1 @@
1
- import{r as e}from"./chunk-BNv3lrIs.js";var t=e({addProject:()=>r,checkpoints:()=>o,default:()=>u,instructions:()=>a,onboarding:()=>l,prerequisites:()=>i,setupChat:()=>s,welcome:()=>c,wizard:()=>n}),n={configureAgents:`Configure {{provider}} agents`,configureSubtitle:`Choose which agents to install and how to run them.`,tabs:{agents:`Agents`,models:`Models`},skipForNow:`Skip for now`,install:`Install`,nextProvider:`Next: {{provider}}`,installingProvider:`Installing {{provider}}…`,installingSpecrails:`Installing specrails...`,installingFromTemplates:`Installing agents from templates`,waitingForOutput:`Waiting for output...`,checkpoints:{baseInstall:`Base installation`,agentSelection:`Agent selection`,agentGeneration:`Agent generation`},steps:{configure:`Configure`},summary:{agents:`Agents`,agentSkills:`Agent skills`,skills:`Skills`,openspecSkills:`OpenSpec skills`,legacyRemoved_one:`Removed {{count}} legacy <code>/specrails:*</code> command`,legacyRemoved_other:`Removed {{count}} legacy <code>/specrails:*</code> commands`},complete:{welcome:`Welcome to <spec>spec</spec><rails>rails</rails>`,configured:`<strong>{{projectName}}</strong> is now configured with AI-powered development workflows. Your specialized agents and commands are ready to use.`,installedForEngines_one:`Installed for {{count}} engine`,installedForEngines_other:`Installed for {{count}} engines`,installed:`Installed`,installFailed:`Install failed`,learnMore:`Learn how to get the most out of specrails:`,continueToProject:`Continue to project`,jira:{title:`Connect a Jira board`,subtitle:`Optional — back this project's specs with a Jira board. You can also do it later in Settings.`,configure:`Configure Jira`,optional:`optional`},mcpHint:`Connect external AI tools to Specrails over a secure local MCP server — enable it in Settings.`,agentChatHint:`Operate Specrails by chatting — the built-in agent drives the whole app for you. Open it from the bubble or ⌘⇧A.`},error:{title:`Setup failed`,skipSetup:`Skip setup`,prereqMissing:`SpecRails setup needs Node.js, npm, npx and Git available on PATH before it can install this project.`,prereqRetryHint:`Install the missing tools, restart Specrails, then retry setup.`}},r={title:`Add Project`,description:`Register a project directory to manage it from Specrails.`,noProviderDetected:`No AI CLI detected. Install Claude Code or Codex CLI first.`,pathLabel:`Project path`,pathPlaceholder:`/Users/me/my-project`,pathHint:`Absolute path to the project root`,browseForFolder:`Browse for folder`,selectProjectFolder:`Select project folder`,nameLabel:`Display name`,optional:`(optional)`,namePlaceholder:`My Project`,nameHint:`Defaults to the directory name`,providersLabel:`AI providers`,notFound:`not found`,multiProviderHint:`Both engines will be set up. The first is the project default. Cannot be changed after creation.`,singleProviderHint:`Cannot be changed after the project is created.`,adding:`Adding...`,submit:`Add Project`,toolsRequired_one:`{{tools}} is required to add a project`,toolsRequired_other:`{{tools}} are required to add a project`,errors:{pathRequired:`Project path is required`,selectProvider:`Select at least one AI provider`,addFailed:`Failed to add project`},toasts:{registered:`Project "{{name}}" registered`}},i={corruptedBundle:`bundle corrupted — reinstall app`,notInstalled:`not installed`,failedToExecute:`found but failed to execute`,failedToExecuteAt:`found at {{path}} but failed to execute`,failedToExecuteWithError:`found but failed to execute ({{error}})`,failedToExecuteAtWithError:`found at {{path}} but failed to execute ({{error}})`,needsMinimum:`{{version}} found — needs {{minVersion}}+`,unknownVersion:`unknown`,installedLabel:`installed`,verifyError:`Could not verify developer tools locally — install will validate.`,allDetected:`All required tools detected`,bundleCorruptedTitle:`App bundle corrupted`,toolsRequired_one:`{{count}} developer tool required`,toolsRequired_other:`{{count}} developer tools required`,reinstallHint:`Reinstall the Specrails app to restore bundled tools.`,installMissingHint:`Install the missing tools to continue.`,moreInfo:`More info`,bundledBadge:`bundled`,optional:`optional`,ghNoAuth:"Not signed in — run `gh auth login`"},a={title:`Install developer tools`,description:`SpecRails needs Node.js, npm, npx, and Git on PATH. Pick the snippet for your OS, run it, then click "I installed it, recheck".`,darwin:{intro:`Homebrew gets you both tools in one line. If you do not have brew, use the official downloads.`,installNodeGit:`Install Node.js and Git via Homebrew`},win32:{intro:`Winget ships with Windows 11 and recent Windows 10. Open PowerShell or Terminal and run:`,installNode:`Install Node.js LTS`,installGit:`Install Git`,note:`After install, restart Specrails so Windows refreshes PATH.`},linux:{intro:`Use your distro package manager:`,debian:`Debian / Ubuntu`,fedora:`Fedora / RHEL`},links:{nodeOfficial:`Node.js (official)`,gitOfficial:`Git (official)`,gitWindows:`Git for Windows (official)`},showOtherPlatforms:`Show other platforms`,hideOtherPlatforms:`Hide other platforms`,recheck:`I installed it, recheck`,diagnostics:{copy:`Copy diagnostics`,copied:`Diagnostics copied`,failed:`Copy failed`},corrupted:{title:`App bundle corrupted`,description:`One or more bundled tools (Node.js, Git) could not be verified.`,body:`This tool is bundled with the Specrails app and cannot be installed separately. If you see this message, the app bundle may be corrupted. Please reinstall Specrails.`}},o={title:`Setup progress`,progress:`{{done}} of {{total}} complete`,rawLog_one:`Raw log ({{count}} line)`,rawLog_other:`Raw log ({{count}} lines)`},s={title:`Setup assistant`,subtitle:`Respond to prompts to configure your project`,settingUp:`Setting up your project...`,placeholder:`Type a response...`,keyboardHint:`Enter to send, Shift+Enter for new line`},c={title:`Welcome to <spec>spec</spec><rails>rails</rails>`,description:`Specrails manages multiple projects from a single interface. Add your first project to get started.`,addFirstProject:`Add your first project`,jiraHint:`Connect each project to its own Jira board — specs stay in sync, both ways.`,mcpHint:`Connect external AI tools to Specrails over a secure local MCP server — enable it in Settings.`,agentChatHint:`Operate Specrails by chatting — a built-in agent drives specs, rails and analytics for you through the local MCP. Open it from the bubble or ⌘⇧A.`},l=JSON.parse(`{"productTour":"Product tour","stepCount":"Step {{current}} of {{total}}","goToStep":"Go to step {{step}}: {{label}}","stepLabel":"Step {{step}}","dontShowAgain":"Don't show this again","skipTour":"Skip tour","getStarted":"Get Started","flow":{"addSpec":"Add Spec","dropInRail":"Drop in a Rail","hitPlay":"Hit Play","ship":"Ship","architect":"Architect","developer":"Developer","reviewer":"Reviewer"},"language":{"nav":"Language","title":"Choose your language","subtitle":"Specrails speaks your language","intro":"Pick the language you want the interface in. It applies instantly — this tour included.","note":"You can change it any time in Settings → Language."},"theme":{"nav":"Theme","title":"Pick your look","subtitle":"Built-in themes, applied instantly","intro":"Choose how Specrails should look — the theme applies the moment you click.","note":"You can change it any time in Settings → Appearance."},"welcome":{"nav":"Welcome","title":"Welcome to Specrails","subtitle":"Your local cockpit for shipping software with AI agents","intro":"Specrails turns an idea into shipped code — and lets you <b>see, steer, and trust</b> every step. Draft a spec by talking to an AI, drop it on an execution rail, and hit Play. The pipeline handles architecture, implementation, review and the pull request, streaming its work live the whole way.","coreLoopLabel":"The core loop","flowCaption":"Each spec flows through <b>Architect → Developer → Reviewer → Ship</b> automatically.","localNote":"<b>100% local · single user · no accounts.</b> Everything runs on your machine. Your code never leaves the laptop unless <i>you</i> spawn an agent against it.","tourNote":"This quick tour walks through everything the app can do — about a minute."},"authorSpecs":{"nav":"Author specs","title":"Turn ideas into specs","subtitle":"Six ways to capture exactly what you want built","intro":"A <b>spec</b> is a description of work you want done. Author one however suits the moment — from a quick one-liner to a full conversation with the AI.","exploreLabel":"Explore — converse","exploreBody":"Describe what you want in a chat; a live draft rebuilds itself every turn. A preset slider tunes how much project context the AI sees — from your message only, up to the full codebase plus your MCP servers.","quickLabel":"Quick — one shot","quickBody":"Already know what you want? Generate a complete spec in a single turn. Optionally enrich it with a Contract Layer: exact names, data shapes, invariants and a file-touch list so the agents don't reinvent anything.","websiteLabel":"From a website","websiteBody":"Opens an embedded browser. Hover-select an element or drag a rectangle, and the screenshot, DOM and applied CSS become attachments. The desktop build ships its own Chromium, so it works offline.","smashLabel":"SMASH a big epic","smashBody":"Explode a large spec into a family of smaller sub-specs in one click — each child carries a short summary on its card.","draftsLabel":"Drafts & Continue Editing","draftsBody":"Park an in-progress exploration as a draft ticket and resume it later; reopen any spec back in Explore to keep refining it.","compareLabel":"Compare side by side","compareBody":"Drag a spec to the screen edge and a picker of your other specs slides in — review two of them together, tablet-style."},"rails":{"nav":"Run on rails","title":"Run the pipeline on rails","subtitle":"Organize specs into lanes, then launch the agents","intro":"The right side of the Dashboard is your <b>Rails</b> — execution lanes. Drag a spec card onto a rail and press <play>▶ Play</play> to launch an implementation job.","jobLabel":"What each job runs","flowCaption":"Every phase streams its logs live as it works.","modeLabel":"Pick a Loop to run","modeBody":"Each rail runs a <b>Loop</b>. Pick a built-in one — <b>Implement</b> (the full structured pipeline), <b>Batch</b> (several specs at once) or <b>Freestyle</b> (Claude works autonomously, no fixed pipeline) — or one you built yourself.","profilesLabel":"Agent profiles","profilesBody":"A per-project, declarative catalog that decides which agents run and which model each one uses — picked per rail and snapshotted per job so concurrent work stays isolated.","jobDetailLabel":"Live job detail","jobDetailBody":"Every job shows a ticket-identity header, a live duration ticker and running turn/token counts, with the authoritative cost resolved on exit.","isolationLabel":"Many projects, isolated","isolationBody":"Each project has its own database and job queue. Run different projects at the same time and switch between them from the left sidebar — your place is remembered per project.","loopsLabel":"Build your own loops","loopsBody":"<b>Loops</b> is a visual builder: chain AI steps, shell commands and a <b>Loop Decider</b> that repeats until a goal is met — e.g. verify → fix → verify until everything is green. Publish a loop and pick it on any rail."},"agent":{"nav":"Agent chat","title":"Operate the app by chatting","subtitle":"A copilot that drives Specrails for you","intro":"The built-in <b>agent chat</b> lets you run Specrails by asking — create specs, launch rails, check analytics — instead of clicking around. It works through Specrails' own <b>MCP</b> tools, and because everything is live you watch the board change as it works.","openLabel":"Always a click away","openBody":"Open it from the floating bubble at the bottom, or press ⌘⇧A (Ctrl+Shift+A) from anywhere. The panel moves, resizes, maximizes and remembers where you left it.","operateLabel":"Drives the whole app","operateBody":"Pick a project (or Home for everything) and a provider, then just ask: “launch the three highest-priority tickets”, “how much did I spend this week?”.","levelsLabel":"You hold the leash","levelsBody":"A live level — <b>Observe → Edit → Operate → Autonomous</b>, cycled with Shift+Tab — decides how far it can go. It never acts above the level you set.","watchLabel":"Watch it happen","watchBody":"The panel is non-modal, so rails and specs appear on the dashboard in real time while the agent works. A status chip shows what it's doing right now.","mcpLabel":"Runs on the local MCP","mcpBody":"The agent drives the app through the embedded Specrails MCP server. If it's off, the panel offers a one-click enable — nothing is installed."},"providers":{"nav":"Your agent","title":"Bring your own agent","subtitle":"Claude Code, Codex and Gemini, as first-class engines","intro":"The app treats <b>Claude Code</b>, <b>Codex CLI</b> and <b>Gemini CLI</b> as interchangeable engines behind one contract. A project can install one or more — the choice is made at install time.","table":{"capability":"Capability","streamingResume":"Streaming & session resume","native":"Native","costReporting":"Cost reporting","providerBilled":"Provider-billed","estimated":"Estimated (~)","telemetry":"Telemetry (OTEL)","synthesized":"Synthesized","agentProfiles":"Agent profiles"},"calloutLabel":"When several are installed","calloutBody":"Pick the engine <b>per spec, per rail, or per terminal launch</b>. The app remembers your last choice per project. Codex cost is estimated from a local rate-card and always flagged with a <mono>~</mono>."},"cost":{"nav":"Track cost","title":"Track every cent","subtitle":"Every billable invocation, recorded and visualized","intro":"Every AI invocation — across rails, Quick, Explore, AI edits, SMASH and file summaries — is recorded for <b>both Claude and Codex</b>. No more guessing what the agents cost.","analyticsLabel":"Analytics page","analyticsBody":"A burn-rate hero, daily timeline, top tickets, model breakdown and a cost-vs-turns scatter. Filter by period (7d / 30d / 90d / All) and by surface.","perTicketLabel":"Per-ticket spending","perTicketBody":"Each spec's detail shows what it cost and how many turns it took, deep-linking into Analytics filtered to that ticket.","honestLabel":"Honest numbers","honestBody":"Claude cost is the provider-billed figure; Codex is estimated and flagged with <mono>~</mono>. Token totals include the cache tiers, so the figures actually reconcile.","budgetsLabel":"Budgets & alerts","budgetsBody":"Set a daily budget and a per-job cost alert; the app auto-pauses the queue when you cross the line. Export anything to CSV or JSON."},"workspace":{"nav":"Workspace","title":"Make it your workspace","subtitle":"Everything you need without leaving the window","terminalLabel":"Terminal panel","terminalBody":"A real VS-Code-style terminal at the bottom (<mod>{{mod}}</mod> <j>J</j>) — WebGL rendering, search, inline images, drag-drop paths and shell integration. Up to 10 sessions per project.","codeLabel":"Code explorer","codeBody":"A read-only file tree and Monaco viewer with plain-language AI summaries and “touched by AI” provenance chips, so anyone can follow what changed and why.","integrationsLabel":"Integrations","integrationsBody":"A per-project marketplace of MCP integrations — Serena semantic code-navigation is bundled. Installs are additive: adding one never disturbs another.","themesLabel":"Themes","themesBody":"Five built-in themes — specrails (default), dracula, aurora-light, obsidian-dark and matrix — applied before the UI paints, so there's no flash. Change them in Settings → Appearance.","chatsLabel":"Minimizable chats","chatsBody":"Park an Explore or AI-Edit session into a dock chip and pick it back up later — never lost across refreshes or project switches.","desktopLabel":"Desktop or browser","desktopBody":"Run Specrails in your browser, or grab the signed desktop app (macOS & Windows) that bundles its own server and runtimes."},"companion":{"nav":"Mobile companion","title":"Take Specrails with you","subtitle":"Specrails Companion — your pipelines, on your phone","intro":"<b>Specrails Companion</b> is a web app at specrails.dev/companion-app — open it on your phone (or add it to your Home Screen) to browse the specs board, launch and stop rails, follow live job logs and glance at analytics. No install, no app store.","localLabel":"100% local, like everything else","localBody":"Your phone connects straight to this computer — peer-to-peer and encrypted (WebRTC). No cloud relay, no account, and your code never leaves your devices.","downloadLabel":"Open it on your phone","downloadHint":"Scan the code with your phone's camera, or open specrails.dev/companion-app in its browser.","open":"Open Specrails Companion","pairLabel":"Pairing takes ten seconds","pairBody":"On your phone open specrails.dev/companion-app, then here go to Settings → Mobile companion → Pair web companion and follow the on-screen steps."},"moveFast":{"nav":"Move fast","title":"Move at the speed of thought","subtitle":"Keyboard-first, everywhere","paletteLabel":"Command palette","paletteShortcut":"<f>Press</f> <mod>{{mod}}</mod> <m>+</m> <k>K</k> <m>anywhere</m>","paletteBody":"Switch projects, run spec commands, jump to any page and find recent jobs — all with fuzzy search.","terminalLabel":"Terminal panel","terminalBody":"Toggle with <mod>{{mod}}</mod> <j>J</j>.","shortcutsLabel":"All shortcuts","shortcutsBody":"Press <q>?</q> to see the full cheat-sheet.","chatLabel":"Chat sidebar","chatBody":"Toggle the right sidebar with <mod>{{mod}}</mod> <bkey>B</bkey>.","projectsLabel":"Projects sidebar","projectsBody":"Toggle the left Arc sidebar with <alt>{{alt}}</alt> <mod>{{mod}}</mod> <bkey>B</bkey>.","outro":"<b>That's the tour.</b> Add a project from the left sidebar and ship your first spec. You can reopen this walkthrough anytime from Settings."},"jira":{"label":"Jira integration","body":"Back any project with a <b>Jira board</b> — each spec becomes a Jira issue, kept in sync both ways: status follows the rail, and a comment is posted when a job finishes. Configure it per project when you add it, or anytime in Settings."}}`),u={wizard:n,addProject:r,prerequisites:i,instructions:a,checkpoints:o,setupChat:s,welcome:c,onboarding:l};export{t};
1
+ import{r as e}from"./chunk-BNv3lrIs.js";var t=e({addProject:()=>r,checkpoints:()=>o,default:()=>u,instructions:()=>a,onboarding:()=>l,prerequisites:()=>i,setupChat:()=>s,welcome:()=>c,wizard:()=>n}),n={configureAgents:`Configure {{provider}} agents`,configureSubtitle:`Choose which agents to install and how to run them.`,tabs:{agents:`Agents`,models:`Models`},skipForNow:`Skip for now`,install:`Install`,nextProvider:`Next: {{provider}}`,installingProvider:`Installing {{provider}}…`,installingSpecrails:`Installing specrails...`,installingFromTemplates:`Installing agents from templates`,waitingForOutput:`Waiting for output...`,checkpoints:{baseInstall:`Base installation`,agentSelection:`Agent selection`,agentGeneration:`Agent generation`},steps:{configure:`Configure`},summary:{agents:`Agents`,agentSkills:`Agent skills`,skills:`Skills`,openspecSkills:`OpenSpec skills`,legacyRemoved_one:`Removed {{count}} legacy <code>/specrails:*</code> command`,legacyRemoved_other:`Removed {{count}} legacy <code>/specrails:*</code> commands`},complete:{welcome:`Welcome to <spec>spec</spec><rails>rails</rails>`,configured:`<strong>{{projectName}}</strong> is now configured with AI-powered development workflows. Your specialized agents and commands are ready to use.`,installedForEngines_one:`Installed for {{count}} engine`,installedForEngines_other:`Installed for {{count}} engines`,installed:`Installed`,installFailed:`Install failed`,learnMore:`Learn how to get the most out of specrails:`,continueToProject:`Continue to project`,jira:{title:`Connect a Jira board`,subtitle:`Optional — back this project's specs with a Jira board. You can also do it later in Settings.`,configure:`Configure Jira`,optional:`optional`},mcpHint:`Connect external AI tools to Specrails over a secure local MCP server — enable it in Settings.`,agentChatHint:`Operate Specrails by chatting — the built-in agent drives the whole app for you. Open it from the bubble or ⌘⇧A.`},error:{title:`Setup failed`,skipSetup:`Skip setup`,prereqMissing:`SpecRails setup needs Node.js, npm, npx and Git available on PATH before it can install this project.`,prereqRetryHint:`Install the missing tools, restart Specrails, then retry setup.`}},r={title:`Add Project`,description:`Register a project directory to manage it from Specrails.`,noProviderDetected:`No AI CLI detected. Install Claude Code or Codex CLI first.`,pathLabel:`Project path`,pathPlaceholder:`/Users/me/my-project`,pathHint:`Absolute path to the project root`,browseForFolder:`Browse for folder`,selectProjectFolder:`Select project folder`,nameLabel:`Display name`,optional:`(optional)`,namePlaceholder:`My Project`,nameHint:`Defaults to the directory name`,providersLabel:`AI providers`,notFound:`not found`,multiProviderHint:`Both engines will be set up. The first is the project default. Cannot be changed after creation.`,singleProviderHint:`Cannot be changed after the project is created.`,adding:`Adding...`,submit:`Add Project`,toolsRequired_one:`{{tools}} is required to add a project`,toolsRequired_other:`{{tools}} are required to add a project`,errors:{pathRequired:`Project path is required`,selectProvider:`Select at least one AI provider`,addFailed:`Failed to add project`},toasts:{registered:`Project "{{name}}" registered`}},i={corruptedBundle:`bundle corrupted — reinstall app`,notInstalled:`not installed`,failedToExecute:`found but failed to execute`,failedToExecuteAt:`found at {{path}} but failed to execute`,failedToExecuteWithError:`found but failed to execute ({{error}})`,failedToExecuteAtWithError:`found at {{path}} but failed to execute ({{error}})`,needsMinimum:`{{version}} found — needs {{minVersion}}+`,unknownVersion:`unknown`,installedLabel:`installed`,verifyError:`Could not verify developer tools locally — install will validate.`,allDetected:`All required tools detected`,bundleCorruptedTitle:`App bundle corrupted`,toolsRequired_one:`{{count}} developer tool required`,toolsRequired_other:`{{count}} developer tools required`,reinstallHint:`Reinstall the Specrails app to restore bundled tools.`,installMissingHint:`Install the missing tools to continue.`,moreInfo:`More info`,bundledBadge:`bundled`,optional:`optional`,ghNoAuth:"Not signed in — run `gh auth login`"},a={title:`Install developer tools`,description:`SpecRails needs Node.js, npm, npx, and Git on PATH. Pick the snippet for your OS, run it, then click "I installed it, recheck".`,darwin:{intro:`Homebrew gets you both tools in one line. If you do not have brew, use the official downloads.`,installNodeGit:`Install Node.js and Git via Homebrew`},win32:{intro:`Winget ships with Windows 11 and recent Windows 10. Open PowerShell or Terminal and run:`,installNode:`Install Node.js LTS`,installGit:`Install Git`,note:`After install, restart Specrails so Windows refreshes PATH.`},linux:{intro:`Use your distro package manager:`,debian:`Debian / Ubuntu`,fedora:`Fedora / RHEL`},links:{nodeOfficial:`Node.js (official)`,gitOfficial:`Git (official)`,gitWindows:`Git for Windows (official)`},showOtherPlatforms:`Show other platforms`,hideOtherPlatforms:`Hide other platforms`,recheck:`I installed it, recheck`,diagnostics:{copy:`Copy diagnostics`,copied:`Diagnostics copied`,failed:`Copy failed`},corrupted:{title:`App bundle corrupted`,description:`One or more bundled tools (Node.js, Git) could not be verified.`,body:`This tool is bundled with the Specrails app and cannot be installed separately. If you see this message, the app bundle may be corrupted. Please reinstall Specrails.`}},o={title:`Setup progress`,progress:`{{done}} of {{total}} complete`,rawLog_one:`Raw log ({{count}} line)`,rawLog_other:`Raw log ({{count}} lines)`},s={title:`Setup assistant`,subtitle:`Respond to prompts to configure your project`,settingUp:`Setting up your project...`,placeholder:`Type a response...`,keyboardHint:`Enter to send, Shift+Enter for new line`},c={title:`Welcome to <spec>spec</spec><rails>rails</rails>`,description:`Specrails manages multiple projects from a single interface. Add your first project to get started.`,addFirstProject:`Add your first project`,jiraHint:`Connect each project to its own Jira board — specs stay in sync, both ways.`,mcpHint:`Connect external AI tools to Specrails over a secure local MCP server — enable it in Settings.`,agentChatHint:`Operate Specrails by chatting — a built-in agent drives specs, rails and analytics for you through the local MCP. Open it from the bubble or ⌘⇧A.`},l=JSON.parse(`{"productTour":"Product tour","stepCount":"Step {{current}} of {{total}}","goToStep":"Go to step {{step}}: {{label}}","stepLabel":"Step {{step}}","dontShowAgain":"Don't show this again","skipTour":"Skip tour","getStarted":"Get Started","flow":{"addSpec":"Add Spec","dropInRail":"Drop in a Rail","hitPlay":"Hit Play","ship":"Ship","architect":"Architect","developer":"Developer","reviewer":"Reviewer"},"language":{"nav":"Language","title":"Choose your language","subtitle":"Specrails speaks your language","intro":"Pick the language you want the interface in. It applies instantly — this tour included.","note":"You can change it any time in Settings → Language."},"theme":{"nav":"Theme","title":"Pick your look","subtitle":"Built-in themes, applied instantly","intro":"Choose how Specrails should look — the theme applies the moment you click.","note":"You can change it any time in Settings → Appearance."},"welcome":{"nav":"Welcome","title":"Welcome to Specrails","subtitle":"Your local cockpit for shipping software with AI agents","intro":"Specrails turns an idea into shipped code — and lets you <b>see, steer, and trust</b> every step. Draft a spec by talking to an AI, drop it on an execution rail, and hit Play. The pipeline handles architecture, implementation, review and the pull request, streaming its work live the whole way.","coreLoopLabel":"The core loop","flowCaption":"Each spec flows through <b>Architect → Developer → Reviewer → Ship</b> automatically.","localNote":"<b>100% local · single user · no accounts.</b> Everything runs on your machine. Your code never leaves the laptop unless <i>you</i> spawn an agent against it.","tourNote":"This quick tour walks through everything the app can do — about a minute."},"authorSpecs":{"nav":"Author specs","title":"Turn ideas into specs","subtitle":"Six ways to capture exactly what you want built","intro":"A <b>spec</b> is a description of work you want done. Author one however suits the moment — from a quick one-liner to a full conversation with the AI.","exploreLabel":"Explore — converse","exploreBody":"Describe what you want in a chat; a live draft rebuilds itself every turn. A preset slider tunes how much project context the AI sees — from your message only, up to the full codebase plus your MCP servers.","quickLabel":"Quick — one shot","quickBody":"Already know what you want? Generate a complete spec in a single turn. Optionally enrich it with a Contract Layer: exact names, data shapes, invariants and a file-touch list so the agents don't reinvent anything.","websiteLabel":"From a website","websiteBody":"Opens an embedded browser. Hover-select an element or drag a rectangle, and the screenshot, DOM and applied CSS become attachments. The desktop build ships its own Chromium, so it works offline.","smashLabel":"SMASH a big epic","smashBody":"Explode a large spec into a family of smaller sub-specs in one click — each child carries a short summary on its card.","draftsLabel":"Drafts & Continue Editing","draftsBody":"Park an in-progress exploration as a draft ticket and resume it later; reopen any spec back in Explore to keep refining it.","compareLabel":"Compare side by side","compareBody":"Drag a spec to the screen edge and a picker of your other specs slides in — review two of them together, tablet-style."},"rails":{"nav":"Run on rails","title":"Run the pipeline on rails","subtitle":"Organize specs into lanes, then launch the agents","intro":"The right side of the Dashboard is your <b>Rails</b> — execution lanes. Drag a spec card onto a rail and press <play>▶ Play</play> to launch an implementation job.","jobLabel":"What each job runs","flowCaption":"Every phase streams its logs live as it works.","modeLabel":"Pick a Loop to run","modeBody":"Each rail runs a <b>Loop</b>. Pick a built-in one — <b>Implement</b> (the full structured pipeline), <b>Batch</b> (several specs at once) or <b>Freestyle</b> (Claude works autonomously, no fixed pipeline) — or one you built yourself.","profilesLabel":"Agent profiles","profilesBody":"A per-project, declarative catalog that decides which agents run and which model each one uses — picked per rail and snapshotted per job so concurrent work stays isolated.","jobDetailLabel":"Live job detail","jobDetailBody":"Every job shows a ticket-identity header, a live duration ticker and running turn/token counts, with the authoritative cost resolved on exit.","isolationLabel":"Many projects, isolated","isolationBody":"Each project has its own database and job queue. Run different projects at the same time and switch between them from the left sidebar — your place is remembered per project.","loopsLabel":"Build your own loops","loopsBody":"<b>Loops</b> is a visual builder: chain AI steps, shell commands and a <b>Loop Decider</b> that repeats until a goal is met — e.g. verify → fix → verify until everything is green. Publish a loop and pick it on any rail."},"agent":{"nav":"Agent chat","title":"Operate the app by chatting","subtitle":"A copilot that drives Specrails for you","intro":"The built-in <b>agent chat</b> lets you run Specrails by asking — create specs, launch rails, check analytics — instead of clicking around. It works through Specrails' own <b>MCP</b> tools, and because everything is live you watch the board change as it works.","openLabel":"Always a click away","openBody":"Open it from the floating bubble at the bottom, or press ⌘⇧A (Ctrl+Shift+A) from anywhere. The panel moves, resizes, maximizes and remembers where you left it.","operateLabel":"Drives the whole app","operateBody":"Pick a project (or Home for everything) and a provider, then just ask: “launch the three highest-priority tickets”, “how much did I spend this week?”.","levelsLabel":"You hold the leash","levelsBody":"A live level — <b>Observe → Edit → Operate → Autonomous</b>, cycled with Shift+Tab — decides how far it can go. It never acts above the level you set.","watchLabel":"Watch it happen","watchBody":"The panel is non-modal, so rails and specs appear on the dashboard in real time while the agent works. A status chip shows what it's doing right now.","mcpLabel":"Runs on the local MCP","mcpBody":"The agent drives the app through the embedded Specrails MCP server. If it's off, the panel offers a one-click enable — nothing is installed."},"providers":{"nav":"Your agent","title":"Bring your own agent","subtitle":"Claude Code, Codex and Gemini, as first-class engines","intro":"The app treats <b>Claude Code</b>, <b>Codex CLI</b> and <b>Gemini CLI</b> as interchangeable engines behind one contract. A project can install one or more — the choice is made at install time.","table":{"capability":"Capability","streamingResume":"Streaming & session resume","native":"Native","costReporting":"Cost reporting","providerBilled":"Provider-billed","estimated":"Estimated (~)","telemetry":"Telemetry (OTEL)","synthesized":"Synthesized","agentProfiles":"Agent profiles"},"calloutLabel":"When several are installed","calloutBody":"Pick the engine <b>per spec, per rail, or per terminal launch</b>. The app remembers your last choice per project. Codex cost is estimated from a local rate-card and always flagged with a <mono>~</mono>."},"cost":{"nav":"Track cost","title":"Track every cent","subtitle":"Every billable invocation, recorded and visualized","intro":"Every AI invocation — across rails, Quick, Explore, AI edits, SMASH and file summaries — is recorded for <b>both Claude and Codex</b>. No more guessing what the agents cost.","analyticsLabel":"Analytics page","analyticsBody":"A burn-rate hero, daily timeline, top tickets, model breakdown and a cost-vs-turns scatter. Filter by period (7d / 30d / 90d / All) and by surface.","perTicketLabel":"Per-ticket spending","perTicketBody":"Each spec's detail shows what it cost and how many turns it took, deep-linking into Analytics filtered to that ticket.","honestLabel":"Honest numbers","honestBody":"Claude cost is the provider-billed figure; Codex is estimated and flagged with <mono>~</mono>. Token totals include the cache tiers, so the figures actually reconcile.","budgetsLabel":"Budgets & alerts","budgetsBody":"Set a daily budget and a per-job cost alert; the app auto-pauses the queue when you cross the line. Export anything to CSV or JSON."},"workspace":{"nav":"Workspace","title":"Make it your workspace","subtitle":"Everything you need without leaving the window","terminalLabel":"Terminal panel","terminalBody":"A real VS-Code-style terminal at the bottom (<mod>{{mod}}</mod> <j>J</j>) — WebGL rendering, search, inline images, drag-drop paths and shell integration. Up to 10 sessions per project.","codeLabel":"Code explorer","codeBody":"A read-only file tree and Monaco viewer with plain-language AI summaries and “touched by AI” provenance chips, so anyone can follow what changed and why.","integrationsLabel":"Integrations","integrationsBody":"A per-project marketplace of MCP integrations — Serena semantic code-navigation is bundled. Installs are additive: adding one never disturbs another.","themesLabel":"Themes","themesBody":"Six built-in themes — specrails (default), dracula, aurora-light, obsidian-dark, code-rain and galaxy — applied before the UI paints, so there's no flash. Change them in Settings → Appearance.","chatsLabel":"Minimizable chats","chatsBody":"Park an Explore or AI-Edit session into a dock chip and pick it back up later — never lost across refreshes or project switches.","desktopLabel":"Desktop or browser","desktopBody":"Run Specrails in your browser, or grab the signed desktop app (macOS & Windows) that bundles its own server and runtimes."},"companion":{"nav":"Mobile companion","title":"Take Specrails with you","subtitle":"Specrails Companion — your pipelines, on your phone","intro":"<b>Specrails Companion</b> is a web app at specrails.dev/companion-app — open it on your phone (or add it to your Home Screen) to browse the specs board, launch and stop rails, follow live job logs and glance at analytics. No install, no app store.","localLabel":"100% local, like everything else","localBody":"Your phone connects straight to this computer — peer-to-peer and encrypted (WebRTC). No cloud relay, no account, and your code never leaves your devices.","downloadLabel":"Open it on your phone","downloadHint":"Scan the code with your phone's camera, or open specrails.dev/companion-app in its browser.","open":"Open Specrails Companion","pairLabel":"Pairing takes ten seconds","pairBody":"On your phone open specrails.dev/companion-app, then here go to Settings → Mobile companion → Pair web companion and follow the on-screen steps."},"moveFast":{"nav":"Move fast","title":"Move at the speed of thought","subtitle":"Keyboard-first, everywhere","paletteLabel":"Command palette","paletteShortcut":"<f>Press</f> <mod>{{mod}}</mod> <m>+</m> <k>K</k> <m>anywhere</m>","paletteBody":"Switch projects, run spec commands, jump to any page and find recent jobs — all with fuzzy search.","terminalLabel":"Terminal panel","terminalBody":"Toggle with <mod>{{mod}}</mod> <j>J</j>.","shortcutsLabel":"All shortcuts","shortcutsBody":"Press <q>?</q> to see the full cheat-sheet.","chatLabel":"Chat sidebar","chatBody":"Toggle the right sidebar with <mod>{{mod}}</mod> <bkey>B</bkey>.","projectsLabel":"Projects sidebar","projectsBody":"Toggle the left Arc sidebar with <alt>{{alt}}</alt> <mod>{{mod}}</mod> <bkey>B</bkey>.","outro":"<b>That's the tour.</b> Add a project from the left sidebar and ship your first spec. You can reopen this walkthrough anytime from Settings."},"jira":{"label":"Jira integration","body":"Back any project with a <b>Jira board</b> — each spec becomes a Jira issue, kept in sync both ways: status follows the rail, and a comment is posted when a job finishes. Configure it per project when you add it, or anytime in Settings."}}`),u={wizard:n,addProject:r,prerequisites:i,instructions:a,checkpoints:o,setupChat:s,welcome:c,onboarding:l};export{t};
@@ -1 +1 @@
1
- import{gn as e}from"./index-DC-REAcL.js";var t=e(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]);export{t};
1
+ import{gn as e}from"./index-B3ejvKSt.js";var t=e(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]);export{t};
@@ -1 +1 @@
1
- import{t as e}from"./chunk-BNv3lrIs.js";import{Kn as t,zn as n}from"./index-DC-REAcL.js";var r=e((e=>{var r=t(),i=n();function a(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var o=typeof Object.is==`function`?Object.is:a,s=i.useSyncExternalStore,c=r.useRef,l=r.useEffect,u=r.useMemo,d=r.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,i){var a=c(null);if(a.current===null){var f={hasValue:!1,value:null};a.current=f}else f=a.current;a=u(function(){function e(e){if(!a){if(a=!0,s=e,e=r(e),i!==void 0&&f.hasValue){var t=f.value;if(i(t,e))return c=t}return c=e}if(t=c,o(s,e))return t;var n=r(e);return i!==void 0&&i(t,n)?(s=e,t):(s=e,c=n)}var a=!1,s,c,l=n===void 0?null:n;return[function(){return e(t())},l===null?void 0:function(){return e(l())}]},[t,n,r,i]);var p=s(e,a[0],a[1]);return l(function(){f.hasValue=!0,f.value=p},[p]),d(p),p}})),i=e(((e,t)=>{t.exports=r()}));function a(e,t,n){e.prototype=t.prototype=n,n.constructor=e}function o(e,t){var n=Object.create(e.prototype);for(var r in t)n[r]=t[r];return n}function s(){}var c=.7,l=1/c,u=`\\s*([+-]?\\d+)\\s*`,d=`\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*`,f=`\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*`,p=/^#([0-9a-f]{3,8})$/,m=RegExp(`^rgb\\(${u},${u},${u}\\)$`),h=RegExp(`^rgb\\(${f},${f},${f}\\)$`),ee=RegExp(`^rgba\\(${u},${u},${u},${d}\\)$`),g=RegExp(`^rgba\\(${f},${f},${f},${d}\\)$`),_=RegExp(`^hsl\\(${d},${f},${f}\\)$`),v=RegExp(`^hsla\\(${d},${f},${f},${d}\\)$`),y={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};a(s,C,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:b,formatHex:b,formatHex8:x,formatHsl:te,formatRgb:S,toString:S});function b(){return this.rgb().formatHex()}function x(){return this.rgb().formatHex8()}function te(){return I(this).formatHsl()}function S(){return this.rgb().formatRgb()}function C(e){var t,n;return e=(e+``).trim().toLowerCase(),(t=p.exec(e))?(n=t[1].length,t=parseInt(t[1],16),n===6?w(t):n===3?new O(t>>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):n===8?T(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):n===4?T(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=m.exec(e))?new O(t[1],t[2],t[3],1):(t=h.exec(e))?new O(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=ee.exec(e))?T(t[1],t[2],t[3],t[4]):(t=g.exec(e))?T(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=_.exec(e))?F(t[1],t[2]/100,t[3]/100,1):(t=v.exec(e))?F(t[1],t[2]/100,t[3]/100,t[4]):y.hasOwnProperty(e)?w(y[e]):e===`transparent`?new O(NaN,NaN,NaN,0):null}function w(e){return new O(e>>16&255,e>>8&255,e&255,1)}function T(e,t,n,r){return r<=0&&(e=t=n=NaN),new O(e,t,n,r)}function E(e){return e instanceof s||(e=C(e)),e?(e=e.rgb(),new O(e.r,e.g,e.b,e.opacity)):new O}function D(e,t,n,r){return arguments.length===1?E(e):new O(e,t,n,r??1)}function O(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}a(O,D,o(s,{brighter(e){return e=e==null?l:l**+e,new O(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?c:c**+e,new O(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new O(N(this.r),N(this.g),N(this.b),M(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:k,formatHex:k,formatHex8:A,formatRgb:j,toString:j}));function k(){return`#${P(this.r)}${P(this.g)}${P(this.b)}`}function A(){return`#${P(this.r)}${P(this.g)}${P(this.b)}${P((isNaN(this.opacity)?1:this.opacity)*255)}`}function j(){let e=M(this.opacity);return`${e===1?`rgb(`:`rgba(`}${N(this.r)}, ${N(this.g)}, ${N(this.b)}${e===1?`)`:`, ${e})`}`}function M(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function N(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function P(e){return e=N(e),(e<16?`0`:``)+e.toString(16)}function F(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new R(e,t,n,r)}function I(e){if(e instanceof R)return new R(e.h,e.s,e.l,e.opacity);if(e instanceof s||(e=C(e)),!e)return new R;if(e instanceof R)return e;e=e.rgb();var t=e.r/255,n=e.g/255,r=e.b/255,i=Math.min(t,n,r),a=Math.max(t,n,r),o=NaN,c=a-i,l=(a+i)/2;return c?(o=t===a?(n-r)/c+(n<r)*6:n===a?(r-t)/c+2:(t-n)/c+4,c/=l<.5?a+i:2-a-i,o*=60):c=l>0&&l<1?0:o,new R(o,c,l,e.opacity)}function L(e,t,n,r){return arguments.length===1?I(e):new R(e,t,n,r??1)}function R(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}a(R,L,o(s,{brighter(e){return e=e==null?l:l**+e,new R(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?c:c**+e,new R(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,i=2*n-r;return new O(V(e>=240?e-240:e+120,i,r),V(e,i,r),V(e<120?e+240:e-120,i,r),this.opacity)},clamp(){return new R(z(this.h),B(this.s),B(this.l),M(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let e=M(this.opacity);return`${e===1?`hsl(`:`hsla(`}${z(this.h)}, ${B(this.s)*100}%, ${B(this.l)*100}%${e===1?`)`:`, ${e})`}`}}));function z(e){return e=(e||0)%360,e<0?e+360:e}function B(e){return Math.max(0,Math.min(1,e||0))}function V(e,t,n){return(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)*255}var H=e=>()=>e;function U(e,t){return function(n){return e+n*t}}function W(e,t,n){return e**=+n,t=t**+n-e,n=1/n,function(r){return(e+r*t)**+n}}function G(e){return(e=+e)==1?K:function(t,n){return n-t?W(t,n,e):H(isNaN(t)?n:t)}}function K(e,t){var n=t-e;return n?U(e,n):H(isNaN(e)?t:e)}var q=(function e(t){var n=G(t);function r(e,t){var r=n((e=D(e)).r,(t=D(t)).r),i=n(e.g,t.g),a=n(e.b,t.b),o=K(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=i(t),e.b=a(t),e.opacity=o(t),e+``}}return r.gamma=e,r})(1);function J(e,t){t||=[];var n=e?Math.min(t.length,e.length):0,r=t.slice(),i;return function(a){for(i=0;i<n;++i)r[i]=e[i]*(1-a)+t[i]*a;return r}}function ne(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function re(e,t){var n=t?t.length:0,r=e?Math.min(n,e.length):0,i=Array(r),a=Array(n),o;for(o=0;o<r;++o)i[o]=$(e[o],t[o]);for(;o<n;++o)a[o]=t[o];return function(e){for(o=0;o<r;++o)a[o]=i[o](e);return a}}function ie(e,t){var n=new Date;return e=+e,t=+t,function(r){return n.setTime(e*(1-r)+t*r),n}}function Y(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}function ae(e,t){var n={},r={},i;for(i in(typeof e!=`object`||!e)&&(e={}),(typeof t!=`object`||!t)&&(t={}),t)i in e?n[i]=$(e[i],t[i]):r[i]=t[i];return function(e){for(i in n)r[i]=n[i](e);return r}}var X=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,Z=new RegExp(X.source,`g`);function oe(e){return function(){return e}}function se(e){return function(t){return e(t)+``}}function Q(e,t){var n=X.lastIndex=Z.lastIndex=0,r,i,a,o=-1,s=[],c=[];for(e+=``,t+=``;(r=X.exec(e))&&(i=Z.exec(t));)(a=i.index)>n&&(a=t.slice(n,a),s[o]?s[o]+=a:s[++o]=a),(r=r[0])===(i=i[0])?s[o]?s[o]+=i:s[++o]=i:(s[++o]=null,c.push({i:o,x:Y(r,i)})),n=Z.lastIndex;return n<t.length&&(a=t.slice(n),s[o]?s[o]+=a:s[++o]=a),s.length<2?c[0]?se(c[0].x):oe(t):(t=c.length,function(e){for(var n=0,r;n<t;++n)s[(r=c[n]).i]=r.x(e);return s.join(``)})}function $(e,t){var n=typeof t,r;return t==null||n===`boolean`?H(t):(n===`number`?Y:n===`string`?(r=C(t))?(t=r,q):Q:t instanceof C?q:t instanceof Date?ie:ne(t)?J:Array.isArray(t)?re:typeof t.valueOf!=`function`&&typeof t.toString!=`function`||isNaN(t)?ae:Y)(e,t)}export{C as a,q as i,Q as n,i as o,Y as r,$ as t};
1
+ import{t as e}from"./chunk-BNv3lrIs.js";import{Kn as t,zn as n}from"./index-B3ejvKSt.js";var r=e((e=>{var r=t(),i=n();function a(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var o=typeof Object.is==`function`?Object.is:a,s=i.useSyncExternalStore,c=r.useRef,l=r.useEffect,u=r.useMemo,d=r.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,i){var a=c(null);if(a.current===null){var f={hasValue:!1,value:null};a.current=f}else f=a.current;a=u(function(){function e(e){if(!a){if(a=!0,s=e,e=r(e),i!==void 0&&f.hasValue){var t=f.value;if(i(t,e))return c=t}return c=e}if(t=c,o(s,e))return t;var n=r(e);return i!==void 0&&i(t,n)?(s=e,t):(s=e,c=n)}var a=!1,s,c,l=n===void 0?null:n;return[function(){return e(t())},l===null?void 0:function(){return e(l())}]},[t,n,r,i]);var p=s(e,a[0],a[1]);return l(function(){f.hasValue=!0,f.value=p},[p]),d(p),p}})),i=e(((e,t)=>{t.exports=r()}));function a(e,t,n){e.prototype=t.prototype=n,n.constructor=e}function o(e,t){var n=Object.create(e.prototype);for(var r in t)n[r]=t[r];return n}function s(){}var c=.7,l=1/c,u=`\\s*([+-]?\\d+)\\s*`,d=`\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*`,f=`\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*`,p=/^#([0-9a-f]{3,8})$/,m=RegExp(`^rgb\\(${u},${u},${u}\\)$`),h=RegExp(`^rgb\\(${f},${f},${f}\\)$`),ee=RegExp(`^rgba\\(${u},${u},${u},${d}\\)$`),g=RegExp(`^rgba\\(${f},${f},${f},${d}\\)$`),_=RegExp(`^hsl\\(${d},${f},${f}\\)$`),v=RegExp(`^hsla\\(${d},${f},${f},${d}\\)$`),y={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};a(s,C,{copy(e){return Object.assign(new this.constructor,this,e)},displayable(){return this.rgb().displayable()},hex:b,formatHex:b,formatHex8:x,formatHsl:te,formatRgb:S,toString:S});function b(){return this.rgb().formatHex()}function x(){return this.rgb().formatHex8()}function te(){return I(this).formatHsl()}function S(){return this.rgb().formatRgb()}function C(e){var t,n;return e=(e+``).trim().toLowerCase(),(t=p.exec(e))?(n=t[1].length,t=parseInt(t[1],16),n===6?w(t):n===3?new O(t>>8&15|t>>4&240,t>>4&15|t&240,(t&15)<<4|t&15,1):n===8?T(t>>24&255,t>>16&255,t>>8&255,(t&255)/255):n===4?T(t>>12&15|t>>8&240,t>>8&15|t>>4&240,t>>4&15|t&240,((t&15)<<4|t&15)/255):null):(t=m.exec(e))?new O(t[1],t[2],t[3],1):(t=h.exec(e))?new O(t[1]*255/100,t[2]*255/100,t[3]*255/100,1):(t=ee.exec(e))?T(t[1],t[2],t[3],t[4]):(t=g.exec(e))?T(t[1]*255/100,t[2]*255/100,t[3]*255/100,t[4]):(t=_.exec(e))?F(t[1],t[2]/100,t[3]/100,1):(t=v.exec(e))?F(t[1],t[2]/100,t[3]/100,t[4]):y.hasOwnProperty(e)?w(y[e]):e===`transparent`?new O(NaN,NaN,NaN,0):null}function w(e){return new O(e>>16&255,e>>8&255,e&255,1)}function T(e,t,n,r){return r<=0&&(e=t=n=NaN),new O(e,t,n,r)}function E(e){return e instanceof s||(e=C(e)),e?(e=e.rgb(),new O(e.r,e.g,e.b,e.opacity)):new O}function D(e,t,n,r){return arguments.length===1?E(e):new O(e,t,n,r??1)}function O(e,t,n,r){this.r=+e,this.g=+t,this.b=+n,this.opacity=+r}a(O,D,o(s,{brighter(e){return e=e==null?l:l**+e,new O(this.r*e,this.g*e,this.b*e,this.opacity)},darker(e){return e=e==null?c:c**+e,new O(this.r*e,this.g*e,this.b*e,this.opacity)},rgb(){return this},clamp(){return new O(N(this.r),N(this.g),N(this.b),M(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:k,formatHex:k,formatHex8:A,formatRgb:j,toString:j}));function k(){return`#${P(this.r)}${P(this.g)}${P(this.b)}`}function A(){return`#${P(this.r)}${P(this.g)}${P(this.b)}${P((isNaN(this.opacity)?1:this.opacity)*255)}`}function j(){let e=M(this.opacity);return`${e===1?`rgb(`:`rgba(`}${N(this.r)}, ${N(this.g)}, ${N(this.b)}${e===1?`)`:`, ${e})`}`}function M(e){return isNaN(e)?1:Math.max(0,Math.min(1,e))}function N(e){return Math.max(0,Math.min(255,Math.round(e)||0))}function P(e){return e=N(e),(e<16?`0`:``)+e.toString(16)}function F(e,t,n,r){return r<=0?e=t=n=NaN:n<=0||n>=1?e=t=NaN:t<=0&&(e=NaN),new R(e,t,n,r)}function I(e){if(e instanceof R)return new R(e.h,e.s,e.l,e.opacity);if(e instanceof s||(e=C(e)),!e)return new R;if(e instanceof R)return e;e=e.rgb();var t=e.r/255,n=e.g/255,r=e.b/255,i=Math.min(t,n,r),a=Math.max(t,n,r),o=NaN,c=a-i,l=(a+i)/2;return c?(o=t===a?(n-r)/c+(n<r)*6:n===a?(r-t)/c+2:(t-n)/c+4,c/=l<.5?a+i:2-a-i,o*=60):c=l>0&&l<1?0:o,new R(o,c,l,e.opacity)}function L(e,t,n,r){return arguments.length===1?I(e):new R(e,t,n,r??1)}function R(e,t,n,r){this.h=+e,this.s=+t,this.l=+n,this.opacity=+r}a(R,L,o(s,{brighter(e){return e=e==null?l:l**+e,new R(this.h,this.s,this.l*e,this.opacity)},darker(e){return e=e==null?c:c**+e,new R(this.h,this.s,this.l*e,this.opacity)},rgb(){var e=this.h%360+(this.h<0)*360,t=isNaN(e)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*t,i=2*n-r;return new O(V(e>=240?e-240:e+120,i,r),V(e,i,r),V(e<120?e+240:e-120,i,r),this.opacity)},clamp(){return new R(z(this.h),B(this.s),B(this.l),M(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){let e=M(this.opacity);return`${e===1?`hsl(`:`hsla(`}${z(this.h)}, ${B(this.s)*100}%, ${B(this.l)*100}%${e===1?`)`:`, ${e})`}`}}));function z(e){return e=(e||0)%360,e<0?e+360:e}function B(e){return Math.max(0,Math.min(1,e||0))}function V(e,t,n){return(e<60?t+(n-t)*e/60:e<180?n:e<240?t+(n-t)*(240-e)/60:t)*255}var H=e=>()=>e;function U(e,t){return function(n){return e+n*t}}function W(e,t,n){return e**=+n,t=t**+n-e,n=1/n,function(r){return(e+r*t)**+n}}function G(e){return(e=+e)==1?K:function(t,n){return n-t?W(t,n,e):H(isNaN(t)?n:t)}}function K(e,t){var n=t-e;return n?U(e,n):H(isNaN(e)?t:e)}var q=(function e(t){var n=G(t);function r(e,t){var r=n((e=D(e)).r,(t=D(t)).r),i=n(e.g,t.g),a=n(e.b,t.b),o=K(e.opacity,t.opacity);return function(t){return e.r=r(t),e.g=i(t),e.b=a(t),e.opacity=o(t),e+``}}return r.gamma=e,r})(1);function J(e,t){t||=[];var n=e?Math.min(t.length,e.length):0,r=t.slice(),i;return function(a){for(i=0;i<n;++i)r[i]=e[i]*(1-a)+t[i]*a;return r}}function ne(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function re(e,t){var n=t?t.length:0,r=e?Math.min(n,e.length):0,i=Array(r),a=Array(n),o;for(o=0;o<r;++o)i[o]=$(e[o],t[o]);for(;o<n;++o)a[o]=t[o];return function(e){for(o=0;o<r;++o)a[o]=i[o](e);return a}}function ie(e,t){var n=new Date;return e=+e,t=+t,function(r){return n.setTime(e*(1-r)+t*r),n}}function Y(e,t){return e=+e,t=+t,function(n){return e*(1-n)+t*n}}function ae(e,t){var n={},r={},i;for(i in(typeof e!=`object`||!e)&&(e={}),(typeof t!=`object`||!t)&&(t={}),t)i in e?n[i]=$(e[i],t[i]):r[i]=t[i];return function(e){for(i in n)r[i]=n[i](e);return r}}var X=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,Z=new RegExp(X.source,`g`);function oe(e){return function(){return e}}function se(e){return function(t){return e(t)+``}}function Q(e,t){var n=X.lastIndex=Z.lastIndex=0,r,i,a,o=-1,s=[],c=[];for(e+=``,t+=``;(r=X.exec(e))&&(i=Z.exec(t));)(a=i.index)>n&&(a=t.slice(n,a),s[o]?s[o]+=a:s[++o]=a),(r=r[0])===(i=i[0])?s[o]?s[o]+=i:s[++o]=i:(s[++o]=null,c.push({i:o,x:Y(r,i)})),n=Z.lastIndex;return n<t.length&&(a=t.slice(n),s[o]?s[o]+=a:s[++o]=a),s.length<2?c[0]?se(c[0].x):oe(t):(t=c.length,function(e){for(var n=0,r;n<t;++n)s[(r=c[n]).i]=r.x(e);return s.join(``)})}function $(e,t){var n=typeof t,r;return t==null||n===`boolean`?H(t):(n===`number`?Y:n===`string`?(r=C(t))?(t=r,q):Q:t instanceof C?q:t instanceof Date?ie:ne(t)?J:Array.isArray(t)?re:typeof t.valueOf!=`function`&&typeof t.toString!=`function`||isNaN(t)?ae:Y)(e,t)}export{C as a,q as i,Q as n,i as o,Y as r,$ as t};
@@ -47,8 +47,14 @@
47
47
  } catch (_) { /* storage unavailable — nothing to migrate */ }
48
48
  try {
49
49
  var k = 'specrails-desktop:ui-theme'
50
- var allowed = ['dracula', 'aurora-light', 'obsidian-dark', 'matrix', 'specrails']
50
+ var legacyThemeIds = { 'star-wars': 'galaxy', matrix: 'code-rain' }
51
+ var allowed = ['dracula', 'aurora-light', 'obsidian-dark', 'code-rain', 'specrails', 'galaxy']
51
52
  var v = localStorage.getItem(k)
53
+ var migrated = legacyThemeIds[v]
54
+ if (migrated) {
55
+ v = migrated
56
+ localStorage.setItem(k, migrated)
57
+ }
52
58
  document.documentElement.dataset.theme =
53
59
  v && allowed.indexOf(v) !== -1 ? v : 'specrails'
54
60
  } catch (_) {
@@ -85,7 +91,7 @@
85
91
  --splash-secondary: #f48fc7;
86
92
  --splash-muted: #8b8fa3;
87
93
  }
88
- html[data-theme="matrix"] {
94
+ html[data-theme="code-rain"] {
89
95
  --splash-bg: #08120e;
90
96
  --splash-fg: #b8ffd9;
91
97
  --splash-primary: #00ff66;
@@ -99,6 +105,13 @@
99
105
  --splash-secondary: #9a6fce;
100
106
  --splash-muted: #6b6f8c;
101
107
  }
108
+ html[data-theme="galaxy"] {
109
+ --splash-bg: hsl(220 20% 4%);
110
+ --splash-fg: hsl(210 30% 94%);
111
+ --splash-primary: hsl(212 100% 62%);
112
+ --splash-secondary: hsl(210 12% 65%);
113
+ --splash-muted: hsl(215 15% 60%);
114
+ }
102
115
  html, body {
103
116
  margin: 0;
104
117
  background: var(--splash-bg);
@@ -191,14 +204,14 @@
191
204
  .specrails-splash__mark .pill { opacity: 1; }
192
205
  }
193
206
  </style>
194
- <script type="module" crossorigin src="/assets/index-DC-REAcL.js"></script>
207
+ <script type="module" crossorigin src="/assets/index-B3ejvKSt.js"></script>
195
208
  <link rel="modulepreload" crossorigin href="/assets/chunk-BNv3lrIs.js">
196
209
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-DSXbuxSR.js">
197
210
  <link rel="modulepreload" crossorigin href="/assets/clsx-CNmW0Nip.js">
198
211
  <link rel="modulepreload" crossorigin href="/assets/auth-Cvsb7-Ek.js">
199
212
  <link rel="modulepreload" crossorigin href="/assets/activity-D8vQJrpW.js">
200
213
  <link rel="modulepreload" crossorigin href="/assets/addspec-DxW6oPsk.js">
201
- <link rel="modulepreload" crossorigin href="/assets/agent-Df3lnHMu.js">
214
+ <link rel="modulepreload" crossorigin href="/assets/agent-_tfCgFUk.js">
202
215
  <link rel="modulepreload" crossorigin href="/assets/agents-Cev2oFfX.js">
203
216
  <link rel="modulepreload" crossorigin href="/assets/agentstudio-CZm2rOzt.js">
204
217
  <link rel="modulepreload" crossorigin href="/assets/aiedit-DYtnZU9H.js">
@@ -209,20 +222,20 @@
209
222
  <link rel="modulepreload" crossorigin href="/assets/code-thSEptMx.js">
210
223
  <link rel="modulepreload" crossorigin href="/assets/commands-CckaBWdV.js">
211
224
  <link rel="modulepreload" crossorigin href="/assets/common-CYaT2yHp.js">
212
- <link rel="modulepreload" crossorigin href="/assets/dashboard-oqS7VRrK.js">
225
+ <link rel="modulepreload" crossorigin href="/assets/dashboard-BcjUOLJr.js">
213
226
  <link rel="modulepreload" crossorigin href="/assets/explore-BKVV5JSu.js">
214
227
  <link rel="modulepreload" crossorigin href="/assets/integrations-CuWnMR5L.js">
215
228
  <link rel="modulepreload" crossorigin href="/assets/jira-B3613-gj.js">
216
229
  <link rel="modulepreload" crossorigin href="/assets/jobs-D5sZzgLs.js">
217
- <link rel="modulepreload" crossorigin href="/assets/loops-YYV2bwjd.js">
230
+ <link rel="modulepreload" crossorigin href="/assets/loops-Brnx4Fji.js">
218
231
  <link rel="modulepreload" crossorigin href="/assets/mcp-CIH0pH1K.js">
219
232
  <link rel="modulepreload" crossorigin href="/assets/nav-CzKzuwH8.js">
220
- <link rel="modulepreload" crossorigin href="/assets/settings-Mr7MnJbf.js">
221
- <link rel="modulepreload" crossorigin href="/assets/setup-VNqXyB6Y.js">
233
+ <link rel="modulepreload" crossorigin href="/assets/settings-D9bDDe2O.js">
234
+ <link rel="modulepreload" crossorigin href="/assets/setup-RiUHzq7E.js">
222
235
  <link rel="modulepreload" crossorigin href="/assets/specs-CmEZY57v.js">
223
236
  <link rel="modulepreload" crossorigin href="/assets/terminal-DFPNRLKp.js">
224
237
  <link rel="modulepreload" crossorigin href="/assets/tickets-CkfbISuK.js">
225
- <link rel="stylesheet" crossorigin href="/assets/index-BtAks9nm.css">
238
+ <link rel="stylesheet" crossorigin href="/assets/index-C695aPdV.css">
226
239
  </head>
227
240
  <body>
228
241
  <div id="specrails-splash" aria-hidden="false" role="status" aria-label="Loading Specrails">
@@ -10,7 +10,7 @@
10
10
 
11
11
  La premisa ("`agy` es el sucesor oficial, no quiero construir sobre algo deprecado") es **correcta a medias y, para nuestro contrato concreto, lleva a la conclusión opuesta**:
12
12
 
13
- 1. **El sunset NO mata el path que nos interesa.** Verificado contra fuente primaria (Google Developers Blog, "Transitioning Gemini CLI to Antigravity CLI"). El 18-jun-2026 lo que deja de servirse son **las peticiones de los logins de suscripción consumer (AI Pro / Ultra) y el tier gratuito**. Literalmente: *"Gemini CLI and Gemini Code Assist IDE extensions will stop serving requests for Google AI Pro and Ultra, as well as those using it free of charge."* Pero el path que un servidor desatendido usaría — **`GEMINI_API_KEY` de pago / enterprise** — **sobrevive explícitamente**: *"Gemini CLI will remain accessible via paid Gemini and Gemini Enterprise Agent Platform API keys"* y *"We'll continue to support Gemini CLI ... with access to the latest Gemini models and other updates."* El repo `google-gemini/gemini-cli` está **vivo** (`archived:false`, último push 2026-06-17, releases activas v0.46.0 estable / v0.48.0-nightly).
13
+ 1. **El sunset NO mata el path que nos interesa.** Verificado contra fuente primaria (Google Developers Blog, "Transitioning Gemini CLI to Antigravity CLI"). El 18-jun-2026 lo que deja de servirse son **las peticiones de los logins de suscripción consumer (AI Pro / Freestyle) y el tier gratuito**. Literalmente: *"Gemini CLI and Gemini Code Assist IDE extensions will stop serving requests for Google AI Pro and Freestyle, as well as those using it free of charge."* Pero el path que un servidor desatendido usaría — **`GEMINI_API_KEY` de pago / enterprise** — **sobrevive explícitamente**: *"Gemini CLI will remain accessible via paid Gemini and Gemini Enterprise Agent Platform API keys"* y *"We'll continue to support Gemini CLI ... with access to the latest Gemini models and other updates."* El repo `google-gemini/gemini-cli` está **vivo** (`archived:false`, último push 2026-06-17, releases activas v0.46.0 estable / v0.48.0-nightly).
14
14
 
15
15
  2. **`agy` no satisface el contrato hoy, en ninguna de sus 5 patas críticas a la vez.** Verificado contra el issue tracker (todos OPEN, cero respuesta de Google, a 2026-06-17): `#76` (stdout 0 bytes en non-TTY → rompe la captura básica de subproceso), `#7` (el conversation/session id **nunca** se expone → no hay handle que capturar para `--resume`), `#31` (sin `--acp`/JSON-RPC), `#119`/`#394` (sin `--output-format json`/stream-json), `#78` (OAuth-only, sin auth por API-key headless). Además `#85` (cerrado sin fix shipado) muestra que en **macOS** — nuestro target de escritorio — un proceso en background re-pide login por el timeout de 1s del keyring. **Coste/tokens no se exponen en NINGÚN sitio** (ni stdout, ni transcript.jsonl, ni CLI): la pata `cost` del contrato es directamente irresoluble hoy.
16
16
 
package/docs/codex.md CHANGED
@@ -120,7 +120,7 @@ the [Gemini guide](gemini.md).)
120
120
  | **Agent format** | `.claude/agents/<id>.md` with `model:` frontmatter | `.codex/skills/<id>/SKILL.md` Skill format | `.gemini/` command + agent target |
121
121
  | **Agent profiles** | Full support (rail `RailProfileSelector`) | **None** — rails force the profile to `null` | **None** — rails force the profile to `null` |
122
122
  | **Pipeline rails** | ✅ all rail types | ✅ (except Freestyle) | ✅ (except Freestyle) |
123
- | **Freestyle rails** (mode `ultracode`) | ✅ Claude-only | ❌ rejected (`Freestyle requires the Claude provider`) | ❌ rejected |
123
+ | **Freestyle rails** (mode `freestyle`) | ✅ Claude-only | ❌ rejected (`Freestyle requires the Claude provider`) | ❌ rejected |
124
124
  | **Contract Refine** | Claude-only (it `--resume`s the Explore session and runs `/specrails:contract-refine`) | **Skipped** — toggling "Enrich with Contract Layer" is a no-op | **Skipped** |
125
125
  | **MCP registration** | Surgical merge of `<project>/.mcp.json` | `codex mcp add` against per-project `CODEX_HOME=~/.specrails/projects/<slug>/codex-home/` (isolated) | Project `.mcp.json` (so Serena-style plugins **do** resolve) |
126
126
  | **Session resume** | `--resume <session_id>` | `exec resume <thread_id>` | `--resume` |
@@ -135,7 +135,7 @@ A few Codex-specific behaviours worth calling out:
135
135
  rails need to apply edits across the repo — but it's worth knowing if
136
136
  you're surprised by a rail touching files outside the working tree.
137
137
  - **Freestyle rails are Claude-only.** Launching a Freestyle rail (mode
138
- `ultracode`) on a Codex (or Gemini) engine is rejected with a 400
138
+ `freestyle`) on a Codex (or Gemini) engine is rejected with a 400
139
139
  (`Freestyle requires the Claude provider`). Pick Claude for that rail.
140
140
 
141
141
  ## Estimated cost
@@ -14,7 +14,7 @@ Gemini supera a Codex en dos capacidades clave verificadas:
14
14
 
15
15
  **Entra en v1 (PR-B beta-gated):** jobs/rails básicos, Explore Spec multi-turno (spawn-per-turn con `--resume`), Quick spec, Analytics/coste vía rate-card, OTEL nativo, terminal CLI launch, detección + prerequisitos, selección de modelo, multi-provider per project.
16
16
 
17
- **NO entra en v1 (paridad Codex, se ocultan por intersección de capacidades):** Agent Profiles, SMASH, Contract Refine, Ultracode (+interactivo), plugins/Serena, persistent-stdin de Explore. Gemini se comporta byte-idéntico a Codex en estas superficies **siempre que declare las capacidades correctas y se ensanchen los tipos** — cero código nuevo en esas superficies.
17
+ **NO entra en v1 (paridad Codex, se ocultan por intersección de capacidades):** Agent Profiles, SMASH, Contract Refine, Freestyle (+interactivo), plugins/Serena, persistent-stdin de Explore. Gemini se comporta byte-idéntico a Codex en estas superficies **siempre que declare las capacidades correctas y se ensanchen los tipos** — cero código nuevo en esas superficies.
18
18
 
19
19
  **Diferido a follow-up explícito (decisiones tomadas, no implementadas en v1):** generalizar `provider-capabilities.ts` para *otorgar* a Gemini features hoy claude-only; bridge Windows multi-line argv; traducción slash-command para rails funcionales en Gemini (esto último es **bloqueante para rails reales**, ver §6).
20
20
 
@@ -238,7 +238,7 @@ Mergeable independiente, no cambia comportamiento observable.
238
238
  | **Integrations/plugins (MCP/Serena)** | **Bloqueado (paridad codex)** | Manifest Serena omite `providerSupport` → claude-only. Paridad: añadir `'gemini'` a `providerSupport` + entry MCP bajo `.gemini/settings.json`. |
239
239
  | **SMASH** | **Bloqueado (paridad codex)** | `isSmashCapable→'claude'`. `smash-runner.ts` spawnea `claude` directo sin adapter. Paridad: reescribir runner sobre `getAdapter()` + prompt/parser Gemini + flip del gate. |
240
240
  | **Contract Refine** | **Bloqueado (inherentemente anthropic en su forma actual)** | `--resume` a sesión Claude + slash `/specrails:contract-refine`. Paridad parcial vía el path no-resume (re-seed por system prompt, como `runContractRefineForQuick`) + de-hardcodear `getAdapter('claude')`. |
241
- | **Ultracode interactivo** | **Bloqueado (paridad codex)** | `mode==='ultracode' && provider!=='claude'→400`; `isUltracode=adapter.id==='claude'`. Paridad: quitar el 400 para gemini, generalizar el branch ultracode-prompt, `persistentStdin:true` para el interactivo. Mecanismo no-anthropic; factible. |
241
+ | **Freestyle interactivo** | **Bloqueado (paridad codex)** | `mode==='freestyle' && provider!=='claude'→400`; `isFreestyle=adapter.id==='claude'`. Paridad: quitar el 400 para gemini, generalizar el branch freestyle-prompt, `persistentStdin:true` para el interactivo. Mecanismo no-anthropic; factible. |
242
242
  | **Analytics/coste** | **Nativo (estimado)** | `nativeCostUsd:false` + filas pricing → coste estimado, `estimated=true`. Filtros engine ya data-driven. |
243
243
  | **OTEL/telemetry** | **Nativo (MEJOR que codex)** | `nativeOtelEnv:true` → env-injection (no bridge). Solo parametrizar el enable-var en `buildTelemetryEnv`. Caveat correlación (§4). |
244
244
  | **Terminal CLI launch** | **Nativo** | `CliLaunchMenu` itera providers; aparece tras ensanchar union + wiring binario. |
@@ -81,4 +81,4 @@ Es gibt kein globales Parallelitäts-Limit, das du einstellen musst. Öffne die
81
81
 
82
82
  - [Rails & Jobs](rails-and-jobs) — das Queue-Modell im Detail.
83
83
  - [Die Job-Detail-Ansicht](the-job-detail-view) — einem Batch-Lauf live zusehen.
84
- - [Engine pro Rail wählen](picking-an-engine-per-rail) — beachte: Batch läuft auf jedem Provider; Ultra gibt es nur bei Claude.
84
+ - [Engine pro Rail wählen](picking-an-engine-per-rail) — beachte: Batch läuft auf jedem Provider; Freestyle gibt es nur bei Claude.
@@ -83,4 +83,4 @@ There's no global concurrency limit to tune. Open the projects or rails you need
83
83
 
84
84
  - [Rails & jobs](rails-and-jobs) — the queue model in depth.
85
85
  - [The Job Detail view](the-job-detail-view) — watch a batch run live.
86
- - [Picking an engine per rail](picking-an-engine-per-rail) — note that Batch runs on any provider; Ultra is Claude-only.
86
+ - [Picking an engine per rail](picking-an-engine-per-rail) — note that Batch runs on any provider; Freestyle is Claude-only.
@@ -81,4 +81,4 @@ No hay límite global de concurrencia que ajustar. Abre los proyectos o rails qu
81
81
 
82
82
  - [Rails y jobs](rails-and-jobs) — el modelo de cola en profundidad.
83
83
  - [La vista de detalle del job](the-job-detail-view) — mira un batch ejecutarse en vivo.
84
- - [Elegir un motor por rail](picking-an-engine-per-rail) — ten en cuenta que Batch corre en cualquier proveedor; Ultra es solo de Claude.
84
+ - [Elegir un motor por rail](picking-an-engine-per-rail) — ten en cuenta que Batch corre en cualquier proveedor; Freestyle es solo de Claude.
@@ -81,4 +81,4 @@ Il n'y a aucune limite globale de concurrence à régler. Ouvrez les projets ou
81
81
 
82
82
  - [Rails et jobs](rails-and-jobs) — le modèle de file d'attente en détail.
83
83
  - [La vue détaillée du job](the-job-detail-view) — regarder un batch s'exécuter en direct.
84
- - [Choisir un moteur par rail](picking-an-engine-per-rail) — notez que Batch fonctionne sur n'importe quel fournisseur ; Ultra est réservé à Claude.
84
+ - [Choisir un moteur par rail](picking-an-engine-per-rail) — notez que Batch fonctionne sur n'importe quel fournisseur ; Freestyle est réservé à Claude.
@@ -81,4 +81,4 @@ Non c'è alcun limite globale di concorrenza da regolare. Apri i progetti o i ra
81
81
 
82
82
  - [Rail e job](rails-and-jobs) — il modello della coda in dettaglio.
83
83
  - [La vista Dettaglio job](the-job-detail-view) — guarda un batch in esecuzione dal vivo.
84
- - [Scegliere un engine per ogni rail](picking-an-engine-per-rail) — nota che il Batch gira su qualsiasi provider; Ultra è solo Claude.
84
+ - [Scegliere un engine per ogni rail](picking-an-engine-per-rail) — nota che il Batch gira su qualsiasi provider; Freestyle è solo Claude.
@@ -81,4 +81,4 @@ Batch モードは、関連するスペックを*順番に処理する*一番す
81
81
 
82
82
  - [レールとジョブ](rails-and-jobs) — キューモデルを掘り下げて。
83
83
  - [ジョブ詳細ビュー](the-job-detail-view) — バッチ実行をライブで見守る。
84
- - [レールごとのエンジン選択](picking-an-engine-per-rail) — Batch はどのプロバイダーでも動きますが、Ultra は Claude 専用である点に注意。
84
+ - [レールごとのエンジン選択](picking-an-engine-per-rail) — Batch はどのプロバイダーでも動きますが、Freestyle は Claude 専用である点に注意。
@@ -81,4 +81,4 @@ Não há limite global de concorrência para ajustar. Abra os projetos ou rails
81
81
 
82
82
  - [Rails e jobs](rails-and-jobs) — o modelo da fila em detalhe.
83
83
  - [A vista de detalhe do job](the-job-detail-view) — ver um batch a correr ao vivo.
84
- - [Escolher um motor por rail](picking-an-engine-per-rail) — note que o Batch corre em qualquer fornecedor; o Ultra é só Claude.
84
+ - [Escolher um motor por rail](picking-an-engine-per-rail) — note que o Batch corre em qualquer fornecedor; o Freestyle é só Claude.
@@ -57,7 +57,7 @@ Um loop que nunca para queimaria dinheiro para sempre, então toda execução te
57
57
  |-------|--------------|
58
58
  | **Max iterations** | Teto rígido de quantas vezes o Decider pode voltar atrás, independentemente do seu veredito. |
59
59
  | **Timeout (min)** | Limite de tempo de relógio para toda a execução. |
60
- | **Max cost ($)** | *Opcional.* Para o loop quando o custo acumulado cruza o seu orçamento. Verificado **entre passos** (o custo de um passo só é conhecido quando ele termina), então pode ultrapassar em um passo. No Claude o custo é exato; no Codex e no Gemini é uma estimativa. Deixe vazio para não ter teto. |
60
+ | **Max cost ($)** | *Opcional.* Para o loop quando o custo acumulado cruza o seu orçamento. Verificado **entre passos** (o custo de um passo só é conhecido quando ele termina), então pode freestylepassar em um passo. No Claude o custo é exato; no Codex e no Gemini é uma estimativa. Deixe vazio para não ter teto. |
61
61
 
62
62
  ## Construindo com confiança
63
63
 
@@ -81,4 +81,4 @@ Project B ▶ Rail running feature Y ┘
81
81
 
82
82
  - [Rail 与任务](rails-and-jobs)——深入理解队列模型。
83
83
  - [任务详情视图](the-job-detail-view)——实时观看一次批量运行。
84
- - [为每条 rail 选择引擎](picking-an-engine-per-rail)——注意 Batch 可在任意提供方上运行;Ultra 仅限 Claude。
84
+ - [为每条 rail 选择引擎](picking-an-engine-per-rail)——注意 Batch 可在任意提供方上运行;Freestyle 仅限 Claude。
@@ -199,7 +199,7 @@ Example — queue a command on a specific provider:
199
199
  | `POST` | `/jobs/:id/finalize` | Finalize a running interactive job (SIGTERM the resident child; final totals + terminal status are stamped when it closes). For a loop run this settles the **current step** and the loop advances. `202` scheduled, `403` interactive jobs disabled, `409` not an active interactive session |
200
200
  | `GET` | `/jobs/:jobId/diagnostic` | Stream a diagnostic ZIP (telemetry + profile + plugins snapshots) |
201
201
 
202
- The two interactive endpoints back the in-job chat that is **on by default for every Claude job** — QueueManager jobs (implement / batch / Freestyle / custom commands) and the loop engine's claude ai-steps alike. Two settle modes: Freestyle/ultracode jobs idle until an explicit finalize (`'finalize'`); everything else settles itself on quiescence (`'auto'` — a turn result with nothing queued), where finalize acts as "wrap up now" / "settle this step". Providers without persistent stdin (Codex, Gemini) run one-shot as before and 409 here. Both endpoints 403 when the server has `SPECRAILS_INTERACTIVE_JOBS=false`. As-built detail: [interactive-jobs.md](interactive-jobs.md).
202
+ The two interactive endpoints back the in-job chat that is **on by default for every Claude job** — QueueManager jobs (implement / batch / Freestyle / custom commands) and the loop engine's claude ai-steps alike. Two settle modes: Freestyle/freestyle jobs idle until an explicit finalize (`'finalize'`); everything else settles itself on quiescence (`'auto'` — a turn result with nothing queued), where finalize acts as "wrap up now" / "settle this step". Providers without persistent stdin (Codex, Gemini) run one-shot as before and 409 here. Both endpoints 403 when the server has `SPECRAILS_INTERACTIVE_JOBS=false`. As-built detail: [interactive-jobs.md](interactive-jobs.md).
203
203
 
204
204
  Example — fetch one job:
205
205
 
@@ -435,7 +435,7 @@ A non-developer-friendly file tree + Monaco viewer with plain-language AI summar
435
435
  | `PUT` | `/:railIndex/profile` | Set the rail's default profile |
436
436
  | `PUT` | `/:railIndex/engine` | Set the rail's AI engine override. Body `{ aiEngine }` (string — one of the project's providers — or `null` to clear) |
437
437
  | `PUT` | `/:railIndex/name` | Set the rail's display name. Body `{ name }` (string or `null` to clear back to the default label); 400 if longer than 60 characters |
438
- | `POST` | `/:railIndex/launch` | Launch the rail. Body `{ mode?, loopId?, profileName?, aiEngine?, model?, reasoning_effort?, originConversationId?, originSurface?, interactive? }`. `mode` is `implement` / `batch-implement` / `ultracode` / `loop`; a factory `loopId` (`factory:implement` etc.) maps to its legacy mode, and a **bare legacy mode with no `loopId`** (MCP / mobile / direct REST) derives the matching factory loop when Loops are enabled, so every launch door gets the same isolation + ask-first PR flow as the dashboard. `model` (haiku/sonnet/opus/fable) applies to ultracode only. The in-job chat is **on by default for every Claude job** — the legacy `interactive` param is accepted and **ignored** (wire compat; the spawn-time gate decides). Returns `202 { jobId, railIndex, mode }`; **`503`** when the Claude or Codex CLI binary is not found (a missing Gemini/other binary surfaces as `500`) |
438
+ | `POST` | `/:railIndex/launch` | Launch the rail. Body `{ mode?, loopId?, profileName?, aiEngine?, model?, reasoning_effort?, originConversationId?, originSurface?, interactive? }`. `mode` is `implement` / `batch-implement` / `freestyle` / `loop`; a factory `loopId` (`factory:implement` etc.) maps to its canonical rail mode, and a **bare mode with no `loopId`** (MCP / mobile / direct REST) derives the matching factory loop when Loops are enabled, so every launch door gets the same isolation + ask-first PR flow as the dashboard. `model` (haiku/sonnet/opus/fable) applies to freestyle only. The in-job chat is **on by default for every Claude job** — the `interactive` param is accepted and **ignored** (wire compat; the spawn-time gate decides). Returns `202 { jobId, railIndex, mode }`; **`503`** when the Claude or Codex CLI binary is not found (a missing Gemini/other binary surfaces as `500`) |
439
439
  | `POST` | `/:railIndex/stop` | Stop the rail's running job (cancels every job the rail registered) |
440
440
 
441
441
  ---
@@ -444,7 +444,7 @@ A non-developer-friendly file tree + Monaco viewer with plain-language AI summar
444
444
 
445
445
  Gated by `SPECRAILS_AGENTS_SECTION !== 'false'`. Rails force legacy (no-profile) mode whenever the chosen engine is not Claude, and the Agents section is hidden in multi-provider projects; profile env-injection itself works for any provider whose adapter advertises `profileEnvSupport`.
446
446
 
447
- > **Provider capability notes.** A few behaviours are not the same across all three providers: **Contract Refine** is Claude-only; **rails force legacy (no-profile) mode** for any non-Claude engine; **Ultracode rails** are Claude-only; the **Serena plugin** (and other `project-json` plugins) work for Claude and Gemini but are filtered out for Codex; and **cost is exact only for Claude** (estimated from a rate card for Codex and Gemini). See the [Codex guide](../codex.md) and [Gemini guide](../gemini.md).
447
+ > **Provider capability notes.** A few behaviours are not the same across all three providers: **Contract Refine** is Claude-only; **rails force no-profile mode** for any non-Claude engine; **Freestyle rails** are Claude-only; the **Serena plugin** (and other `project-json` plugins) work for Claude and Gemini but are filtered out for Codex; and **cost is exact only for Claude** (estimated from a rate card for Codex and Gemini). See the [Codex guide](../codex.md) and [Gemini guide](../gemini.md).
448
448
 
449
449
  ### Profile CRUD
450
450
 
@@ -45,10 +45,10 @@ The companion is a **light-control mirror**. It has no typed `Rail` model: rails
45
45
 
46
46
  ## 2. What rails-as-loops changed — the divergence list
47
47
 
48
- - **`loopId` is the new primary launch verb.** `POST /rails/:i/launch` now accepts `{mode='implement', profileName, aiEngine, model, interactive, loopId, reasoning_effort}` (`rails-router.ts:214-215`). `VALID_MODES` is now `{implement, batch-implement, ultracode, loop}` (`rails-router.ts:25`).
48
+ - **`loopId` is the new primary launch verb.** `POST /rails/:i/launch` now accepts `{mode='implement', profileName, aiEngine, model, interactive, loopId, reasoning_effort}` (`rails-router.ts:214-215`). `VALID_MODES` is now `{implement, batch-implement, freestyle, loop}` (`rails-router.ts:25`).
49
49
  - **The mode segmented-control was removed** from the desktop UI and replaced by `RailLoopSelector` (`RailControls.tsx:51-53` comment; `RailRow.tsx:414-421, 597-604`). `RailMode` still exists but is now **derived** from the loop via `deriveRailMode()` (`rail-loops.ts:34-39`), not user-picked.
50
- - **Factory→mode mapping (the compat layer).** Client factory ids `factory:implement|factory:batch|factory:ultracode` (`rail-loops.ts:8-25`); server mirror `loop-factory.ts:33-55`. `factoryLoopMode()` maps `factory:implement→implement`, `factory:batch→batch-implement`, `factory:ultracode→ultracode` (`rails-router.ts:220-224`); any custom loop → `mode='loop'`.
51
- - **Loop runs are NOT job-queue jobs.** When `isLoopsEnabled()` (default ON, `feature-flags.ts:51-52`, `!== 'false'`) AND a `loopId` is present (factory OR custom), the launch routes through **`LoopRunManager`**, not `QueueManager` (`rails-router.ts:301-381`). It returns `202 {loopRunIds, railIndex, mode}` with **no `jobId`** (`rails-router.ts:379`), and rows live in a **separate `loop_runs` table** (`loop-runs-store.ts:12-32`) keyed by `loopRunId`. The legacy ultracode/implement paths still return `{jobId, ...}` (`rails-router.ts:428, 453`).
50
+ - **Factory→mode mapping (the compat layer).** Client factory ids `factory:implement|factory:batch|factory:freestyle` (`rail-loops.ts:8-25`); server mirror `loop-factory.ts:33-55`. `factoryLoopMode()` maps `factory:implement→implement`, `factory:batch→batch-implement`, `factory:freestyle→freestyle` (`rails-router.ts:220-224`); any custom loop → `mode='loop'`.
51
+ - **Loop runs are NOT job-queue jobs.** When `isLoopsEnabled()` (default ON, `feature-flags.ts:51-52`, `!== 'false'`) AND a `loopId` is present (factory OR custom), the launch routes through **`LoopRunManager`**, not `QueueManager` (`rails-router.ts:301-381`). It returns `202 {loopRunIds, railIndex, mode}` with **no `jobId`** (`rails-router.ts:379`), and rows live in a **separate `loop_runs` table** (`loop-runs-store.ts:12-32`) keyed by `loopRunId`. QueueManager fallback freestyle/implement paths still return `{jobId, ...}` (`rails-router.ts:428, 453`).
52
52
  - **New WS lifecycle family.** `loop.run_started`/`loop.run_progress`/`loop.run_stopped`/`loop.run_completed` (`types.ts:756-790`), emitted by `LoopRunManager` (`loop-run-manager.ts:469`), NOT by the `project-registry.ts:543` `onJobFinished` path that emits `rail.job_completed`. Keying: `loop.run_started`/`loop.run_stopped`/`loop.run_completed` carry `railIndex` + `loopRunId`; **`loop.run_progress` carries only `loopRunId`/`iteration`/`activeNode`/`reasoning` — NO `railIndex`** (`types.ts:756-790`). `loop.run_completed.status ∈ {success, max-iterations, stopped, failed, blocked, stalled}` — `max-iterations` is a **successful** terminal state, not a failure; **`blocked`** (the Loop Decider flagged the run needs a human decision it can't make) and **`stalled`** (the non-convergence guard aborted after consecutive iterations left the working tree unchanged) are controlled HALTS: NOT in the success set, and the settle maps them to job status `canceled` (tickets revert to todo, no PR delivery). A naive `ok = status=='success'` already treats them as non-success — correct.
53
53
  - **`GET /rails` gained `activeLoopRuns`** → `{rails, activeJobs:{[idx]:{jobId,mode}}, activeLoopRuns:{[idx]:{loopRunId}}}` (`rails-router.ts:78-82`).
54
54
  - **`loopId`/`effort` are NOT persisted on the rail row.** `RailState` is still `{railIndex, ticketIds, mode, profileName, aiEngine, name}` (`rails-store.ts:3-13`); rails table cols are `rail_index, ticket_id, position, mode, profile_name, ai_engine` (`db.ts:236`), `name` in `rail_meta` (migration 28). `loopId` is purely a per-launch param; `reasoning_effort` persists only on `loop_runs.reasoning_effort`.
@@ -73,7 +73,7 @@ The list fetch never crashes (untyped maps, tolerant parsers). But a rail runnin
73
73
  Loop runs have a `loopRunId`, never a `jobId`, and are **not in the jobs/queue tables** (`loop-runs-store.ts:12-32`). The companion's "View running job log" routes by `jobId` (`rails_zone.dart:271-281`); `watch_job`/`log_batch`/`job_event` key on `jobId` (`mobile-ws.ts:196-243`). With no `jobId`, the job-tail surface never populates and the run is absent from Execution History (`JobHistoryScreen` reads queue jobs only). **Critically, a loop run produces NO tailable log at all** — its sole live heartbeat is `loop.run_progress` (`iteration`/`activeNode`), which is dropped at `topicFor()`. So even discounting the job-log routing, there is **no live-progress channel** for a running loop rail today: the running surface is a binary running/idle black box. For legacy non-loop launches the job-tail still WORKS.
74
74
 
75
75
  **(c) LAUNCH a rail — WORKS (factory/legacy only) / BROKEN (custom loops).**
76
- The companion sends bare `{mode}` (`rails_zone.dart:317` picker = `implement|batch-implement|ultracode`; `desktop_repository.dart:116-123`). This still validates server-side (`VALID_MODES` includes the three; default `mode='implement'` at `rails-router.ts:214`). Crucially, the gateway narrowing **strips `loopId`** (`mobile-router.ts:191-196`), so even a future companion that sent `loopId` would be silently ignored. Custom loops are unreachable (`mode='loop'` without `loopId` → 400, `rails-router.ts:385-386`). **Caveat:** the *running-state feedback* after launch is broken per (a)/(b) when the launch resolves to a `LoopRunManager` run (default-ON factory loops emit `loop.run_*`, no `rail.job_started`) — so the launch HTTP call succeeds (202) but the phone sees no live activity, no progress, and no completion notification.
76
+ The companion sends bare `{mode}` (`rails_zone.dart:317` picker = `implement|batch-implement|freestyle`; `desktop_repository.dart:116-123`). This still validates server-side (`VALID_MODES` includes the three; default `mode='implement'` at `rails-router.ts:214`). Crucially, the gateway narrowing **strips `loopId`** (`mobile-router.ts:191-196`), so even a future companion that sent `loopId` would be silently ignored. Custom loops are unreachable (`mode='loop'` without `loopId` → 400, `rails-router.ts:385-386`). **Caveat:** the *running-state feedback* after launch is broken per (a)/(b) when the launch resolves to a `LoopRunManager` run (default-ON factory loops emit `loop.run_*`, no `rail.job_started`) — so the launch HTTP call succeeds (202) but the phone sees no live activity, no progress, and no completion notification.
77
77
 
78
78
  **(d) Stop / assign tickets / engine — DEGRADED (stop) / WORKS (tickets) / WORKS-with-display-drift (engine).**
79
79
  - **Engine:** `PUT /rails/:i/engine {aiEngine}` WORKS end-to-end for *setting* the override (`desktop_repository.dart:127`; `mobile-router.ts:199-206`); `rail.updated` carries `aiEngine` (`types.ts:749`). The mutation needs no change. **But** the *displayed* engine drifts for loop-backed runs as noted in (a): the rail config `aiEngine` may be null while the actual run used the resolved provider/model from `loop_runs`, which is never forwarded.
@@ -133,7 +133,7 @@ Extending `Job.fromJson` tolerance (`models.dart:73-85`) is unnecessary (loop ru
133
133
  - Tile subtitle (`:73-74, :87`) and sheet "Mode:" line (`:151, :218`): render `rail['loopName'] ?? rail['mode']` so a loop-running rail shows the loop identity, not stale `implement`. For engine, prefer the forwarded `rail['provider']`/`rail['model']` (4.3) over the possibly-null config `aiEngine`.
134
134
  - Running detection (`:72`): include `rail['loopRunId'] != null` so loop-running rails show Cancel, not Launch.
135
135
  - **Live-progress view:** for loop-backed rails, render `iteration`/`activeNode` from `loop.run_progress` (forwarded per 4.4) and/or poll `GET /v1/.../loop-runs/:id` (4.2) — this is the replacement for the `jobId` log tail that loop runs will never have. Do NOT route "View running job log" (`:271-281`) to `JobDetailScreen` by a null `jobId`; disable it or route to the loop-run progress view.
136
- - Launch picker (`confirmLaunchRail`, `:308-354, :317`): replace the hardcoded `implement|batch-implement|ultracode` bottom-sheet with a **Loop picker** populated from the new loop-catalog endpoint (4.2). Send `loopId` (factory or custom). Keep a fallback to bare `mode` for old-desktop compat (see phasing). For factory loops, the picker can offer the three factory ids (`factory:implement|factory:batch|factory:ultracode`).
136
+ - Launch picker (`confirmLaunchRail`, `:308-354, :317`): replace the hardcoded `implement|batch-implement|freestyle` bottom-sheet with a **Loop picker** populated from the new loop-catalog endpoint (4.2). Send `loopId` (factory or custom). Keep a fallback to bare `mode` for old-desktop compat (see phasing). For factory loops, the picker can offer the three factory ids (`factory:implement|factory:batch|factory:freestyle`).
137
137
 
138
138
  **5.4 WS handlers for loop runs — `lib/features/project/project_shell.dart`.**
139
139
  `project_shell.dart:62-80` handles `rail.*` only. Add a `startsWith('loop.run_')` branch **inside** the existing inbound guard (`:62`, the `projectId`-filter) — loop runs ARE `projectId`-scoped (carried via `boundBroadcast`) so they pass the filter; read `m['projectId']` consistently so the branch isn't accidentally gated. The branch must: (a) invalidate `railsProvider`/`jobsProvider` (same as `rail.*` at `:67`); (b) on `loop.run_completed`, fire `NotificationService.jobOutcome` mapping the **success set `{success, max-iterations}`** → success (note `max-iterations` is a *successful* terminal state, NOT a failure — a naive `ok = status=='success'` mislabels it), mirroring the `rail.job_completed`/`status=='completed'` path at `:70-77`, using `loopRunId`/`ticketIds`.
@@ -196,4 +196,4 @@ Add the loop-catalog/loop-run read routes (4.2/5.5), the Loop picker UI (5.3), a
196
196
 
197
197
  - **Job-history blindness persists.** Loop runs live in `loop_runs`, not `jobs`/`queue` (`loop-runs-store.ts:12-32`), so they will not appear in the companion's Execution History or `Job`-model cost surfacing from WS fixes alone. The `GET /loop-runs/:id` read route (4.2) feeds the *running* surface; full history parity additionally needs a list route + a `LoopRun` model — flag as a follow-up beyond the mirror passes.
198
198
 
199
- - **Single point holding mobile launch alive.** The factory→legacy-mode mapping (`rails-router.ts:220-224`) plus the bare-`mode` default (`:214`) is the only thing keeping the v1 companion's launch working. If desktop ever removes bare-`mode` acceptance, the companion's `{mode}`-only `launchRail` (`desktop_repository.dart:116-123`) 400s. Treat bare-`mode` acceptance as frozen.
199
+ - **Single point holding mobile launch alive.** The factory→legacy-mode mapping (`rails-router.ts:220-224`) plus the bare-`mode` default (`:214`) is the only thing keeping the v1 companion's launch working. If desktop ever removes bare-`mode` acceptance, the companion's `{mode}`-only `launchRail` (`desktop_repository.dart:116-123`) 400s. Treat bare-`mode` acceptance as frozen.