specrails-desktop 2.44.0 → 2.44.2

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 (67) hide show
  1. package/client/dist/assets/{ActivityFeedPage-CG2fhd_k.js → ActivityFeedPage-CL1BUXoj.js} +1 -1
  2. package/client/dist/assets/{AgentBrowserCapture-C6BVsTfo.js → AgentBrowserCapture-BQem50z4.js} +1 -1
  3. package/client/dist/assets/{AgentModeAnalyticsPane-90q1FOYY.js → AgentModeAnalyticsPane-BC_xbT_l.js} +2 -2
  4. package/client/dist/assets/{AgentModeCodePane-CzNPXJND.js → AgentModeCodePane-DK-q3K6Y.js} +2 -2
  5. package/client/dist/assets/{AgentModeJobsPane-CS4XPM5K.js → AgentModeJobsPane-C7ELTPC1.js} +1 -1
  6. package/client/dist/assets/{AgentsPage-DgF8yxlz.js → AgentsPage-DbLezyI6.js} +1 -1
  7. package/client/dist/assets/{AnalyticsPage-BZRZpWTe.js → AnalyticsPage-DTsg-N5z.js} +1 -1
  8. package/client/dist/assets/{CodePage-CobZpY2J.js → CodePage-DwgbeqQ_.js} +1 -1
  9. package/client/dist/assets/{DesktopAnalyticsPage-B75I8Hyl.js → DesktopAnalyticsPage-Y0Z1ryQr.js} +1 -1
  10. package/client/dist/assets/{DocsDialog-AEU1MV8y.js → DocsDialog-KeCOxvGH.js} +1 -1
  11. package/client/dist/assets/{DocsPage-Dn2j2nSl.js → DocsPage-Bt1PgYPO.js} +1 -1
  12. package/client/dist/assets/{ExportDropdown-Xvbax18F.js → ExportDropdown-DczgU4at.js} +1 -1
  13. package/client/dist/assets/{InteractiveJobComposer-COH-v0lE.js → InteractiveJobComposer-BcR6xlHU.js} +1 -1
  14. package/client/dist/assets/{JobDetailModal-CyFzkOM-.js → JobDetailModal-DKA_DUHe.js} +1 -1
  15. package/client/dist/assets/{JobDetailPage-CAILeuTY.js → JobDetailPage-vaOcE-cI.js} +1 -1
  16. package/client/dist/assets/{JobsPage-CzOmMhkp.js → JobsPage-Bwoe-Fb0.js} +1 -1
  17. package/client/dist/assets/{LoopBuilderPage-_Snk4Cv7.js → LoopBuilderPage-CqC4hbXb.js} +1 -1
  18. package/client/dist/assets/{LoopPreviewModal-C2yekwCg.js → LoopPreviewModal-T0zuFv6y.js} +1 -1
  19. package/client/dist/assets/{LoopsPage-C4GXI81g.js → LoopsPage-DrQGcZv2.js} +1 -1
  20. package/client/dist/assets/{MinimizedChatsContext-0mMk-eoH.js → MinimizedChatsContext-C843Y13h.js} +1 -1
  21. package/client/dist/assets/{PluginsPage-pPmHG9nI.js → PluginsPage-CTUHX_Lu.js} +1 -1
  22. package/client/dist/assets/{ProjectSettingsDialog-Bcsq5o0U.js → ProjectSettingsDialog-DeL8md1s.js} +1 -1
  23. package/client/dist/assets/{RepositoryDeliveries-DJTjRht9.js → RepositoryDeliveries-bgIHE8ep.js} +1 -1
  24. package/client/dist/assets/{RepositoryScopeSelector-CvOfpd2g.js → RepositoryScopeSelector-CZ_U_R3U.js} +1 -1
  25. package/client/dist/assets/{ReviewPacketPage-BPG3cVpM.js → ReviewPacketPage-DbKO6pT8.js} +1 -1
  26. package/client/dist/assets/{TemplatePreviewModal-Dx_3cTQN.js → TemplatePreviewModal-_CgCCV7L.js} +1 -1
  27. package/client/dist/assets/{TicketDetailModalContext-0sPSvSmT.js → TicketDetailModalContext-BbRA6cb7.js} +1 -1
  28. package/client/dist/assets/{Trans-BrG0crRZ.js → Trans-mjFZpHw1.js} +1 -1
  29. package/client/dist/assets/{formatDistanceToNow-CEH5-6MR.js → formatDistanceToNow-BIL-HxGy.js} +1 -1
  30. package/client/dist/assets/{getTimezoneOffsetInMilliseconds-C4NbLIYo.js → getTimezoneOffsetInMilliseconds-Cs9z2sdO.js} +1 -1
  31. package/client/dist/assets/{index-BIEV2BG8.js → index-UnaJTMIy.js} +6 -6
  32. package/client/dist/assets/{jira-api-BuMzFZx1.js → jira-api-B2BBZQTx.js} +1 -1
  33. package/client/dist/assets/{project-repositories-CAW6v3SO.js → project-repositories-xSqimlaj.js} +1 -1
  34. package/client/dist/assets/settings-2Yx_9yJM.js +1 -0
  35. package/client/dist/assets/settings-BLOsrXEw.js +1 -0
  36. package/client/dist/assets/settings-C6s9PtRD.js +1 -0
  37. package/client/dist/assets/settings-CCNZN5Q-.js +1 -0
  38. package/client/dist/assets/{settings-Deupji9c.js → settings-CpKwTew1.js} +1 -1
  39. package/client/dist/assets/settings-DPjNiUsS.js +1 -0
  40. package/client/dist/assets/settings-FIqwhTup.js +1 -0
  41. package/client/dist/assets/{settings-CrMi3kSi.js → settings-NSWQjY5B.js} +1 -1
  42. package/client/dist/assets/{spending-DI73ic0T.js → spending-DXOcv1tn.js} +1 -1
  43. package/client/dist/assets/{useDesktop-DA-nfO01.js → useDesktop-gVGoWWiY.js} +1 -1
  44. package/client/dist/assets/{useSharedWebSocket-D-czsPTl.js → useSharedWebSocket-DbGL_YOt.js} +2 -2
  45. package/client/dist/index.html +14 -14
  46. package/docs/guide/de/settings/3-pipeline-telemetry-and-diagnostics.md +1 -1
  47. package/docs/guide/en/settings/3-pipeline-telemetry-and-diagnostics.md +1 -1
  48. package/docs/guide/es/settings/3-pipeline-telemetry-and-diagnostics.md +1 -1
  49. package/docs/guide/fr/settings/3-pipeline-telemetry-and-diagnostics.md +1 -1
  50. package/docs/guide/it/settings/3-pipeline-telemetry-and-diagnostics.md +1 -1
  51. package/docs/guide/ja/settings/3-pipeline-telemetry-and-diagnostics.md +1 -1
  52. package/docs/guide/pt/settings/3-pipeline-telemetry-and-diagnostics.md +1 -1
  53. package/docs/guide/zh/settings/3-pipeline-telemetry-and-diagnostics.md +1 -1
  54. package/docs/internals/verification-handoff-regression.md +70 -0
  55. package/package.json +1 -1
  56. package/server/dist/background-windows-bootstrap.js +6 -3
  57. package/server/dist/core-execution.js +45 -0
  58. package/server/dist/db.js +1 -1
  59. package/server/dist/framework-manager.js +23 -4
  60. package/server/dist/loop-executors.js +6 -0
  61. package/server/dist/loop-run-manager.js +18 -3
  62. package/client/dist/assets/settings-BBt2xtDQ.js +0 -1
  63. package/client/dist/assets/settings-BJB9RKJj.js +0 -1
  64. package/client/dist/assets/settings-CHwQR2rB.js +0 -1
  65. package/client/dist/assets/settings-DKyhDGD1.js +0 -1
  66. package/client/dist/assets/settings-DqRMmwAM.js +0 -1
  67. package/client/dist/assets/settings-J4rj6vo-.js +0 -1
@@ -204,7 +204,7 @@
204
204
  .specrails-splash__mark .pill { opacity: 1; }
205
205
  }
206
206
  </style>
207
- <script type="module" crossorigin src="/assets/index-BIEV2BG8.js"></script>
207
+ <script type="module" crossorigin src="/assets/index-UnaJTMIy.js"></script>
208
208
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-CNC7AqOf.js">
209
209
  <link rel="modulepreload" crossorigin href="/assets/jsx-runtime-zu2_FqZY.js">
210
210
  <link rel="modulepreload" crossorigin href="/assets/react-dom-DiWzBDP9.js">
@@ -234,20 +234,20 @@
234
234
  <link rel="modulepreload" crossorigin href="/assets/narration-B-ynWTpn.js">
235
235
  <link rel="modulepreload" crossorigin href="/assets/nav-Ch-zHBG5.js">
236
236
  <link rel="modulepreload" crossorigin href="/assets/packet-Cx-zRuWn.js">
237
- <link rel="modulepreload" crossorigin href="/assets/settings-BJB9RKJj.js">
237
+ <link rel="modulepreload" crossorigin href="/assets/settings-CCNZN5Q-.js">
238
238
  <link rel="modulepreload" crossorigin href="/assets/setup-Ba11l2JA.js">
239
239
  <link rel="modulepreload" crossorigin href="/assets/specs-DII0C8gw.js">
240
240
  <link rel="modulepreload" crossorigin href="/assets/terminal-BAzpHtpY.js">
241
241
  <link rel="modulepreload" crossorigin href="/assets/tickets-W6pBmbrX.js">
242
242
  <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-Bjbbp_KS.js">
243
- <link rel="modulepreload" crossorigin href="/assets/useSharedWebSocket-D-czsPTl.js">
244
- <link rel="modulepreload" crossorigin href="/assets/Trans-BrG0crRZ.js">
245
- <link rel="modulepreload" crossorigin href="/assets/useDesktop-DA-nfO01.js">
243
+ <link rel="modulepreload" crossorigin href="/assets/useSharedWebSocket-DbGL_YOt.js">
244
+ <link rel="modulepreload" crossorigin href="/assets/Trans-mjFZpHw1.js">
245
+ <link rel="modulepreload" crossorigin href="/assets/useDesktop-gVGoWWiY.js">
246
246
  <link rel="modulepreload" crossorigin href="/assets/save-B6wGWwBR.js">
247
- <link rel="modulepreload" crossorigin href="/assets/spending-DI73ic0T.js">
247
+ <link rel="modulepreload" crossorigin href="/assets/spending-DXOcv1tn.js">
248
248
  <link rel="modulepreload" crossorigin href="/assets/sparkles-DrY8hb0X.js">
249
249
  <link rel="modulepreload" crossorigin href="/assets/x-CBMI9ejn.js">
250
- <link rel="modulepreload" crossorigin href="/assets/MinimizedChatsContext-0mMk-eoH.js">
250
+ <link rel="modulepreload" crossorigin href="/assets/MinimizedChatsContext-C843Y13h.js">
251
251
  <link rel="modulepreload" crossorigin href="/assets/file-text-BcLCfcWZ.js">
252
252
  <link rel="modulepreload" crossorigin href="/assets/circle-x-CMYsN4ZH.js">
253
253
  <link rel="modulepreload" crossorigin href="/assets/download-CFHyyHcw.js">
@@ -259,21 +259,21 @@
259
259
  <link rel="modulepreload" crossorigin href="/assets/search-Cq_gE3Ik.js">
260
260
  <link rel="modulepreload" crossorigin href="/assets/trash-2-BOU3WdZZ.js">
261
261
  <link rel="modulepreload" crossorigin href="/assets/triangle-alert-H9T4jAmh.js">
262
- <link rel="modulepreload" crossorigin href="/assets/jira-api-BuMzFZx1.js">
262
+ <link rel="modulepreload" crossorigin href="/assets/jira-api-B2BBZQTx.js">
263
263
  <link rel="modulepreload" crossorigin href="/assets/zap-CHo3aCD1.js">
264
264
  <link rel="modulepreload" crossorigin href="/assets/clsx-CjueKrWZ.js">
265
265
  <link rel="modulepreload" crossorigin href="/assets/utils-BC4DHlz2.js">
266
266
  <link rel="modulepreload" crossorigin href="/assets/dialog-xXB2q5HJ.js">
267
267
  <link rel="modulepreload" crossorigin href="/assets/lib-CGdyxIWg.js">
268
- <link rel="modulepreload" crossorigin href="/assets/getTimezoneOffsetInMilliseconds-C4NbLIYo.js">
269
- <link rel="modulepreload" crossorigin href="/assets/formatDistanceToNow-CEH5-6MR.js">
268
+ <link rel="modulepreload" crossorigin href="/assets/getTimezoneOffsetInMilliseconds-Cs9z2sdO.js">
269
+ <link rel="modulepreload" crossorigin href="/assets/formatDistanceToNow-BIL-HxGy.js">
270
270
  <link rel="modulepreload" crossorigin href="/assets/button-Ccc9Dc-D.js">
271
- <link rel="modulepreload" crossorigin href="/assets/project-repositories-CAW6v3SO.js">
272
- <link rel="modulepreload" crossorigin href="/assets/RepositoryScopeSelector-CvOfpd2g.js">
271
+ <link rel="modulepreload" crossorigin href="/assets/project-repositories-xSqimlaj.js">
272
+ <link rel="modulepreload" crossorigin href="/assets/RepositoryScopeSelector-CZ_U_R3U.js">
273
273
  <link rel="modulepreload" crossorigin href="/assets/provider-capabilities-B-wOHfLP.js">
