specrails-desktop 2.26.0 → 2.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/dist/assets/{ActivityFeedPage-1eXnoNAo.js → ActivityFeedPage-C1LftFSE.js} +1 -1
- package/client/dist/assets/{AgentBrowserCapture-BHW_6Vm0.js → AgentBrowserCapture-B5prW-V0.js} +1 -1
- package/client/dist/assets/{AgentModeCodePane-C89SAJzI.js → AgentModeCodePane-b6UmdjwB.js} +2 -2
- package/client/dist/assets/{AgentModeJobsPane-BG_4r4Dm.js → AgentModeJobsPane-DW3Wj5oi.js} +1 -1
- package/client/dist/assets/{AgentsPage-BrkWfc9s.js → AgentsPage-DBMnhdlq.js} +3 -3
- package/client/dist/assets/{AnalyticsPage-CMZRUPrT.js → AnalyticsPage-DjFf1OxU.js} +1 -1
- package/client/dist/assets/{BarChart-BtF3zJHa.js → BarChart-nmDbbUiR.js} +1 -1
- package/client/dist/assets/{CodePage-Cime5FRs.js → CodePage-DHd46Sm7.js} +1 -1
- package/client/dist/assets/{DesktopAnalyticsPage-CSKHSBBF.js → DesktopAnalyticsPage-ee0bpk-F.js} +1 -1
- package/client/dist/assets/{DocsDialog-ClTq6Fzj.js → DocsDialog-CGUzB1zX.js} +1 -1
- package/client/dist/assets/{DocsPage-DTxfOpTu.js → DocsPage-96iws84I.js} +1 -1
- package/client/dist/assets/{ExportDropdown-Ho9zdPvK.js → ExportDropdown-Dzk2Lkxw.js} +1 -1
- package/client/dist/assets/{IntegrationsPage-DWNyo6jk.js → IntegrationsPage-Bta2lAhq.js} +1 -1
- package/client/dist/assets/{InteractiveJobComposer-CYxXOKld.js → InteractiveJobComposer-B9S_ZGJS.js} +5 -5
- package/client/dist/assets/{JobDetailModal-DrNafHY5.js → JobDetailModal-DhrwU2z0.js} +1 -1
- package/client/dist/assets/{JobDetailPage-4VKw33GW.js → JobDetailPage-BnhoXkql.js} +1 -1
- package/client/dist/assets/{JobsPage-cFr6wWaH.js → JobsPage-BBT9fyhg.js} +1 -1
- package/client/dist/assets/{LoopBuilderPage-Bk8zVvEX.js → LoopBuilderPage-5ucN9Hq9.js} +2 -2
- package/client/dist/assets/{LoopPreviewModal-XFSO2Vcs.js → LoopPreviewModal-wKAts-Wf.js} +1 -1
- package/client/dist/assets/{LoopsPage-DWMwDj9g.js → LoopsPage-COyxf6Pa.js} +1 -1
- package/client/dist/assets/{ProjectSettingsDialog-DnSe_yWm.js → ProjectSettingsDialog-CcToBI-Z.js} +1 -1
- package/client/dist/assets/{TemplatePreviewModal-B30-TY_v.js → TemplatePreviewModal-_Dy6ceXg.js} +1 -1
- package/client/dist/assets/{agent-CRYdi9-t.js → agent-BmH52J4j.js} +1 -1
- package/client/dist/assets/{agent-BZqfQhI_.js → agent-Bxb9RRNW.js} +1 -1
- package/client/dist/assets/{agent-Bjy1SlT5.js → agent-Cg49-TGZ.js} +1 -1
- package/client/dist/assets/{agent-D5QNn9np2.js → agent-DgDtg-0Y2.js} +1 -1
- package/client/dist/assets/{agent-DgwPsxWQ.js → agent-DolxzTol.js} +1 -1
- package/client/dist/assets/{agent-6mhkV25_2.js → agent-DwDR2Exf2.js} +1 -1
- package/client/dist/assets/agent-_tfCgFUk.js +1 -0
- package/client/dist/assets/{agent-DgFoLgrF2.js → agent-gFi-qvxO2.js} +1 -1
- package/client/dist/assets/{brain-DcXkQwzO.js → brain-BJ2Gd98j.js} +1 -1
- package/client/dist/assets/dashboard-90r0QcUc2.js +1 -0
- package/client/dist/assets/dashboard-B0C6mJP-.js +1 -0
- package/client/dist/assets/dashboard-BOx0FR1L2.js +1 -0
- package/client/dist/assets/dashboard-BcjUOLJr.js +1 -0
- package/client/dist/assets/dashboard-C27kNpjn.js +1 -0
- package/client/dist/assets/dashboard-DJAj2EbH.js +1 -0
- package/client/dist/assets/dashboard-DNd1Gobs.js +1 -0
- package/client/dist/assets/dashboard-DZWrDAYm2.js +1 -0
- package/client/dist/assets/{dist-js-BAWwLSIj.js → dist-js-CXAsO0Z8.js} +1 -1
- package/client/dist/assets/{dist-js-6U6hyD6z.js → dist-js-D7smLA35.js} +1 -1
- package/client/dist/assets/index-B3ejvKSt.js +156 -0
- package/client/dist/assets/{index-cvOunQkD.css → index-C695aPdV.css} +1 -1
- package/client/dist/assets/{lib-Bsny0zZp.js → lib-BIHmUkcn.js} +1 -1
- package/client/dist/assets/{settings-DHd1lQ1k.js → settings-BHdPchJP.js} +1 -1
- package/client/dist/assets/{settings-FJXpJ3k92.js → settings-BeCczBFS2.js} +1 -1
- package/client/dist/assets/{settings-BWIf3vv4.js → settings-BlLi719f.js} +1 -1
- package/client/dist/assets/{settings-DTYQ5COE.js → settings-C_nY14Yz.js} +1 -1
- package/client/dist/assets/{settings-DE8t6aYv.js → settings-CaZ26a0S.js} +1 -1
- package/client/dist/assets/{settings-Dgv_q4qf2.js → settings-D54_cgl12.js} +1 -1
- package/client/dist/assets/{settings-DXgPh9-k.js → settings-D9bDDe2O.js} +1 -1
- package/client/dist/assets/{settings-BhuXe7ek2.js → settings-cn0tbve62.js} +1 -1
- package/client/dist/assets/{setup-iY8vH8pB.js → setup-7J8TjG4O.js} +1 -1
- package/client/dist/assets/{setup-D674kWQH.js → setup-BXpw07r-.js} +1 -1
- package/client/dist/assets/{setup-B590KsTX.js → setup-BiduSX9d.js} +1 -1
- package/client/dist/assets/{setup-cnqZsQSX2.js → setup-BuQNKztt2.js} +1 -1
- package/client/dist/assets/{setup-CEj6uY3-2.js → setup-BwMovM9z2.js} +1 -1
- package/client/dist/assets/{setup-BkyGoby6.js → setup-D84y3wx-.js} +1 -1
- package/client/dist/assets/{setup-CbIerFGf2.js → setup-DU0ULX8q2.js} +1 -1
- package/client/dist/assets/{setup-VNqXyB6Y.js → setup-RiUHzq7E.js} +1 -1
- package/client/dist/assets/{upload-49vX83IZ.js → upload-xdQuJvXN.js} +1 -1
- package/client/dist/assets/{value-Bo8EiTZE.js → value-Bk2f9AUg.js} +1 -1
- package/client/dist/index.html +21 -8
- package/package.json +1 -1
- package/server/dist/agent-operator-prompt.js +45 -5
- package/server/dist/desktop-router.js +9 -2
- package/server/dist/mcp/guide.js +33 -4
- package/server/dist/mcp/tools/app-settings.js +18 -2
- package/server/dist/mcp/tools/catalog.js +2 -0
- package/server/dist/mcp/tools/rails.js +25 -6
- package/server/dist/mcp/tools/support.js +324 -0
- package/server/dist/rail-isolated-launch.js +5 -1
- package/server/dist/rails-router.js +56 -7
- package/client/dist/assets/agent-Bn6ZmjHj.js +0 -1
- package/client/dist/assets/dashboard-CuGuy2__2.js +0 -1
- package/client/dist/assets/dashboard-CxP3TZ3I2.js +0 -1
- package/client/dist/assets/dashboard-DWHVfP7U.js +0 -1
- package/client/dist/assets/dashboard-D_Pgs6QH2.js +0 -1
- package/client/dist/assets/dashboard-Dwnssayh.js +0 -1
- package/client/dist/assets/dashboard-S_pT1yxN.js +0 -1
- package/client/dist/assets/dashboard-tCxOFOxx.js +0 -1
- package/client/dist/assets/dashboard-zefbBNyG.js +0 -1
- package/client/dist/assets/index-DnkfABxY.js +0 -156
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.supportTools = supportTools;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const mcp_tiers_1 = require("../mcp-tiers");
|
|
6
|
+
const types_1 = require("./types");
|
|
7
|
+
const projects_1 = require("./projects");
|
|
8
|
+
const SUPPORT_TOPICS = [
|
|
9
|
+
'installation',
|
|
10
|
+
'project_setup',
|
|
11
|
+
'provider_cli',
|
|
12
|
+
'mcp_connection',
|
|
13
|
+
'agent_chat',
|
|
14
|
+
'framework_install',
|
|
15
|
+
'specs_backlog',
|
|
16
|
+
'rails_jobs',
|
|
17
|
+
'git_pr',
|
|
18
|
+
'analytics_costs',
|
|
19
|
+
'plugins_integrations',
|
|
20
|
+
'general_usage',
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Support triage and repair entry point. This is intentionally NOT a spec
|
|
24
|
+
* creation path: it keeps user-help requests in the conversation and routes
|
|
25
|
+
* framework repairs through explicit support actions.
|
|
26
|
+
*/
|
|
27
|
+
function supportTools() {
|
|
28
|
+
return [
|
|
29
|
+
{
|
|
30
|
+
name: 'specrails_support',
|
|
31
|
+
title: 'Support & troubleshooting',
|
|
32
|
+
description: 'Support and troubleshooting for Specrails installation and usage problems. Use this when the user needs help setting up Specrails, adding/provisioning a project, fixing missing agents/skills/commands from the global specrails-core framework, provider CLI/MCP/agent-chat issues, rails/jobs/specs, or GitHub/PR/cost/plugin questions. ' +
|
|
33
|
+
'Actions: triage (read-only support playbook + diagnostics), core_update_status/check/apply (global specrails-core framework update). ' +
|
|
34
|
+
'This tool never creates specs; repair actions require the normal permission tier and explicit user confirmation.',
|
|
35
|
+
tier: (a) => (String(a.action) === 'core_update_apply' ? 'ai-spawn' : 'read'),
|
|
36
|
+
hintTier: 'read',
|
|
37
|
+
inputSchema: {
|
|
38
|
+
action: zod_1.z
|
|
39
|
+
.enum([
|
|
40
|
+
'triage',
|
|
41
|
+
'core_update_status',
|
|
42
|
+
'core_update_check',
|
|
43
|
+
'core_update_apply',
|
|
44
|
+
])
|
|
45
|
+
.describe('Support operation to perform'),
|
|
46
|
+
question: zod_1.z
|
|
47
|
+
.string()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('The user-facing problem or question to triage, in the user wording when possible'),
|
|
50
|
+
topic: zod_1.z
|
|
51
|
+
.enum(SUPPORT_TOPICS)
|
|
52
|
+
.optional()
|
|
53
|
+
.describe('Optional explicit support topic; omit to infer from question'),
|
|
54
|
+
projectId: zod_1.z
|
|
55
|
+
.string()
|
|
56
|
+
.optional()
|
|
57
|
+
.describe('Optional project id when the issue is project-specific; defaults to the active project when selected'),
|
|
58
|
+
version: zod_1.z
|
|
59
|
+
.string()
|
|
60
|
+
.optional()
|
|
61
|
+
.describe('core_update_apply: optional target specrails-core version; omit to use the latest version found by core_update_check'),
|
|
62
|
+
includeDiagnostics: zod_1.z
|
|
63
|
+
.boolean()
|
|
64
|
+
.optional()
|
|
65
|
+
.describe('When true or omitted, include read-only local diagnostics such as prerequisites, providers, settings, and projects. Project setup checkpoints are skipped for specrails-core installation triage because they are not a core health signal.'),
|
|
66
|
+
},
|
|
67
|
+
async handler(ctx, args) {
|
|
68
|
+
const action = String(args.action);
|
|
69
|
+
switch (action) {
|
|
70
|
+
case 'core_update_status':
|
|
71
|
+
return (0, types_1.apiCall)(ctx, 'GET', '/core-update/status');
|
|
72
|
+
case 'core_update_check':
|
|
73
|
+
return (0, types_1.apiCall)(ctx, 'POST', '/core-update/check', {});
|
|
74
|
+
case 'core_update_apply': {
|
|
75
|
+
const body = typeof args.version === 'string' && args.version.trim()
|
|
76
|
+
? { version: args.version.trim() }
|
|
77
|
+
: {};
|
|
78
|
+
const r = await (0, types_1.apiCall)(ctx, 'POST', '/core-update/update', body);
|
|
79
|
+
return {
|
|
80
|
+
...(typeof r === 'object' && r !== null ? r : { result: r }),
|
|
81
|
+
hint: 'Core update is async and app-global. Progress streams as core_update.progress / framework.updated. This updates the global specrails-core framework; it is not a per-project setup/install action.',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
case 'triage':
|
|
85
|
+
break;
|
|
86
|
+
default:
|
|
87
|
+
throw new Error(`Unknown action "${action}".`);
|
|
88
|
+
}
|
|
89
|
+
const question = typeof args.question === 'string' ? args.question.trim() : '';
|
|
90
|
+
const topic = isSupportTopic(args.topic) ? args.topic : inferTopic(question);
|
|
91
|
+
const includeDiagnostics = args.includeDiagnostics !== false;
|
|
92
|
+
const diagnostics = includeDiagnostics
|
|
93
|
+
? await collectDiagnostics(ctx, args.projectId, topic)
|
|
94
|
+
: { skipped: true };
|
|
95
|
+
return {
|
|
96
|
+
mode: 'support-triage',
|
|
97
|
+
doNotCreateSpec: true,
|
|
98
|
+
topic,
|
|
99
|
+
question: question || null,
|
|
100
|
+
supportPrompt: [
|
|
101
|
+
'Treat this as a help/support conversation, not product backlog intake.',
|
|
102
|
+
'Answer in the user language and solve the immediate setup or usage problem with concrete steps.',
|
|
103
|
+
'Do not create or propose a spec unless the user explicitly pivots from troubleshooting to new product work.',
|
|
104
|
+
'Prefer read-only diagnostics first. Ask at most two targeted questions if the next step depends on missing local context.',
|
|
105
|
+
'If a fix requires write, ai-spawn, or destructive permissions, explain the exact action and ask for confirmation before calling another tool.',
|
|
106
|
+
'For missing agents, skills, slash commands, or specrails-core framework files during a job, explain that these definitions live in the app-global specrails-core framework. Do not use project setup checkpoints as evidence of core health or as a reason to run project setup.',
|
|
107
|
+
],
|
|
108
|
+
localDiagnostics: diagnostics,
|
|
109
|
+
recommendedNextSteps: nextSteps(topic),
|
|
110
|
+
suggestedReadTools: suggestedTools(topic),
|
|
111
|
+
availableRepairActions: repairActions(topic),
|
|
112
|
+
responseChecklist: [
|
|
113
|
+
'State what the diagnostics show, including any unknowns or failed probes.',
|
|
114
|
+
'Give the smallest next action the user can take in the app or terminal.',
|
|
115
|
+
'Name the exact Specrails surface when relevant: Add Project, Setup, Settings > MCP, Agent Chat, Rails board, Job Detail, Analytics, Integrations.',
|
|
116
|
+
'If the issue is already resolved by state, say so and explain how to verify it.',
|
|
117
|
+
],
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
function isSupportTopic(value) {
|
|
124
|
+
return typeof value === 'string' && SUPPORT_TOPICS.includes(value);
|
|
125
|
+
}
|
|
126
|
+
function inferTopic(question) {
|
|
127
|
+
const q = question.toLowerCase();
|
|
128
|
+
if (/\b(mcp|claude desktop|cursor|external ai|token|settings.*mcp)\b/.test(q))
|
|
129
|
+
return 'mcp_connection';
|
|
130
|
+
if (/\b(agent chat|chat panel|shift\+tab|permission level|observe|operate|autonomous)\b/.test(q))
|
|
131
|
+
return 'agent_chat';
|
|
132
|
+
if (/\b(specrails-core|core framework|missing agents?|missing skills?|no agents?|no skills?|slash command|command not found|propose-feature|opsx|framework files?|reinstall)\b/.test(q))
|
|
133
|
+
return 'framework_install';
|
|
134
|
+
if (/\b(claude|codex|gemini|provider|engine|cli|auth|login|api key|path)\b/.test(q))
|
|
135
|
+
return 'provider_cli';
|
|
136
|
+
if (/\b(add project|project setup|setup wizard|provision|checkpoint|install config)\b/.test(q))
|
|
137
|
+
return 'project_setup';
|
|
138
|
+
if (/\b(install|installation|setup|prerequisite|node|npm|npx|git)\b/.test(q))
|
|
139
|
+
return 'installation';
|
|
140
|
+
if (/\b(rail|job|launch|run|queue|stuck|failed|logs?)\b/.test(q))
|
|
141
|
+
return 'rails_jobs';
|
|
142
|
+
if (/\b(github|git|pr|pull request|remote|branch|merge|integrate locally)\b/.test(q))
|
|
143
|
+
return 'git_pr';
|
|
144
|
+
if (/\b(cost|spend|budget|analytics|tokens?)\b/.test(q))
|
|
145
|
+
return 'analytics_costs';
|
|
146
|
+
if (/\b(plugin|integration|serena|marketplace)\b/.test(q))
|
|
147
|
+
return 'plugins_integrations';
|
|
148
|
+
if (/\b(spec|ticket|backlog|draft|todo|done|review)\b/.test(q))
|
|
149
|
+
return 'specs_backlog';
|
|
150
|
+
return 'general_usage';
|
|
151
|
+
}
|
|
152
|
+
async function collectDiagnostics(ctx, projectId, topic) {
|
|
153
|
+
const projects = ctx.registry.listContexts().map((c) => (0, projects_1.serializeProject)(c.project));
|
|
154
|
+
const selectedProjectId = projectId ?? (0, types_1.getActiveProject)(ctx) ?? undefined;
|
|
155
|
+
const out = {
|
|
156
|
+
mcp: {
|
|
157
|
+
enabled: (0, mcp_tiers_1.isMcpEnabled)(ctx.desktopDb),
|
|
158
|
+
tierWrite: (0, mcp_tiers_1.isTierEnabled)(ctx.desktopDb, 'write'),
|
|
159
|
+
tierAiSpawn: (0, mcp_tiers_1.isTierEnabled)(ctx.desktopDb, 'ai-spawn'),
|
|
160
|
+
tierDestructive: (0, mcp_tiers_1.isTierEnabled)(ctx.desktopDb, 'destructive'),
|
|
161
|
+
},
|
|
162
|
+
activeProjectId: (0, types_1.getActiveProject)(ctx),
|
|
163
|
+
projectCount: projects.length,
|
|
164
|
+
projects,
|
|
165
|
+
prerequisites: await safeDiagnostic(() => (0, types_1.apiCall)(ctx, 'GET', '/setup-prerequisites?diagnostic=1')),
|
|
166
|
+
availableProviders: await safeDiagnostic(() => (0, types_1.apiCall)(ctx, 'GET', '/available-providers')),
|
|
167
|
+
coreUpdate: await safeDiagnostic(() => (0, types_1.apiCall)(ctx, 'GET', '/core-update/status')),
|
|
168
|
+
};
|
|
169
|
+
if (!selectedProjectId) {
|
|
170
|
+
out.project = {
|
|
171
|
+
ok: false,
|
|
172
|
+
error: 'No active project or projectId was provided. Project-specific diagnostics need specrails_select_project or projectId.',
|
|
173
|
+
};
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
176
|
+
const project = safeLocal(() => (0, projects_1.serializeProject)((0, types_1.requireProject)(ctx, selectedProjectId).project));
|
|
177
|
+
out.project = project;
|
|
178
|
+
if (project.ok && topic !== 'framework_install') {
|
|
179
|
+
out.setupCheckpoints = await safeDiagnostic(() => (0, types_1.apiCall)(ctx, 'GET', `/projects/${selectedProjectId}/setup/checkpoints`));
|
|
180
|
+
}
|
|
181
|
+
else if (topic === 'framework_install') {
|
|
182
|
+
out.setupCheckpoints = {
|
|
183
|
+
skipped: true,
|
|
184
|
+
reason: 'Skipped intentionally: project setup checkpoints are not a specrails-core health check. Pending checkpoints or 0 agent/command counts must not be used to diagnose global core installation.',
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
async function safeDiagnostic(fn) {
|
|
190
|
+
try {
|
|
191
|
+
return { ok: true, data: await fn() };
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function safeLocal(fn) {
|
|
198
|
+
try {
|
|
199
|
+
return { ok: true, data: fn() };
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function nextSteps(topic) {
|
|
206
|
+
switch (topic) {
|
|
207
|
+
case 'installation':
|
|
208
|
+
return [
|
|
209
|
+
'Read prerequisites and availableProviders from localDiagnostics.',
|
|
210
|
+
'If Node/npm/npx/git are missing, tell the user to install them, restart Specrails, then recheck.',
|
|
211
|
+
'If a provider CLI is missing, install and authenticate that CLI before retrying project setup.',
|
|
212
|
+
];
|
|
213
|
+
case 'project_setup':
|
|
214
|
+
return [
|
|
215
|
+
'Check whether the project is registered and whether setupCheckpoints.isInstalling is still true.',
|
|
216
|
+
'If setup is running, tell the user to wait or poll checkpoints; if failed, surface the last log lines and retry only the failed setup step.',
|
|
217
|
+
'If no project is selected, ask for the repo path and provider choices before using specrails_setup.',
|
|
218
|
+
];
|
|
219
|
+
case 'provider_cli':
|
|
220
|
+
return [
|
|
221
|
+
'Compare availableProviders with the providers installed on the project.',
|
|
222
|
+
'Ask the user to verify the provider CLI in a fresh terminal only when the local probe is missing or ambiguous.',
|
|
223
|
+
'For auth failures, direct them to the provider CLI login/API-key flow, then re-open or retry Specrails setup.',
|
|
224
|
+
];
|
|
225
|
+
case 'mcp_connection':
|
|
226
|
+
return [
|
|
227
|
+
'Check localDiagnostics.mcp.enabled and explain that external clients also need the Settings > MCP config and token.',
|
|
228
|
+
'If MCP is off, tell the user to enable it in Settings > MCP; do not try to mutate the MCP enable flag through this tool.',
|
|
229
|
+
'If a tier blocks an action, name the exact tier to enable in Settings > MCP.',
|
|
230
|
+
];
|
|
231
|
+
case 'agent_chat':
|
|
232
|
+
return [
|
|
233
|
+
'Explain the in-app permission ladder: observe, edit, operate, autonomous.',
|
|
234
|
+
'If a tool was refused, tell the user which level to switch to with Shift+Tab.',
|
|
235
|
+
'If Agent Chat cannot operate, check MCP enabled state and installed provider state first.',
|
|
236
|
+
];
|
|
237
|
+
case 'framework_install':
|
|
238
|
+
return [
|
|
239
|
+
'For specrails-core installation questions, evaluate only global core status and prerequisites. Do not treat project setup checkpoints as evidence of a core problem.',
|
|
240
|
+
'If global core status is current/healthy and the user has not provided an actual job error, say the core installation looks healthy and ask for the concrete failing job/error before recommending repair.',
|
|
241
|
+
'If a job explicitly reports missing agents, missing skills, unresolved slash commands, or missing /specrails:* commands, explain that those definitions come from the app-global specrails-core framework.',
|
|
242
|
+
'If an update is available, offer core_update_check followed by core_update_apply with confirmation. If no update is available but the job still fails with missing core definitions, give the manual fallback: run `npx specrails-core@latest update` from the project root, then retry, or collect the job diagnostic for a framework-loading bug.',
|
|
243
|
+
'Never recommend specrails_setup(install) or a project reinstall solely because setup/checkpoints show pending or 0 agents/commands.',
|
|
244
|
+
];
|
|
245
|
+
case 'rails_jobs':
|
|
246
|
+
return [
|
|
247
|
+
'Use read tools for rails/jobs status before guessing: specrails_rails, specrails_jobs, and specrails_watch only when the user asks to wait.',
|
|
248
|
+
'For a failed or stuck job, inspect the Job Detail logs and report the real failure.',
|
|
249
|
+
'Do not relaunch or stop anything without confirmation and the required permission level.',
|
|
250
|
+
];
|
|
251
|
+
case 'git_pr':
|
|
252
|
+
return [
|
|
253
|
+
'Use specrails_git read-only diagnostics for remote, status, branch, gh_auth, gh_repo, and PR questions.',
|
|
254
|
+
'Explain that PR creation/integration belongs to the rail PR-decision surface, not this support tool.',
|
|
255
|
+
'If there is no GitHub remote, explain local-only delivery and Integrate locally.',
|
|
256
|
+
];
|
|
257
|
+
case 'analytics_costs':
|
|
258
|
+
return [
|
|
259
|
+
'Use specrails_analytics(spending) for actual cost questions.',
|
|
260
|
+
'Distinguish app-wide budget settings from per-project analytics budget caps.',
|
|
261
|
+
'Prefix cost with ~ when the provider reports estimates.',
|
|
262
|
+
];
|
|
263
|
+
case 'plugins_integrations':
|
|
264
|
+
return [
|
|
265
|
+
'Use specrails_plugins read actions before suggesting install/uninstall.',
|
|
266
|
+
'For degraded plugins, report health details and avoid blocking rail launches.',
|
|
267
|
+
'Mutating plugin actions need explicit confirmation and the matching permission level.',
|
|
268
|
+
];
|
|
269
|
+
case 'specs_backlog':
|
|
270
|
+
return [
|
|
271
|
+
'Use specrails_specs list/get to explain current backlog state.',
|
|
272
|
+
'Only create or edit specs if the user asks for backlog work, not when they are asking how Specrails works.',
|
|
273
|
+
'Do not patch pipeline-managed statuses unless the user explicitly asks and understands the consequence.',
|
|
274
|
+
];
|
|
275
|
+
case 'general_usage':
|
|
276
|
+
return [
|
|
277
|
+
'Use specrails_guide and specrails_search to find the relevant domain.',
|
|
278
|
+
'Explain the UI path first, then offer to perform safe read/write actions from chat when appropriate.',
|
|
279
|
+
'Keep the answer short and operational; ask one targeted question if the requested surface is unclear.',
|
|
280
|
+
];
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function suggestedTools(topic) {
|
|
284
|
+
switch (topic) {
|
|
285
|
+
case 'installation':
|
|
286
|
+
return ['specrails_support', 'specrails_setup(prerequisites)', 'specrails_setup(available_providers)'];
|
|
287
|
+
case 'project_setup':
|
|
288
|
+
return ['specrails_projects(list|get)', 'specrails_setup(checkpoints)', 'specrails_setup(prerequisites)'];
|
|
289
|
+
case 'provider_cli':
|
|
290
|
+
return ['specrails_setup(available_providers)', 'specrails_setup(prerequisites)', 'specrails_projects(get)'];
|
|
291
|
+
case 'mcp_connection':
|
|
292
|
+
return ['specrails_settings(get)', 'specrails_guide', 'specrails_describe'];
|
|
293
|
+
case 'agent_chat':
|
|
294
|
+
return ['specrails_settings(get)', 'specrails_projects(list|get)', 'specrails_guide'];
|
|
295
|
+
case 'framework_install':
|
|
296
|
+
return ['specrails_support(triage|core_update_status|core_update_check)', 'specrails_jobs(get)', 'specrails_jobs(diagnostic)'];
|
|
297
|
+
case 'rails_jobs':
|
|
298
|
+
return ['specrails_rails', 'specrails_jobs', 'specrails_watch'];
|
|
299
|
+
case 'git_pr':
|
|
300
|
+
return ['specrails_git(remote|status|branch|gh_auth|gh_repo|gh_pr_list|gh_pr_view)'];
|
|
301
|
+
case 'analytics_costs':
|
|
302
|
+
return ['specrails_analytics(spending)', 'specrails_settings(get)'];
|
|
303
|
+
case 'plugins_integrations':
|
|
304
|
+
return ['specrails_plugins(list|health|preview)', 'specrails_projects(get)'];
|
|
305
|
+
case 'specs_backlog':
|
|
306
|
+
return ['specrails_specs(list|get)', 'specrails_guide'];
|
|
307
|
+
case 'general_usage':
|
|
308
|
+
return ['specrails_guide', 'specrails_search', 'specrails_describe'];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
function repairActions(topic) {
|
|
312
|
+
if (topic === 'framework_install') {
|
|
313
|
+
return [
|
|
314
|
+
'specrails_support(core_update_check) then specrails_support(core_update_apply) - apply requires operate/ai-spawn and only makes sense when a newer global specrails-core framework is available.',
|
|
315
|
+
'Manual fallback when no update is available but a real job still cannot load core definitions: run `npx specrails-core@latest update` from the project root, then retry or collect a job diagnostic.',
|
|
316
|
+
];
|
|
317
|
+
}
|
|
318
|
+
if (topic !== 'project_setup' && topic !== 'installation')
|
|
319
|
+
return [];
|
|
320
|
+
return [
|
|
321
|
+
'specrails_setup(install, projectId) - operate/ai-spawn: use only for actual project setup/provisioning, not for specrails-core global installation questions.',
|
|
322
|
+
'specrails_support(core_update_check) then specrails_support(core_update_apply) - apply requires operate/ai-spawn: updates the app-global specrails-core framework when a newer version is available.',
|
|
323
|
+
];
|
|
324
|
+
}
|
|
@@ -301,6 +301,7 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
301
301
|
originSurface: input.originSurface ?? 'dashboard',
|
|
302
302
|
originConversationId: input.originConversationId ?? null,
|
|
303
303
|
}).id;
|
|
304
|
+
input.onPrDeliveryCreated?.(prDeliveryId);
|
|
304
305
|
if (launchContinuation) {
|
|
305
306
|
(0, rail_pr_store_1.transitionDecision)(ctx.db, prDeliveryId, 'building', 'building', {
|
|
306
307
|
branch: launchContinuation.branch,
|
|
@@ -393,7 +394,10 @@ async function launchIsolatedRail(input, io = {}) {
|
|
|
393
394
|
}
|
|
394
395
|
// Close the just-inserted decision row (kept as 'discarded' for audit, never
|
|
395
396
|
// deleted) so a wedged 'building' row can never block relaunching the slot.
|
|
396
|
-
|
|
397
|
+
// Router-driven PR continuations may intentionally fall back to shared-cwd
|
|
398
|
+
// on the same PR branch; in that case the router preserves and updates the
|
|
399
|
+
// row as the live iteration card instead of showing a false discard.
|
|
400
|
+
if (!input.preservePrDeliveryOnAllocationFailure && prDeliveryId && (0, rail_pr_store_1.transitionDecision)(ctx.db, prDeliveryId, 'building', 'discarded')) {
|
|
397
401
|
broadcastPrState();
|
|
398
402
|
syncOriginCard('update');
|
|
399
403
|
}
|
|
@@ -25,6 +25,7 @@ const rail_isolated_launch_1 = require("./rail-isolated-launch");
|
|
|
25
25
|
const worktree_manager_1 = require("./worktree-manager");
|
|
26
26
|
const pr_publisher_1 = require("./pr-publisher");
|
|
27
27
|
const ids_1 = require("./ids");
|
|
28
|
+
const agent_chat_registry_1 = require("./agent-chat-registry");
|
|
28
29
|
const VALID_MODES = new Set(['implement', 'batch-implement', 'freestyle', 'loop']);
|
|
29
30
|
// Models the freestyle picker exposes (Claude aliases). Mirrors the client
|
|
30
31
|
// RailModelSelector options and the project-router orchestrator-model allow-list.
|
|
@@ -32,6 +33,24 @@ const VALID_FREESTYLE_MODELS = new Set(['haiku', 'sonnet', 'opus', 'fable']);
|
|
|
32
33
|
// Reasoning-effort tiers a loop launch may request (mirrors the client selector
|
|
33
34
|
// + the provider adapters' supported values).
|
|
34
35
|
const VALID_REASONING_EFFORTS = new Set(['low', 'medium', 'high']);
|
|
36
|
+
function prDeliveryContinuesTickets(delivery, ticketIds) {
|
|
37
|
+
if (delivery.decision !== 'pr_draft' && delivery.decision !== 'pr_ready')
|
|
38
|
+
return false;
|
|
39
|
+
if (!delivery.prUrl || !delivery.branch)
|
|
40
|
+
return false;
|
|
41
|
+
const covered = new Set(delivery.ticketIds);
|
|
42
|
+
return ticketIds.length > 0 && ticketIds.every((id) => covered.has(id));
|
|
43
|
+
}
|
|
44
|
+
function emitPrDeliveryUpdate(c, prDeliveryId) {
|
|
45
|
+
const row = (0, rail_pr_store_1.getPrDelivery)(c.db, prDeliveryId);
|
|
46
|
+
if (!row)
|
|
47
|
+
return;
|
|
48
|
+
const snap = (0, rail_pr_store_1.toPrDeliverySnapshot)(row);
|
|
49
|
+
c.broadcast((0, rail_pr_store_1.toRailPrStateMessage)(c.project.id, snap));
|
|
50
|
+
if (row.origin_conversation_id) {
|
|
51
|
+
(0, agent_chat_registry_1.getAgentChatManager)()?.updatePrDecisionCard(row.origin_conversation_id, (0, rail_pr_store_1.toPrDecisionCardEnvelope)(c.project.id, snap));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
35
54
|
function createRailsRouter() {
|
|
36
55
|
const router = (0, express_1.Router)({ mergeParams: true });
|
|
37
56
|
function ctx(req) {
|
|
@@ -516,21 +535,26 @@ function createRailsRouter() {
|
|
|
516
535
|
// client so a silent fallback (no delivery row → no implementation
|
|
517
536
|
// cards) is diagnosable from the UI, not just the server log.
|
|
518
537
|
let isolationUnavailableDetail;
|
|
538
|
+
let continuablePrDeliveryForFallback = null;
|
|
539
|
+
let fallbackPrDeliveryId = null;
|
|
519
540
|
// Read-only vs mutating is DERIVED from the loop's nodes (see loop-effect),
|
|
520
541
|
// not a user flag — a content-read-only loop (no ai-step/shell) never writes,
|
|
521
542
|
// so it is not isolated; anything that can write is.
|
|
522
543
|
const loopReadOnly = (0, loop_effect_1.classifyLoopEffect)(loopGraph) === 'read-only';
|
|
523
544
|
if ((0, rail_isolation_1.isolationApplies)({ loopsEnabled: (0, feature_flags_1.isLoopsEnabled)(), scope, ticketCount: rail.ticketIds.length, readOnly: loopReadOnly })) {
|
|
524
|
-
// Relaunch collision (ask-first PR delivery): a
|
|
525
|
-
//
|
|
526
|
-
//
|
|
527
|
-
//
|
|
545
|
+
// Relaunch collision (ask-first PR delivery): a delivery that has not
|
|
546
|
+
// produced a real PR yet still needs a user decision before more work
|
|
547
|
+
// can safely append to its branches. Once a draft/published PR exists
|
|
548
|
+
// and covers this rail's tickets, relaunch is intentional continuation
|
|
549
|
+
// of that PR head branch (resolved inside launchIsolatedRail).
|
|
528
550
|
if ((0, rail_isolation_1.isRailPrDeliveryEnabled)()) {
|
|
529
551
|
const pending = (0, rail_pr_store_1.getActivePrDeliveryByRail)(c.db, railIndex);
|
|
530
|
-
|
|
531
|
-
|
|
552
|
+
const pendingSnapshot = pending ? (0, rail_pr_store_1.toPrDeliverySnapshot)(pending) : null;
|
|
553
|
+
if (pendingSnapshot && !prDeliveryContinuesTickets(pendingSnapshot, rail.ticketIds)) {
|
|
554
|
+
res.status(409).json({ error: 'pr_decision_pending', prDeliveryId: pendingSnapshot.id });
|
|
532
555
|
return;
|
|
533
556
|
}
|
|
557
|
+
continuablePrDeliveryForFallback = pendingSnapshot;
|
|
534
558
|
}
|
|
535
559
|
// Worktree isolation needs a git repo WITH at least one commit (an
|
|
536
560
|
// unborn HEAD can't be branched). Fall back (with a message) otherwise.
|
|
@@ -546,6 +570,8 @@ function createRailsRouter() {
|
|
|
546
570
|
provider: loopProvider, model: loopModel, effort, scope,
|
|
547
571
|
originSurface: originSurface ?? 'dashboard',
|
|
548
572
|
originConversationId: originConversationId ?? null,
|
|
573
|
+
preservePrDeliveryOnAllocationFailure: Boolean(continuablePrDeliveryForFallback),
|
|
574
|
+
onPrDeliveryCreated: (id) => { fallbackPrDeliveryId = id; },
|
|
549
575
|
});
|
|
550
576
|
res.status(202).json({ loopRunIds: ids, railIndex, mode, isolated: true });
|
|
551
577
|
return;
|
|
@@ -562,6 +588,7 @@ function createRailsRouter() {
|
|
|
562
588
|
// via SPECRAILS_REPO_DIR + `--add-dir` exactly like QueueManager.
|
|
563
589
|
const loopExec = (0, workspace_resolution_1.resolveProjectExecution)({ slug: c.project.slug, path: c.project.path });
|
|
564
590
|
const loopRunIds = [];
|
|
591
|
+
const sharedRunSettles = [];
|
|
565
592
|
const launchLoopRun = (runId, ticketIds, spec) => {
|
|
566
593
|
c.railLoopRuns.set(runId, { railIndex, ticketIds });
|
|
567
594
|
// Code-Explorer provenance for shared-cwd loop runs (isolated runs
|
|
@@ -594,7 +621,7 @@ function createRailsRouter() {
|
|
|
594
621
|
broadcast: (msg) => c.broadcast(msg),
|
|
595
622
|
});
|
|
596
623
|
};
|
|
597
|
-
c.loopRunManager
|
|
624
|
+
const runPromise = c.loopRunManager
|
|
598
625
|
.run({
|
|
599
626
|
runId,
|
|
600
627
|
loopId,
|
|
@@ -614,12 +641,15 @@ function createRailsRouter() {
|
|
|
614
641
|
.then((r) => {
|
|
615
642
|
recordRunProvenance();
|
|
616
643
|
c.onLoopRunFinished(r.runId, r.outcome);
|
|
644
|
+
return r.outcome === 'success';
|
|
617
645
|
})
|
|
618
646
|
.catch((err) => {
|
|
619
647
|
console.error('[rails-router] loop run failed:', err);
|
|
620
648
|
recordRunProvenance();
|
|
621
649
|
c.onLoopRunFinished(runId, 'failed');
|
|
650
|
+
return false;
|
|
622
651
|
});
|
|
652
|
+
sharedRunSettles.push(runPromise);
|
|
623
653
|
loopRunIds.push(runId);
|
|
624
654
|
try {
|
|
625
655
|
c.jiraSyncManager.onRailLaunch(ticketIds, runId);
|
|
@@ -637,6 +667,25 @@ function createRailsRouter() {
|
|
|
637
667
|
launchLoopRun((0, ids_1.newId)(), [ticketId], c.getTicketSpec(ticketId));
|
|
638
668
|
}
|
|
639
669
|
}
|
|
670
|
+
if (fallbackPrDeliveryId) {
|
|
671
|
+
const row = (0, rail_pr_store_1.getPrDelivery)(c.db, fallbackPrDeliveryId);
|
|
672
|
+
const isExistingPrIteration = row?.decision === 'building' && row.pr_state === 'pr-created' && Boolean(row.pr_url && row.branch);
|
|
673
|
+
if (isExistingPrIteration) {
|
|
674
|
+
if ((0, rail_pr_store_1.transitionDecision)(c.db, fallbackPrDeliveryId, 'building', 'building', { runIds: loopRunIds })) {
|
|
675
|
+
emitPrDeliveryUpdate(c, fallbackPrDeliveryId);
|
|
676
|
+
}
|
|
677
|
+
void Promise.allSettled(sharedRunSettles).then(() => {
|
|
678
|
+
const current = (0, rail_pr_store_1.getPrDelivery)(c.db, fallbackPrDeliveryId);
|
|
679
|
+
if (current?.decision !== 'building')
|
|
680
|
+
return;
|
|
681
|
+
if (current.pr_state === 'pr-created' && current.pr_url && current.branch) {
|
|
682
|
+
if ((0, rail_pr_store_1.transitionDecision)(c.db, fallbackPrDeliveryId, 'building', 'pr_ready')) {
|
|
683
|
+
emitPrDeliveryUpdate(c, fallbackPrDeliveryId);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
}
|
|
640
689
|
res.status(202).json({
|
|
641
690
|
loopRunIds, railIndex, mode,
|
|
642
691
|
...(isolationUnavailable ? { isolationUnavailable } : {}),
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as ee}from"./chunk-BNv3lrIs.js";var te=ee({addFavoriteConversation:()=>W,approval:()=>T,attachFile:()=>V,chip:()=>M,close:()=>u,composerPlaceholder:()=>r,confirmDeleteConversation:()=>U,confirmShort:()=>K,connecting:()=>h,consultingCode:()=>g,copy:()=>o,default:()=>re,degraded:()=>k,deleteConversation:()=>H,effort:()=>J,emptyHint:()=>p,emptyTitle:()=>f,emptyTitleMatrix:()=>Y,error:()=>j,favoriteMissions:()=>R,git:()=>S,header:()=>$,history:()=>y,home:()=>L,imagesUnsupported:()=>q,maximize:()=>s,minimize:()=>l,mission:()=>D,model:()=>v,newAgent:()=>N,newConversation:()=>d,noProvider:()=>O,palette:()=>ne,prCard:()=>X,project:()=>E,provider:()=>C,queue:()=>b,queueEdit:()=>x,refs:()=>Q,removeFavoriteConversation:()=>G,restore:()=>c,search:()=>I,send:()=>i,size:()=>_,specDraft:()=>Z,stop:()=>a,subtitle:()=>t,switchToAgent:()=>P,switchToKanban:()=>F,thinking:()=>m,tier:()=>w,title:()=>e,toolCard:()=>A,trigger:()=>n,untitled:()=>z,workspace:()=>B}),e=`Mission Control`,t=`Operate Specrails by chatting`,n=`Mission Control`,r=`Ask the agent to do anything…`,i=`Send`,a=`Stop`,o=`Copy`,s=`Maximize`,c=`Restore`,l=`Minimize`,u=`Close`,d=`New mission`,f=`What's the mission?`,p=`Pick a project, then ask. The board updates live as the agent works.`,m=`Thinking…`,h=`Connecting…`,g=`Consulting the app…`,_={compact:`Compact`,comfortable:`Comfortable`,max:`Maximize`},v={label:`Model`},y={hint:`Browsing prompt history — type to edit, ↑↓ to navigate`},b={queued:`Queued`,send:`Send to queue`,sendHint:`The agent is still working — this message will queue and run next`,placeholder:`Add more while the agent works — it will queue…`},x={editing:`Editing queued message {{n}} of {{m}}`,hint:`↑↓ to navigate · Enter saves · Esc cancels`,save:`Save queued message`,cancel:`Cancel editing`,dispatched:`That queued message was already sent — your text is kept as a draft`,saveFailed:`Couldn't save the queued message`},S={branch:`Branch`,detached:`(detached)`,dirty:`Uncommitted changes`,switched:`Switched to {{branch}}`,switchFailed:`Couldn't switch branch`,lockedWhileWorking:`Branch locked while the agent works`,searchPlaceholder:`Search branches…`,noMatches:`No branches match`,worktrees:`Worktrees`,worktreePathCopied:`Worktree path copied`,copyWorktreePath:`Copy worktree path`},C={label:`Provider`,claude:`Claude`,codex:`Codex`,gemini:`Gemini`},w={cycleHint:`⇧⇥ to change`,observe:{name:`Observe`,desc:`Read only — nothing changes`},edit:{name:`Edit`,desc:`Create and edit (reversible)`},operate:{name:`Operate`,desc:`Launch AI — costs money`},autonomous:{name:`Autonomous`,desc:`Delete and kill — irreversible`},lockedTitle:`Needs a higher level`,lockedBody:`That action needs the "{{level}}" level. You're on "{{current}}".`,raiseHint:`⇧⇥ to raise the level, or ask another way.`},T={title:`Confirm action`,costAction:`{{action}} · ~{{cost}} · {{tier}}`,approve:`Approve`,cancel:`Cancel`,dontAskAgain:`Don't ask again this session`,approved:`Approved`,cancelled:`Cancelled`},E={home:`Home`,searchPlaceholder:`Talk to Specrails…`,recents:`Recents`,allProjects:`All projects`,searchAll:`Search across all projects`,addProject:`Add project…`,homeHint:`No project selected — operating across all projects.`,askCreateOrSearch:`No project is selected. Do you want to create a new project, or search across all projects?`},ne={remove:`Remove {{label}}`,addContextAction:`Add context or action`,filtering:`Filtering "{{query}}"`,keyboard:`↑↓ Enter Esc`,noMatches:`No matches`,noMatchesFor:`No matches for "{{query}}"`,mode:{reference:{title:`Reference`,hint:`@ projects, specs, missions`},trace:{title:`Trace`,hint:`# jobs, runs, IDs`},action:{title:`Action`,hint:`/ commands for this context`}},plus:{reference:`Reference`,referenceHint:`Projects, specs, missions`,trace:`Trace`,traceHint:`Jobs, runs, IDs`,action:`Action`,actionHint:`Create, launch, inspect`,fileAttachment:`File attachment`,fileAttachmentHint:`Add docs, images, logs`,browserCapture:`Browser capture`,browserCaptureHint:`Available from workspace browser`}},D={label:`Switch mission`,untitled:`New mission`,new:`New mission`,searchPlaceholder:`Search missions…`,noMatches:`No missions match`,working:`Agent working`,queuedBadge:`{{n}} queued`,delete:`Delete mission "{{title}}"`,deleteConfirm:`Delete?`,deleteLiveConfirm:`Agent is working — delete anyway?`,confirmDelete:`Confirm delete`,cancelDelete:`Keep mission`,deleteFailed:`Couldn't delete the mission`},O={title:`No AI provider installed`,body:`The agent needs Claude, Codex or Gemini on your machine. Install one, then reopen the agent to start chatting.`,placeholder:`Install an AI provider to use the agent…`},k={title:`Specrails MCP is off`,body:`The agent needs the embedded MCP server to operate the app.`,enable:`Enable Specrails MCP`,enabling:`Enabling…`,enabled:`MCP enabled`},A={live:`live`,queued:`queued`,running:`running`,done:`done`,failed:`failed`},j={generic:`Something went wrong. Try again.`,busy:`The agent is busy. Try again in a moment.`},M={kindAgent:`Agent mission`},N=`New Mission`,P=`Switch to Mission Control`,F=`Switch to Board`,I=`Search`,L=`Home`,R=`Favorite missions`,z=`Untitled`,B={title:`On workspace`,terminal:`Terminal`,files:`Files`,browser:`Browser`,requiresProject:`Select a project to use this tool`,resizeCode:`Resize code pane`,closeFiles:`Close code`,browserConfirm:`Add to agent`,browserCaptured:`Capture added`,uploadFailed:`Upload failed`,requiresConversation:`Start a mission to use this tool`,jobs:`Jobs`,closeJobs:`Close jobs`,resizeJobs:`Resize jobs pane`,noJobs:`No jobs yet — ask the agent to launch one`},V=`Attach file`,H=`Delete "{{title}}"`,U=`Confirm delete "{{title}}"`,W=`Add "{{title}}" to favorites`,G=`Remove "{{title}}" from favorites`,K=`confirm?`,q=`This provider can't read images yet — attach text files instead`,J={label:`Effort`,minimal:`Minimal`,low:`Low`,medium:`Medium`,high:`High`,xhigh:`Extra high`},Y=`What's the mission, Neo?`,X={rail:`Rail {{index}}`,specCount_one:`{{count}} spec`,specCount_other:`{{count}} specs`,base:`Base branch`,openPr:`Open PR`,existingPr:`Existing PR`,title:{building:`Implementing in an isolated worktree…`,buildingExistingPr:`Applying changes to an existing PR…`,on_review:`Implementation ready for review`,pr_draft:`Draft PR created`,pr_draft_degraded:`PR delivery incomplete`,pr_ready:`PR ready for merge`,pr_failed:`PR creation failed`,merged:`PR merged`,discarded:`Discarded`},buildingHint:`You'll be asked to create the PR when it settles.`,buildingExistingPrHint:`Specrails is working on the existing PR branch and will push the review changes back to that PR.`,createPr:`Create PR`,publish:`Publish`,retry:`Retry`,retryPr:`Retry PR`,checkMerge:`Check merge`,discard:`Discard`,confirmDiscard:`Confirm discard?`,mergedNote:`Merged — specs moved to Done`,discardedNote:`Discarded — specs returned to the backlog`,degraded:{pushed:`The branch was pushed but the PR could not be created — retry to finish.`,localOnly:`The changes were assembled locally but not pushed — retry to publish the PR.`},alreadyResolved:`Already resolved elsewhere`,actionFailed:`Action failed`,notMergedYet:`Not merged yet`,viewLog:`View run log for {{ref}}`,runElapsedAria:`{{elapsed}} elapsed`,runCostAria:`{{cost}} spent`,pinned:{label:`Pinned`,marker:`Implementation card — pinned above`,collapse:`Minimize pinned card`,expand:`Expand pinned card`,expandCard:`Expand this card`,collapseCard:`Minimize this card`,collapsed_one:`Implementation card`,collapsed_other:`{{count}} implementation cards`,state:{building:`Building`,on_review:`Review`,pr_draft:`Draft PR`,pr_ready:`Published`,pr_failed:`Failed`,merged:`Merged`,discarded:`Discarded`}},mergeLocal:`Integrate locally`,mergeLocalTooltip:`Merge the delivered branches into {{base}} in your local checkout (no GitHub needed)`,mergeLocalBlockedDirty:`Cannot integrate: your working tree on {{base}} has uncommitted changes. Commit or stash them, then retry.`,mergeLocalBlockedBranch:`Cannot integrate: your checkout is on {{current}}, not {{base}}. Check out {{base}}, then retry.`,mergedLocally:`Integrated into {{base}} locally`},Z={heading:`Spec draft`,drafting:`Updating draft…`,acceptanceCriteria:`Acceptance criteria`,untitled:`Untitled spec`,expand:`Show full description`,collapse:`Collapse description`},Q={openTicket:`Open spec #{{id}}`,openPullRequest:`Open PR #{{id}}`,openJob:`Open job {{id}}`,openLoop:`Open loop {{id}}`,ticketNotFound:`Spec #{{id}} not found — it may have been deleted`,pullRequestUrlMissing:`PR #{{id}} was referenced without a URL`,pullRequestNotFound:`PR #{{id}} could not be found in this project`,jobNotFound:`Job not found — it may have been deleted`,loopNotFound:`Loop not found — it may have been deleted`,lookupFailed:`Couldn't verify the reference — try again`},$={untitled:`Untitled mission`,menu:`Mission menu`,rename:`Rename`,renamePlaceholder:`Mission name`,renameHint:`Double-click to rename`,renameFailed:`Could not rename`,addFavorite:`Add to favorites`,removeFavorite:`Remove from favorites`,copyName:`Copy mission name`,copyId:`Copy mission ID`,copyProject:`Copy project name`,copyProjectPath:`Copy project path`,copyFailed:`Couldn't copy`,delete:`Delete mission`,deleteConfirm:`Delete this mission? This cannot be undone.`,deleteFailed:`Could not delete the mission`},re={title:e,subtitle:t,trigger:n,composerPlaceholder:r,send:i,stop:a,copy:o,maximize:s,restore:c,minimize:l,close:u,newConversation:d,emptyTitle:f,emptyHint:p,thinking:m,connecting:h,consultingCode:g,size:_,model:v,history:y,queue:b,queueEdit:x,git:S,provider:C,tier:w,approval:T,project:E,palette:ne,mission:D,noProvider:O,degraded:k,toolCard:A,error:j,chip:M,newAgent:N,switchToAgent:P,switchToKanban:F,search:I,home:L,favoriteMissions:R,untitled:z,workspace:B,attachFile:V,deleteConversation:H,confirmDeleteConversation:U,addFavoriteConversation:W,removeFavoriteConversation:G,confirmShort:K,imagesUnsupported:q,effort:J,emptyTitleMatrix:Y,prCard:X,specDraft:Z,refs:Q,header:$};export{te as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e={railAdded:`已添加 Rail {{n}}`,railRemoved:`已移除 {{rail}}`,railLimitReached:`已达到 Rail 上限(最多 {{max}} 个)`,railDeleteFailed:`无法移除该 Rail — 它包含 Spec、正在运行或有待处理的 PR 决定`,launchTicketsInFlight:`该 Rail 上的某个 Spec 已在被一个活动运行处理`,launchAllSummary_one:`已并行启动 {{count}} 个 Rail`,launchAllSummary_other:`已并行启动 {{count}} 个 Rail`,launchAllNoneEligible:`没有可启动的 Rail — 请先将 Spec 分配到空闲的 Rail`,launchAllFailed:`没有任何 Rail 能够启动`,railCompleted:`Rail {{n}} 已完成`,railFailed:`Rail {{n}} 失败 — Spec 已退回 Specs`,railEnded:`Rail {{n}} {{status}} — Spec 已退回 Specs`,alreadyOnRail:`已在 {{rail}} 上`,movedToRail:`已移至 {{rail}}`,railRunningStopFirst:`{{rail}} 正在运行 — 请先停止再移除`,removedFromRail:`已从 {{rail}} 移除`,queuedOnRail:`已在 {{rail}} 排队`,queuedOnRailDescription:`Rail 正在运行`,railStopped:`{{rail}} 已停止`,stopFailed:`停止 Rail 失败`,syncTicketsFailed:`同步 Rail 工单失败`,launchFailed:`启动 Rail 失败`,launchNetworkError:`启动 Rail 时网络错误`,railLaunched:`{{rail}} 已启动`,launchDescription_one:`{{mode}},共 {{count}} 个 Spec`,launchDescription_other:`{{mode}},共 {{count}} 个 Spec`,railWorktreeNeedsReview:`Rail {{n}}:合并后 spec #{{ticket}} 需要复查`,railWorktreesNoGit:`worktree 隔离不可用:该项目不是 git 仓库 — 以共享模式运行。`,railWorktreesNoCommits:`worktree 隔离不可用:仓库还没有任何提交 — 先做一次初始提交再重新启动。`,railWorktreesError:`Worktree 隔离失败 — 此次运行将在没有 PR 审查流程的情况下继续(无实施卡片)。请查看下方错误详情。`,onReviewCannotMoveToRail:`该 Spec 正在等待 PR 评审 — 请先处理 PR 决定`,onReviewNotLaunchable:`该 Rail 上有 Spec 正在等待 PR 评审 — 请先处理 PR 决定再启动`},t={readyForReview:`评审就绪`,draftPr:`草稿 PR`,branchPushed:`分支已推送 — PR 待创建`,branchPushedHint:`分支已推送,但无法创建 PR(GitHub CLI 不可用)。请重试以创建。`,prReady:`PR 已就绪`,prFailed:`PR 失败`,prFailedDetail:`PR 失败:{{detail}}`,createDegraded:`无法发布 PR — {{detail}}。解决后请重试。`,createPr:`创建 PR`,createPrTooltip:`→ {{base}}`,publish:`发布`,publishTooltip:`将草稿 PR 开放给团队评审`,discard:`丢弃`,discardTooltip:`删除相关分支并将工单退回 Specs`,retryPr:`重试 PR`,retry:`重试`,checkMerge:`检查合并`,checkMergeTooltip:`向 GitHub 查询该 PR 是否已合并`,prLinkFallback:`PR`,openPrTitle:`在 GitHub 上打开该 PR`,notMergedYet:`尚未合并`,alreadyResolved:`已在其他地方处理`,ghFailed:`GitHub CLI 失败:{{detail}}`,actionFailed:`无法应用 PR 决定`,mergedToast:`PR 已合并 — 工单已移至完成`,discardedToast:`PR 已丢弃 — 工单已退回 Specs`,decisionPending:`该 Rail 有待处理的 PR 决定 — 请先创建、发布或丢弃,再重新启动`,discardConfirmTitle:`丢弃本次交付?`,discardConfirmBody:`将删除本次启动的分支和 worktree,其工单会退回 Specs。此操作无法撤销。`,mergeLocal:`本地集成`,mergeLocalTooltip:`将交付的分支合并到本地检出的 {{base}}(无需 GitHub)`,mergeLocalConfirmTitle:`本地集成?`,mergeLocalConfirmBody:`交付的分支将合并到本地检出的 {{base}}。你的检出必须位于 {{base}} 且工作树干净。`,mergeLocalBlockedDirty:`无法集成:{{base}} 上的工作树有未提交的更改。请提交或暂存后重试。`,mergeLocalBlockedBranch:`无法集成:当前检出在 {{current}},而不是 {{base}}。请切换到 {{base}} 后重试。`,mergeLocalFailed:`本地合并失败:{{detail}}`,mergedLocally:`已在本地集成到 {{base}}`},n={title:`Rails`,runningCount_one:`{{count}} 个运行中`,runningCount_other:`{{count}} 个运行中`,launchAll:`全部启动`,launchAllTitle:`并行启动所有就绪的 Rail — 每次运行都隔离在自己的 git worktree 中`},r={skipRunning_one:`{{count}} 个已在运行`,skipRunning_other:`{{count}} 个已在运行`,skipEmpty_one:`{{count}} 个没有 Spec`,skipEmpty_other:`{{count}} 个没有 Spec`,skipPendingDecision_one:`{{count}} 个等待 PR 决定`,skipPendingDecision_other:`{{count}} 个等待 PR 决定`,skipOnReview_one:`{{count}} 个包含审查中的 Spec`,skipOnReview_other:`{{count}} 个包含审查中的 Spec`,skipInFlight_one:`{{count}} 个已跳过(Spec 已在进行中)`,skipInFlight_other:`{{count}} 个已跳过(Spec 已在进行中)`,failedCount_one:`{{count}} 个失败`,failedCount_other:`{{count}} 个失败`},i={title:`启动所有 Rail`,railsCount_one:`{{count}} 个 Rail`,railsCount_other:`{{count}} 个 Rail`,specsCount_one:`{{count}} 个 Spec`,specsCount_other:`{{count}} 个 Spec`,isolationTitle:`并行且隔离。`,isolationBody:`每个 Rail 都在自己的 git worktree 中运行 — 同时启动永不冲突。`,pipelinesTitle_one:`{{count}} 条 AI 流水线。`,pipelinesTitle_other:`{{count}} 条 AI 流水线。`,pipelinesBody:`每个 Rail 启动一次,各自使用配置好的模式、引擎和 Profile。`,costTitle:`成本成倍增加。`,costBody:`每个 Rail 都会产生自己的 AI 运行 — 花费随 Rail 数量增长。`,launch_one:`启动 {{count}} 个 Rail`,launch_other:`启动 {{count}} 个 Rail`},a={viewJobLog:`查看任务日志`,log:`日志`,implement:`实现`,batch:`批量`,freestyle:`Freestyle`,freestyleTitle:`Freestyle — Claude 自主实现该 Spec,不走流水线`,loop:`Loop`,loopTitle:`Loop — 针对该轨道的 Spec 运行已发布的自动化循环`,pickLoop:`选择一个循环…`,effortTitle:`推理强度`,stop:`停止`,play:`运行`,failedRetry:`任务失败 — 点击重试`,addSpecsFirst:`请先向此 Rail 添加 Spec`,builtInLoops:`内置`,customLoops:`自定义循环`,worktreesMerged:`已合并 {{count}}`,worktreesNeedsReview:`{{count}} 需复查`,execSteps:`{{count}} 步`,execLines:`{{count}} 行`,openspec:`OpenSpec`},o={moveToSpecs:`移至 Specs`,deleteRail:`删除 {{label}}`,dropHere:`拖放到此处`,dropOnThisRail:`拖放到此 Rail`,dragSpecsHere:`将 Spec 拖到此处`},s={title:`以 Freestyle 模式启动`,context_one:`{{rail}} · {{count}} 个 Spec`,context_other:`{{rail}} · {{count}} 个 Spec`,noPipelineTitle:`无 OpenSpec 流水线。`,noPipelineBody:`完全跳过架构师 → 开发者 → 审查者的结构化流程。`,autonomyTitle:`Claude 原生自主模式。`,autonomyBody:`Claude 使用原生 Agent 和动态工作流自主工作。`,costTitle:`成本不固定。`,costBody:`花费取决于 Claude 的决策 — 可能高于预期。`,continue:`继续`},c={fetchFailed:`获取 Rails 失败:{{status}}`},l={toasts:e,railPr:t,railsBoard:n,launchAll:r,launchAllDialog:i,railControls:a,railRow:o,freestyleDialog:s,useRails:c};export{l as default,s as freestyleDialog,r as launchAll,i as launchAllDialog,a as railControls,t as railPr,o as railRow,n as railsBoard,e as toasts,c as useRails};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e={railAdded:`Rail {{n}} añadido`,railRemoved:`{{rail}} eliminado`,railLimitReached:`Límite de rails alcanzado ({{max}} máx.)`,railDeleteFailed:`No se pudo eliminar el rail — tiene specs, está en ejecución o tiene una decisión de PR pendiente`,launchTicketsInFlight:`Una spec de este rail ya está siendo trabajada por una ejecución activa`,launchAllSummary_one:`{{count}} rail lanzado en paralelo`,launchAllSummary_other:`{{count}} rails lanzados en paralelo`,launchAllNoneEligible:`No hay rails listos para lanzar — asigna specs a un rail libre primero`,launchAllFailed:`No se pudo lanzar ningún rail`,railCompleted:`Rail {{n}} completado`,railFailed:`Rail {{n}} fallido — las specs han vuelto a Specs`,railEnded:`Rail {{n}} {{status}} — las specs han vuelto a Specs`,alreadyOnRail:`Ya está en {{rail}}`,movedToRail:`Movida a {{rail}}`,railRunningStopFirst:`{{rail}} está en ejecución — detenlo antes de eliminarlo`,removedFromRail:`Quitada de {{rail}}`,queuedOnRail:`En cola en {{rail}}`,queuedOnRailDescription:`El rail está en ejecución`,railStopped:`{{rail}} detenido`,stopFailed:`No se pudo detener el rail`,syncTicketsFailed:`No se pudieron sincronizar los tickets del rail`,launchFailed:`No se pudo lanzar el rail`,launchNetworkError:`Error de red al lanzar el rail`,railLaunched:`{{rail}} lanzado`,launchDescription_one:`{{mode}} con {{count}} spec`,launchDescription_other:`{{mode}} con {{count}} specs`,railWorktreeNeedsReview:`Rail {{n}}: la spec #{{ticket}} necesita revisión tras el merge`,railWorktreesNoGit:`Aislamiento por worktrees no disponible: el proyecto no es un repositorio git — ejecutando en modo compartido.`,railWorktreesNoCommits:`Aislamiento por worktrees no disponible: el repositorio aún no tiene commits — haz un commit inicial y relanza.`,railWorktreesError:`La aislación por worktrees falló — este run continúa SIN el flujo de revisión por PR (sin tarjeta de implementación). Mira el detalle del error abajo.`,onReviewCannotMoveToRail:`Esta spec está pendiente de revisión de PR — resuelve primero la decisión de la PR`,onReviewNotLaunchable:`Una spec de este rail está pendiente de revisión de PR — resuelve la decisión de la PR antes de lanzar`},t={readyForReview:`Listo para revisión`,draftPr:`PR en borrador`,branchPushed:`Rama subida — PR pendiente`,branchPushedHint:`La rama se subió pero no se pudo crear la PR (GitHub CLI no disponible). Reintenta para crearla.`,prReady:`PR lista`,prFailed:`PR fallida`,prFailedDetail:`PR fallida: {{detail}}`,createDegraded:`No se pudo publicar la PR — {{detail}}. Reintenta cuando esté resuelto.`,createPr:`Crear PR`,createPrTooltip:`→ {{base}}`,publish:`Publicar`,publishTooltip:`Abre la PR en borrador para la revisión del equipo`,discard:`Descartar`,discardTooltip:`Elimina las ramas y devuelve los tickets a Specs`,retryPr:`Reintentar PR`,retry:`Reintentar`,checkMerge:`Comprobar merge`,checkMergeTooltip:`Consulta a GitHub si ya se ha hecho merge de la PR`,prLinkFallback:`PR`,openPrTitle:`Abrir la PR en GitHub`,notMergedYet:`Aún sin merge`,alreadyResolved:`Ya resuelta en otro sitio`,ghFailed:`GitHub CLI falló: {{detail}}`,actionFailed:`No se pudo aplicar la decisión de la PR`,mergedToast:`Merge de la PR completado — los tickets han pasado a Hecho`,discardedToast:`PR descartada — los tickets han vuelto a Specs`,decisionPending:`Este rail tiene una decisión de PR pendiente — créala, publícala o descártala antes de relanzar`,discardConfirmTitle:`¿Descartar esta entrega?`,discardConfirmBody:`Se eliminarán las ramas y worktrees del lanzamiento y sus tickets volverán a Specs. Esta acción no se puede deshacer.`,mergeLocal:`Integrar en local`,mergeLocalTooltip:`Fusiona las ramas entregadas en {{base}} en tu checkout local (sin necesidad de GitHub)`,mergeLocalConfirmTitle:`¿Integrar en local?`,mergeLocalConfirmBody:`Las ramas entregadas se fusionarán en {{base}} en tu checkout local. Tu checkout debe estar en {{base}} con el árbol de trabajo limpio.`,mergeLocalBlockedDirty:`No se puede integrar: tu árbol de trabajo en {{base}} tiene cambios sin commitear. Haz commit o stash y reintenta.`,mergeLocalBlockedBranch:`No se puede integrar: tu checkout está en {{current}}, no en {{base}}. Cambia a {{base}} y reintenta.`,mergeLocalFailed:`La fusión local falló: {{detail}}`,mergedLocally:`Integrado en {{base}} en local`},n={title:`Rails`,runningCount_one:`{{count}} en ejecución`,runningCount_other:`{{count}} en ejecución`,launchAll:`Lanzar todos`,launchAllTitle:`Lanza en paralelo todos los rails listos — cada ejecución se aísla en su propio worktree de git`},r={skipRunning_one:`{{count}} ya en ejecución`,skipRunning_other:`{{count}} ya en ejecución`,skipEmpty_one:`{{count}} sin specs`,skipEmpty_other:`{{count}} sin specs`,skipPendingDecision_one:`{{count}} con decisión de PR pendiente`,skipPendingDecision_other:`{{count}} con decisión de PR pendiente`,skipOnReview_one:`{{count}} con specs en revisión`,skipOnReview_other:`{{count}} con specs en revisión`,skipInFlight_one:`{{count}} omitido (spec ya en curso)`,skipInFlight_other:`{{count}} omitidos (specs ya en curso)`,failedCount_one:`{{count}} fallido`,failedCount_other:`{{count}} fallidos`},i={title:`Lanzar todos los rails`,railsCount_one:`{{count}} rail`,railsCount_other:`{{count}} rails`,specsCount_one:`{{count}} spec`,specsCount_other:`{{count}} specs`,isolationTitle:`Paralelo y aislado.`,isolationBody:`Cada rail se ejecuta en su propio worktree de git — los lanzamientos simultáneos nunca colisionan.`,pipelinesTitle_one:`{{count}} pipeline de IA.`,pipelinesTitle_other:`{{count}} pipelines de IA.`,pipelinesBody:`Un lanzamiento por rail, cada uno con su modo, motor y perfil configurados.`,costTitle:`Coste multiplicado.`,costBody:`Cada rail genera su propia ejecución de IA — el gasto escala con el número de rails.`,launch_one:`Lanzar {{count}} rail`,launch_other:`Lanzar {{count}} rails`},a={viewJobLog:`Ver log del job`,log:`Log`,implement:`Implement`,batch:`Batch`,freestyle:`Freestyle`,freestyleTitle:`Freestyle — Claude implementa la spec de forma autónoma, sin pipeline`,loop:`Loop`,loopTitle:`Loop — ejecuta un bucle de automatización publicado sobre las specs del rail`,pickLoop:`Elige un bucle…`,effortTitle:`Esfuerzo de razonamiento`,stop:`Detener`,play:`Iniciar`,failedRetry:`El job ha fallado — haz clic para reintentar`,addSpecsFirst:`Añade primero specs a este rail`,builtInLoops:`Integrados`,customLoops:`Loops personalizados`,worktreesMerged:`{{count}} fusionados`,worktreesNeedsReview:`{{count}} a revisar`,execSteps:`{{count}} pasos`,execLines:`{{count}} líneas`,openspec:`OpenSpec`},o={moveToSpecs:`Mover a Specs`,deleteRail:`Eliminar {{label}}`,dropHere:`Suelta aquí`,dropOnThisRail:`Suelta en este rail`,dragSpecsHere:`Arrastra specs aquí`},s={title:`Lanzar en modo Freestyle`,context_one:`{{rail}} · {{count}} spec`,context_other:`{{rail}} · {{count}} specs`,noPipelineTitle:`Sin pipeline de OpenSpec.`,noPipelineBody:`El flujo estructurado architect → developer → reviewer se omite por completo.`,autonomyTitle:`Autonomía nativa de Claude.`,autonomyBody:`Claude trabaja por su cuenta con agentes nativos y flujos dinámicos.`,costTitle:`Coste variable.`,costBody:`El gasto depende de lo que Claude decida hacer — puede ser mayor de lo esperado.`,continue:`Continuar`},c={fetchFailed:`No se pudieron obtener los rails: {{status}}`},l={toasts:e,railPr:t,railsBoard:n,launchAll:r,launchAllDialog:i,railControls:a,railRow:o,freestyleDialog:s,useRails:c};export{l as default,s as freestyleDialog,r as launchAll,i as launchAllDialog,a as railControls,t as railPr,o as railRow,n as railsBoard,e as toasts,c as useRails};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e={railAdded:`レール {{n}} を追加しました`,railRemoved:`{{rail}} を削除しました`,railLimitReached:`レールの上限に達しました(最大 {{max}})`,railDeleteFailed:`レールを削除できません — スペックを保持しているか、実行中か、PR の判断待ちです`,launchTicketsInFlight:`このレールのスペックは既にアクティブな実行で処理中です`,launchAllSummary_one:`{{count}} 件のレールを並列で起動しました`,launchAllSummary_other:`{{count}} 件のレールを並列で起動しました`,launchAllNoneEligible:`起動できるレールがありません — まず空きレールにスペックを割り当ててください`,launchAllFailed:`起動できたレールはありません`,railCompleted:`レール {{n}} が完了しました`,railFailed:`レール {{n}} が失敗しました — スペックは Specs に戻されました`,railEnded:`レール {{n}}: {{status}} — スペックは Specs に戻されました`,alreadyOnRail:`すでに {{rail}} にあります`,movedToRail:`{{rail}} に移動しました`,railRunningStopFirst:`{{rail}} は実行中です — 削除する前に停止してください`,removedFromRail:`{{rail}} から削除しました`,queuedOnRail:`{{rail}} のキューに追加しました`,queuedOnRailDescription:`レールは現在実行中です`,railStopped:`{{rail}} を停止しました`,stopFailed:`レールの停止に失敗しました`,syncTicketsFailed:`レールのチケット同期に失敗しました`,launchFailed:`レールの起動に失敗しました`,launchNetworkError:`レール起動中にネットワークエラーが発生しました`,railLaunched:`{{rail}} を起動しました`,launchDescription_one:`{{mode}} · スペック {{count}} 件`,launchDescription_other:`{{mode}} · スペック {{count}} 件`,railWorktreeNeedsReview:`Rail {{n}}:マージ後、spec #{{ticket}} は要確認です`,railWorktreesNoGit:`worktree 分離は利用できません:このプロジェクトは git リポジトリではありません — 共有モードで実行します。`,railWorktreesNoCommits:`worktree 分離は利用できません:リポジトリにまだコミットがありません — 初回コミットを作成してから再実行してください。`,railWorktreesError:`ワークツリー分離に失敗しました — この実行は PR レビューフローなし(実装カードなし)で続行されます。下のエラー詳細を確認してください。`,onReviewCannotMoveToRail:`このスペックは PR レビュー待ちです — まず PR の決定を処理してください`,onReviewNotLaunchable:`このレールのスペックが PR レビュー待ちです — 起動する前に PR の決定を処理してください`},t={readyForReview:`レビュー準備完了`,draftPr:`ドラフト PR`,branchPushed:`ブランチはプッシュ済み — PR は未作成`,branchPushedHint:`ブランチはプッシュされましたが、PR を作成できませんでした(GitHub CLI が利用できません)。再試行して作成してください。`,prReady:`PR 準備完了`,prFailed:`PR 失敗`,prFailedDetail:`PR 失敗: {{detail}}`,createDegraded:`PR を公開できませんでした — {{detail}}。解決後に再試行してください。`,createPr:`PR を作成`,createPrTooltip:`→ {{base}}`,publish:`公開`,publishTooltip:`ドラフト PR をチームのレビューに公開します`,discard:`破棄`,discardTooltip:`ブランチを削除し、チケットを Specs に戻します`,retryPr:`PR を再試行`,retry:`再試行`,checkMerge:`マージを確認`,checkMergeTooltip:`PR がマージ済みかどうかを GitHub に確認します`,prLinkFallback:`PR`,openPrTitle:`GitHub で PR を開く`,notMergedYet:`まだマージされていません`,alreadyResolved:`すでに他の場所で解決済み`,ghFailed:`GitHub CLI が失敗しました:{{detail}}`,actionFailed:`PR の決定を適用できませんでした`,mergedToast:`PR がマージされました — チケットは完了に移動しました`,discardedToast:`PR を破棄しました — チケットは Specs に戻されました`,decisionPending:`このレールには未処理の PR 決定があります — 再起動する前に作成・公開・破棄のいずれかを行ってください`,discardConfirmTitle:`この成果物を破棄しますか?`,discardConfirmBody:`この起動のブランチと worktree は削除され、チケットは Specs に戻ります。この操作は元に戻せません。`,mergeLocal:`ローカルに統合`,mergeLocalTooltip:`配信されたブランチをローカルチェックアウトの {{base}} にマージします(GitHub 不要)`,mergeLocalConfirmTitle:`ローカルに統合しますか?`,mergeLocalConfirmBody:`配信されたブランチがローカルチェックアウトの {{base}} にマージされます。チェックアウトは {{base}} でワークツリーがクリーンである必要があります。`,mergeLocalBlockedDirty:`統合できません:{{base}} のワークツリーに未コミットの変更があります。コミットまたはスタッシュして再試行してください。`,mergeLocalBlockedBranch:`統合できません:チェックアウトは {{current}} で、{{base}} ではありません。{{base}} に切り替えて再試行してください。`,mergeLocalFailed:`ローカルマージに失敗しました:{{detail}}`,mergedLocally:`ローカルで {{base}} に統合しました`},n={title:`レール`,runningCount_one:`{{count}} 件実行中`,runningCount_other:`{{count}} 件実行中`,launchAll:`すべて起動`,launchAllTitle:`準備完了のレールをすべて並列で起動します — 各実行は専用の git worktree に隔離されます`},r={skipRunning_one:`{{count}} 件は既に実行中`,skipRunning_other:`{{count}} 件は既に実行中`,skipEmpty_one:`{{count}} 件はスペックなし`,skipEmpty_other:`{{count}} 件はスペックなし`,skipPendingDecision_one:`{{count}} 件は PR の判断待ち`,skipPendingDecision_other:`{{count}} 件は PR の判断待ち`,skipOnReview_one:`{{count}} 件はレビュー中のスペックあり`,skipOnReview_other:`{{count}} 件はレビュー中のスペックあり`,skipInFlight_one:`{{count}} 件をスキップ(スペックは処理中)`,skipInFlight_other:`{{count}} 件をスキップ(スペックは処理中)`,failedCount_one:`{{count}} 件が失敗`,failedCount_other:`{{count}} 件が失敗`},i={title:`すべてのレールを起動`,railsCount_one:`レール {{count}} 件`,railsCount_other:`レール {{count}} 件`,specsCount_one:`スペック {{count}} 件`,specsCount_other:`スペック {{count}} 件`,isolationTitle:`並列かつ隔離。`,isolationBody:`各レールは専用の git worktree で実行され、同時起動が衝突することはありません。`,pipelinesTitle_one:`{{count}} 本の AI パイプライン。`,pipelinesTitle_other:`{{count}} 本の AI パイプライン。`,pipelinesBody:`レールごとに 1 回起動し、それぞれ設定済みのモード・エンジン・プロファイルを使います。`,costTitle:`コストは倍増します。`,costBody:`各レールが独自の AI 実行を生成します — 支出はレール数に比例します。`,launch_one:`レール {{count}} 件を起動`,launch_other:`レール {{count}} 件を起動`},a={viewJobLog:`ジョブログを表示`,log:`ログ`,implement:`実装`,batch:`バッチ`,freestyle:`Freestyle`,freestyleTitle:`Freestyle — Claude がパイプラインなしでスペックを自律的に実装します`,loop:`Loop`,loopTitle:`Loop — 公開済みの自動化ループをレールのスペックに対して実行します`,pickLoop:`ループを選択…`,effortTitle:`推論の労力`,stop:`停止`,play:`実行`,failedRetry:`ジョブが失敗しました — クリックして再試行`,addSpecsFirst:`先にこのレールにスペックを追加してください`,builtInLoops:`組み込み`,customLoops:`カスタムループ`,worktreesMerged:`{{count}} 件マージ済み`,worktreesNeedsReview:`{{count}} 件要確認`,execSteps:`{{count}} ステップ`,execLines:`{{count}} 行`,openspec:`OpenSpec`},o={moveToSpecs:`Specs に移動`,deleteRail:`{{label}} を削除`,dropHere:`ここにドロップ`,dropOnThisRail:`このレールにドロップ`,dragSpecsHere:`ここにスペックをドラッグ`},s={title:`Freestyle モードで起動`,context_one:`{{rail}} · スペック {{count}} 件`,context_other:`{{rail}} · スペック {{count}} 件`,noPipelineTitle:`OpenSpec パイプラインなし。`,noPipelineBody:`アーキテクト → 開発者 → レビュアーの構造化フローは完全にスキップされます。`,autonomyTitle:`Claude ネイティブの自律性。`,autonomyBody:`Claude はネイティブエージェントと動的ワークフローを使って自律的に作業します。`,costTitle:`コストは変動します。`,costBody:`支出は Claude の判断に依存し、想定より高くなることがあります。`,continue:`続行`},c={fetchFailed:`レールの取得に失敗しました: {{status}}`},l={toasts:e,railPr:t,railsBoard:n,launchAll:r,launchAllDialog:i,railControls:a,railRow:o,freestyleDialog:s,useRails:c};export{l as default,s as freestyleDialog,r as launchAll,i as launchAllDialog,a as railControls,t as railPr,o as railRow,n as railsBoard,e as toasts,c as useRails};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e={railAdded:`Rail {{n}} aggiunto`,railRemoved:`{{rail}} rimosso`,railLimitReached:`Limite di rail raggiunto ({{max}} max)`,railDeleteFailed:`Impossibile rimuovere il rail — contiene spec, è in esecuzione o ha una decisione PR in sospeso`,launchTicketsInFlight:`Una spec di questo rail è già in lavorazione da un'esecuzione attiva`,launchAllSummary_one:`{{count}} rail lanciato in parallelo`,launchAllSummary_other:`{{count}} rail lanciati in parallelo`,launchAllNoneEligible:`Nessun rail pronto al lancio — assegna prima le spec a un rail libero`,launchAllFailed:`Nessun rail è stato lanciato`,railCompleted:`Rail {{n}} completato`,railFailed:`Rail {{n}} non riuscito — le spec sono tornate in Specs`,railEnded:`Rail {{n}} {{status}} — le spec sono tornate in Specs`,alreadyOnRail:`Già su {{rail}}`,movedToRail:`Spostata su {{rail}}`,railRunningStopFirst:`{{rail}} è in esecuzione — fermalo prima di rimuoverlo`,removedFromRail:`Rimossa da {{rail}}`,queuedOnRail:`In coda su {{rail}}`,queuedOnRailDescription:`Il rail è attualmente in esecuzione`,railStopped:`{{rail}} fermato`,stopFailed:`Impossibile fermare il rail`,syncTicketsFailed:`Impossibile sincronizzare i ticket del rail`,launchFailed:`Impossibile avviare il rail`,launchNetworkError:`Errore di rete durante l'avvio del rail`,railLaunched:`{{rail}} avviato`,launchDescription_one:`{{mode}} con {{count}} spec`,launchDescription_other:`{{mode}} con {{count}} spec`,railWorktreeNeedsReview:`Rail {{n}}: la spec #{{ticket}} richiede revisione dopo il merge`,railWorktreesNoGit:`Isolamento con worktree non disponibile: il progetto non è un repository git — esecuzione in modalità condivisa.`,railWorktreesNoCommits:`Isolamento con worktree non disponibile: il repository non ha ancora commit — crea un commit iniziale e rilancia.`,railWorktreesError:`L'isolamento tramite worktree è fallito — questa esecuzione continua SENZA il flusso di revisione PR (nessuna scheda di implementazione). Vedi il dettaglio dell'errore sotto.`,onReviewCannotMoveToRail:`Questa spec è in attesa della revisione della PR — risolvi prima la decisione sulla PR`,onReviewNotLaunchable:`Una spec di questo rail è in attesa della revisione della PR — risolvi la decisione sulla PR prima di lanciare`},t={readyForReview:`Pronto per la revisione`,draftPr:`PR in bozza`,branchPushed:`Ramo inviato — PR in sospeso`,branchPushedHint:`Il ramo è stato inviato ma non è stato possibile creare la PR (GitHub CLI non disponibile). Riprova per crearla.`,prReady:`PR pronta`,prFailed:`PR non riuscita`,prFailedDetail:`PR non riuscita: {{detail}}`,createDegraded:`Impossibile pubblicare la PR — {{detail}}. Riprova una volta risolto.`,createPr:`Crea PR`,createPrTooltip:`→ {{base}}`,publish:`Pubblica`,publishTooltip:`Apre la PR in bozza per la revisione del team`,discard:`Scarta`,discardTooltip:`Elimina i rami e riporta i ticket in Specs`,retryPr:`Riprova PR`,retry:`Riprova`,checkMerge:`Verifica merge`,checkMergeTooltip:`Chiede a GitHub se è stato fatto il merge della PR`,prLinkFallback:`PR`,openPrTitle:`Apri la PR su GitHub`,notMergedYet:`Ancora nessun merge`,alreadyResolved:`Già risolta altrove`,ghFailed:`GitHub CLI non riuscita: {{detail}}`,actionFailed:`Impossibile applicare la decisione sulla PR`,mergedToast:`Merge della PR effettuato — i ticket sono passati a Completato`,discardedToast:`PR scartata — i ticket sono tornati in Specs`,decisionPending:`Questo rail ha una decisione sulla PR in sospeso — creala, pubblicala o scartala prima di rilanciare`,discardConfirmTitle:`Scartare questa consegna?`,discardConfirmBody:`I rami e i worktree del lancio verranno eliminati e i loro ticket torneranno in Specs. L'operazione non può essere annullata.`,mergeLocal:`Integra in locale`,mergeLocalTooltip:`Unisce i branch consegnati in {{base}} nel tuo checkout locale (senza GitHub)`,mergeLocalConfirmTitle:`Integrare in locale?`,mergeLocalConfirmBody:`I branch consegnati verranno uniti in {{base}} nel tuo checkout locale. Il checkout deve essere su {{base}} con albero di lavoro pulito.`,mergeLocalBlockedDirty:`Impossibile integrare: il tuo albero di lavoro su {{base}} ha modifiche non committate. Fai commit o stash e riprova.`,mergeLocalBlockedBranch:`Impossibile integrare: il tuo checkout è su {{current}}, non su {{base}}. Passa a {{base}} e riprova.`,mergeLocalFailed:`Merge locale fallito: {{detail}}`,mergedLocally:`Integrato in {{base}} in locale`},n={title:`Rails`,runningCount_one:`{{count}} in esecuzione`,runningCount_other:`{{count}} in esecuzione`,launchAll:`Lancia tutti`,launchAllTitle:`Lancia in parallelo tutti i rail pronti — ogni esecuzione è isolata nel proprio worktree git`},r={skipRunning_one:`{{count}} già in esecuzione`,skipRunning_other:`{{count}} già in esecuzione`,skipEmpty_one:`{{count}} senza spec`,skipEmpty_other:`{{count}} senza spec`,skipPendingDecision_one:`{{count}} in attesa di una decisione PR`,skipPendingDecision_other:`{{count}} in attesa di una decisione PR`,skipOnReview_one:`{{count}} con spec in revisione`,skipOnReview_other:`{{count}} con spec in revisione`,skipInFlight_one:`{{count}} saltato (spec già in corso)`,skipInFlight_other:`{{count}} saltati (spec già in corso)`,failedCount_one:`{{count}} non riuscito`,failedCount_other:`{{count}} non riusciti`},i={title:`Lancia tutti i rail`,railsCount_one:`{{count}} rail`,railsCount_other:`{{count}} rail`,specsCount_one:`{{count}} spec`,specsCount_other:`{{count}} spec`,isolationTitle:`Parallelo e isolato.`,isolationBody:`Ogni rail gira nel proprio worktree git — i lanci simultanei non collidono mai.`,pipelinesTitle_one:`{{count}} pipeline IA.`,pipelinesTitle_other:`{{count}} pipeline IA.`,pipelinesBody:`Un lancio per rail, ciascuno con la propria modalità, engine e profilo configurati.`,costTitle:`Costo moltiplicato.`,costBody:`Ogni rail genera la propria esecuzione IA — la spesa cresce con il numero di rail.`,launch_one:`Lancia {{count}} rail`,launch_other:`Lancia {{count}} rail`},a={viewJobLog:`Visualizza log del job`,log:`Log`,implement:`Implementa`,batch:`Batch`,freestyle:`Freestyle`,freestyleTitle:`Freestyle — Claude implementa la spec in autonomia, senza pipeline`,loop:`Loop`,loopTitle:`Loop — esegui un loop di automazione pubblicato sulle spec del rail`,pickLoop:`Scegli un loop…`,effortTitle:`Sforzo di ragionamento`,stop:`Stop`,play:`Avvia`,failedRetry:`Job non riuscito — clicca per riprovare`,addSpecsFirst:`Aggiungi prima delle spec a questo rail`,builtInLoops:`Integrati`,customLoops:`Loop personalizzati`,worktreesMerged:`{{count}} uniti`,worktreesNeedsReview:`{{count}} da rivedere`,execSteps:`{{count}} passi`,execLines:`{{count}} righe`,openspec:`OpenSpec`},o={moveToSpecs:`Sposta in Specs`,deleteRail:`Elimina {{label}}`,dropHere:`Rilascia qui`,dropOnThisRail:`Rilascia su questo rail`,dragSpecsHere:`Trascina qui le spec`},s={title:`Avvia in modalità Freestyle`,context_one:`{{rail}} · {{count}} spec`,context_other:`{{rail}} · {{count}} spec`,noPipelineTitle:`Nessuna pipeline OpenSpec.`,noPipelineBody:`Il flusso strutturato architect → developer → reviewer viene saltato del tutto.`,autonomyTitle:`Autonomia nativa di Claude.`,autonomyBody:`Claude lavora in autonomia usando agenti nativi e workflow dinamici.`,costTitle:`Costo variabile.`,costBody:`La spesa dipende da cosa Claude decide di fare — può essere più alta del previsto.`,continue:`Continua`},c={fetchFailed:`Impossibile recuperare i rail: {{status}}`},l={toasts:e,railPr:t,railsBoard:n,launchAll:r,launchAllDialog:i,railControls:a,railRow:o,freestyleDialog:s,useRails:c};export{l as default,s as freestyleDialog,r as launchAll,i as launchAllDialog,a as railControls,t as railPr,o as railRow,n as railsBoard,e as toasts,c as useRails};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-BNv3lrIs.js";var t=e({default:()=>d,freestyleDialog:()=>l,launchAll:()=>a,launchAllDialog:()=>o,railControls:()=>s,railPr:()=>r,railRow:()=>c,railsBoard:()=>i,toasts:()=>n,useRails:()=>u}),n={railAdded:`Rail {{n}} added`,railRemoved:`{{rail}} removed`,railLimitReached:`Rail limit reached ({{max}} max)`,railDeleteFailed:`Couldn't remove the rail — it holds specs, is running, or has a pending PR decision`,launchTicketsInFlight:`A spec on this rail is already being worked by an active run`,launchAllSummary_one:`{{count}} rail launched in parallel`,launchAllSummary_other:`{{count}} rails launched in parallel`,launchAllNoneEligible:`No rails ready to launch — assign specs to an idle rail first`,launchAllFailed:`No rails could be launched`,railCompleted:`Rail {{n}} completed`,railFailed:`Rail {{n}} failed — specs returned to Specs`,railEnded:`Rail {{n}} {{status}} — specs returned to Specs`,alreadyOnRail:`Already on {{rail}}`,movedToRail:`Moved to {{rail}}`,railRunningStopFirst:`{{rail}} is running — stop it before removing`,removedFromRail:`Removed from {{rail}}`,queuedOnRail:`Queued on {{rail}}`,queuedOnRailDescription:`Rail is currently running`,railStopped:`{{rail}} stopped`,stopFailed:`Failed to stop rail`,syncTicketsFailed:`Failed to sync rail tickets`,launchFailed:`Failed to launch rail`,launchNetworkError:`Network error launching rail`,railLaunched:`{{rail}} launched`,launchDescription_one:`{{mode}} with {{count}} spec`,launchDescription_other:`{{mode}} with {{count}} specs`,railWorktreeNeedsReview:`Rail {{n}}: spec #{{ticket}} needs review after merge`,railWorktreesNoGit:`Worktree isolation unavailable: this project isn't a git repository — running in shared mode.`,railWorktreesNoCommits:`Worktree isolation unavailable: the repository has no commits yet — make an initial commit, then relaunch.`,railWorktreesError:`Worktree isolation failed — this run continues WITHOUT the PR review flow (no implementation card). See the error detail below.`,onReviewCannotMoveToRail:`This spec is awaiting PR review — resolve the PR decision first`,onReviewNotLaunchable:`A spec on this rail is awaiting PR review — resolve the PR decision before launching`},r={readyForReview:`Ready for review`,draftPr:`Draft PR`,branchPushed:`Branch pushed — PR pending`,branchPushedHint:`The branch was pushed but the PR couldn't be created (GitHub CLI unavailable). Retry to create it.`,prReady:`PR ready`,prFailed:`PR failed`,prFailedDetail:`PR failed: {{detail}}`,createDegraded:`Couldn't publish the PR — {{detail}}. Retry when resolved.`,createPr:`Create PR`,createPrTooltip:`→ {{base}}`,publish:`Publish`,publishTooltip:`Open this draft PR for team review`,discard:`Discard`,discardTooltip:`Drop the branches and return the tickets to Specs`,retryPr:`Retry PR`,retry:`Retry`,checkMerge:`Check merge`,checkMergeTooltip:`Ask GitHub whether the PR has been merged`,prLinkFallback:`PR`,openPrTitle:`Open the PR on GitHub`,notMergedYet:`Not merged yet`,alreadyResolved:`Already resolved elsewhere`,ghFailed:`GitHub CLI failed: {{detail}}`,actionFailed:`Couldn't apply the PR decision`,mergedToast:`PR merged — tickets moved to Done`,discardedToast:`PR discarded — tickets returned to Specs`,decisionPending:`This rail has a pending PR decision — create, publish or discard it before relaunching`,discardConfirmTitle:`Discard this delivery?`,discardConfirmBody:`The launch's branches and worktrees will be dropped and its tickets will return to Specs. This cannot be undone.`,mergeLocal:`Integrate locally`,mergeLocalTooltip:`Merge the delivered branches into {{base}} in your local checkout (no GitHub needed)`,mergeLocalConfirmTitle:`Integrate locally?`,mergeLocalConfirmBody:`The delivered branches will be merged into {{base}} in your local checkout. Your checkout must be on {{base}} with a clean working tree.`,mergeLocalBlockedDirty:`Cannot integrate: your working tree on {{base}} has uncommitted changes. Commit or stash them, then retry.`,mergeLocalBlockedBranch:`Cannot integrate: your checkout is on {{current}}, not {{base}}. Check out {{base}}, then retry.`,mergeLocalFailed:`Local merge failed: {{detail}}`,mergedLocally:`Integrated into {{base}} locally`},i={title:`Rails`,runningCount_one:`{{count}} running`,runningCount_other:`{{count}} running`,launchAll:`Launch all`,launchAllTitle:`Launch every ready rail in parallel — each run is isolated in its own git worktree`},a={skipRunning_one:`{{count}} already running`,skipRunning_other:`{{count}} already running`,skipEmpty_one:`{{count}} without specs`,skipEmpty_other:`{{count}} without specs`,skipPendingDecision_one:`{{count}} awaiting a PR decision`,skipPendingDecision_other:`{{count}} awaiting a PR decision`,skipOnReview_one:`{{count}} with specs on review`,skipOnReview_other:`{{count}} with specs on review`,skipInFlight_one:`{{count}} skipped (spec already in flight)`,skipInFlight_other:`{{count}} skipped (specs already in flight)`,failedCount_one:`{{count}} failed`,failedCount_other:`{{count}} failed`},o={title:`Launch all rails`,railsCount_one:`{{count}} rail`,railsCount_other:`{{count}} rails`,specsCount_one:`{{count}} spec`,specsCount_other:`{{count}} specs`,isolationTitle:`Parallel & isolated.`,isolationBody:`Each rail runs in its own git worktree — concurrent launches never collide.`,pipelinesTitle_one:`{{count}} AI pipeline.`,pipelinesTitle_other:`{{count}} AI pipelines.`,pipelinesBody:`One launch per rail, each with its configured mode, engine and profile.`,costTitle:`Multiplied cost.`,costBody:`Every rail spawns its own AI run — spend scales with the number of rails.`,launch_one:`Launch {{count}} rail`,launch_other:`Launch {{count}} rails`},s={viewJobLog:`View job log`,log:`Log`,implement:`Implement`,batch:`Batch`,freestyle:`Freestyle`,freestyleTitle:`Freestyle — Claude implements the spec autonomously, no pipeline`,loop:`Loop`,loopTitle:`Loop — run a published automation loop against the rail's specs`,pickLoop:`Pick a loop…`,effortTitle:`Reasoning effort`,stop:`Stop`,play:`Play`,failedRetry:`Job failed — click to retry`,addSpecsFirst:`Add specs to this rail first`,builtInLoops:`Built-in`,customLoops:`Custom loops`,worktreesMerged:`{{count}} merged`,worktreesNeedsReview:`{{count}} need review`,execSteps:`{{count}} steps`,execLines:`{{count}} lines`,openspec:`OpenSpec`},c={moveToSpecs:`Move to Specs`,deleteRail:`Delete {{label}}`,dropHere:`Drop here`,dropOnThisRail:`Drop on this rail`,dragSpecsHere:`Drag specs here`},l={title:`Launch in Freestyle mode`,context_one:`{{rail}} · {{count}} spec`,context_other:`{{rail}} · {{count}} specs`,noPipelineTitle:`No OpenSpec pipeline.`,noPipelineBody:`The structured architect → developer → reviewer flow is skipped entirely.`,autonomyTitle:`Native Claude autonomy.`,autonomyBody:`Claude works on its own using native agents and dynamic workflows.`,costTitle:`Variable cost.`,costBody:`Spend depends on what Claude decides to do — it can be higher than expected.`,continue:`Continue`},u={fetchFailed:`Failed to fetch rails: {{status}}`},d={toasts:n,railPr:r,railsBoard:i,launchAll:a,launchAllDialog:o,railControls:s,railRow:c,freestyleDialog:l,useRails:u};export{t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e={railAdded:`Rail {{n}} hinzugefügt`,railRemoved:`{{rail}} entfernt`,railLimitReached:`Rail-Limit erreicht (max. {{max}})`,railDeleteFailed:`Rail konnte nicht entfernt werden – es enthält Specs, läuft gerade oder hat eine ausstehende PR-Entscheidung`,launchTicketsInFlight:`Eine Spec dieses Rails wird bereits von einem aktiven Lauf bearbeitet`,launchAllSummary_one:`{{count}} Rail parallel gestartet`,launchAllSummary_other:`{{count}} Rails parallel gestartet`,launchAllNoneEligible:`Keine Rails startbereit – weise zuerst Specs einem freien Rail zu`,launchAllFailed:`Es konnte kein Rail gestartet werden`,railCompleted:`Rail {{n}} abgeschlossen`,railFailed:`Rail {{n}} fehlgeschlagen – Specs zurück in Specs`,railEnded:`Rail {{n}} {{status}} – Specs zurück in Specs`,alreadyOnRail:`Bereits auf {{rail}}`,movedToRail:`Auf {{rail}} verschoben`,railRunningStopFirst:`{{rail}} läuft – vor dem Entfernen stoppen`,removedFromRail:`Von {{rail}} entfernt`,queuedOnRail:`Auf {{rail}} eingereiht`,queuedOnRailDescription:`Rail läuft gerade`,railStopped:`{{rail}} gestoppt`,stopFailed:`Rail konnte nicht gestoppt werden`,syncTicketsFailed:`Rail-Tickets konnten nicht synchronisiert werden`,launchFailed:`Rail konnte nicht gestartet werden`,launchNetworkError:`Netzwerkfehler beim Starten des Rails`,railLaunched:`{{rail}} gestartet`,launchDescription_one:`{{mode}} mit {{count}} Spec`,launchDescription_other:`{{mode}} mit {{count}} Specs`,railWorktreeNeedsReview:`Rail {{n}}: Spec #{{ticket}} muss nach dem Merge geprüft werden`,railWorktreesNoGit:`Worktree-Isolation nicht verfügbar: Dieses Projekt ist kein Git-Repository — Ausführung im gemeinsamen Modus.`,railWorktreesNoCommits:`Worktree-Isolation nicht verfügbar: Das Repository hat noch keine Commits — erstelle einen ersten Commit und starte neu.`,railWorktreesError:`Worktree-Isolation fehlgeschlagen — dieser Lauf läuft OHNE den PR-Review-Flow weiter (keine Implementierungskarte). Siehe Fehlerdetail unten.`,onReviewCannotMoveToRail:`Diese Spec wartet auf die PR-Prüfung — löse zuerst die PR-Entscheidung`,onReviewNotLaunchable:`Eine Spec auf diesem Rail wartet auf die PR-Prüfung — löse die PR-Entscheidung vor dem Start`},t={readyForReview:`Bereit zur Prüfung`,draftPr:`Entwurfs-PR`,branchPushed:`Branch gepusht — PR ausstehend`,branchPushedHint:`Der Branch wurde gepusht, aber die PR konnte nicht erstellt werden (GitHub CLI nicht verfügbar). Erneut versuchen, um sie zu erstellen.`,prReady:`PR bereit`,prFailed:`PR fehlgeschlagen`,prFailedDetail:`PR fehlgeschlagen: {{detail}}`,createDegraded:`PR konnte nicht veröffentlicht werden — {{detail}}. Nach Behebung erneut versuchen.`,createPr:`PR erstellen`,createPrTooltip:`→ {{base}}`,publish:`Veröffentlichen`,publishTooltip:`Öffnet den Entwurfs-PR für das Review des Teams`,discard:`Verwerfen`,discardTooltip:`Verwirft die Branches und schickt die Tickets zurück zu Specs`,retryPr:`PR erneut versuchen`,retry:`Erneut versuchen`,checkMerge:`Merge prüfen`,checkMergeTooltip:`Bei GitHub nachfragen, ob die PR gemergt wurde`,prLinkFallback:`PR`,openPrTitle:`PR auf GitHub öffnen`,notMergedYet:`Noch nicht gemergt`,alreadyResolved:`Bereits anderweitig erledigt`,ghFailed:`GitHub CLI fehlgeschlagen: {{detail}}`,actionFailed:`PR-Entscheidung konnte nicht angewendet werden`,mergedToast:`PR gemergt — Tickets nach Fertig verschoben`,discardedToast:`PR verworfen — Tickets zurück in Specs`,decisionPending:`Dieser Rail hat eine ausstehende PR-Entscheidung — erstelle, veröffentliche oder verwirf sie, bevor du neu startest`,discardConfirmTitle:`Diese Lieferung verwerfen?`,discardConfirmBody:`Die Branches und Worktrees des Launches werden verworfen und die Tickets kehren zurück zu Specs. Das kann nicht rückgängig gemacht werden.`,mergeLocal:`Lokal integrieren`,mergeLocalTooltip:`Führt die gelieferten Branches lokal in {{base}} zusammen (ohne GitHub)`,mergeLocalConfirmTitle:`Lokal integrieren?`,mergeLocalConfirmBody:`Die gelieferten Branches werden lokal in {{base}} zusammengeführt. Dein Checkout muss auf {{base}} stehen und sauber sein.`,mergeLocalBlockedDirty:`Integration nicht möglich: dein Arbeitsverzeichnis auf {{base}} hat uncommittete Änderungen. Committe oder stashe sie und versuche es erneut.`,mergeLocalBlockedBranch:`Integration nicht möglich: dein Checkout steht auf {{current}}, nicht auf {{base}}. Wechsle zu {{base}} und versuche es erneut.`,mergeLocalFailed:`Lokaler Merge fehlgeschlagen: {{detail}}`,mergedLocally:`Lokal in {{base}} integriert`},n={title:`Rails`,runningCount_one:`{{count}} läuft`,runningCount_other:`{{count}} laufen`,launchAll:`Alle starten`,launchAllTitle:`Startet alle startbereiten Rails parallel – jeder Lauf ist in seinem eigenen Git-Worktree isoliert`},r={skipRunning_one:`{{count}} läuft bereits`,skipRunning_other:`{{count}} laufen bereits`,skipEmpty_one:`{{count}} ohne Specs`,skipEmpty_other:`{{count}} ohne Specs`,skipPendingDecision_one:`{{count}} wartet auf eine PR-Entscheidung`,skipPendingDecision_other:`{{count}} warten auf eine PR-Entscheidung`,skipOnReview_one:`{{count}} mit Specs im Review`,skipOnReview_other:`{{count}} mit Specs im Review`,skipInFlight_one:`{{count}} übersprungen (Spec bereits in Arbeit)`,skipInFlight_other:`{{count}} übersprungen (Specs bereits in Arbeit)`,failedCount_one:`{{count}} fehlgeschlagen`,failedCount_other:`{{count}} fehlgeschlagen`},i={title:`Alle Rails starten`,railsCount_one:`{{count}} Rail`,railsCount_other:`{{count}} Rails`,specsCount_one:`{{count}} Spec`,specsCount_other:`{{count}} Specs`,isolationTitle:`Parallel und isoliert.`,isolationBody:`Jedes Rail läuft in seinem eigenen Git-Worktree – gleichzeitige Starts kollidieren nie.`,pipelinesTitle_one:`{{count}} KI-Pipeline.`,pipelinesTitle_other:`{{count}} KI-Pipelines.`,pipelinesBody:`Ein Start pro Rail, jeweils mit dem konfigurierten Modus, Engine und Profil.`,costTitle:`Vervielfachte Kosten.`,costBody:`Jedes Rail erzeugt seinen eigenen KI-Lauf – die Ausgaben skalieren mit der Anzahl der Rails.`,launch_one:`{{count}} Rail starten`,launch_other:`{{count}} Rails starten`},a={viewJobLog:`Job-Log anzeigen`,log:`Log`,implement:`Implement`,batch:`Batch`,freestyle:`Freestyle`,freestyleTitle:`Freestyle – Claude implementiert die Spec autonom, ohne Pipeline`,loop:`Loop`,loopTitle:`Loop – eine veröffentlichte Automatisierungsschleife gegen die Specs des Rails ausführen`,pickLoop:`Schleife auswählen…`,effortTitle:`Denkaufwand`,stop:`Stopp`,play:`Start`,failedRetry:`Job fehlgeschlagen – zum Wiederholen klicken`,addSpecsFirst:`Füge zuerst Specs zu diesem Rail hinzu`,builtInLoops:`Integriert`,customLoops:`Eigene Loops`,worktreesMerged:`{{count}} zusammengeführt`,worktreesNeedsReview:`{{count}} zu prüfen`,execSteps:`{{count}} Schritte`,execLines:`{{count}} Zeilen`,openspec:`OpenSpec`},o={moveToSpecs:`Nach Specs verschieben`,deleteRail:`{{label}} löschen`,dropHere:`Hier ablegen`,dropOnThisRail:`Auf diesem Rail ablegen`,dragSpecsHere:`Specs hierher ziehen`},s={title:`Im Freestyle-Modus starten`,context_one:`{{rail}} · {{count}} Spec`,context_other:`{{rail}} · {{count}} Specs`,noPipelineTitle:`Keine OpenSpec-Pipeline.`,noPipelineBody:`Der strukturierte Flow Architect → Developer → Reviewer wird komplett übersprungen.`,autonomyTitle:`Native Claude-Autonomie.`,autonomyBody:`Claude arbeitet eigenständig mit nativen Agenten und dynamischen Workflows.`,costTitle:`Variable Kosten.`,costBody:`Die Ausgaben hängen davon ab, was Claude entscheidet – sie können höher ausfallen als erwartet.`,continue:`Weiter`},c={fetchFailed:`Rails konnten nicht geladen werden: {{status}}`},l={toasts:e,railPr:t,railsBoard:n,launchAll:r,launchAllDialog:i,railControls:a,railRow:o,freestyleDialog:s,useRails:c};export{l as default,s as freestyleDialog,r as launchAll,i as launchAllDialog,a as railControls,t as railPr,o as railRow,n as railsBoard,e as toasts,c as useRails};
|