274
- <link rel="modulepreload" crossorigin href="/assets/TicketDetailModalContext-0sPSvSmT.js">
274
+ <link rel="modulepreload" crossorigin href="/assets/TicketDetailModalContext-BbRA6cb7.js">
275
275
  <link rel="modulepreload" crossorigin href="/assets/core-B3mKBIh5.js">
276
- <link rel="modulepreload" crossorigin href="/assets/RepositoryDeliveries-DJTjRht9.js">
276
+ <link rel="modulepreload" crossorigin href="/assets/RepositoryDeliveries-bgIHE8ep.js">
277
277
  <link rel="modulepreload" crossorigin href="/assets/event-Bt7f3wXe.js">
278
278
  <link rel="stylesheet" crossorigin href="/assets/index-Bfj8HvX1.css">
279
279
  </head>
@@ -1,6 +1,6 @@
1
1
  # Pipeline-Telemetrie & Diagnose
2
2
 
3
- Wenn ein Pipeline-Job nicht so läuft, wie du es erwartet hast, liefert dir die Telemetrie eine detaillierte Aufzeichnung dessen, was die AI-CLI hinter den Kulissen tatsächlich getan hat. Sie ist **standardmäßig aus** und vollständig optional, pro Projekt – aktiviere sie nur dann, wenn du sie wirklich willst.
3
+ Die Telemetrie zeichnet Pipeline-Diagnosen lokal auf. Sie ist für Projekte ohne gespeicherte Einstellung **standardmäßig aktiviert**. Du kannst sie pro Projekt deaktivieren; ausdrücklich gespeicherte Einstellungen bleiben erhalten.
4
4
 
5
5
  ## Was es ist
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Pipeline telemetry & diagnostics
2
2
 
3
- When a pipeline job doesn't go the way you expected, telemetry gives you a detailed, behind-the-scenes record of what the AI CLI actually did. It's **off by default** and entirely opt-in, per project — turn it on only when you want it.
3
+ Telemetry records pipeline diagnostics locally. It is **on by default** for projects without a saved preference. You can turn it off per project; an explicitly saved choice is preserved.
4
4
 
5
5
  ## What it is
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Telemetría del pipeline y diagnósticos
2
2
 
3
- Cuando un job del pipeline no sale como esperabas, la telemetría te ofrece un registro detallado, entre bambalinas, de lo que el CLI de IA hizo en realidad. Está **desactivada por defecto** y es totalmente opcional, por proyecto: actívala solo cuando la quieras.
3
+ La telemetría registra los diagnósticos del pipeline en local. Está **activada por defecto** en los proyectos sin una preferencia guardada. Puedes desactivarla por proyecto; se respeta cualquier elección guardada explícitamente.
4
4
 
5
5
  ## Qué es
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Télémétrie & diagnostics du pipeline
2
2
 
3
- Quand un job de pipeline ne se déroule pas comme prévu, la télémétrie vous offre un compte rendu détaillé et en coulisses de ce que la CLI d'IA a réellement fait. Elle est **désactivée par défaut** et entièrement optionnelle, projet par projet — ne l'activez que lorsque vous en avez besoin.
3
+ La télémétrie enregistre les diagnostics du pipeline localement. Elle est **activée par défaut** pour les projets sans préférence enregistrée. Vous pouvez la désactiver par projet ; les choix explicitement enregistrés sont conservés.
4
4
 
5
5
  ## De quoi s'agit-il
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Telemetria della pipeline e diagnostica
2
2
 
3
- Quando un job della pipeline non va come ti aspettavi, la telemetria ti offre un resoconto dettagliato e dietro le quinte di ciò che la AI CLI ha realmente fatto. È **disattivata per impostazione predefinita** e completamente opzionale, per ogni progetto — attivala solo quando ti serve.
3
+ La telemetria registra i dati diagnostici della pipeline in locale. È **attivata per impostazione predefinita** nei progetti senza una preferenza salvata. Puoi disattivarla per progetto; le scelte salvate esplicitamente vengono rispettate.
4
4
 
5
5
  ## Cos'è
6
6
 
@@ -1,6 +1,6 @@
1
1
  # パイプラインテレメトリと診断
2
2
 
3
- パイプラインのジョブが思いどおりに進まなかったとき、テレメトリは AI CLI が実際に何をしたのかを、舞台裏まで詳しく記録して見せてくれます。**デフォルトはオフ** で、プロジェクトごとに完全に任意です。必要なときだけオンにしてください。
3
+ テレメトリはパイプラインの診断情報をローカルに記録します。設定が保存されていないプロジェクトでは**デフォルトでオン**です。プロジェクトごとにオフにでき、明示的に保存された設定は維持されます。
4
4
 
5
5
  ## テレメトリとは
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Telemetria do pipeline e diagnóstico
2
2
 
3
- Quando um job do pipeline não corre como esperava, a telemetria dá-lhe um registo detalhado, dos bastidores, do que a CLI de IA fez de facto. Está **desativada por omissão** e é totalmente opcional, por projeto — ative-a apenas quando quiser.
3
+ A telemetria regista os diagnósticos do pipeline localmente. Está **ativada por omissão** nos projetos sem uma preferência guardada. Pode desativá-la por projeto; as escolhas guardadas explicitamente são respeitadas.
4
4
 
5
5
  ## O que é
6
6
 
@@ -1,6 +1,6 @@
1
1
  # 流水线遥测与诊断
2
2
 
3
- 当一个流水线任务的运行结果不如你所料时,遥测能为你提供一份详尽的幕后记录,告诉你 AI CLI 实际做了什么。它**默认关闭**、完全按需开启、按项目独立配置——只有在你需要时才开启它。
3
+ 遥测在本地记录流水线诊断信息。未保存偏好的项目**默认开启**。可以按项目关闭;明确保存的选择会保留。
4
4
 
5
5
  ## 它是什么
6
6
 
@@ -0,0 +1,70 @@
1
+ # Verification handoff and framework activation regression
2
+
3
+ The September 10, 2026 implementation incident ended with an agent reporting
4
+ success while Core reported `implementation=complete`, `validation=blocked`,
5
+ `archive=done`, and `delivery=pending-host`. The repository's 127 tests passed;
6
+ inspection rejected the receipt with `Verification environment changed: npm`.
7
+
8
+ A second Windows execution reproduced the same terminal contradiction after
9
+ the coordinator reported successful unit and browser checks, completed archive,
10
+ and skipped host-owned shipping/CI phases. It refreshed verification and moved
11
+ archive execution into the coordinator's session to avoid handoff drift, but
12
+ the host still reported blocked validation. This corroborates the cross-process
13
+ failure pattern; the transcript alone does not identify the differing variables
14
+ or establish a cloud-synced project path as the cause. Runtime diagnostics now
15
+ report added/removed environment key names without values. If only values differ,
16
+ the aggregate hash cannot identify the individual key.
17
+
18
+ Three independent problems made recovery unreliable:
19
+
20
+ 1. The installed app bundled Core 5.2.2, but `framework/current` still resolved to
21
+ 5.2.1. Desktop materialized the providers in its project catalog, omitting Kimi
22
+ already represented in `current`. Core correctly refused to activate the
23
+ incomplete destination. The session-identity fix in 5.2.2 was never active.
24
+ 2. Verification included agent-session metadata and automatically generated
25
+ untracked memory in its evidence. A process handoff or a final memory write
26
+ could invalidate verification after a successful check. Ignoring metadata in
27
+ the fingerprint alone also left those unrecorded inputs visible to tests.
28
+ 3. A successful provider process could become a successful implementation step
29
+ without a final deterministic check of Core's state.
30
+
31
+ ## Required invariants
32
+
33
+ - Framework materialization must satisfy the same provider union as Core's
34
+ activation gate: requested providers, the shared registry, and provider
35
+ directories or completion stamps represented in `current`. Failure leaves the
36
+ previous version active.
37
+ - Core removes known session/launcher metadata from verification subprocesses
38
+ as well as from their environment fingerprint. Explicit command overrides are
39
+ retained and bound without storing their values. Application configuration,
40
+ PATH, NODE_OPTIONS, custom variables and SPECRAILS configuration still count.
41
+ Windows environment names are normalized without changing POSIX semantics.
42
+ - Only untracked files under known provider `agent-memory/` roots are excluded
43
+ as generated notes. Tracked memory, settings, skills and other source inputs
44
+ remain part of the candidate.
45
+ - Old environment-policy receipts require a fresh full verification. Do not
46
+ edit receipts or phase records to turn an old failure into success.
47
+ - Desktop checks installed Core after Implement/Batch steps, for both interactive
48
+ and one-shot execution. Blocked validation, incomplete phases, an invalid full
49
+ receipt, a failed status call or mismatched run identity prevents success.
50
+ `pending-host` describes delivery ownership and does not invalidate otherwise
51
+ verified implementation work.
52
+
53
+ ## Regression coverage and rollout
54
+
55
+ Core's `pipeline-state.test.ts` exercises real subprocess handoffs, archive
56
+ completion followed by a host inspection, explicit overrides, environment/input
57
+ changes, generated versus tracked memory and Windows environment normalization.
58
+ Desktop's `loop-core-completion.test.ts` runs the completion-status subprocess
59
+ through the loop engine and verifies the stored result. Framework tests cover
60
+ the omitted-provider activation failure and preservation of the previous version.
61
+ An offline test with the actual 5.2.1 and bundled 5.2.2 packages also validated
62
+ the provider-union update in an isolated home.
63
+
64
+ Activating the existing 5.2.2 bundle repairs the missed previous update. The
65
+ additional environment, memory, completion and materialization changes require
66
+ new Core and Desktop releases. These changes have been ported onto Core 5.2.2
67
+ and Desktop 2.44.1 for review. Never replace a newer installed runtime with an
68
+ older checkout build, and verify both
69
+ the selected package version and the actual `framework/current` target after
70
+ activation. Refresh copied workspace files through the normal reseed lifecycle.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specrails-desktop",
3
- "version": "2.44.0",
3
+ "version": "2.44.2",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.WINDOWS_BACKGROUND_BOOTSTRAP = void 0;
6
+ exports.WINDOWS_BACKGROUND_BOOTSTRAP = exports.WINDOWS_JOB_PREPARATION_TIMEOUT_MS = void 0;
7
7
  exports.spawnWindowsBackgroundBootstrap = spawnWindowsBackgroundBootstrap;
8
8
  const child_process_1 = require("child_process");
9
9
  const node_net_1 = require("node:net");
@@ -14,6 +14,9 @@ const node_crypto_1 = require("node:crypto");
14
14
  const path_resolver_1 = require("./path-resolver");
15
15
  const win_spawn_1 = require("./util/win-spawn");
16
16
  const windows_job_supervisor_1 = require("./windows-job-supervisor");
17
+ // PowerShell startup and Add-Type compilation can exceed 15s on cold Windows
18
+ // ARM runners. Keep preparation bounded without admitting any application code.
19
+ exports.WINDOWS_JOB_PREPARATION_TIMEOUT_MS = 60_000;
17
20
  // Keep the owned Windows root alive until its creation identity is captured.
18
21
  // User commands never enter argv and cannot start before the parent opens stdin.
19
22
  exports.WINDOWS_BACKGROUND_BOOTSTRAP = String.raw `
@@ -130,12 +133,12 @@ function spawnWindowsBackgroundBootstrap(command, cwd) {
130
133
  }
131
134
  catch { /* no child */ } });
132
135
  const startupTimer = setTimeout(() => {
133
- fail(new Error('Windows job containment preparation timed out; no application was admitted.'));
136
+ fail(new Error(`Windows job containment preparation timed out after ${exports.WINDOWS_JOB_PREPARATION_TIMEOUT_MS}ms (${socket ? 'control pipe connected, awaiting job assignment' : 'awaiting supervisor control pipe'}); no application was admitted.`));
134
137
  try {
135
138
  child?.kill();
136
139
  }
137
140
  catch { /* already gone */ }
138
- }, 15_000);
141
+ }, exports.WINDOWS_JOB_PREPARATION_TIMEOUT_MS);
139
142
  startupTimer.unref?.();
140
143
  const cleanup = () => {
141
144
  clearTimeout(startupTimer);
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.prepareCoreExecution = prepareCoreExecution;
4
4
  exports.coreVerificationContext = coreVerificationContext;
5
+ exports.checkCoreCompletion = checkCoreCompletion;
5
6
  const node_child_process_1 = require("node:child_process");
6
7
  const node_fs_1 = require("node:fs");
7
8
  const node_path_1 = require("node:path");
@@ -110,3 +111,47 @@ function coreVerificationContext(contextPath, cwd, env, runId) {
110
111
  return '';
111
112
  }
112
113
  }
114
+ /** A successful provider turn is not a completed implementation. Ask Core to
115
+ * revalidate the journal on disk before Desktop accepts the implementation step,
116
+ * including when an agent claims PASS after its final receipt went stale. */
117
+ function checkCoreCompletion(contextPath, cwd, env, runId) {
118
+ const helper = (0, node_path_1.join)(cwd, '.specrails', 'runtime', 'pipeline.mjs');
119
+ if (!(0, node_fs_1.existsSync)(helper))
120
+ return { valid: false, reason: 'Core completion cannot be validated: pipeline runtime is missing' };
121
+ try {
122
+ const stdout = (0, node_child_process_1.execFileSync)((0, path_resolver_1.resolveBundledNodeExe)() ?? process.execPath, [helper, 'status', '--context', contextPath], {
123
+ cwd, env, encoding: 'utf8', timeout: 15_000, maxBuffer: 4 * 1024 * 1024, stdio: ['ignore', 'pipe', 'pipe'],
124
+ });
125
+ const status = JSON.parse(stdout);
126
+ if (status.schemaVersion !== 1 || status.runId !== runId)
127
+ return { valid: false, reason: 'Core completion returned an invalid or mismatched run identity' };
128
+ const reasons = [];
129
+ // Core 5.1 exposes phases/verification; newer runtimes also provide an
130
+ // explicit completion verdict. Never override a newer blocked verdict with
131
+ // older phase statuses or an agent-authored summary.
132
+ if (status.completion) {
133
+ for (const [key, expected] of [['implementation', 'complete'], ['archive', 'done']]) {
134
+ if (status.completion[key] !== expected)
135
+ reasons.push(`${key}=${status.completion[key] ?? 'missing'}`);
136
+ }
137
+ if (!['verified', 'with-exceptions'].includes(status.completion.validation ?? ''))
138
+ reasons.push(`validation=${status.completion.validation ?? 'missing'}`);
139
+ if (reasons.length)
140
+ reasons.push(...(status.completion.reasons ?? []));
141
+ }
142
+ for (const phase of ['architect', 'developer', 'reviewer', 'archive']) {
143
+ if (status.phases?.[phase]?.status !== 'done')
144
+ reasons.push(`${phase} phase is incomplete`);
145
+ }
146
+ if (status.resumePhase && ['architect', 'developer', 'reviewer', 'archive'].includes(status.resumePhase))
147
+ reasons.push(`resume from ${status.resumePhase}`);
148
+ const receipt = status.verification?.receipt;
149
+ if (status.verification?.valid !== true || receipt?.kind !== 'full' || !receipt.commands?.length || receipt.commands.some(command => command.exitCode !== 0)) {
150
+ reasons.push(...(status.verification?.reasons?.length ? status.verification.reasons : ['No valid full verification receipt']));
151
+ }
152
+ return reasons.length ? { valid: false, reason: `Core completion blocked: ${[...new Set(reasons)].join('; ')}` } : { valid: true };
153
+ }
154
+ catch {
155
+ return { valid: false, reason: 'Core completion cannot be validated: pipeline status failed or returned invalid JSON' };
156
+ }
157
+ }
package/server/dist/db.js CHANGED
@@ -2085,7 +2085,7 @@ function getProjectSettings(db) {
2085
2085
  const integrationBranchRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.integration_branch'`).get();
2086
2086
  const worktreeEnvPassthroughRow = db.prepare(`SELECT value FROM queue_state WHERE key = 'config.worktree_env_passthrough'`).get();
2087
2087
  return {
2088
- pipelineTelemetryEnabled: telemetryRow?.value === 'true',
2088
+ pipelineTelemetryEnabled: telemetryRow?.value !== 'false',
2089
2089
  orchestratorModel: modelRow?.value ?? 'sonnet',
2090
2090
  orchestratorModelExplicit: modelRow?.value !== undefined,
2091
2091
  prePrompt: prePromptRow?.value ?? '',
@@ -44,6 +44,28 @@ function realpathOrSelf(p) {
44
44
  return p;
45
45
  }
46
46
  }
47
+ /** Match Core's swap-current provider requirement: a project removed from the
48
+ * Desktop catalog can still have live links through current. A subtree OR its
49
+ * completion stamp is enough to require that provider in the next version. */
50
+ function requiredFrameworkProviders(fwDir, requested, home) {
51
+ const directories = {
52
+ claude: '.claude', codex: '.codex', gemini: '.gemini', kimi: '.kimi-code',
53
+ };
54
+ const required = new Set(requested);
55
+ for (const entry of Object.values((0, artifact_registry_1.readRegistryOrEmpty)(home).projects)) {
56
+ for (const provider of [...(entry.providers ?? []), entry.primaryProvider]) {
57
+ if (Object.hasOwn(directories, provider))
58
+ required.add(provider);
59
+ }
60
+ }
61
+ for (const [provider, directory] of Object.entries(directories)) {
62
+ if (fs_1.default.existsSync(path_1.default.join(fwDir, 'current', directory))
63
+ || fs_1.default.existsSync(path_1.default.join(fwDir, 'current', `.framework-stamp${directory}.json`))) {
64
+ required.add(provider);
65
+ }
66
+ }
67
+ return [...required];
68
+ }
47
69
  class FrameworkManager {
48
70
  home;
49
71
  broadcast;
@@ -101,7 +123,7 @@ class FrameworkManager {
101
123
  fs_1.default.mkdirSync(fwDir, { recursive: true });
102
124
  const errors = [];
103
125
  const done = [];
104
- for (const provider of dedupe(providers)) {
126
+ for (const provider of requiredFrameworkProviders(fwDir, providers, this.home)) {
105
127
  const res = (0, child_process_1.spawnSync)(nodeInterpreter(), [
106
128
  cli,
107
129
  'install-framework',
@@ -357,6 +379,3 @@ class FrameworkManager {
357
379
  }
358
380
  }
359
381
  exports.FrameworkManager = FrameworkManager;
360
- function dedupe(values) {
361
- return Array.from(new Set(values));
362
- }
@@ -489,6 +489,12 @@ function createLoopExecutors(opts = {}) {
489
489
  ...(effectiveIdleTimeoutMs > 0 ? { idleTimeoutMs: effectiveIdleTimeoutMs } : {}),
490
490
  };
491
491
  },
492
+ validateCoreCompletion({ coreRun, provider, model, effort, profileName, cwd, repoDir, executionManifest }) {
493
+ const baseStepEnv = withProfileEnv(aiStepEnv(resolveEnv(), repoDir, executionManifest), provider, profileName);
494
+ const core = (0, core_execution_1.prepareCoreExecution)({ run: coreRun, cwd, repoDir, manifest: executionManifest, env: baseStepEnv });
495
+ const env = (0, runtime_1.buildProviderEnv)((0, providers_1.getAdapter)(provider), { prompt: '', model, reasoning_effort: effort }, core.env);
496
+ return (0, core_execution_1.checkCoreCompletion)(core.contextPath, cwd, env, coreRun.runId);
497
+ },
492
498
  async runShell({ command, cwd, repoDir, onLine, onSpawn, timeoutMs }) {
493
499
  const env = resolveEnv();
494
500
  return runShellCommand(command, repoDir ?? cwd, repoDir ? { ...env, SPECRAILS_REPO_DIR: repoDir } : env, timeoutMs ?? SHELL_TIMEOUT_MS, onLine, onSpawn);
@@ -1058,6 +1058,8 @@ class LoopRunManager {
1058
1058
  // --yes`, codex `$implement #<id> --yes`) — then resolve `{{spec.*}}`
1059
1059
  // data tokens and finally `{{const:*}}` library constants.
1060
1060
  const rawTemplate = String(node.data?.prompt ?? '');
1061
+ const requiresCoreCompletion = /\{\{\s*cmd:(?:implement|batch)\s*\}\}/.test(rawTemplate)
1062
+ || /^\s*(?:\/specrails:|\/skill:specrails-|\$)(?:implement|batch-implement)(?:\s|$)/.test(rawTemplate);
1061
1063
  const expanded = (0, loop_constants_1.resolveConstants)(resolveRunVars((0, loop_graph_1.interpolateSpec)((0, loop_command_catalog_1.expandCommands)(rawTemplate, { provider: nodeProvider, ticketIds: req.spec?.ticketIds, specId: req.spec?.id }), req.spec), runVars), constMap);
1062
1064
  const base = [(0, multi_repo_execution_store_1.executionManifestPrompt)(req.executionManifest), withReviewContinuationContext(expanded, rawTemplate, req.spec)].filter(Boolean).join('\n\n');
1063
1065
  // Inject the cross-iteration history only when there's no live session
@@ -1220,6 +1222,19 @@ class LoopRunManager {
1220
1222
  settled = true;
1221
1223
  break;
1222
1224
  }
1225
+ if (!res.failed && !zeroWork && !this._cancelled.has(runId)
1226
+ && requiresCoreCompletion
1227
+ && this.executors.validateCoreCompletion) {
1228
+ const completion = this.executors.validateCoreCompletion({
1229
+ coreRun: { runId, spec: req.spec, goal: req.spec ? undefined : JSON.stringify({ loop: req.loopName, graph: req.graph }), repositoryId: req.repositoryId },
1230
+ provider: nodeProvider, model: nodeModel, effort: nodeEffort, profileName: req.profileName,
1231
+ cwd: req.cwd, repoDir: req.repoDir, executionManifest: req.executionManifest,
1232
+ });
1233
+ if (!completion.valid) {
1234
+ res = { ...res, failed: true, errorText: completion.reason ?? 'Core implementation is incomplete' };
1235
+ logLine(`✖ ${res.errorText}`, 'stderr');
1236
+ }
1237
+ }
1223
1238
  const blockedReason = aiStepBlockedReason(res.text);
1224
1239
  const requiresVerification = node.data?.requireVerificationPass === true
1225
1240
  || /\{\{cmd:(?:verify|revision-verify|opsx:verify)\}\}/.test(rawTemplate);
@@ -1613,8 +1628,6 @@ class LoopRunManager {
1613
1628
  catch (err) {
1614
1629
  console.error(`[loop] staged accounting reconciliation failed for ${runId}:`, err);
1615
1630
  }
1616
- console.log(`[loop] settle run=${runId} outcome=${outcome} iterations=${iteration} ` +
1617
- (usageTelemetryAvailable ? `cost=$${totalCost.toFixed(4)}` : 'usage=unavailable'));
1618
1631
  // Execution and acceptance are separate facts. Persist the runtime's own
1619
1632
  // terminal snapshot alongside counters so history does not depend on prose.
1620
1633
  let coreCompletion = null;
@@ -1625,6 +1638,8 @@ class LoopRunManager {
1625
1638
  const executionOutcome = outcome;
1626
1639
  if (outcome === 'success' && coreCompletion && (coreCompletion.completion.implementation !== 'complete' || !['verified', 'with-exceptions'].includes(coreCompletion.completion.validation)))
1627
1640
  outcome = 'blocked';
1641
+ console.log(`[loop] settle run=${runId} outcome=${outcome} iterations=${iteration} ` +
1642
+ (usageTelemetryAvailable ? `cost=$${totalCost.toFixed(4)}` : 'usage=unavailable'));
1628
1643
  emitRunEvent('loop_completion', {
1629
1644
  version: 1, execution: executionOutcome, steps: stepNum, deciderEvaluations: iteration,
1630
1645
  turns: finalJobUsage.numTurns, costUsd: usageTelemetryAvailable ? totalCost : null,
@@ -1642,7 +1657,7 @@ class LoopRunManager {
1642
1657
  // `≥` when any cost-bearing step ended unpriced (timeout/crash) — the figure
1643
1658
  // is a lower bound, not exact. Providers without usage telemetry get an
1644
1659
  // explicit unavailable marker, never a fabricated "$0.0000".
1645
- logLine(`\n■ Loop execution finished: ${executionOutcome} — ${stepNum} step${stepNum === 1 ? '' : 's'}, ${iteration} decider evaluation${iteration === 1 ? '' : 's'}, ${finalJobUsage.numTurns ?? 'unknown'} agent turns, ` +
1660
+ logLine(`\n■ Loop execution finished: ${outcome} — ${stepNum} step${stepNum === 1 ? '' : 's'}, ${iteration} decider evaluation${iteration === 1 ? '' : 's'}, ${finalJobUsage.numTurns ?? 'unknown'} agent turns, ` +
1646
1661
  (usageTelemetryAvailable
1647
1662
  ? `${costUncertain ? '≥ ' : ''}$${totalCost.toFixed(4)}`
1648
1663
  : 'usage/cost unavailable'));
@@ -1 +0,0 @@
1
- var e={title:`Idioma`,description:`Idioma de la UI para todo Desktop. Se aplica al instante — no hace falta reiniciar.`,selectLabel:`Idioma de la interfaz`,updateFailed:`No se pudo guardar la preferencia de idioma`},t={title:`Ajustes del proyecto`},n={saveFailed:`Error al guardar: {{message}}`},r={title:`Telemetría del pipeline`,description:`Captura el uso de tokens, la duración de las fases y la actividad de los subagentes para exportar diagnósticos. Desactivada por defecto.`,toggleLabel:`Activar telemetría del pipeline`,toggleDescription:`Cuando está activa, los datos OTEL de los jobs del pipeline se capturan en local. Usa el botón <mono>Exportar diagnóstico</mono> en cualquier tarjeta de job para descargarlos.`,enabled:`Telemetría del pipeline activada`,disabled:`Telemetría del pipeline desactivada`,saveFailed:`No se pudo guardar el ajuste de telemetría`},i={title:`Pre-prompt de rail`,description:`Instrucciones extra específicas del proyecto que se añaden a los jobs de rail implement y batch-implement, después del contexto del ticket y antes de la ejecución.`,label:`Pre-prompt`,placeholder:`Ejemplo: Prefiere cambios incrementales, mantén las migraciones retrocompatibles y añade tests para cada cambio de rail.`,helper:`Úsalo para directrices estables del proyecto que deban acompañar cada ejecución de implementación en rail.`,saveButton:`Guardar pre-prompt`,cleared:`Pre-prompt borrado`,saved:`Pre-prompt guardado`,saveFailed:`No se pudo guardar el pre-prompt`},a={title:`Pre-prompt de Freestyle`,description:`Instrucción enviada al proveedor seleccionado en Freestyle. Freestyle se salta el pipeline de OpenSpec — le entrega al proveedor este pre-prompt más el texto de la spec y le deja implementar de forma autónoma. Déjalo en blanco para usar el valor por defecto integrado.`,label:`Pre-prompt Freestyle`,placeholder:`Déjalo en blanco para usar la instrucción por defecto de Freestyle.`,helper:`El texto de la spec se añade automáticamente después de este pre-prompt. Vacío = por defecto.`,saveButton:`Guardar pre-prompt Freestyle`,resetToDefault:`Pre-prompt Freestyle restablecido al valor por defecto`,saved:`Pre-prompt Freestyle guardado`,saveFailed:`No se pudo guardar el pre-prompt Freestyle`},o={title:`Presupuesto`,description:`Define un límite de gasto diario para este proyecto. La cola se pausa automáticamente al alcanzar el límite.`,dailyLabel:`Presupuesto diario (USD)`,dailyHelper:`Déjalo en blanco para desactivarlo. El gasto se calcula sobre las últimas 24 horas.`,dailyPlaceholder:`p. ej. 5.00`,perJobLabel:`Alerta de coste por job (USD)`,perJobHelper:`Avisa cuando un único job de este proyecto supere este importe.`,perJobPlaceholder:`p. ej. 0.50`,invalidNumber:`Introduce un número positivo o déjalo en blanco para desactivar`,dailyRemoved:`Presupuesto diario eliminado`,dailySet:"Presupuesto diario fijado en ${{amount}}",perJobAlertDisabled:`Alerta de coste por job desactivada`,alertSet:"Alerta configurada para jobs de más de ${{amount}}",saveBudgetFailed:`No se pudo guardar el presupuesto`,saveThresholdFailed:`No se pudo guardar el umbral`},s={nav:{appearance:`Apariencia`,specrailsAgents:`Specrails Agents`,code:`Código`,terminal:`Terminal`,updates:`Actualizaciones`,mobile:`Móvil`,mcp:`MCP`,projects:`Proyectos`,advanced:`Avanzado`,webhooks:`Webhooks`,about:`Acerca de`,effects:`Efectos`},title:`Ajustes de Desktop`,description:`Gestiona los proyectos registrados y consulta la información de Desktop.`,registeredProjects:`Proyectos registrados`,noProjects:`Aún no hay proyectos registrados`,techUrlDescription:`URL base de la API de specrails-tech (por defecto: http://localhost:3000)`,techUrlSaved:`URL de specrails-tech guardada`,techUrlSaveFailed:`No se pudo guardar la URL`,budgetAlertsHeading:`Presupuesto y alertas`,dailyBudgetLabel:`Presupuesto diario de Desktop (USD)`,dailyBudgetHelper:`Límite global de gasto diario en todos los proyectos. Las colas se pausan automáticamente al superarlo.`,dailyBudgetPlaceholder:`p. ej. 10.00`,perJobHelper:`Avisa cuando un único job supere este importe. Déjalo en blanco para desactivarlo.`,costAlertsDisabled:`Alertas de coste desactivadas`,dailyBudgetRemoved:`Presupuesto diario de Desktop eliminado`,dailyBudgetSet:"Presupuesto diario de Desktop fijado en ${{amount}}",dailyBudgetSaveFailed:`No se pudo guardar el presupuesto diario de Desktop`,projectRemoved:`Proyecto eliminado`,projectRemoveFailed:`No se pudo eliminar el proyecto`,onboardingHeading:`Onboarding`,platformTour:`Tour de la plataforma`,platformTourDescription:`Vuelve a ver el asistente de bienvenida para repasar las funciones clave.`,replayTour:`Repetir tour`,terminalPanelHeading:`Panel de terminal`,infoHeading:`Información de Desktop`,infoPort:`Puerto`,infoProjects:`Proyectos`,infoDb:`BD de Desktop`},c={heading:`Notificaciones del sistema`,description:`Muestra notificaciones nativas de escritorio cuando los jobs se completan o fallan. Las notificaciones solo aparecen cuando la pestaña no tiene el foco.`,enableLabel:`Activar notificaciones del sistema`,notifyOn:`Notificar en:`,filterAll:`Todos (completados y fallidos)`,filterCompleted:`Solo completados`,filterFailed:`Solo fallidos`,enabledToast:`Notificaciones del sistema activadas`,disabledToast:`Notificaciones del sistema desactivadas`},l={heading:`Webhooks salientes`,description:`Notifica a herramientas externas (Slack, Zapier, CI/CD) los eventos de Desktop. Las peticiones se firman con <code>X-Specrails-Signature</code> cuando hay un secreto configurado.`,eventJobCompleted:`Job completado`,eventJobFailed:`Job fallido`,eventDailyBudgetExceeded:`Presupuesto diario superado`,statusOn:`on`,statusOff:`off`,disable:`Desactivar`,enable:`Activar`,sendTestPing:`Enviar ping de prueba`,addHeading:`Añadir webhook`,secretPlaceholder:`Secreto de firma (opcional)`,addButton:`Añadir webhook`,urlRequired:`La URL es obligatoria`,selectEvent:`Selecciona al menos un evento`,added:`Webhook añadido`,addFailed:`No se pudo añadir el webhook`,updateFailed:`No se pudo actualizar el webhook`,removed:`Webhook eliminado`,removeFailed:`No se pudo eliminar el webhook`,testPingSent:`Ping de prueba enviado`,testPingFailed:`No se pudo enviar el ping de prueba`},u={title:`Panel de terminal`,desktopDescription:`Valores por defecto de Desktop aplicados a todos los proyectos salvo que exista un override por proyecto.`,projectDescription:`Overrides por proyecto para el panel de terminal. Deja un campo sin cambios para heredar el valor por defecto de Desktop.`,fontFamily:`Familia tipográfica`,fontSize:`Tamaño de fuente ({{min}}–{{max}})`,renderMode:`Modo de renderizado`,copyOnSelect:`Copiar al seleccionar`,shellIntegration:`Integración con el shell (marcas OSC 133)`,notifyLongRunning:`Notificar comandos de larga duración`,longCommandThreshold:`Umbral de comando largo (ms)`,imageRendering:`Renderizado de imágenes inline (Sixel + iTerm2)`,browserShortcutUrl:`URL del atajo de navegador`,quickScript:`Script rápido (se pega en el terminal activo — pulsa Enter manualmente)`,reset:`Restablecer`,unsavedChanges:`Cambios sin guardar`,clearOverride:`Quitar override`,clear:`Quitar`,inheritingDefault:`Heredando el valor por defecto de Desktop`,nothingToSave:`Nada que guardar`,saved:`Ajustes del terminal guardados`},d={heading:`Sección de código`,summaryLanguage:`Idioma de los resúmenes`,monthlyBudget:`Presupuesto mensual (USD)`,budgetHelper:"Tope de gasto de `surface=file-summary` por mes natural. Las regeneraciones iniciadas por el usuario pueden sobrepasarlo."},f={taglines:{dracula:`El original — oscuro con tinte púrpura y acentos neón vivos`,"aurora-light":`Claro premium — índigo inspirado en Linear sobre blanco cálido`,"obsidian-dark":`Oscuro premium — casi negro con tinte azul y acentos eléctricos`,specrails:`Tema de marca — azul marino-índigo profundo con acentos cian saturados`,"code-rain":`Terminal de fósforo — menta suave sobre casi negro verdoso`,galaxy:`Azul de espacio profundo con una estela de hoja brillante`},heading:`Apariencia`,themeGroupLabel:`Tema`,currentlyActive:`Activo actualmente`,updateFailed:`No se pudo actualizar el tema`},p={heading:`App móvil`,description:`Controla Specrails desde la app SpecRails Companion de tu teléfono, 100 % a través de tu red local. Desactivado por defecto.`,accessOn:`Acceso móvil activado`,accessOff:`Acceso móvil desactivado`,listeningOnPort:`A la escucha en el puerto {{port}}`,notListening:`No está a la escucha`,turnOn:`Activar`,turnOff:`Desactivar`,pairWebDevice:`Emparejar companion web`,reset:`Restablecer`,resetConfirm:`¿Restablecer la identidad móvil? Todos los dispositivos emparejados se revocarán y tendrán que emparejarse de nuevo.`,identityReset:`Identidad móvil restablecida`,enableFailed:`No se pudo activar el acceso móvil: {{message}}`,disableFailed:`No se pudo desactivar el acceso móvil: {{message}}`,windowsFirewall:`El Firewall de Windows pedirá permiso para el servidor de SpecRails la primera vez que lo actives — elige «Permitir en redes privadas».`,pairedDevices:`Dispositivos emparejados`,noDevices:`Aún no hay dispositivos emparejados.`,revokeDevice:`Revocar {{name}}`},m={title:`Emparejar companion web`,description:`Abre specrails.dev/companion-app en tu teléfono y escanea este código con él.`,startFailed:`No se pudo iniciar el emparejamiento: {{error}}`,showThenScan:`Cuando tu teléfono haya escaneado esto, toca «Escanear código del teléfono» y apunta la cámara hacia tu teléfono.`,scanAnswer:`Escanear código del teléfono`,scanning:`Apunta la cámara al código de tu teléfono…`,cameraFailed:`Cámara no disponible: {{message}}`,notAnswer:`Ese QR no es una respuesta de emparejamiento.`,connecting:`Conectando…`,paired:`✓ Emparejado`,pairedToast:`Companion web emparejado`,answerRejected:`El equipo de escritorio rechazó ese código. Genera uno nuevo e inténtalo de nuevo.`,copyCode:`Copiar código`,codeCopied:`Código copiado`,cancel:`Cancelar`},h={heading:`Specrails Core`,installed:`Instalado:`,updateAvailable:`Actualización disponible: {{version}}`,upToDate:`Actualizado`,neverChecked:`Sin comprobar`,check:`Buscar actualizaciones`,checking:`Comprobando…`,update:`Actualizar a {{version}}`,downloading:`Descargando…`,materializing:`Instalando…`,affectsAll:`Afecta a todos los proyectos — sin reiniciar.`,unavailable:`Las actualizaciones del core no están disponibles en esta versión.`,toastDone:`Specrails Core actualizado a {{version}}`,toastError:`Error al actualizar el core: {{message}}`,toastUpToDate:`Specrails Core está actualizado`,toastCheckFailed:`Error al comprobar actualizaciones: {{message}}`,loadFailed:`No se pudo actualizar el estado de Core. Reintentar`,runtime:`Motor: {{version}}`,bundled:`Incluido en Desktop: {{version}}`,sources:{override:`Selección explícita`,managed:`Gestionado por Desktop`,bundled:`Incluido en Desktop`,local:`Paquete local`,global:`CLI externo`},repair:`Completar actualización {{version}}`},g={heading:`Specrails Desktop`,installed:`Instalada:`,check:`Buscar actualizaciones`,checking:`Comprobando…`,upToDate:`Tienes la última versión`,updateAvailable:`Actualización disponible: {{version}}`,autoHint:`Se comprueba automáticamente al arrancar y cada 6 horas.`,unavailable:`Las actualizaciones solo están disponibles en la app de escritorio.`,toastUpToDate:`Specrails Desktop está actualizado`,toastCheckFailed:`Error al buscar actualizaciones: {{message}}`},_={title:`{{name}} — Ajustes`,description:`Configuración del proyecto: prompts, rama base, entorno, presupuesto, telemetría y terminal.`,nav:{general:`General`,branch:`Rama base`,environment:`Entorno`,budget:`Presupuesto`,telemetry:`Telemetría`,terminal:`Terminal`}},v={title:`Rama de integración`,description:`La rama desde la que parten los rails paralelos y a la que apuntan sus PRs en borrador. Déjalo vacío para resolver automáticamente a la rama por defecto del repositorio.`,placeholder:`automático (rama por defecto)`,resolved:`Los rails parten de <mono>{{branch}}</mono>`,save:`Guardar rama`,saved:`Rama de integración guardada`,saveFailed:`No se pudo guardar la rama de integración`},y={title:`Entorno de worktrees`,description:`Elige los nombres de variables de entorno que este proyecto pasa a jobs de rail y worktrees aislados de loops. Solo se guardan nombres; los valores se leen al iniciar la ejecución, recuperándolos del login shell si faltan en el proceso de escritorio.`,label:`Variable de entorno`,placeholder:`NODE_AUTH_TOKEN`,helper:`Pulsa Enter o Añadir. Puedes pegar varios nombres separados por comas o espacios.`,add:`Añadir`,empty:`Aún no hay variables específicas para este proyecto.`,remove:`Quitar {{name}}`,save:`Guardar entorno`,saved:`Entorno de worktrees guardado`,saveFailed:`No se pudo guardar el entorno de worktrees`,invalidName:`{{name}} no es un nombre válido de variable de entorno`,noValues:`Añade solo nombres de variables, no secretos KEY=value.`},b={heading:`Specrails Agents`,description:`Personaliza los agentes del pipeline de specrails-core por proveedor de IA — modelo y esfuerzo de razonamiento. Los cambios aplican a la siguiente ejecución, sin reiniciar.`,loadFailed:`No se pudieron cargar los ajustes de agentes.`,modeDefault:`Por defecto`,modeCustom:`Personalizado`,notDetected:`No detectado`,notSignedIn:`Sin iniciar sesión`,pipeline:`Pipeline`,pipelineHint:`Modelo y esfuerzo de toda la ejecución — los subagentes los heredan salvo que los cambies abajo.`,model:`Modelo`,effort:`Esfuerzo`,defaultModel:`Por defecto ({{model}})`,defaultEffort:`Esfuerzo por defecto`,agentsTitle:`Agentes del pipeline`,agentsHint:`Modelo por agente para este proveedor.`,inheritNote:`Los subagentes de Codex heredan el modelo y esfuerzo del pipeline por diseño.`,noPerAgentNote:`Este proveedor no admite modelos por agente.`,reset:`Restaurar valores por defecto`,agentNames:{"sr-architect":`Arquitecto`,"sr-developer":`Desarrollador`,"sr-reviewer":`Revisor`}},x={heading:`Efectos`,description:`Detalles visuales de la app. Cada uno se puede desactivar aquí.`,thinkingHalo:{label:`Halo de pensamiento en el composer del agente`,description:`Mientras el agente piensa o escribe, el anillo orbitante del Constructor brilla alrededor del composer: aparece con un fundido al empezar el turno y se desvanece al terminar la respuesta.`},reducedMotion:`Respeta el ajuste de movimiento reducido del sistema: el anillo queda como un brillo estático.`,preview:`Vista previa`,previewThinking:`Pensando…`},S={language:e,page:t,errors:n,telemetry:r,prePrompt:i,freestylePrePrompt:a,budget:o,desktop:s,notifications:c,webhooks:l,terminal:u,codeSection:d,appearance:f,mobile:p,pairWeb:m,coreUpdate:h,appUpdate:g,projectDialog:_,integrationBranch:v,worktreeEnv:y,specrailsAgents:b,effects:x};export{g as appUpdate,f as appearance,o as budget,d as codeSection,h as coreUpdate,S as default,s as desktop,x as effects,n as errors,a as freestylePrePrompt,v as integrationBranch,e as language,p as mobile,c as notifications,t as page,m as pairWeb,i as prePrompt,_ as projectDialog,b as specrailsAgents,r as telemetry,u as terminal,l as webhooks,y as worktreeEnv};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-CNC7AqOf.js";var t=e({appUpdate:()=>v,appearance:()=>m,budget:()=>c,codeSection:()=>p,coreUpdate:()=>_,default:()=>w,desktop:()=>l,effects:()=>C,errors:()=>i,freestylePrePrompt:()=>s,integrationBranch:()=>b,language:()=>n,mobile:()=>h,notifications:()=>u,page:()=>r,pairWeb:()=>g,prePrompt:()=>o,projectDialog:()=>y,specrailsAgents:()=>S,telemetry:()=>a,terminal:()=>f,webhooks:()=>d,worktreeEnv:()=>x}),n={title:`Language`,description:`Desktop-wide UI language. Applies instantly — no restart needed.`,selectLabel:`Interface language`,updateFailed:`Could not save the language preference`},r={title:`Project Settings`},i={saveFailed:`Failed to save: {{message}}`},a={title:`Pipeline Telemetry`,description:`Capture token usage, phase durations, and subagent activity for diagnostic export. Off by default.`,toggleLabel:`Enable pipeline telemetry`,toggleDescription:`When on, OTEL data from pipeline jobs is captured locally. Use the <mono>Export diagnostic</mono> button on any job card to download.`,enabled:`Pipeline telemetry enabled`,disabled:`Pipeline telemetry disabled`,saveFailed:`Failed to save telemetry setting`},o={title:`Rail Pre-prompt`,description:`Extra project-specific instructions appended to implement and batch-implement rail jobs after the ticket context and before execution.`,label:`Pre-prompt`,placeholder:`Example: Prefer incremental changes, keep migrations backward compatible, and add tests for every rail change.`,helper:`Use this for stable project guidance that should accompany every rail implementation run.`,saveButton:`Save pre-prompt`,cleared:`Pre-prompt cleared`,saved:`Pre-prompt saved`,saveFailed:`Failed to save pre-prompt`},s={title:`Freestyle pre-prompt`,description:`Instruction sent to the selected provider in Freestyle. Freestyle skips the OpenSpec pipeline — it hands the provider this pre-prompt plus the spec text and lets it implement autonomously. Leave blank to use the built-in default.`,label:`Freestyle pre-prompt`,placeholder:`Leave blank to use the default Freestyle instruction.`,helper:`The spec text is appended automatically after this pre-prompt. Empty = default.`,saveButton:`Save Freestyle pre-prompt`,resetToDefault:`Freestyle pre-prompt reset to default`,saved:`Freestyle pre-prompt saved`,saveFailed:`Failed to save Freestyle pre-prompt`},c={title:`Budget`,description:`Set a daily spend cap for this project. The queue auto-pauses when the limit is hit.`,dailyLabel:`Daily budget (USD)`,dailyHelper:`Leave blank to disable. Spend is calculated over the last 24 hours.`,dailyPlaceholder:`e.g. 5.00`,perJobLabel:`Per-job cost alert (USD)`,perJobHelper:`Alert when a single job in this project exceeds this amount.`,perJobPlaceholder:`e.g. 0.50`,invalidNumber:`Enter a positive number or leave blank to disable`,dailyRemoved:`Daily budget removed`,dailySet:"Daily budget set to ${{amount}}",perJobAlertDisabled:`Per-job cost alert disabled`,alertSet:"Alert set for jobs over ${{amount}}",saveBudgetFailed:`Failed to save budget`,saveThresholdFailed:`Failed to save threshold`},l={nav:{appearance:`Appearance`,specrailsAgents:`Specrails Agents`,code:`Code`,terminal:`Terminal`,updates:`Updates`,mobile:`Mobile`,mcp:`MCP`,projects:`Projects`,advanced:`Advanced`,webhooks:`Webhooks`,about:`About`,effects:`Effects`},title:`Desktop Settings`,description:`Manage registered projects and view Desktop information.`,registeredProjects:`Registered Projects`,noProjects:`No projects registered yet`,techUrlDescription:`Base URL for the specrails-tech API (default: http://localhost:3000)`,techUrlSaved:`specrails-tech URL saved`,techUrlSaveFailed:`Failed to save URL`,budgetAlertsHeading:`Budget & Alerts`,dailyBudgetLabel:`Desktop daily budget (USD)`,dailyBudgetHelper:`Global daily spend limit across all projects. Queues auto-pause when exceeded.`,dailyBudgetPlaceholder:`e.g. 10.00`,perJobHelper:`Alert when a single job exceeds this amount. Leave blank to disable.`,costAlertsDisabled:`Cost alerts disabled`,dailyBudgetRemoved:`Desktop daily budget removed`,dailyBudgetSet:"Desktop daily budget set to ${{amount}}",dailyBudgetSaveFailed:`Failed to save Desktop daily budget`,projectRemoved:`Project removed`,projectRemoveFailed:`Failed to remove project`,onboardingHeading:`Onboarding`,platformTour:`Platform Tour`,platformTourDescription:`Replay the welcome wizard to review key features.`,replayTour:`Replay Tour`,terminalPanelHeading:`Terminal Panel`,infoHeading:`Desktop Information`,infoPort:`Port`,infoProjects:`Projects`,infoDb:`Desktop DB`},u={heading:`OS Notifications`,description:`Show native desktop notifications when jobs complete or fail. Notifications only appear when the tab is not focused.`,enableLabel:`Enable OS Notifications`,notifyOn:`Notify on:`,filterAll:`All (completed & failed)`,filterCompleted:`Completed only`,filterFailed:`Failed only`,enabledToast:`OS notifications enabled`,disabledToast:`OS notifications disabled`},d={heading:`Outbound Webhooks`,description:`Notify external tools (Slack, Zapier, CI/CD) on Desktop events. Requests are signed via <code>X-Specrails-Signature</code> when a secret is set.`,eventJobCompleted:`Job completed`,eventJobFailed:`Job failed`,eventDailyBudgetExceeded:`Daily budget exceeded`,statusOn:`on`,statusOff:`off`,disable:`Disable`,enable:`Enable`,sendTestPing:`Send test ping`,addHeading:`Add webhook`,secretPlaceholder:`Signing secret (optional)`,addButton:`Add Webhook`,urlRequired:`URL is required`,selectEvent:`Select at least one event`,added:`Webhook added`,addFailed:`Failed to add webhook`,updateFailed:`Failed to update webhook`,removed:`Webhook removed`,removeFailed:`Failed to remove webhook`,testPingSent:`Test ping sent`,testPingFailed:`Failed to send test ping`},f={title:`Terminal panel`,desktopDescription:`Desktop-wide defaults applied to every project unless a per-project override is set.`,projectDescription:`Per-project overrides for the terminal panel. Leave a field unchanged to inherit the Desktop default.`,fontFamily:`Font family`,fontSize:`Font size ({{min}}–{{max}})`,renderMode:`Render mode`,copyOnSelect:`Copy on select`,shellIntegration:`Shell integration (OSC 133 marks)`,notifyLongRunning:`Notify on long-running commands`,longCommandThreshold:`Long-command threshold (ms)`,imageRendering:`Inline image rendering (Sixel + iTerm2)`,browserShortcutUrl:`Browser shortcut URL`,quickScript:`Quick script (pasted into active terminal — Enter manually)`,reset:`Reset`,unsavedChanges:`Unsaved changes`,clearOverride:`Clear override`,clear:`Clear`,inheritingDefault:`Inheriting Desktop default`,nothingToSave:`Nothing to save`,saved:`Terminal settings saved`},p={heading:`Code section`,summaryLanguage:`Summary language`,monthlyBudget:`Monthly budget (USD)`,budgetHelper:"Cap on `surface=file-summary` spend per calendar month. User-initiated regenerations can override."},m={taglines:{dracula:`The original — dark purple-tinted with vivid neon accents`,"aurora-light":`Premium light — Linear-inspired indigo on warm off-white`,"obsidian-dark":`Premium dark — near-black blue-tinted with electric accents`,specrails:`Brand theme — deep navy-indigo with saturated cyan accents`,"code-rain":`Phosphor terminal — soft mint on green-tinted near-black`,galaxy:`Deep-space blue with a glowing blade trail`},heading:`Appearance`,themeGroupLabel:`Theme`,currentlyActive:`Currently active`,updateFailed:`Failed to update theme`},h={heading:`Mobile companion`,description:`Control Specrails from the SpecRails Companion app on your phone, 100% over your local network. Off by default.`,accessOn:`Mobile access on`,accessOff:`Mobile access off`,listeningOnPort:`Listening on port {{port}}`,notListening:`Not listening`,turnOn:`Turn on`,turnOff:`Turn off`,pairWebDevice:`Pair web companion`,reset:`Reset`,resetConfirm:`Reset the mobile identity? Every paired device will be revoked and must pair again.`,identityReset:`Mobile identity reset`,enableFailed:`Could not enable mobile access: {{message}}`,disableFailed:`Could not disable mobile access: {{message}}`,windowsFirewall:`Windows Firewall will ask to allow the SpecRails server on first enable — choose “Allow on private networks”.`,pairedDevices:`Paired devices`,noDevices:`No devices paired yet.`,revokeDevice:`Revoke {{name}}`},g={title:`Pair web companion`,description:`Open specrails.dev/companion-app on your phone, then scan this code with it.`,startFailed:`Could not start pairing: {{error}}`,showThenScan:`After your phone scans this, tap “Scan phone's code” and point the camera at your phone.`,scanAnswer:`Scan phone's code`,scanning:`Point the camera at the code on your phone…`,cameraFailed:`Camera unavailable: {{message}}`,notAnswer:`That QR isn't a pairing answer.`,connecting:`Connecting…`,paired:`✓ Paired`,pairedToast:`Web companion paired`,answerRejected:`The desktop rejected that code. Generate a fresh one and retry.`,copyCode:`Copy code`,codeCopied:`Code copied`,cancel:`Cancel`},_={heading:`Specrails Core`,installed:`Installed:`,updateAvailable:`Update available: {{version}}`,upToDate:`Up to date`,neverChecked:`Not checked yet`,check:`Check for updates`,checking:`Checking…`,update:`Update to {{version}}`,downloading:`Downloading…`,materializing:`Installing…`,affectsAll:`Applies to all projects — no restart needed.`,unavailable:`Core updates aren't available in this build.`,toastDone:`Specrails Core updated to {{version}}`,toastError:`Core update failed: {{message}}`,toastUpToDate:`Specrails Core is up to date`,toastCheckFailed:`Update check failed: {{message}}`,loadFailed:`Could not refresh Core status. Retry`,runtime:`Runtime: {{version}}`,bundled:`Included in Desktop: {{version}}`,sources:{override:`Explicit override`,managed:`Managed by Desktop`,bundled:`Included in Desktop`,local:`Local package`,global:`External CLI`},repair:`Finish updating {{version}}`},v={heading:`Specrails Desktop`,installed:`Installed:`,check:`Check for updates`,checking:`Checking…`,upToDate:`You're on the latest version`,updateAvailable:`Update available: {{version}}`,autoHint:`Checks automatically at launch and every 6 hours.`,unavailable:`App updates are only available in the desktop app.`,toastUpToDate:`Specrails Desktop is up to date`,toastCheckFailed:`Update check failed: {{message}}`},y={title:`{{name}} — Settings`,description:`Project-level configuration: prompts, branch, environment, budget, telemetry and terminal.`,nav:{general:`General`,branch:`Branch`,environment:`Environment`,budget:`Budget`,telemetry:`Telemetry`,terminal:`Terminal`}},b={title:`Integration branch`,description:`The branch parallel rails branch from and target their draft PRs at. Leave empty to auto-resolve to the repository's default branch.`,placeholder:`auto (repository default)`,resolved:`Rails branch off <mono>{{branch}}</mono>`,save:`Save branch`,saved:`Integration branch saved`,saveFailed:`Could not save the integration branch`},x={title:`Worktree environment`,description:`Choose environment variable names this project passes to rail jobs and isolated loop worktrees. Only names are saved; values are read when a run starts, with login-shell recovery when the desktop process is missing them.`,label:`Environment variable`,placeholder:`NODE_AUTH_TOKEN`,helper:`Press Enter or Add. You can paste several names separated by commas or spaces.`,add:`Add`,empty:`No project-specific variables configured yet.`,remove:`Remove {{name}}`,save:`Save environment`,saved:`Worktree environment saved`,saveFailed:`Could not save the worktree environment`,invalidName:`{{name}} is not a valid environment variable name`,noValues:`Add only variable names here, not KEY=value secrets.`},S={heading:`Specrails Agents`,description:`Customize the specrails-core pipeline agents per AI provider — model and reasoning effort. Changes apply to the next run, no restart needed.`,loadFailed:`Could not load the agent defaults.`,modeDefault:`Default`,modeCustom:`Custom`,notDetected:`Not detected`,notSignedIn:`Not signed in`,pipeline:`Pipeline`,pipelineHint:`Model and effort for the whole run — sub-agents inherit them unless overridden below.`,model:`Model`,effort:`Effort`,defaultModel:`Default ({{model}})`,defaultEffort:`Default effort`,agentsTitle:`Pipeline agents`,agentsHint:`Per-agent model override for this provider.`,inheritNote:`Codex sub-agents inherit the pipeline model and effort by design.`,noPerAgentNote:`This provider does not support per-agent model overrides.`,reset:`Restore defaults`,agentNames:{"sr-architect":`Architect`,"sr-developer":`Developer`,"sr-reviewer":`Reviewer`}},C={heading:`Effects`,description:`Visual flourishes across the app. Each one can be switched off here.`,thinkingHalo:{label:`Thinking halo on the agent composer`,description:`While the agent is thinking or writing, the Builder's orbiting ring glows around the composer — it fades in when a turn starts and fades out when the reply settles.`},reducedMotion:`Follows your system's reduced-motion setting: the ring stays as a static glow.`,preview:`Preview`,previewThinking:`Thinking…`},w={language:n,page:r,errors:i,telemetry:a,prePrompt:o,freestylePrePrompt:s,budget:c,desktop:l,notifications:u,webhooks:d,terminal:f,codeSection:p,appearance:m,mobile:h,pairWeb:g,coreUpdate:_,appUpdate:v,projectDialog:y,integrationBranch:b,worktreeEnv:x,specrailsAgents:S,effects:C};export{t};
@@ -1 +0,0 @@
1
- var e={title:`Sprache`,description:`Desktop-weite UI-Sprache. Wird sofort angewendet – kein Neustart nötig.`,selectLabel:`Oberflächensprache`,updateFailed:`Spracheinstellung konnte nicht gespeichert werden`},t={title:`Projekteinstellungen`},n={saveFailed:`Speichern fehlgeschlagen: {{message}}`},r={title:`Pipeline-Telemetrie`,description:`Erfasst Token-Verbrauch, Phasendauern und Subagent-Aktivität für den Diagnose-Export. Standardmäßig aus.`,toggleLabel:`Pipeline-Telemetrie aktivieren`,toggleDescription:`Wenn aktiviert, werden OTEL-Daten aus Pipeline-Jobs lokal erfasst. Verwenden Sie zum Herunterladen die Schaltfläche <mono>Diagnose exportieren</mono> auf einer beliebigen Job-Karte.`,enabled:`Pipeline-Telemetrie aktiviert`,disabled:`Pipeline-Telemetrie deaktiviert`,saveFailed:`Telemetrie-Einstellung konnte nicht gespeichert werden`},i={title:`Rail-Pre-Prompt`,description:`Zusätzliche projektspezifische Anweisungen, die an implement- und batch-implement-Rail-Jobs angehängt werden – nach dem Ticket-Kontext und vor der Ausführung.`,label:`Pre-Prompt`,placeholder:`Beispiel: Bevorzuge inkrementelle Änderungen, halte Migrationen abwärtskompatibel und füge Tests für jede Rail-Änderung hinzu.`,helper:`Für stabile Projektleitlinien, die jeden Rail-Implementierungslauf begleiten sollen.`,saveButton:`Pre-Prompt speichern`,cleared:`Pre-Prompt gelöscht`,saved:`Pre-Prompt gespeichert`,saveFailed:`Pre-Prompt konnte nicht gespeichert werden`},a={title:`Freestyle-Pre-Prompt`,description:`Anweisung, die in Freestyle an den ausgewählten Anbieter gesendet wird. Freestyle überspringt die OpenSpec-Pipeline – der Anbieter erhält diesen Pre-Prompt plus den Spec-Text und implementiert autonom. Leer lassen, um den eingebauten Standard zu verwenden.`,label:`Freestyle-Pre-Prompt`,placeholder:`Leer lassen, um die Standard-Freestyle-Anweisung zu verwenden.`,helper:`Der Spec-Text wird automatisch nach diesem Pre-Prompt angehängt. Leer = Standard.`,saveButton:`Freestyle-Pre-Prompt speichern`,resetToDefault:`Freestyle-Pre-Prompt auf Standard zurückgesetzt`,saved:`Freestyle-Pre-Prompt gespeichert`,saveFailed:`Freestyle-Pre-Prompt konnte nicht gespeichert werden`},o={title:`Budget`,description:`Tagesausgabenlimit für dieses Projekt festlegen. Die Queue pausiert automatisch, wenn das Limit erreicht ist.`,dailyLabel:`Tagesbudget (USD)`,dailyHelper:`Leer lassen zum Deaktivieren. Ausgaben werden über die letzten 24 Stunden berechnet.`,dailyPlaceholder:`z. B. 5.00`,perJobLabel:`Kostenalarm pro Job (USD)`,perJobHelper:`Alarm, wenn ein einzelner Job in diesem Projekt diesen Betrag überschreitet.`,perJobPlaceholder:`z. B. 0.50`,invalidNumber:`Positive Zahl eingeben oder leer lassen zum Deaktivieren`,dailyRemoved:`Tagesbudget entfernt`,dailySet:"Tagesbudget auf ${{amount}} gesetzt",perJobAlertDisabled:`Kostenalarm pro Job deaktiviert`,alertSet:"Alarm für Jobs über ${{amount}} gesetzt",saveBudgetFailed:`Budget konnte nicht gespeichert werden`,saveThresholdFailed:`Schwellenwert konnte nicht gespeichert werden`},s={nav:{appearance:`Darstellung`,specrailsAgents:`Specrails Agents`,code:`Code`,terminal:`Terminal`,updates:`Updates`,mobile:`Mobil`,mcp:`MCP`,projects:`Projekte`,advanced:`Erweitert`,webhooks:`Webhooks`,about:`Info`,effects:`Effekte`},title:`Desktop-Einstellungen`,description:`Registrierte Projekte verwalten und Desktop-Informationen einsehen.`,registeredProjects:`Registrierte Projekte`,noProjects:`Noch keine Projekte registriert`,techUrlDescription:`Basis-URL für die specrails-tech-API (Standard: http://localhost:3000)`,techUrlSaved:`specrails-tech-URL gespeichert`,techUrlSaveFailed:`URL konnte nicht gespeichert werden`,budgetAlertsHeading:`Budget & Alarme`,dailyBudgetLabel:`Desktop-Tagesbudget (USD)`,dailyBudgetHelper:`Globales Tagesausgabenlimit über alle Projekte. Queues pausieren automatisch bei Überschreitung.`,dailyBudgetPlaceholder:`z. B. 10.00`,perJobHelper:`Alarm, wenn ein einzelner Job diesen Betrag überschreitet. Leer lassen zum Deaktivieren.`,costAlertsDisabled:`Kostenalarme deaktiviert`,dailyBudgetRemoved:`Desktop-Tagesbudget entfernt`,dailyBudgetSet:"Desktop-Tagesbudget auf ${{amount}} gesetzt",dailyBudgetSaveFailed:`Desktop-Tagesbudget konnte nicht gespeichert werden`,projectRemoved:`Projekt entfernt`,projectRemoveFailed:`Projekt konnte nicht entfernt werden`,onboardingHeading:`Onboarding`,platformTour:`Plattform-Tour`,platformTourDescription:`Den Willkommensassistenten erneut abspielen, um die wichtigsten Funktionen zu sehen.`,replayTour:`Tour erneut abspielen`,terminalPanelHeading:`Terminal-Panel`,infoHeading:`Desktop-Informationen`,infoPort:`Port`,infoProjects:`Projekte`,infoDb:`Desktop-DB`},c={heading:`OS-Benachrichtigungen`,description:`Native Desktop-Benachrichtigungen anzeigen, wenn Jobs abgeschlossen werden oder fehlschlagen. Benachrichtigungen erscheinen nur, wenn der Tab nicht fokussiert ist.`,enableLabel:`OS-Benachrichtigungen aktivieren`,notifyOn:`Benachrichtigen bei:`,filterAll:`Alle (abgeschlossen & fehlgeschlagen)`,filterCompleted:`Nur abgeschlossen`,filterFailed:`Nur fehlgeschlagen`,enabledToast:`OS-Benachrichtigungen aktiviert`,disabledToast:`OS-Benachrichtigungen deaktiviert`},l={heading:`Ausgehende Webhooks`,description:`Externe Tools (Slack, Zapier, CI/CD) bei Desktop-Ereignissen benachrichtigen. Anfragen werden über <code>X-Specrails-Signature</code> signiert, wenn ein Secret gesetzt ist.`,eventJobCompleted:`Job abgeschlossen`,eventJobFailed:`Job fehlgeschlagen`,eventDailyBudgetExceeded:`Tagesbudget überschritten`,statusOn:`an`,statusOff:`aus`,disable:`Deaktivieren`,enable:`Aktivieren`,sendTestPing:`Test-Ping senden`,addHeading:`Webhook hinzufügen`,secretPlaceholder:`Signatur-Secret (optional)`,addButton:`Webhook hinzufügen`,urlRequired:`URL ist erforderlich`,selectEvent:`Mindestens ein Ereignis auswählen`,added:`Webhook hinzugefügt`,addFailed:`Webhook konnte nicht hinzugefügt werden`,updateFailed:`Webhook konnte nicht aktualisiert werden`,removed:`Webhook entfernt`,removeFailed:`Webhook konnte nicht entfernt werden`,testPingSent:`Test-Ping gesendet`,testPingFailed:`Test-Ping konnte nicht gesendet werden`},u={title:`Terminal-Panel`,desktopDescription:`Desktop-weite Standardwerte für alle Projekte, sofern kein projektspezifischer Override gesetzt ist.`,projectDescription:`Projektspezifische Overrides für das Terminal-Panel. Lassen Sie ein Feld unverändert, um den Desktop-Standard zu erben.`,fontFamily:`Schriftfamilie`,fontSize:`Schriftgröße ({{min}}–{{max}})`,renderMode:`Render-Modus`,copyOnSelect:`Beim Auswählen kopieren`,shellIntegration:`Shell-Integration (OSC-133-Marken)`,notifyLongRunning:`Bei lang laufenden Befehlen benachrichtigen`,longCommandThreshold:`Schwellenwert für lange Befehle (ms)`,imageRendering:`Inline-Bilddarstellung (Sixel + iTerm2)`,browserShortcutUrl:`Browser-Shortcut-URL`,quickScript:`Quick-Skript (wird ins aktive Terminal eingefügt – Enter manuell drücken)`,reset:`Zurücksetzen`,unsavedChanges:`Ungespeicherte Änderungen`,clearOverride:`Override entfernen`,clear:`Entfernen`,inheritingDefault:`Erbt Desktop-Standard`,nothingToSave:`Nichts zu speichern`,saved:`Terminal-Einstellungen gespeichert`},d={heading:`Code-Bereich`,summaryLanguage:`Sprache der Zusammenfassungen`,monthlyBudget:`Monatsbudget (USD)`,budgetHelper:"Obergrenze für `surface=file-summary`-Ausgaben pro Kalendermonat. Von Nutzern angestoßene Neugenerierungen können sie überschreiten."},f={taglines:{dracula:`Das Original — dunkel mit Violettstich und lebhaften Neon-Akzenten`,"aurora-light":`Premium hell — Linear-inspiriertes Indigo auf warmem Cremeweiß`,"obsidian-dark":`Premium dunkel — fast schwarz mit Blaustich und elektrischen Akzenten`,specrails:`Marken-Theme — tiefes Marine-Indigo mit satten Cyan-Akzenten`,"code-rain":`Phosphor-Terminal — sanftes Mint auf grünlichem Fast-Schwarz`,galaxy:`Tiefraum-Blau mit einer leuchtenden Klingenspur`},heading:`Erscheinungsbild`,themeGroupLabel:`Theme`,currentlyActive:`Derzeit aktiv`,updateFailed:`Theme konnte nicht aktualisiert werden`},p={heading:`Mobile Companion`,description:`Steuern Sie Specrails über die SpecRails Companion-App auf Ihrem Smartphone – zu 100 % über Ihr lokales Netzwerk. Standardmäßig aus.`,accessOn:`Mobilzugriff an`,accessOff:`Mobilzugriff aus`,listeningOnPort:`Lauscht auf Port {{port}}`,notListening:`Lauscht nicht`,turnOn:`Einschalten`,turnOff:`Ausschalten`,pairWebDevice:`Web-Companion koppeln`,reset:`Zurücksetzen`,resetConfirm:`Mobile Identität zurücksetzen? Alle gekoppelten Geräte werden widerrufen und müssen neu gekoppelt werden.`,identityReset:`Mobile Identität zurückgesetzt`,enableFailed:`Mobilzugriff konnte nicht aktiviert werden: {{message}}`,disableFailed:`Mobilzugriff konnte nicht deaktiviert werden: {{message}}`,windowsFirewall:`Die Windows-Firewall fragt beim ersten Aktivieren, ob der SpecRails-Server zugelassen werden soll – wählen Sie „In privaten Netzwerken zulassen“.`,pairedDevices:`Gekoppelte Geräte`,noDevices:`Noch keine Geräte gekoppelt.`,revokeDevice:`{{name}} widerrufen`},m={title:`Web-Companion koppeln`,description:`Öffnen Sie specrails.dev/companion-app auf Ihrem Smartphone und scannen Sie damit diesen Code.`,startFailed:`Koppeln konnte nicht gestartet werden: {{error}}`,showThenScan:`Nachdem Ihr Smartphone dies gescannt hat, tippen Sie auf „Code des Smartphones scannen“ und richten Sie die Kamera auf Ihr Smartphone.`,scanAnswer:`Code des Smartphones scannen`,scanning:`Richten Sie die Kamera auf den Code auf Ihrem Smartphone…`,cameraFailed:`Kamera nicht verfügbar: {{message}}`,notAnswer:`Dieser QR-Code ist keine Kopplungsantwort.`,connecting:`Verbinden…`,paired:`✓ Gekoppelt`,pairedToast:`Web-Companion gekoppelt`,answerRejected:`Der Desktop hat diesen Code abgelehnt. Erzeugen Sie einen neuen und versuchen Sie es erneut.`,copyCode:`Code kopieren`,codeCopied:`Code kopiert`,cancel:`Abbrechen`},h={heading:`Specrails Core`,installed:`Installiert:`,updateAvailable:`Update verfügbar: {{version}}`,upToDate:`Aktuell`,neverChecked:`Nicht geprüft`,check:`Nach Updates suchen`,checking:`Wird geprüft…`,update:`Auf {{version}} aktualisieren`,downloading:`Wird heruntergeladen…`,materializing:`Wird installiert…`,affectsAll:`Gilt für alle Projekte — kein Neustart nötig.`,unavailable:`Core-Updates sind in diesem Build nicht verfügbar.`,toastDone:`Specrails Core auf {{version}} aktualisiert`,toastError:`Core-Update fehlgeschlagen: {{message}}`,toastUpToDate:`Specrails Core ist aktuell`,toastCheckFailed:`Update-Prüfung fehlgeschlagen: {{message}}`,loadFailed:`Core-Status konnte nicht geladen werden. Erneut versuchen`,runtime:`Laufzeit: {{version}}`,bundled:`In Desktop enthalten: {{version}}`,sources:{override:`Explizite Auswahl`,managed:`Von Desktop verwaltet`,bundled:`In Desktop enthalten`,local:`Lokales Paket`,global:`Externe CLI`},repair:`Update auf {{version}} abschließen`},g={heading:`Specrails Desktop`,installed:`Installiert:`,check:`Nach Updates suchen`,checking:`Wird geprüft…`,upToDate:`Du hast die neueste Version`,updateAvailable:`Update verfügbar: {{version}}`,autoHint:`Wird beim Start und alle 6 Stunden automatisch geprüft.`,unavailable:`App-Updates sind nur in der Desktop-App verfügbar.`,toastUpToDate:`Specrails Desktop ist aktuell`,toastCheckFailed:`Update-Prüfung fehlgeschlagen: {{message}}`},_={title:`{{name}} — Einstellungen`,description:`Projektkonfiguration: Prompts, Branch, Umgebung, Budget, Telemetrie und Terminal.`,nav:{general:`Allgemein`,branch:`Branch`,environment:`Umgebung`,budget:`Budget`,telemetry:`Telemetrie`,terminal:`Terminal`}},v={title:`Integrationszweig`,description:`Der Branch, von dem parallele Rails abzweigen und auf den ihre Entwurfs-PRs zielen. Leer lassen, um automatisch den Standard-Branch des Repositorys zu verwenden.`,placeholder:`automatisch (Standard-Branch)`,resolved:`Rails zweigen von <mono>{{branch}}</mono> ab`,save:`Branch speichern`,saved:`Integrationszweig gespeichert`,saveFailed:`Integrationszweig konnte nicht gespeichert werden`},y={title:`Worktree-Umgebung`,description:`Wählen Sie die Namen der Umgebungsvariablen, die dieses Projekt an Rail-Jobs und isolierte Loop-Worktrees weitergibt. Gespeichert werden nur Namen; Werte werden beim Start gelesen und bei Bedarf aus der Login-Shell nachgeladen.`,label:`Umgebungsvariable`,placeholder:`NODE_AUTH_TOKEN`,helper:`Drücken Sie Enter oder Hinzufügen. Mehrere Namen können durch Kommas oder Leerzeichen getrennt eingefügt werden.`,add:`Hinzufügen`,empty:`Für dieses Projekt sind noch keine eigenen Variablen konfiguriert.`,remove:`{{name}} entfernen`,save:`Umgebung speichern`,saved:`Worktree-Umgebung gespeichert`,saveFailed:`Worktree-Umgebung konnte nicht gespeichert werden`,invalidName:`{{name}} ist kein gültiger Name für eine Umgebungsvariable`,noValues:`Fügen Sie hier nur Variablennamen hinzu, keine KEY=value-Geheimnisse.`},b={heading:`Specrails Agents`,description:`Passe die specrails-core-Pipeline-Agenten pro KI-Anbieter an — Modell und Reasoning-Aufwand. Änderungen gelten ab dem nächsten Lauf, ohne Neustart.`,loadFailed:`Agent-Einstellungen konnten nicht geladen werden.`,modeDefault:`Standard`,modeCustom:`Angepasst`,notDetected:`Nicht erkannt`,notSignedIn:`Nicht angemeldet`,pipeline:`Pipeline`,pipelineHint:`Modell und Aufwand für den gesamten Lauf — Subagenten erben sie, sofern unten nichts anderes gesetzt ist.`,model:`Modell`,effort:`Aufwand`,defaultModel:`Standard ({{model}})`,defaultEffort:`Standard-Aufwand`,agentsTitle:`Pipeline-Agenten`,agentsHint:`Modell-Override pro Agent für diesen Anbieter.`,inheritNote:`Codex-Subagenten erben Modell und Aufwand der Pipeline — by design.`,noPerAgentNote:`Dieser Anbieter unterstützt keine Modelle pro Agent.`,reset:`Standardwerte wiederherstellen`,agentNames:{"sr-architect":`Architekt`,"sr-developer":`Entwickler`,"sr-reviewer":`Reviewer`}},x={heading:`Effekte`,description:`Visuelle Akzente in der App. Jeder lässt sich hier abschalten.`,thinkingHalo:{label:`Denk-Halo am Agent-Composer`,description:`Während der Agent nachdenkt oder schreibt, leuchtet der kreisende Ring des Builders um den Composer: er blendet beim Start eines Turns ein und beim Abschluss der Antwort aus.`},reducedMotion:`Folgt der Systemeinstellung für reduzierte Bewegung: der Ring bleibt ein statisches Leuchten.`,preview:`Vorschau`,previewThinking:`Denkt nach…`},S={language:e,page:t,errors:n,telemetry:r,prePrompt:i,freestylePrePrompt:a,budget:o,desktop:s,notifications:c,webhooks:l,terminal:u,codeSection:d,appearance:f,mobile:p,pairWeb:m,coreUpdate:h,appUpdate:g,projectDialog:_,integrationBranch:v,worktreeEnv:y,specrailsAgents:b,effects:x};export{g as appUpdate,f as appearance,o as budget,d as codeSection,h as coreUpdate,S as default,s as desktop,x as effects,n as errors,a as freestylePrePrompt,v as integrationBranch,e as language,p as mobile,c as notifications,t as page,m as pairWeb,i as prePrompt,_ as projectDialog,b as specrailsAgents,r as telemetry,u as terminal,l as webhooks,y as worktreeEnv};
@@ -1 +0,0 @@
1
- var e={title:`Langue`,description:`Langue de l'interface pour tout Desktop. S'applique instantanément — aucun redémarrage requis.`,selectLabel:`Langue de l'interface`,updateFailed:`Impossible d'enregistrer la préférence de langue`},t={title:`Paramètres du projet`},n={saveFailed:`Échec de l'enregistrement : {{message}}`},r={title:`Télémétrie du pipeline`,description:`Capture l'usage des tokens, la durée des phases et l'activité des sous-agents pour l'export de diagnostic. Désactivé par défaut.`,toggleLabel:`Activer la télémétrie du pipeline`,toggleDescription:`Quand elle est activée, les données OTEL des jobs du pipeline sont capturées localement. Utilisez le bouton <mono>Exporter le diagnostic</mono> sur n'importe quelle carte de job pour les télécharger.`,enabled:`Télémétrie du pipeline activée`,disabled:`Télémétrie du pipeline désactivée`,saveFailed:`Échec de l'enregistrement du réglage de télémétrie`},i={title:`Pré-prompt de rail`,description:`Instructions supplémentaires propres au projet, ajoutées aux jobs de rail implement et batch-implement après le contexte du ticket et avant l'exécution.`,label:`Pré-prompt`,placeholder:`Exemple : privilégier les changements incrémentaux, garder les migrations rétrocompatibles et ajouter des tests pour chaque changement de rail.`,helper:`À utiliser pour des consignes projet stables qui doivent accompagner chaque exécution d'implémentation sur rail.`,saveButton:`Enregistrer le pré-prompt`,cleared:`Pré-prompt effacé`,saved:`Pré-prompt enregistré`,saveFailed:`Échec de l'enregistrement du pré-prompt`},a={title:`Pré-prompt Freestyle`,description:`Instruction envoyée au fournisseur sélectionné en mode Freestyle. Freestyle saute le pipeline OpenSpec — il transmet au fournisseur ce pré-prompt plus le texte de la spec et le laisse implémenter en autonomie. Laissez vide pour utiliser la valeur par défaut intégrée.`,label:`Pré-prompt Freestyle`,placeholder:`Laissez vide pour utiliser l'instruction Freestyle par défaut.`,helper:`Le texte de la spec est ajouté automatiquement après ce pré-prompt. Vide = défaut.`,saveButton:`Enregistrer le pré-prompt Freestyle`,resetToDefault:`Pré-prompt Freestyle réinitialisé à la valeur par défaut`,saved:`Pré-prompt Freestyle enregistré`,saveFailed:`Échec de l'enregistrement du pré-prompt Freestyle`},o={title:`Budget`,description:`Définissez un plafond de dépense quotidien pour ce projet. La file se met automatiquement en pause quand la limite est atteinte.`,dailyLabel:`Budget quotidien (USD)`,dailyHelper:`Laissez vide pour désactiver. La dépense est calculée sur les dernières 24 heures.`,dailyPlaceholder:`ex. 5.00`,perJobLabel:`Alerte de coût par job (USD)`,perJobHelper:`Alerte quand un seul job de ce projet dépasse ce montant.`,perJobPlaceholder:`ex. 0.50`,invalidNumber:`Saisissez un nombre positif ou laissez vide pour désactiver`,dailyRemoved:`Budget quotidien supprimé`,dailySet:`Budget quotidien défini à {{amount}} $`,perJobAlertDisabled:`Alerte de coût par job désactivée`,alertSet:`Alerte définie pour les jobs dépassant {{amount}} $`,saveBudgetFailed:`Échec de l'enregistrement du budget`,saveThresholdFailed:`Échec de l'enregistrement du seuil`},s={nav:{appearance:`Apparence`,specrailsAgents:`Specrails Agents`,code:`Code`,terminal:`Terminal`,updates:`Mises à jour`,mobile:`Mobile`,mcp:`MCP`,projects:`Projets`,advanced:`Avancé`,webhooks:`Webhooks`,about:`À propos`,effects:`Effets`},title:`Paramètres de Desktop`,description:`Gérez les projets enregistrés et consultez les informations de Desktop.`,registeredProjects:`Projets enregistrés`,noProjects:`Aucun projet enregistré pour l'instant`,techUrlDescription:`URL de base de l'API specrails-tech (par défaut : http://localhost:3000)`,techUrlSaved:`URL specrails-tech enregistrée`,techUrlSaveFailed:`Échec de l'enregistrement de l'URL`,budgetAlertsHeading:`Budget & alertes`,dailyBudgetLabel:`Budget quotidien de Desktop (USD)`,dailyBudgetHelper:`Limite de dépense quotidienne globale pour tous les projets. Les files se mettent automatiquement en pause en cas de dépassement.`,dailyBudgetPlaceholder:`ex. 10.00`,perJobHelper:`Alerte quand un seul job dépasse ce montant. Laissez vide pour désactiver.`,costAlertsDisabled:`Alertes de coût désactivées`,dailyBudgetRemoved:`Budget quotidien de Desktop supprimé`,dailyBudgetSet:`Budget quotidien de Desktop défini à {{amount}} $`,dailyBudgetSaveFailed:`Échec de l'enregistrement du budget quotidien de Desktop`,projectRemoved:`Projet supprimé`,projectRemoveFailed:`Échec de la suppression du projet`,onboardingHeading:`Onboarding`,platformTour:`Visite de la plateforme`,platformTourDescription:`Rejouez l'assistant de bienvenue pour revoir les fonctionnalités clés.`,replayTour:`Rejouer la visite`,terminalPanelHeading:`Panneau de terminal`,infoHeading:`Informations de Desktop`,infoPort:`Port`,infoProjects:`Projets`,infoDb:`BD de Desktop`},c={heading:`Notifications système`,description:`Affiche des notifications de bureau natives quand des jobs se terminent ou échouent. Les notifications n'apparaissent que lorsque l'onglet n'a pas le focus.`,enableLabel:`Activer les notifications système`,notifyOn:`Notifier pour :`,filterAll:`Tout (terminés & échoués)`,filterCompleted:`Terminés uniquement`,filterFailed:`Échoués uniquement`,enabledToast:`Notifications système activées`,disabledToast:`Notifications système désactivées`},l={heading:`Webhooks sortants`,description:`Notifiez des outils externes (Slack, Zapier, CI/CD) lors des événements de Desktop. Les requêtes sont signées via <code>X-Specrails-Signature</code> quand un secret est défini.`,eventJobCompleted:`Job terminé`,eventJobFailed:`Job en échec`,eventDailyBudgetExceeded:`Budget quotidien dépassé`,statusOn:`actif`,statusOff:`inactif`,disable:`Désactiver`,enable:`Activer`,sendTestPing:`Envoyer un ping de test`,addHeading:`Ajouter un webhook`,secretPlaceholder:`Secret de signature (facultatif)`,addButton:`Ajouter le webhook`,urlRequired:`L'URL est requise`,selectEvent:`Sélectionnez au moins un événement`,added:`Webhook ajouté`,addFailed:`Échec de l'ajout du webhook`,updateFailed:`Échec de la mise à jour du webhook`,removed:`Webhook supprimé`,removeFailed:`Échec de la suppression du webhook`,testPingSent:`Ping de test envoyé`,testPingFailed:`Échec de l'envoi du ping de test`},u={title:`Panneau de terminal`,desktopDescription:`Valeurs par défaut de Desktop, appliquées à chaque projet sauf surcharge par projet.`,projectDescription:`Surcharges par projet pour le panneau de terminal. Laissez un champ inchangé pour hériter de la valeur par défaut de Desktop.`,fontFamily:`Police`,fontSize:`Taille de police ({{min}}–{{max}})`,renderMode:`Mode de rendu`,copyOnSelect:`Copier à la sélection`,shellIntegration:`Intégration shell (marques OSC 133)`,notifyLongRunning:`Notifier les commandes de longue durée`,longCommandThreshold:`Seuil de commande longue (ms)`,imageRendering:`Rendu d'images inline (Sixel + iTerm2)`,browserShortcutUrl:`URL du raccourci navigateur`,quickScript:`Script rapide (collé dans le terminal actif — Entrée manuelle)`,reset:`Réinitialiser`,unsavedChanges:`Modifications non enregistrées`,clearOverride:`Effacer la surcharge`,clear:`Effacer`,inheritingDefault:`Hérite de la valeur par défaut de Desktop`,nothingToSave:`Rien à enregistrer`,saved:`Paramètres du terminal enregistrés`},d={heading:`Section Code`,summaryLanguage:`Langue des résumés`,monthlyBudget:`Budget mensuel (USD)`,budgetHelper:"Plafond de dépense `surface=file-summary` par mois calendaire. Les régénérations lancées par l'utilisateur peuvent le dépasser."},f={taglines:{dracula:`L'original — sombre teinté de violet aux accents néon éclatants`,"aurora-light":`Clair premium — indigo inspiré de Linear sur blanc cassé chaleureux`,"obsidian-dark":`Sombre premium — presque noir teinté de bleu aux accents électriques`,specrails:`Thème de la marque — bleu marine-indigo profond aux accents cyan saturés`,"code-rain":`Terminal phosphore — menthe douce sur fond presque noir verdâtre`,galaxy:`Bleu spatial profond avec une traînée de lame lumineuse`},heading:`Apparence`,themeGroupLabel:`Thème`,currentlyActive:`Actuellement actif`,updateFailed:`Échec de la mise à jour du thème`},p={heading:`Compagnon mobile`,description:`Contrôlez Specrails depuis l'application SpecRails Companion sur votre téléphone, 100 % via votre réseau local. Désactivé par défaut.`,accessOn:`Accès mobile activé`,accessOff:`Accès mobile désactivé`,listeningOnPort:`À l'écoute sur le port {{port}}`,notListening:`Pas à l'écoute`,turnOn:`Activer`,turnOff:`Désactiver`,pairWebDevice:`Appairer le compagnon web`,reset:`Réinitialiser`,resetConfirm:`Réinitialiser l'identité mobile ? Tous les appareils appairés seront révoqués et devront s'appairer à nouveau.`,identityReset:`Identité mobile réinitialisée`,enableFailed:`Impossible d'activer l'accès mobile : {{message}}`,disableFailed:`Impossible de désactiver l'accès mobile : {{message}}`,windowsFirewall:`Le Pare-feu Windows demandera d'autoriser le serveur SpecRails à la première activation — choisissez « Autoriser sur les réseaux privés ».`,pairedDevices:`Appareils appairés`,noDevices:`Aucun appareil appairé pour l'instant.`,revokeDevice:`Révoquer {{name}}`},m={title:`Appairer le compagnon web`,description:`Ouvrez specrails.dev/companion-app sur votre téléphone, puis scannez ce code avec.`,startFailed:`Impossible de démarrer l'appairage : {{error}}`,showThenScan:`Une fois que votre téléphone l'a scanné, appuyez sur « Scanner le code du téléphone » et pointez la caméra vers votre téléphone.`,scanAnswer:`Scanner le code du téléphone`,scanning:`Pointez la caméra vers le code sur votre téléphone…`,cameraFailed:`Caméra indisponible : {{message}}`,notAnswer:`Ce QR code n'est pas une réponse d'appairage.`,connecting:`Connexion…`,paired:`✓ Appairé`,pairedToast:`Compagnon web appairé`,answerRejected:`Le bureau a rejeté ce code. Générez-en un nouveau et réessayez.`,copyCode:`Copier le code`,codeCopied:`Code copié`,cancel:`Annuler`},h={heading:`Specrails Core`,installed:`Installé :`,updateAvailable:`Mise à jour disponible : {{version}}`,upToDate:`À jour`,neverChecked:`Non vérifié`,check:`Rechercher des mises à jour`,checking:`Vérification…`,update:`Mettre à jour vers {{version}}`,downloading:`Téléchargement…`,materializing:`Installation…`,affectsAll:`S'applique à tous les projets — aucun redémarrage requis.`,unavailable:`Les mises à jour du core ne sont pas disponibles dans cette version.`,toastDone:`Specrails Core mis à jour vers {{version}}`,toastError:`Échec de la mise à jour du core : {{message}}`,toastUpToDate:`Specrails Core est à jour`,toastCheckFailed:`Échec de la vérification : {{message}}`,loadFailed:`Impossible de charger l’état de Core. Réessayer`,runtime:`Moteur : {{version}}`,bundled:`Inclus dans Desktop : {{version}}`,sources:{override:`Sélection explicite`,managed:`Géré par Desktop`,bundled:`Inclus dans Desktop`,local:`Paquet local`,global:`CLI externe`},repair:`Terminer la mise à jour {{version}}`},g={heading:`Specrails Desktop`,installed:`Installée :`,check:`Rechercher des mises à jour`,checking:`Vérification…`,upToDate:`Vous avez la dernière version`,updateAvailable:`Mise à jour disponible : {{version}}`,autoHint:`Vérification automatique au lancement et toutes les 6 heures.`,unavailable:`Les mises à jour ne sont disponibles que dans l'app de bureau.`,toastUpToDate:`Specrails Desktop est à jour`,toastCheckFailed:`Échec de la recherche de mises à jour : {{message}}`},_={title:`{{name}} — Paramètres`,description:`Configuration du projet : prompts, branche, environnement, budget, télémétrie et terminal.`,nav:{general:`Général`,branch:`Branche`,environment:`Environnement`,budget:`Budget`,telemetry:`Télémétrie`,terminal:`Terminal`}},v={title:`Branche d'intégration`,description:`La branche depuis laquelle les rails parallèles se ramifient et que ciblent leurs PR en brouillon. Laissez vide pour résoudre automatiquement vers la branche par défaut du dépôt.`,placeholder:`automatique (branche par défaut)`,resolved:`Les rails partent de <mono>{{branch}}</mono>`,save:`Enregistrer la branche`,saved:`Branche d'intégration enregistrée`,saveFailed:`Impossible d'enregistrer la branche d'intégration`},y={title:`Environnement des worktrees`,description:`Choisissez les noms de variables d'environnement que ce projet transmet aux jobs de rail et aux worktrees isolés des loops. Seuls les noms sont enregistrés ; les valeurs sont lues au démarrage, avec récupération depuis le login shell si le processus Desktop ne les a pas.`,label:`Variable d'environnement`,placeholder:`NODE_AUTH_TOKEN`,helper:`Appuyez sur Entrée ou Ajouter. Vous pouvez coller plusieurs noms séparés par des virgules ou des espaces.`,add:`Ajouter`,empty:`Aucune variable propre à ce projet n'est encore configurée.`,remove:`Supprimer {{name}}`,save:`Enregistrer l'environnement`,saved:`Environnement des worktrees enregistré`,saveFailed:`Impossible d'enregistrer l'environnement des worktrees`,invalidName:`{{name}} n'est pas un nom de variable d'environnement valide`,noValues:`Ajoutez uniquement des noms de variables, pas de secrets KEY=value.`},b={heading:`Specrails Agents`,description:`Personnalisez les agents du pipeline specrails-core par fournisseur d'IA — modèle et effort de raisonnement. Les changements s'appliquent à la prochaine exécution, sans redémarrage.`,loadFailed:`Impossible de charger les réglages des agents.`,modeDefault:`Par défaut`,modeCustom:`Personnalisé`,notDetected:`Non détecté`,notSignedIn:`Non connecté`,pipeline:`Pipeline`,pipelineHint:`Modèle et effort pour toute l'exécution — les sous-agents en héritent sauf réglage ci-dessous.`,model:`Modèle`,effort:`Effort`,defaultModel:`Par défaut ({{model}})`,defaultEffort:`Effort par défaut`,agentsTitle:`Agents du pipeline`,agentsHint:`Modèle par agent pour ce fournisseur.`,inheritNote:`Les sous-agents Codex héritent du modèle et de l'effort du pipeline, par conception.`,noPerAgentNote:`Ce fournisseur ne prend pas en charge les modèles par agent.`,reset:`Restaurer les valeurs par défaut`,agentNames:{"sr-architect":`Architecte`,"sr-developer":`Développeur`,"sr-reviewer":`Réviseur`}},x={heading:`Effets`,description:`Touches visuelles de l'app. Chacune peut être désactivée ici.`,thinkingHalo:{label:`Halo de réflexion sur le composeur de l'agent`,description:`Pendant que l'agent réfléchit ou écrit, l'anneau orbital du Constructeur brille autour du composeur : il apparaît en fondu au début du tour et s'estompe quand la réponse se termine.`},reducedMotion:`Respecte le réglage système de réduction des animations : l'anneau reste une lueur statique.`,preview:`Aperçu`,previewThinking:`Réflexion…`},S={language:e,page:t,errors:n,telemetry:r,prePrompt:i,freestylePrePrompt:a,budget:o,desktop:s,notifications:c,webhooks:l,terminal:u,codeSection:d,appearance:f,mobile:p,pairWeb:m,coreUpdate:h,appUpdate:g,projectDialog:_,integrationBranch:v,worktreeEnv:y,specrailsAgents:b,effects:x};export{g as appUpdate,f as appearance,o as budget,d as codeSection,h as coreUpdate,S as default,s as desktop,x as effects,n as errors,a as freestylePrePrompt,v as integrationBranch,e as language,p as mobile,c as notifications,t as page,m as pairWeb,i as prePrompt,_ as projectDialog,b as specrailsAgents,r as telemetry,u as terminal,l as webhooks,y as worktreeEnv};