specrails-desktop 2.29.2 → 2.29.3
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-ClpD5CFj.js → ActivityFeedPage-CFB4UBhT.js} +1 -1
- package/client/dist/assets/{AgentBrowserCapture-CSPs9Ofc.js → AgentBrowserCapture-C-T0r16B.js} +1 -1
- package/client/dist/assets/{AgentModeCodePane-DwcyklA5.js → AgentModeCodePane-IljV5FOQ.js} +2 -2
- package/client/dist/assets/{AgentModeJobsPane-C69bqlMa.js → AgentModeJobsPane-B5miH10_.js} +1 -1
- package/client/dist/assets/{AgentsPage-pRiRr9-W.js → AgentsPage-BgYQrAcH.js} +1 -1
- package/client/dist/assets/{AnalyticsPage-C14exKsC.js → AnalyticsPage-BtVCuNjL.js} +1 -1
- package/client/dist/assets/{CodePage-CK76JKm9.js → CodePage-Cb_jAjSV.js} +1 -1
- package/client/dist/assets/{DesktopAnalyticsPage-Cnv0f3XQ.js → DesktopAnalyticsPage-s_Cc_JL1.js} +1 -1
- package/client/dist/assets/{DocsDialog-CHUm_Ym0.js → DocsDialog-Cr47QI9L.js} +1 -1
- package/client/dist/assets/{DocsPage-COI-oDok.js → DocsPage-C_WPRuG_.js} +1 -1
- package/client/dist/assets/{InteractiveJobComposer-CypM7R1F.js → InteractiveJobComposer-NfFOciRB.js} +1 -1
- package/client/dist/assets/{JobDetailModal-B_W0H9dw.js → JobDetailModal-DqEW7Z7K.js} +1 -1
- package/client/dist/assets/{JobDetailPage-CeeXOoKS.js → JobDetailPage-D4ppEpDE.js} +1 -1
- package/client/dist/assets/{JobsPage-CwhJG9jw.js → JobsPage-DStSoMyq.js} +1 -1
- package/client/dist/assets/{LoopBuilderPage-C51t1WOM.js → LoopBuilderPage-DltCwS4P.js} +1 -1
- package/client/dist/assets/{LoopPreviewModal-Y2HgtIJu.js → LoopPreviewModal-BWaiAbUq.js} +1 -1
- package/client/dist/assets/{LoopsPage-Bvn1Kw5V.js → LoopsPage-BqjbXuBZ.js} +1 -1
- package/client/dist/assets/{MinimizedChatsContext-DiFvZDPW.js → MinimizedChatsContext--o3JAM9F.js} +1 -1
- package/client/dist/assets/{PluginsPage-BGPRJpdf.js → PluginsPage-B-UOmzXw.js} +1 -1
- package/client/dist/assets/{ProjectSettingsDialog-D_GTyGLc.js → ProjectSettingsDialog-DkGajIxE.js} +1 -1
- package/client/dist/assets/{TemplatePreviewModal-szwBhd7h.js → TemplatePreviewModal-5CUXlkw7.js} +1 -1
- package/client/dist/assets/{TicketDetailModal-9UEyK974.js → TicketDetailModal-B_igqmti.js} +4 -4
- package/client/dist/assets/{Trans-B_vKZ-Hb.js → Trans-DDMIBBUd.js} +1 -1
- package/client/dist/assets/agent-BXc59ARK2.js +1 -0
- package/client/dist/assets/agent-BbIFXdDq.js +1 -0
- package/client/dist/assets/agent-BqEfA5u5.js +1 -0
- package/client/dist/assets/agent-BtGzgTC4.js +1 -0
- package/client/dist/assets/agent-CIhys_5d.js +1 -0
- package/client/dist/assets/agent-CJPaqsVR.js +1 -0
- package/client/dist/assets/agent-n-hY4GuL.js +1 -0
- package/client/dist/assets/agent-tJ-efa3_2.js +1 -0
- package/client/dist/assets/common-6MLbD-jM.js +1 -0
- package/client/dist/assets/common-BKGEu4rm.js +1 -0
- package/client/dist/assets/common-BNbnv8cE2.js +1 -0
- package/client/dist/assets/common-BqGWtDbt.js +1 -0
- package/client/dist/assets/common-DBtTzeYm2.js +1 -0
- package/client/dist/assets/common-DEW3Nr8n.js +1 -0
- package/client/dist/assets/{common-DVQuhs-m.js → common-DHsv9N5d.js} +1 -1
- package/client/dist/assets/common-mkrEcW-Y.js +1 -0
- package/client/dist/assets/dashboard-BYzxom0L.js +1 -0
- package/client/dist/assets/dashboard-BmDZmHyY.js +1 -0
- package/client/dist/assets/dashboard-CnNtJBQ5.js +1 -0
- package/client/dist/assets/dashboard-D4Uj-XWc2.js +1 -0
- package/client/dist/assets/dashboard-D57uRaGw2.js +1 -0
- package/client/dist/assets/dashboard-DAr6F9et.js +1 -0
- package/client/dist/assets/dashboard-vAcsn0L3.js +1 -0
- package/client/dist/assets/dashboard-vrjZvxWy.js +1 -0
- package/client/dist/assets/{dist-js-CcBCbb32.js → dist-js-BCUhGUXS.js} +1 -1
- package/client/dist/assets/{dist-js-VwztRkGj.js → dist-js-DcoXTnEI.js} +1 -1
- package/client/dist/assets/{formatDistanceToNow-ByHIauTQ.js → formatDistanceToNow-DP3Ab6fX.js} +1 -1
- package/client/dist/assets/{getTimezoneOffsetInMilliseconds-BxHAksaU.js → getTimezoneOffsetInMilliseconds-DdKKL8Fx.js} +1 -1
- package/client/dist/assets/{i18n-CgaRxpII.js → i18n-DREQCE2F.js} +2 -2
- package/client/dist/assets/index-B784m8RT.js +76 -0
- package/client/dist/assets/index-CQBIemiz.css +2 -0
- package/client/dist/assets/{spending-C4p06nen.js → spending-CtY7yYes.js} +1 -1
- package/client/dist/assets/{useBrowserCaptureSession-2OqX0vap.js → useBrowserCaptureSession-BFBdW59q.js} +1 -1
- package/client/dist/assets/{useDesktop-X8YB9xzv.js → useDesktop-uWVZ8eia.js} +1 -1
- package/client/dist/index.html +14 -14
- package/docs/internals/safe-pr-review-flow.md +221 -38
- package/package.json +1 -1
- package/server/dist/active-pr-continuation.js +237 -52
- package/server/dist/agent-chat-manager.js +29 -12
- package/server/dist/agent-store.js +19 -4
- package/server/dist/db.js +21 -0
- package/server/dist/pr-lifecycle.js +100 -8
- package/server/dist/project-git.js +62 -2
- package/server/dist/rail-isolated-launch.js +644 -108
- package/server/dist/rail-pr-decision.js +1065 -181
- package/server/dist/rail-pr-recovery-git.js +235 -0
- package/server/dist/rail-pr-store.js +120 -9
- package/server/dist/rail-worktree-release.js +290 -4
- package/server/dist/rails-router.js +97 -9
- package/server/dist/worktree-manager.js +120 -16
- package/server/dist/worktree-overlay.js +166 -4
- package/client/dist/assets/agent-4rmXoo_p.js +0 -1
- package/client/dist/assets/agent-BxZuNGih.js +0 -1
- package/client/dist/assets/agent-C3uXOYv_.js +0 -1
- package/client/dist/assets/agent-CA8Y4wbw.js +0 -1
- package/client/dist/assets/agent-CASKrhG12.js +0 -1
- package/client/dist/assets/agent-Cv-jud5n2.js +0 -1
- package/client/dist/assets/agent-DitUxYh2.js +0 -1
- package/client/dist/assets/agent-Doow4X7o.js +0 -1
- package/client/dist/assets/common-CD1QHriA2.js +0 -1
- package/client/dist/assets/common-CwwPaRxx.js +0 -1
- package/client/dist/assets/common-Dg2jaX7d.js +0 -1
- package/client/dist/assets/common-DuBwj6tK.js +0 -1
- package/client/dist/assets/common-MRj9MHcc.js +0 -1
- package/client/dist/assets/common-O4ZpnMLp.js +0 -1
- package/client/dist/assets/common-fyeF0v7C2.js +0 -1
- package/client/dist/assets/dashboard-B_NkSHYm.js +0 -1
- package/client/dist/assets/dashboard-ClBb_3pq.js +0 -1
- package/client/dist/assets/dashboard-CpCmJvMB.js +0 -1
- package/client/dist/assets/dashboard-Czohu35O2.js +0 -1
- package/client/dist/assets/dashboard-DcjbD0UK.js +0 -1
- package/client/dist/assets/dashboard-Dvx5F3we.js +0 -1
- package/client/dist/assets/dashboard-R1bOPjBh2.js +0 -1
- package/client/dist/assets/dashboard-owcDucDi.js +0 -1
- package/client/dist/assets/index-BflYQpWm.css +0 -2
- package/client/dist/assets/index-C1_-BTXy.js +0 -72
|
@@ -63,13 +63,21 @@ const child_process_1 = require("child_process");
|
|
|
63
63
|
const fs = __importStar(require("fs"));
|
|
64
64
|
const path = __importStar(require("path"));
|
|
65
65
|
const win_spawn_1 = require("./util/win-spawn");
|
|
66
|
+
const GIT_RUNNER_TIMEOUT_MS = 120_000;
|
|
66
67
|
exports.defaultGitRunner = {
|
|
67
68
|
run(args, cwd) {
|
|
68
69
|
return new Promise((resolve) => {
|
|
69
70
|
// SystemRoot/ComSpec backfill so worktree + PR-decision git ops don't fail
|
|
70
71
|
// to start under a pkg-stripped Windows sidecar env. No-op on POSIX.
|
|
71
72
|
const env = (0, win_spawn_1.windowsSpawnEnv)();
|
|
72
|
-
(0, child_process_1.execFile)('git', args, {
|
|
73
|
+
(0, child_process_1.execFile)('git', args, {
|
|
74
|
+
cwd,
|
|
75
|
+
env,
|
|
76
|
+
timeout: GIT_RUNNER_TIMEOUT_MS,
|
|
77
|
+
killSignal: 'SIGTERM',
|
|
78
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
79
|
+
windowsHide: true,
|
|
80
|
+
}, (err, stdout, stderr) => {
|
|
73
81
|
const code = err && typeof err.code === 'number' ? err.code : err ? 1 : 0;
|
|
74
82
|
resolve({ code, stdout: stdout?.toString() ?? '', stderr: stderr?.toString() ?? '' });
|
|
75
83
|
});
|
|
@@ -233,8 +241,63 @@ async function gitRun(git, args, cwd) {
|
|
|
233
241
|
}
|
|
234
242
|
}
|
|
235
243
|
function commitPathspecs(excludePaths) {
|
|
236
|
-
|
|
237
|
-
|
|
244
|
+
return [
|
|
245
|
+
'--', '.',
|
|
246
|
+
...exports.PR_NEVER_STAGE_PATHS.map((p) => `:(exclude)${p}`),
|
|
247
|
+
// Overlay names originate in the workspace filesystem. Treat them as
|
|
248
|
+
// literal top-level paths so glob/pathspec metacharacters cannot broaden
|
|
249
|
+
// the never-commit surface.
|
|
250
|
+
...excludePaths.map((p) => `:(top,exclude,literal)${p}`),
|
|
251
|
+
];
|
|
252
|
+
}
|
|
253
|
+
const INDEX_AUDIT_ARGS = [
|
|
254
|
+
'diff', '--cached', '--name-only', '--no-renames', '-z',
|
|
255
|
+
'--diff-filter=ACDMRTUXB', '--',
|
|
256
|
+
];
|
|
257
|
+
const PR_NEVER_STAGE_ROOTS = [...new Set(exports.PR_NEVER_STAGE_PATHS.map((entry) => entry.endsWith('/**') ? entry.slice(0, -3) : entry))];
|
|
258
|
+
function normalizedGitPath(value) {
|
|
259
|
+
return path.sep === '\\' ? value.replaceAll('\\', '/') : value;
|
|
260
|
+
}
|
|
261
|
+
function isPathAtOrBelow(candidate, root) {
|
|
262
|
+
return candidate === root || candidate.startsWith(`${root}/`);
|
|
263
|
+
}
|
|
264
|
+
function forbiddenStagedPaths(staged, excludePaths) {
|
|
265
|
+
const overlayRoots = excludePaths.map(normalizedGitPath).filter(Boolean);
|
|
266
|
+
return staged.filter((candidate) => (PR_NEVER_STAGE_ROOTS.some((root) => isPathAtOrBelow(candidate, root))
|
|
267
|
+
|| overlayRoots.some((root) => isPathAtOrBelow(candidate, root))));
|
|
268
|
+
}
|
|
269
|
+
function parseNulTerminatedPaths(result, phase) {
|
|
270
|
+
if (result.code !== 0) {
|
|
271
|
+
return { paths: [], error: `${phase}: ${gitFailure(result, `git diff failed with exit ${result.code}`)}` };
|
|
272
|
+
}
|
|
273
|
+
if (result.stdout === '')
|
|
274
|
+
return { paths: [] };
|
|
275
|
+
if (!result.stdout.endsWith('\0')) {
|
|
276
|
+
return { paths: [], error: `${phase}: git returned a malformed non-NUL-terminated path list` };
|
|
277
|
+
}
|
|
278
|
+
const paths = result.stdout.slice(0, -1).split('\0');
|
|
279
|
+
if (paths.some((entry) => entry.length === 0)) {
|
|
280
|
+
return { paths: [], error: `${phase}: git returned a malformed path list containing an empty entry` };
|
|
281
|
+
}
|
|
282
|
+
return { paths };
|
|
283
|
+
}
|
|
284
|
+
async function auditStagedPaths(git, worktreePath, excludePaths, phase) {
|
|
285
|
+
const result = await gitRun(git, [...INDEX_AUDIT_ARGS], worktreePath);
|
|
286
|
+
const parsed = parseNulTerminatedPaths(result, phase);
|
|
287
|
+
if (parsed.error)
|
|
288
|
+
return { forbidden: [], error: parsed.error };
|
|
289
|
+
return { forbidden: forbiddenStagedPaths(parsed.paths, excludePaths) };
|
|
290
|
+
}
|
|
291
|
+
function forbiddenResetPathspecs(excludePaths) {
|
|
292
|
+
return [
|
|
293
|
+
'--',
|
|
294
|
+
...PR_NEVER_STAGE_ROOTS.map((entry) => `:(top,literal)${entry}`),
|
|
295
|
+
...excludePaths.map(normalizedGitPath).filter(Boolean).map((entry) => `:(top,literal)${entry}`),
|
|
296
|
+
];
|
|
297
|
+
}
|
|
298
|
+
function describeForbiddenPaths(paths) {
|
|
299
|
+
const shown = paths.slice(0, 5).map((entry) => JSON.stringify(entry)).join(', ');
|
|
300
|
+
return paths.length > 5 ? `${shown}, and ${paths.length - 5} more` : shown;
|
|
238
301
|
}
|
|
239
302
|
/**
|
|
240
303
|
* Commit the worktree's current deliverable changes to its branch and verify
|
|
@@ -245,24 +308,64 @@ function commitPathspecs(excludePaths) {
|
|
|
245
308
|
async function commitWorktreeAndVerify(git, worktreePath, message, excludePaths = []) {
|
|
246
309
|
const pathspecs = commitPathspecs(excludePaths);
|
|
247
310
|
const add = await gitRun(git, ['add', '-A', ...pathspecs], worktreePath);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
311
|
+
let indexSafe = false;
|
|
312
|
+
let indexError;
|
|
313
|
+
if (add.code === 0) {
|
|
314
|
+
const initialAudit = await auditStagedPaths(git, worktreePath, excludePaths, 'git index audit failed before commit');
|
|
315
|
+
if (initialAudit.error) {
|
|
316
|
+
indexError = initialAudit.error;
|
|
317
|
+
}
|
|
318
|
+
else if (initialAudit.forbidden.length === 0) {
|
|
319
|
+
indexSafe = true;
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
// Exclude pathspecs prevent newly-staged private/overlay files, but an
|
|
323
|
+
// earlier process may already have put them in the index. Reset only the
|
|
324
|
+
// prohibited roots back to HEAD: working files remain intact for recovery.
|
|
325
|
+
const reset = await gitRun(git, ['reset', '--quiet', ...forbiddenResetPathspecs(excludePaths)], worktreePath);
|
|
326
|
+
if (reset.code !== 0) {
|
|
327
|
+
indexError = `git could not safely unstage forbidden paths: ${gitFailure(reset, `git reset failed with exit ${reset.code}`)}`;
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
const finalAudit = await auditStagedPaths(git, worktreePath, excludePaths, 'git index re-audit failed after unstaging forbidden paths');
|
|
331
|
+
if (finalAudit.error) {
|
|
332
|
+
indexError = finalAudit.error;
|
|
333
|
+
}
|
|
334
|
+
else if (finalAudit.forbidden.length > 0) {
|
|
335
|
+
indexError = `forbidden paths remain staged after safe unstage: ${describeForbiddenPaths(finalAudit.forbidden)}`;
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
indexSafe = true;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
// `--only` makes the allow/exclude pathspecs authoritative at commit time,
|
|
344
|
+
// not merely at the earlier `git add`/audit. This closes the remaining race
|
|
345
|
+
// where another process could stage a private path between audit and commit.
|
|
346
|
+
// Automated delivery also bypasses repository hooks: a pre-commit hook runs
|
|
347
|
+
// after our final audit and could otherwise stage an excluded secret into the
|
|
348
|
+
// commit. User working files and the ordinary index remain preserved.
|
|
349
|
+
const commit = add.code === 0 && indexSafe
|
|
350
|
+
? await gitRun(git, ['commit', '--no-verify', '--only', '-m', message, ...pathspecs], worktreePath)
|
|
351
|
+
: { code: 1, stdout: '', stderr: 'skipped commit because the index was not proven safe' };
|
|
251
352
|
const status = await gitRun(git, ['status', '--porcelain', '--untracked-files=all', ...pathspecs], worktreePath);
|
|
252
353
|
const dirty = status.code === 0
|
|
253
354
|
? status.stdout.split('\n').map((line) => line.trimEnd()).filter(Boolean)
|
|
254
355
|
: [];
|
|
255
356
|
const error = add.code !== 0
|
|
256
357
|
? gitFailure(add, `git add failed with exit ${add.code}`)
|
|
257
|
-
:
|
|
258
|
-
?
|
|
259
|
-
:
|
|
260
|
-
? gitFailure(
|
|
261
|
-
:
|
|
358
|
+
: indexError
|
|
359
|
+
? indexError
|
|
360
|
+
: status.code !== 0
|
|
361
|
+
? gitFailure(status, `git status failed with exit ${status.code}`)
|
|
362
|
+
: commit.code !== 0 && dirty.length > 0
|
|
363
|
+
? gitFailure(commit, `git commit failed with exit ${commit.code}`)
|
|
364
|
+
: undefined;
|
|
262
365
|
return {
|
|
263
366
|
staged: add.code === 0,
|
|
264
367
|
committed: commit.code === 0,
|
|
265
|
-
clean: status.code === 0 && dirty.length === 0,
|
|
368
|
+
clean: indexSafe && status.code === 0 && dirty.length === 0,
|
|
266
369
|
dirty,
|
|
267
370
|
...(error ? { error } : {}),
|
|
268
371
|
};
|
|
@@ -276,11 +379,12 @@ async function commitWorktreeAndVerify(git, worktreePath, message, excludePaths
|
|
|
276
379
|
async function commitWorktree(git, worktreePath, message, excludePaths = []) {
|
|
277
380
|
await commitWorktreeAndVerify(git, worktreePath, message, excludePaths);
|
|
278
381
|
}
|
|
279
|
-
/** Remove a worktree
|
|
280
|
-
*
|
|
281
|
-
*
|
|
382
|
+
/** Remove a worktree and optionally delete its branch. Explicit cleanup keeps
|
|
383
|
+
* the historical force default; automatic cleanup opts out. Removal failures
|
|
384
|
+
* throw so callers do not mark the ledger released while it is still mounted.
|
|
385
|
+
* Branch deletion remains best-effort. */
|
|
282
386
|
async function removeWorktree(git, input) {
|
|
283
|
-
const removed = await git.run(['worktree', 'remove', '--force', input.worktreePath], input.repoDir);
|
|
387
|
+
const removed = await git.run(['worktree', 'remove', ...(input.force === false ? [] : ['--force']), input.worktreePath], input.repoDir);
|
|
284
388
|
if (removed.code !== 0) {
|
|
285
389
|
throw new Error(`git worktree remove failed for ${input.worktreePath}: ${gitFailure(removed, `exit ${removed.code}`)}`);
|
|
286
390
|
}
|
|
@@ -4,6 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.OVERLAY_MANIFEST = void 0;
|
|
7
|
+
exports.fingerprintOverlayCleanupPath = fingerprintOverlayCleanupPath;
|
|
8
|
+
exports.captureOverlayCleanupEvidence = captureOverlayCleanupEvidence;
|
|
9
|
+
exports.matchesOverlayCleanupEvidence = matchesOverlayCleanupEvidence;
|
|
10
|
+
exports.matchesOverlayCleanupEvidenceAtPath = matchesOverlayCleanupEvidenceAtPath;
|
|
11
|
+
exports.revalidateOverlayCleanupEvidence = revalidateOverlayCleanupEvidence;
|
|
7
12
|
exports.applyWorktreeOverlay = applyWorktreeOverlay;
|
|
8
13
|
/**
|
|
9
14
|
* Per-run worktree overlay — materializes a project's framework surface INTO an
|
|
@@ -44,6 +49,7 @@ exports.applyWorktreeOverlay = applyWorktreeOverlay;
|
|
|
44
49
|
*/
|
|
45
50
|
const fs_1 = __importDefault(require("fs"));
|
|
46
51
|
const path_1 = __importDefault(require("path"));
|
|
52
|
+
const crypto_1 = require("crypto");
|
|
47
53
|
/** Overlay manifest filename (worktree root). Overlay-owned + git-excluded. */
|
|
48
54
|
exports.OVERLAY_MANIFEST = '.sr-rail-overlay.json';
|
|
49
55
|
/** providerDir children that must NEVER be linked into a worktree: nested
|
|
@@ -82,6 +88,161 @@ function readManifest(manifestPath) {
|
|
|
82
88
|
return [];
|
|
83
89
|
}
|
|
84
90
|
}
|
|
91
|
+
function safeRelativePath(value) {
|
|
92
|
+
// `value` is already constructed with POSIX separators. Preserve whitespace
|
|
93
|
+
// and, on POSIX, a literal backslash: both are valid filename characters.
|
|
94
|
+
// On Windows a backslash is a separator and is rejected fail-closed.
|
|
95
|
+
if (process.platform === 'win32' && value.includes('\\'))
|
|
96
|
+
return null;
|
|
97
|
+
if (value.split('/').includes('..'))
|
|
98
|
+
return null;
|
|
99
|
+
const normalized = path_1.default.posix.normalize(value);
|
|
100
|
+
if (!normalized || normalized === '.' || normalized.startsWith('../') ||
|
|
101
|
+
path_1.default.posix.isAbsolute(normalized) || normalized.includes('\0'))
|
|
102
|
+
return null;
|
|
103
|
+
return normalized;
|
|
104
|
+
}
|
|
105
|
+
function sourcePathForOverlayEntry(input, rel) {
|
|
106
|
+
if (rel === '.mcp.json' || rel === input.instructionsFilename) {
|
|
107
|
+
return path_1.default.join(input.sourceRoot, rel);
|
|
108
|
+
}
|
|
109
|
+
const providerPrefix = `${input.providerDir}/`;
|
|
110
|
+
if (!rel.startsWith(providerPrefix))
|
|
111
|
+
return null;
|
|
112
|
+
const providerRel = rel.slice(providerPrefix.length);
|
|
113
|
+
if (!providerRel || providerRel === 'worktrees' || providerRel.startsWith('worktrees/'))
|
|
114
|
+
return null;
|
|
115
|
+
return path_1.default.join(input.sourceRoot, ...rel.split('/'));
|
|
116
|
+
}
|
|
117
|
+
function sha256(parts) {
|
|
118
|
+
const hash = (0, crypto_1.createHash)('sha256');
|
|
119
|
+
for (const part of parts)
|
|
120
|
+
hash.update(part);
|
|
121
|
+
return hash.digest('hex');
|
|
122
|
+
}
|
|
123
|
+
/** Content fingerprint that follows nested links. This deliberately matches
|
|
124
|
+
* the copy fallback's dereferencing semantics. */
|
|
125
|
+
function dereferencedDigest(target, ancestors = new Set()) {
|
|
126
|
+
try {
|
|
127
|
+
const stat = fs_1.default.statSync(target);
|
|
128
|
+
if (stat.isFile())
|
|
129
|
+
return sha256(['file\0', fs_1.default.readFileSync(target)]);
|
|
130
|
+
if (!stat.isDirectory())
|
|
131
|
+
return null;
|
|
132
|
+
const real = fs_1.default.realpathSync(target);
|
|
133
|
+
if (ancestors.has(real))
|
|
134
|
+
return null;
|
|
135
|
+
const nextAncestors = new Set(ancestors).add(real);
|
|
136
|
+
const parts = ['directory\0'];
|
|
137
|
+
for (const name of fs_1.default.readdirSync(target).sort()) {
|
|
138
|
+
const childDigest = dereferencedDigest(path_1.default.join(target, name), nextAncestors);
|
|
139
|
+
if (!childDigest)
|
|
140
|
+
return null;
|
|
141
|
+
parts.push(name, '\0', childDigest, '\0');
|
|
142
|
+
}
|
|
143
|
+
return sha256(parts);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function fingerprintOverlayCleanupPath(target) {
|
|
150
|
+
try {
|
|
151
|
+
const stat = fs_1.default.lstatSync(target);
|
|
152
|
+
if (stat.isSymbolicLink()) {
|
|
153
|
+
const resolved = path_1.default.resolve(path_1.default.dirname(target), fs_1.default.readlinkSync(target));
|
|
154
|
+
return { kind: 'symlink', digest: sha256(['symlink\0', resolved]) };
|
|
155
|
+
}
|
|
156
|
+
if (stat.isFile())
|
|
157
|
+
return { kind: 'file', digest: sha256(['file\0', fs_1.default.readFileSync(target)]) };
|
|
158
|
+
if (stat.isDirectory()) {
|
|
159
|
+
const digest = dereferencedDigest(target);
|
|
160
|
+
return digest ? { kind: 'directory', digest } : null;
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/** Authenticate candidate manifest entries against the configured overlay
|
|
169
|
+
* source and capture immutable cleanup evidence. The writable manifest alone
|
|
170
|
+
* never grants ownership of an arbitrary worktree path. */
|
|
171
|
+
function captureOverlayCleanupEvidence(input, candidates, includeManifest = false) {
|
|
172
|
+
const evidence = [];
|
|
173
|
+
const seen = new Set();
|
|
174
|
+
for (const candidate of candidates) {
|
|
175
|
+
if (typeof candidate !== 'string')
|
|
176
|
+
continue;
|
|
177
|
+
const rel = safeRelativePath(candidate);
|
|
178
|
+
if (!rel || seen.has(rel))
|
|
179
|
+
continue;
|
|
180
|
+
const destination = path_1.default.join(input.worktreePath, ...rel.split('/'));
|
|
181
|
+
if (rel === exports.OVERLAY_MANIFEST) {
|
|
182
|
+
if (!includeManifest)
|
|
183
|
+
continue;
|
|
184
|
+
const fingerprint = fingerprintOverlayCleanupPath(destination);
|
|
185
|
+
if (fingerprint) {
|
|
186
|
+
evidence.push({ path: rel, ...fingerprint });
|
|
187
|
+
seen.add(rel);
|
|
188
|
+
}
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
const source = sourcePathForOverlayEntry(input, rel);
|
|
192
|
+
if (!source)
|
|
193
|
+
continue;
|
|
194
|
+
const destinationStat = lstatSafe(destination);
|
|
195
|
+
if (!destinationStat)
|
|
196
|
+
continue;
|
|
197
|
+
if (destinationStat.isSymbolicLink()) {
|
|
198
|
+
try {
|
|
199
|
+
if (path_1.default.resolve(path_1.default.dirname(destination), fs_1.default.readlinkSync(destination)) !== path_1.default.resolve(source))
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
const sourceDigest = dereferencedDigest(source);
|
|
208
|
+
const destinationDigest = dereferencedDigest(destination);
|
|
209
|
+
if (!sourceDigest || sourceDigest !== destinationDigest)
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
const fingerprint = fingerprintOverlayCleanupPath(destination);
|
|
213
|
+
if (!fingerprint)
|
|
214
|
+
continue;
|
|
215
|
+
evidence.push({ path: rel, ...fingerprint });
|
|
216
|
+
seen.add(rel);
|
|
217
|
+
}
|
|
218
|
+
return evidence;
|
|
219
|
+
}
|
|
220
|
+
/** Revalidate one persisted overlay proof against the live worktree. */
|
|
221
|
+
function matchesOverlayCleanupEvidence(worktreePath, evidence) {
|
|
222
|
+
const rel = safeRelativePath(evidence.path);
|
|
223
|
+
if (!rel || !/^[0-9a-f]{64}$/.test(evidence.digest))
|
|
224
|
+
return false;
|
|
225
|
+
return matchesOverlayCleanupEvidenceAtPath(path_1.default.join(worktreePath, ...rel.split('/')), evidence);
|
|
226
|
+
}
|
|
227
|
+
/** Revalidate persisted evidence against an explicit path. Cleanup uses this
|
|
228
|
+
* for leaf-by-leaf deletion inside an authenticated copied directory. */
|
|
229
|
+
function matchesOverlayCleanupEvidenceAtPath(target, evidence) {
|
|
230
|
+
if (!/^[0-9a-f]{64}$/.test(evidence.digest))
|
|
231
|
+
return false;
|
|
232
|
+
const live = fingerprintOverlayCleanupPath(target);
|
|
233
|
+
return live?.kind === evidence.kind && live.digest === evidence.digest;
|
|
234
|
+
}
|
|
235
|
+
/** Narrow allocation-time authority after a run. Revalidation may revoke an
|
|
236
|
+
* entry but can never replace its original fingerprint with a newly modified
|
|
237
|
+
* value (especially important for the source-less writable manifest). */
|
|
238
|
+
function revalidateOverlayCleanupEvidence(input, original) {
|
|
239
|
+
const originalByPath = new Map(original.map((entry) => [entry.path, entry]));
|
|
240
|
+
return captureOverlayCleanupEvidence(input, original.map((entry) => entry.path), true)
|
|
241
|
+
.filter((live) => {
|
|
242
|
+
const prior = originalByPath.get(live.path);
|
|
243
|
+
return prior?.kind === live.kind && prior.digest === live.digest;
|
|
244
|
+
});
|
|
245
|
+
}
|
|
85
246
|
/**
|
|
86
247
|
* Create `dest` as a link to `src` (symlink on POSIX; junction-then-symlink on
|
|
87
248
|
* Windows for dirs), degrading to a dereferencing COPY when links fail.
|
|
@@ -189,15 +350,15 @@ function applyWorktreeOverlay(input) {
|
|
|
189
350
|
const warnings = [];
|
|
190
351
|
const created = [];
|
|
191
352
|
const manifestPath = path_1.default.join(worktreePath, exports.OVERLAY_MANIFEST);
|
|
192
|
-
const prior = readManifest(manifestPath);
|
|
353
|
+
const prior = captureOverlayCleanupEvidence(input, readManifest(manifestPath)).map((entry) => entry.path);
|
|
193
354
|
try {
|
|
194
355
|
if (!isDir(worktreePath)) {
|
|
195
356
|
warnings.push(`worktree dir missing: ${worktreePath}`);
|
|
196
|
-
return { createdPaths:
|
|
357
|
+
return { createdPaths: [], cleanupEvidence: [], warnings };
|
|
197
358
|
}
|
|
198
359
|
if (path_1.default.resolve(sourceRoot) === path_1.default.resolve(worktreePath)) {
|
|
199
360
|
// Paranoia: never overlay a worktree onto itself.
|
|
200
|
-
return { createdPaths:
|
|
361
|
+
return { createdPaths: [], cleanupEvidence: [], warnings };
|
|
201
362
|
}
|
|
202
363
|
// 1. providerDir merge-overlay (commands/agents/skills/rules/settings/…).
|
|
203
364
|
const srcProvider = path_1.default.join(sourceRoot, providerDir);
|
|
@@ -257,5 +418,6 @@ function applyWorktreeOverlay(input) {
|
|
|
257
418
|
warnings.push(`failed to write overlay manifest: ${errMsg(err)}`);
|
|
258
419
|
}
|
|
259
420
|
}
|
|
260
|
-
|
|
421
|
+
const cleanupEvidence = captureOverlayCleanupEvidence(input, all, true);
|
|
422
|
+
return { createdPaths: cleanupEvidence.map((entry) => entry.path), cleanupEvidence, warnings };
|
|
261
423
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as ee}from"./rolldown-runtime-CNC7AqOf.js";var te=ee({addFavoriteConversation:()=>G,approval:()=>E,attachFile:()=>H,attachment:()=>s,chip:()=>N,close:()=>d,composerPlaceholder:()=>r,confirmDeleteConversation:()=>W,confirmShort:()=>q,connecting:()=>g,consultingCode:()=>_,copy:()=>o,default:()=>ie,degraded:()=>A,deleteConversation:()=>U,effort:()=>Y,emptyHint:()=>m,emptyTitle:()=>p,emptyTitleCodeRain:()=>re,error:()=>M,favoriteMissions:()=>z,git:()=>C,header:()=>$,history:()=>b,home:()=>R,imagesUnsupported:()=>J,maximize:()=>c,minimize:()=>u,mission:()=>O,model:()=>y,newAgent:()=>P,newConversation:()=>f,noProvider:()=>k,palette:()=>D,prCard:()=>X,project:()=>ne,provider:()=>w,queue:()=>x,queueEdit:()=>S,refs:()=>Q,removeFavoriteConversation:()=>K,restore:()=>l,search:()=>L,send:()=>i,size:()=>v,specDraft:()=>Z,stop:()=>a,subtitle:()=>t,switchToAgent:()=>F,switchToKanban:()=>I,thinking:()=>h,tier:()=>T,title:()=>e,toolCard:()=>j,trigger:()=>n,untitled:()=>B,workspace:()=>V}),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={openPreview:`Preview {{name}}`,openDownload:`Download {{name}}`,previewTitle:`Preview {{name}}`,downloadTitle:`Download file?`,downloadPrompt:`This file cannot be previewed here. Do you want to download it?`,download:`Download`,cancelDownload:`Not now`,loading:`Preparing file…`,loadFailed:`Could not load attachment`,loadError:`Could not load attachment: {{error}}`},c=`Maximize`,l=`Restore`,u=`Minimize`,d=`Close`,f=`New mission`,p=`What's the mission?`,m=`Pick a project, then ask. The board updates live as the agent works.`,h=`Thinking…`,g=`Connecting…`,_=`Consulting the app…`,v={compact:`Compact`,comfortable:`Comfortable`,max:`Maximize`},y={label:`Model`,loading:`Loading models…`,unavailable:`Models unavailable`},b={hint:`Browsing prompt history — type to edit, ↑↓ to navigate`},x={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…`},S={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`},C={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`},w={label:`Provider`,claude:`Claude`,codex:`Codex`,gemini:`Gemini`},T={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.`},E={title:`Confirm action`,costAction:`{{action}} · ~{{cost}} · {{tier}}`,approve:`Approve`,cancel:`Cancel`,dontAskAgain:`Don't ask again this session`,approved:`Approved`,cancelled:`Cancelled`},ne={home:`Home`,searchPlaceholder:`Talk to Specrails…`,searchProjectsPlaceholder:`Search projects…`,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?`},D={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`}},O={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`},k={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…`},A={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`},j={live:`live`,queued:`queued`,running:`running`,done:`done`,failed:`failed`},M={generic:`Something went wrong. Try again.`,busy:`The agent is busy. Try again in a moment.`},N={kindAgent:`Agent mission`},P=`New Mission`,F=`Switch to Mission Control`,I=`Switch to Board`,L=`Search`,R=`Home`,z=`Favorite missions`,B=`Untitled`,V={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`},H=`Attach file`,U=`Delete "{{title}}"`,W=`Confirm delete "{{title}}"`,G=`Add "{{title}}" to favorites`,K=`Remove "{{title}}" from favorites`,q=`confirm?`,J=`This provider can't read images yet — attach text files instead`,Y={label:`Effort`,minimal:`Minimal`,low:`Low`,medium:`Medium`,high:`High`,xhigh:`Extra high`},X={operation:{inProgress:`Action in progress…`,"create-pr":`Creating PR…`,publish:`Publishing…`,discard:`Discarding…`,dismiss:`Dismissing…`,"poll-merge":`Checking merge…`,reopen:`Reopening…`,"merge-local":`Integrating locally…`,"acknowledge-no-changes":`Marking done…`},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…`,paused:`Needs a human decision`,on_review:`Implementation ready for review`,pr_draft:`Draft PR created`,pr_draft_degraded:`PR delivery incomplete`,pr_ready:`PR ready for merge`,no_changes:`No changes needed`,partial:`Partially implemented`,delivery_blocked:`Implementation complete — delivery needs attention`,update_failed:`Implementation complete — update failed`,pr_closed:`PR closed without merge`,superseded:`Superseded by a newer run`,existing_pr_updated:`Existing PR updated`,implementation_failed:`Implementation failed`,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.`,paused:`Implementation paused`,pausedForRun:`Paused on {{ref}}`,resume:`Resume`,stopExecution:`Stop execution`,stopExecutionSent:`Stop signal sent`,stopExecutionFailed:`Could not stop execution`,partialSummary:`{{succeeded}} of {{total}} completed; {{failed}} failed`,unit:{failed:`implementation failed`,blocked:`delivery blocked`,noChanges:`no changes`,succeeded:`ready`},createPr:`Create PR`,publish:`Publish`,checkout:`Checkout`,checkoutTooltip:`Check out {{branch}} in the main project folder`,checkoutSuccess:`Checked out {{branch}}`,checkoutFailed:`Could not check out the PR branch`,retry:`Retry`,retryPr:`Retry PR`,checkMerge:`Check merge`,discard:`Discard`,dismiss:`Dismiss`,discardLocalResult:`Discard local result`,markDone:`Mark done`,refine:`Refine`,retryPush:`Retry push`,reopen:`Reopen`,createPartialPr:`Create PR with {{count}}`,confirmDiscard:`Confirm discard?`,mergedNote:`Merged — specs moved to Done`,discardedNote:`Discarded — specs returned to the backlog`,supersededNote:`A newer implementation run replaced this card.`,completedNote:`Confirmed — specs moved to Done`,noChangesExisting:`No new changes were needed; the existing PR is unchanged.`,noChangesNote:`No code changes were needed. Mark the specs done or return them to the backlog to refine.`,deliveryNeedsAttention:`Implementation complete; delivery needs attention`,deliveryBlockedNote:`Implementation succeeded, but delivery is blocked. Review the stage detail and run logs before discarding the local result.`,retryPushNote:`Implementation succeeded and the changes are safe locally. Retry only the push.`,cleanupIncomplete_one:`Cleanup is incomplete ({{count}} warning)`,cleanupIncomplete_other:`Cleanup is incomplete ({{count}} warnings)`,implementationFailedNote:`The implementation run failed before there was anything deliverable. Open the run log to inspect the failure, then discard this card before relaunching.`,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`,no_changes:`No changes`,completed:`Completed`,pr_closed:`Closed`,superseded:`Superseded`,implementation_failed:`Failed`,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`,confirm:{mergeLocalTitle:`Integrate locally?`,mergeLocalBody:`The delivered branches will be merged into {{base}} in your local checkout. Your checkout must be on {{base}} with a clean working tree.`,freshDiscardTitle:`Discard this delivery?`,freshDiscardBody:`The launch's branches and worktrees will be removed and its specs will return to the backlog. This cannot be undone.`,implementationFailedDiscardTitle:`Discard this failed delivery?`,implementationFailedDiscardBody:`The card will be cleared and its specs will return to the backlog. Local work and branches will be kept for inspection. Only resources proven safe to clean up may be removed.`,dismissTitle:`Dismiss this follow-up?`,dismissBody:`Only this follow-up card and its owned worktree will be cleared. The existing PR, its branch, and review state will remain unchanged.`,discardLocalTitle:`Discard the local result?`,discardLocalBody:`The recoverable local iteration will be removed. Any existing PR and its branch will remain unchanged. This cannot be undone.`,noChangesDoneTitle:`Mark these specs done?`,noChangesDoneBody:`The implementation confirmed that no code changes are needed. The specs will move to Done and the no-change worktree will be cleaned up.`,refineTitle:`Refine these specs?`,refineBody:`The no-change result will be closed and the specs will return to the backlog so you can refine them. The run logs remain available.`}},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`,copyTranscript:`Copy transcript`,copyTranscriptSuccess:`Transcript copied`,copyTranscriptFailed:`Could not copy transcript`,exportTranscript:`Export transcript (.txt)`,exportTranscriptSuccess:`Transcript export started`,exportTranscriptFailed:`Could not export transcript`,delete:`Delete mission`,deleteConfirm:`Delete this mission? This cannot be undone.`,deleteFailed:`Could not delete the mission`},re=`What should we build next?`,ie={title:e,subtitle:t,trigger:n,composerPlaceholder:r,send:i,stop:a,copy:o,attachment:s,maximize:c,restore:l,minimize:u,close:d,newConversation:f,emptyTitle:p,emptyHint:m,thinking:h,connecting:g,consultingCode:_,size:v,model:y,history:b,queue:x,queueEdit:S,git:C,provider:w,tier:T,approval:E,project:ne,palette:D,mission:O,noProvider:k,degraded:A,toolCard:j,error:M,chip:N,newAgent:P,switchToAgent:F,switchToKanban:I,search:L,home:R,favoriteMissions:z,untitled:B,workspace:V,attachFile:H,deleteConversation:U,confirmDeleteConversation:W,addFavoriteConversation:G,removeFavoriteConversation:K,confirmShort:q,imagesUnsupported:J,effort:Y,prCard:X,specDraft:Z,refs:Q,header:$,emptyTitleCodeRain:re};export{te as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=`Controllo missioni`,t=`Gestisci Specrails chattando`,n=`Controllo missioni`,r=`Chiedi all'agente qualsiasi cosa…`,i=`Invia`,a=`Ferma`,o=`Copia`,s={openPreview:`Anteprima di {{name}}`,openDownload:`Scarica {{name}}`,previewTitle:`Anteprima di {{name}}`,downloadTitle:`Scaricare il file?`,downloadPrompt:`Questo file non può essere visualizzato qui. Vuoi scaricarlo?`,download:`Scarica`,cancelDownload:`Non ora`,loading:`Preparazione del file…`,loadFailed:`Impossibile caricare l'allegato`,loadError:`Impossibile caricare l'allegato: {{error}}`},c=`Massimizza`,l=`Ripristina`,u=`Riduci a icona`,d=`Chiudi`,f=`Nuova missione`,p=`Qual è la missione?`,m=`Scegli un progetto, poi chiedi. La board si aggiorna in tempo reale mentre l'agente lavora.`,h=`Sto pensando…`,g=`Connessione…`,_=`Consulto l'app…`,v={compact:`Compatto`,comfortable:`Comodo`,max:`Ingrandisci`},y={label:`Modello`,loading:`Caricamento modelli…`,unavailable:`Modelli non disponibili`},b={hint:`Cronologia prompt — scrivi per modificare, ↑↓ per navigare`},x={queued:`In coda`,send:`Invia in coda`,sendHint:`L'agente sta ancora lavorando — questo messaggio verrà messo in coda ed eseguito dopo`,placeholder:`Aggiungi altro mentre l'agente lavora — verrà messo in coda…`},S={editing:`Modifica del messaggio in coda {{n}} di {{m}}`,hint:`↑↓ per navigare · Invio salva · Esc annulla`,save:`Salva messaggio in coda`,cancel:`Annulla modifica`,dispatched:`Quel messaggio in coda è già stato inviato — il tuo testo è conservato come bozza`,saveFailed:`Impossibile salvare il messaggio in coda`},C={branch:`Branch`,detached:`(detached)`,dirty:`Modifiche non committate`,switched:`Passato a {{branch}}`,switchFailed:`Impossibile cambiare branch`,lockedWhileWorking:`Branch bloccato mentre l'agente lavora`,searchPlaceholder:`Cerca branch…`,noMatches:`Nessun branch corrisponde`,worktrees:`Worktree`,worktreePathCopied:`Percorso del worktree copiato`,copyWorktreePath:`Copia percorso del worktree`},w={label:`Provider`,claude:`Claude`,codex:`Codex`,gemini:`Gemini`},T={cycleHint:`⇧⇥ per cambiare`,observe:{name:`Osserva`,desc:`Solo lettura — niente cambia`},edit:{name:`Modifica`,desc:`Crea e modifica (reversibile)`},operate:{name:`Opera`,desc:`Avvia l'IA — ha un costo`},autonomous:{name:`Autonomo`,desc:`Elimina e arresta — irreversibile`},lockedTitle:`Serve un livello superiore`,lockedBody:`Quell'azione richiede il livello «{{level}}». Sei su «{{current}}».`,raiseHint:`⇧⇥ per alzare il livello, o chiedi in un altro modo.`},E={title:`Conferma azione`,costAction:`{{action}} · ~{{cost}} · {{tier}}`,approve:`Approva`,cancel:`Annulla`,dontAskAgain:`Non chiedere più in questa sessione`,approved:`Approvato`,cancelled:`Annullato`},D={home:`Home`,searchPlaceholder:`Parla con Specrails…`,searchProjectsPlaceholder:`Cerca progetti…`,recents:`Recenti`,allProjects:`Tutti i progetti`,searchAll:`Cerca in tutti i progetti`,addProject:`Aggiungi progetto…`,homeHint:`Nessun progetto selezionato — operando su tutti i progetti.`,askCreateOrSearch:`Nessun progetto è selezionato. Vuoi creare un nuovo progetto o cercare in tutti i progetti?`},O={remove:`Rimuovi {{label}}`,addContextAction:`Aggiungi contesto o azione`,filtering:`Filtro "{{query}}"`,keyboard:`↑↓ Enter Esc`,noMatches:`Nessun risultato`,noMatchesFor:`Nessun risultato per "{{query}}"`,mode:{reference:{title:`Riferimento`,hint:`@ progetti, spec, missioni`},trace:{title:`Traccia`,hint:`# job, esecuzioni, ID`},action:{title:`Azione`,hint:`/ comandi per questo contesto`}},plus:{reference:`Riferimento`,referenceHint:`Progetti, spec, missioni`,trace:`Traccia`,traceHint:`Job, esecuzioni, ID`,action:`Azione`,actionHint:`Crea, avvia, ispeziona`,fileAttachment:`File allegato`,fileAttachmentHint:`Aggiungi doc, immagini, log`,browserCapture:`Cattura browser`,browserCaptureHint:`Disponibile dal browser del workspace`}},k={label:`Cambia missione`,untitled:`Nuova missione`,new:`Nuova missione`,searchPlaceholder:`Cerca missioni…`,noMatches:`Nessuna missione corrisponde`,working:`L'agente sta lavorando`,queuedBadge:`{{n}} in coda`,delete:`Elimina missione "{{title}}"`,deleteConfirm:`Eliminare?`,deleteLiveConfirm:`L'agente sta lavorando — eliminare comunque?`,confirmDelete:`Conferma eliminazione`,cancelDelete:`Mantieni missione`,deleteFailed:`Impossibile eliminare la missione`},A={title:`Nessun provider IA installato`,body:`L'agente richiede Claude, Codex o Gemini sul tuo computer. Installane uno e riapri l'agente per iniziare a chattare.`,placeholder:`Installa un provider IA per usare l'agente…`},j={title:`L'MCP di Specrails è spento`,body:`L'agente ha bisogno del server MCP integrato per gestire l'app.`,enable:`Attiva l'MCP di Specrails`,enabling:`Attivazione…`,enabled:`MCP attivato`},M={live:`in diretta`,queued:`in coda`,running:`in corso`,done:`completato`,failed:`fallito`},N={generic:`Qualcosa è andato storto. Riprova.`,busy:`L'agente è occupato. Riprova tra un momento.`},P={kindAgent:`Missione dell'agente`},F=`Nuova missione`,I=`Passa al Controllo missioni`,L=`Passa alla board`,R=`Cerca`,z=`Home`,B=`Missioni preferite`,V=`Senza titolo`,H={title:`Nel workspace`,terminal:`Terminale`,files:`File`,browser:`Browser`,requiresProject:`Seleziona un progetto per usare questo strumento`,resizeCode:`Ridimensiona pannello codice`,closeFiles:`Chiudi codice`,browserConfirm:`Aggiungi all'agente`,browserCaptured:`Cattura aggiunta`,uploadFailed:`Caricamento non riuscito`,requiresConversation:`Avvia una missione per usare questo strumento`,jobs:`Jobs`,closeJobs:`Chiudi jobs`,resizeJobs:`Ridimensiona pannello jobs`,noJobs:`Ancora nessun job — chiedi all'agente di lanciarne uno`},U=`Allega file`,W=`Elimina «{{title}}»`,G=`Conferma eliminazione di «{{title}}»`,K=`Aggiungi «{{title}}» ai preferiti`,q=`Rimuovi «{{title}}» dai preferiti`,J=`confermare?`,Y=`Questo provider non legge ancora le immagini — allega file di testo`,X={label:`Sforzo`,minimal:`Minimo`,low:`Basso`,medium:`Medio`,high:`Alto`,xhigh:`Extra alto`},Z={operation:{inProgress:`Azione in corso…`,"create-pr":`Creazione PR…`,publish:`Pubblicazione…`,discard:`Eliminazione…`,dismiss:`Chiusura avviso…`,"poll-merge":`Verifica merge…`,reopen:`Riapertura…`,"merge-local":`Integrazione locale…`,"acknowledge-no-changes":`Contrassegno come completato…`},markDone:`Segna come completate`,refine:`Perfeziona`,completedNote:`Confermato — le spec sono passate a Completate`,partialSummary:`{{succeeded}} di {{total}} completate; {{failed}} non riuscite`,unit:{failed:`implementazione non riuscita`,blocked:`consegna bloccata`,noChanges:`nessuna modifica`,succeeded:`pronta`},rail:`Rail {{index}}`,specCount_one:`{{count}} spec`,specCount_other:`{{count}} spec`,base:`Ramo base`,openPr:`Apri PR`,existingPr:`PR esistente`,title:{no_changes:`Nessuna modifica necessaria`,partial:`Implementazione parziale`,delivery_blocked:`Implementazione completa — la consegna richiede attenzione`,update_failed:`Implementazione completa — aggiornamento non riuscito`,pr_closed:`PR chiusa senza merge`,superseded:`Sostituita da un’esecuzione più recente`,existing_pr_updated:`PR esistente aggiornata`,building:`Implementazione in un worktree isolato…`,buildingExistingPr:`Applicazione delle modifiche su una PR esistente…`,paused:`Serve una decisione umana`,on_review:`Implementazione pronta per la revisione`,pr_draft:`PR in bozza creata`,pr_draft_degraded:`Consegna della PR incompleta`,pr_ready:`PR pronta per il merge`,implementation_failed:`Implementazione non riuscita`,pr_failed:`Creazione della PR non riuscita`,merged:`Merge della PR effettuato`,discarded:`Scartata`},buildingHint:`Al termine ti verrà chiesto se creare la PR.`,buildingExistingPrHint:`Specrails sta lavorando sul branch della PR esistente e invierà le modifiche di review a quella stessa PR.`,paused:`Implementazione in pausa`,pausedForRun:`In pausa su {{ref}}`,resume:`Riprendi`,stopExecution:`Interrompi esecuzione`,stopExecutionSent:`Segnale di stop inviato`,stopExecutionFailed:`Impossibile interrompere l’esecuzione`,createPr:`Crea PR`,publish:`Pubblica`,checkout:`Checkout`,checkoutTooltip:`Esegui il checkout di {{branch}} nella cartella principale del progetto`,checkoutSuccess:`Checkout eseguito su {{branch}}`,checkoutFailed:`Impossibile eseguire il checkout del branch della PR`,retry:`Riprova`,retryPr:`Riprova PR`,checkMerge:`Verifica merge`,discard:`Scarta`,confirmDiscard:`Confermare lo scarto?`,mergedNote:`Merge effettuato — le spec sono passate a Completato`,discardedNote:`Scartata — le spec sono tornate nel backlog`,implementationFailedNote:`Il run di implementazione non è riuscito prima di produrre qualcosa di consegnabile. Apri il log del run per controllare l'errore, poi scarta questa scheda prima di rilanciare.`,dismiss:`Ignora`,discardLocalResult:`Elimina risultato locale`,retryPush:`Riprova push`,reopen:`Riapri`,createPartialPr:`Crea PR con {{count}}`,supersededNote:`Un’esecuzione di implementazione più recente ha sostituito questa scheda.`,noChangesExisting:`Non erano necessarie nuove modifiche; la PR esistente resta invariata.`,noChangesNote:`Non erano necessarie modifiche al codice. Segna le spec come completate oppure riportale nel backlog per perfezionarle.`,deliveryNeedsAttention:`Implementazione completa; la consegna richiede attenzione`,deliveryBlockedNote:`L’implementazione è riuscita, ma la consegna è bloccata. Controlla il dettaglio della fase e i log prima di eliminare il risultato locale.`,retryPushNote:`L’implementazione è riuscita e le modifiche sono al sicuro in locale. Riprova solo il push.`,cleanupIncomplete_one:`Pulizia incompleta ({{count}} avviso)`,cleanupIncomplete_other:`Pulizia incompleta ({{count}} avvisi)`,confirm:{noChangesDoneTitle:`Segnare queste spec come completate?`,noChangesDoneBody:`L’implementazione ha confermato che non servono modifiche al codice. Le spec passeranno a Completate e il worktree senza modifiche verrà ripulito.`,refineTitle:`Perfezionare queste spec?`,refineBody:`Il risultato senza modifiche verrà chiuso e le spec torneranno nel backlog per essere perfezionate. I log di esecuzione resteranno disponibili.`,mergeLocalTitle:`Integrare localmente?`,mergeLocalBody:`I branch consegnati verranno uniti in {{base}} nel checkout locale. Il checkout deve trovarsi su {{base}} con un albero di lavoro pulito.`,freshDiscardTitle:`Eliminare questa consegna?`,freshDiscardBody:`I branch e i worktree dell’esecuzione verranno rimossi e le spec torneranno nel backlog. L’azione non può essere annullata.`,implementationFailedDiscardTitle:`Scartare questa consegna non riuscita?`,implementationFailedDiscardBody:`La scheda verrà chiusa e le spec torneranno nel backlog. Il lavoro locale e i branch saranno conservati per l’ispezione. Potranno essere rimosse solo le risorse la cui pulizia è dimostrata sicura.`,dismissTitle:`Ignorare questo follow-up?`,dismissBody:`Verranno rimossi solo questa scheda di follow-up e il relativo worktree. La PR esistente, il suo branch e lo stato di revisione resteranno invariati.`,discardLocalTitle:`Eliminare il risultato locale?`,discardLocalBody:`L’iterazione locale recuperabile verrà rimossa. Qualsiasi PR esistente e il suo branch resteranno invariati. L’azione non può essere annullata.`},degraded:{pushed:`Il ramo è stato inviato ma non è stato possibile creare la PR — riprova per completare.`,localOnly:`Le modifiche sono state assemblate in locale ma non inviate — riprova per pubblicare la PR.`},alreadyResolved:`Già risolta altrove`,actionFailed:`Azione non riuscita`,notMergedYet:`Ancora nessun merge`,viewLog:`Vedi il log di esecuzione di {{ref}}`,runElapsedAria:`{{elapsed}} trascorsi`,runCostAria:`{{cost}} spesi`,pinned:{label:`Fissata`,marker:`Scheda di implementazione — fissata sopra`,collapse:`Riduci la scheda fissata`,expand:`Espandi la scheda fissata`,expandCard:`Espandi questa scheda`,collapseCard:`Riduci questa scheda`,collapsed_one:`Scheda di implementazione`,collapsed_other:`{{count}} schede di implementazione`,state:{completed:`Completata`,no_changes:`Nessuna modifica`,pr_closed:`Chiusa`,superseded:`Sostituita`,building:`In corso`,on_review:`Revisione`,pr_draft:`PR bozza`,pr_ready:`Pubblicata`,implementation_failed:`Fallita`,pr_failed:`Fallita`,merged:`Unita`,discarded:`Scartata`}},mergeLocal:`Integra in locale`,mergeLocalTooltip:`Unisce i branch consegnati in {{base}} nel tuo checkout locale (senza GitHub)`,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.`,mergedLocally:`Integrato in {{base}} in locale`},Q={heading:`Bozza della spec`,drafting:`Aggiornamento della bozza…`,acceptanceCriteria:`Criteri di accettazione`,untitled:`Spec senza titolo`,expand:`Mostra descrizione completa`,collapse:`Comprimi descrizione`},$={openTicket:`Apri la spec #{{id}}`,openPullRequest:`Apri PR #{{id}}`,openJob:`Apri il job {{id}}`,openLoop:`Apri loop {{id}}`,ticketNotFound:`Spec #{{id}} non trovata — potrebbe essere stata eliminata`,pullRequestUrlMissing:`La PR #{{id}} è stata citata senza URL`,pullRequestNotFound:`La PR #{{id}} non è stata trovata in questo progetto`,jobNotFound:`Job non trovato — potrebbe essere stato eliminato`,loopNotFound:`Loop non trovato — potrebbe essere stato eliminato`,lookupFailed:`Impossibile verificare il riferimento — riprova`},ee={untitled:`Missione senza titolo`,menu:`Menu della missione`,rename:`Rinomina`,renamePlaceholder:`Nome della missione`,renameHint:`Doppio clic per rinominare`,renameFailed:`Impossibile rinominare`,addFavorite:`Aggiungi ai preferiti`,removeFavorite:`Rimuovi dai preferiti`,copyName:`Copia nome missione`,copyId:`Copia ID missione`,copyProject:`Copia nome progetto`,copyProjectPath:`Copia percorso progetto`,copyFailed:`Impossibile copiare`,copyTranscript:`Copia trascrizione`,copyTranscriptSuccess:`Trascrizione copiata`,copyTranscriptFailed:`Impossibile copiare la trascrizione`,exportTranscript:`Esporta trascrizione (.txt)`,exportTranscriptSuccess:`Esportazione della trascrizione avviata`,exportTranscriptFailed:`Impossibile esportare la trascrizione`,delete:`Elimina missione`,deleteConfirm:`Eliminare questa missione? Non è reversibile.`,deleteFailed:`Impossibile eliminare la missione`},te=`Cosa costruiamo adesso?`,ne={title:e,subtitle:t,trigger:n,composerPlaceholder:r,send:i,stop:a,copy:o,attachment:s,maximize:c,restore:l,minimize:u,close:d,newConversation:f,emptyTitle:p,emptyHint:m,thinking:h,connecting:g,consultingCode:_,size:v,model:y,history:b,queue:x,queueEdit:S,git:C,provider:w,tier:T,approval:E,project:D,palette:O,mission:k,noProvider:A,degraded:j,toolCard:M,error:N,chip:P,newAgent:F,switchToAgent:I,switchToKanban:L,search:R,home:z,favoriteMissions:B,untitled:V,workspace:H,attachFile:U,deleteConversation:W,confirmDeleteConversation:G,addFavoriteConversation:K,removeFavoriteConversation:q,confirmShort:J,imagesUnsupported:Y,effort:X,prCard:Z,specDraft:Q,refs:$,header:ee,emptyTitleCodeRain:te};export{K as addFavoriteConversation,E as approval,U as attachFile,s as attachment,P as chip,d as close,r as composerPlaceholder,G as confirmDeleteConversation,J as confirmShort,g as connecting,_ as consultingCode,o as copy,ne as default,j as degraded,W as deleteConversation,X as effort,m as emptyHint,p as emptyTitle,te as emptyTitleCodeRain,N as error,B as favoriteMissions,C as git,ee as header,b as history,z as home,Y as imagesUnsupported,c as maximize,u as minimize,k as mission,y as model,F as newAgent,f as newConversation,A as noProvider,O as palette,Z as prCard,D as project,w as provider,x as queue,S as queueEdit,$ as refs,q as removeFavoriteConversation,l as restore,R as search,i as send,v as size,Q as specDraft,a as stop,t as subtitle,I as switchToAgent,L as switchToKanban,h as thinking,T as tier,e as title,M as toolCard,n as trigger,V as untitled,H as workspace};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=`任务中心`,t=`通过对话操作 Specrails`,n=`任务中心`,r=`让智能体做任何事…`,i=`发送`,a=`停止`,o=`复制`,s={openPreview:`预览 {{name}}`,openDownload:`下载 {{name}}`,previewTitle:`{{name}} 预览`,downloadTitle:`下载文件?`,downloadPrompt:`此文件无法在此处预览。要下载它吗?`,download:`下载`,cancelDownload:`暂不`,loading:`正在准备文件…`,loadFailed:`无法加载附件`,loadError:`无法加载附件:{{error}}`},c=`最大化`,l=`还原`,u=`最小化`,d=`关闭`,f=`新任务`,p=`这次的任务是什么?`,m=`先选择一个项目,然后提问。智能体工作时看板会实时更新。`,h=`思考中…`,g=`连接中…`,_=`正在查询应用…`,v={compact:`紧凑`,comfortable:`舒适`,max:`最大化`},y={label:`模型`,loading:`正在加载模型…`,unavailable:`模型不可用`},b={hint:`浏览提示历史 — 输入以编辑,↑↓ 导航`},x={queued:`排队中`,send:`发送到队列`,sendHint:`智能体仍在工作——此消息将排队并在之后执行`,placeholder:`智能体工作时可继续输入——消息将排队…`},S={editing:`正在编辑排队消息 {{n}}/{{m}}`,hint:`↑↓ 导航 · 回车保存 · Esc 取消`,save:`保存排队消息`,cancel:`取消编辑`,dispatched:`该排队消息已发送——你的文本已保留为草稿`,saveFailed:`无法保存排队消息`},C={branch:`分支`,detached:`(分离头指针)`,dirty:`有未提交的更改`,switched:`已切换到 {{branch}}`,switchFailed:`无法切换分支`,lockedWhileWorking:`智能体工作时分支已锁定`,searchPlaceholder:`搜索分支…`,noMatches:`没有匹配的分支`,worktrees:`工作树`,worktreePathCopied:`已复制工作树路径`,copyWorktreePath:`复制工作树路径`},w={label:`提供方`,claude:`Claude`,codex:`Codex`,gemini:`Gemini`},T={cycleHint:`⇧⇥ 切换`,observe:{name:`观察`,desc:`只读 — 不做任何更改`},edit:{name:`编辑`,desc:`创建和编辑(可撤销)`},operate:{name:`操作`,desc:`启动 AI — 会产生费用`},autonomous:{name:`自主`,desc:`删除和终止 — 不可逆`},lockedTitle:`需要更高的级别`,lockedBody:`该操作需要「{{level}}」级别。你当前处于「{{current}}」。`,raiseHint:`⇧⇥ 提升级别,或换一种方式询问。`},E={title:`确认操作`,costAction:`{{action}} · ~{{cost}} · {{tier}}`,approve:`批准`,cancel:`取消`,dontAskAgain:`本次会话不再询问`,approved:`已批准`,cancelled:`已取消`},D={home:`主页`,searchPlaceholder:`与 Specrails 对话…`,searchProjectsPlaceholder:`搜索项目…`,recents:`最近`,allProjects:`所有项目`,searchAll:`在所有项目中搜索`,addProject:`添加项目…`,homeHint:`未选择项目 — 正在跨所有项目操作。`,askCreateOrSearch:`未选择任何项目。你想创建一个新项目,还是在所有项目中搜索?`},O={remove:`移除 {{label}}`,addContextAction:`添加上下文或操作`,filtering:`筛选 "{{query}}"`,keyboard:`↑↓ Enter Esc`,noMatches:`无匹配结果`,noMatchesFor:`没有 "{{query}}" 的匹配结果`,mode:{reference:{title:`引用`,hint:`@ 项目、规格、任务`},trace:{title:`追踪`,hint:`# 作业、运行、ID`},action:{title:`操作`,hint:`/ 此上下文的命令`}},plus:{reference:`引用`,referenceHint:`项目、规格、任务`,trace:`追踪`,traceHint:`作业、运行、ID`,action:`操作`,actionHint:`创建、启动、检查`,fileAttachment:`文件附件`,fileAttachmentHint:`添加文档、图片、日志`,browserCapture:`浏览器捕获`,browserCaptureHint:`可从工作区浏览器使用`}},k={label:`切换任务`,untitled:`新任务`,new:`新任务`,searchPlaceholder:`搜索任务…`,noMatches:`没有匹配的任务`,working:`代理正在工作`,queuedBadge:`{{n}} 条排队`,delete:`删除任务 "{{title}}"`,deleteConfirm:`删除?`,deleteLiveConfirm:`代理正在工作 — 仍要删除?`,confirmDelete:`确认删除`,cancelDelete:`保留任务`,deleteFailed:`无法删除任务`},A={title:`未安装 AI 提供方`,body:`智能体需要在你的机器上安装 Claude、Codex 或 Gemini。安装其中之一后重新打开智能体即可开始对话。`,placeholder:`请安装 AI 提供方以使用智能体…`},j={title:`Specrails MCP 已关闭`,body:`智能体需要内置的 MCP 服务器来操作应用。`,enable:`启用 Specrails MCP`,enabling:`正在启用…`,enabled:`MCP 已启用`},M={live:`实时`,queued:`排队中`,running:`运行中`,done:`已完成`,failed:`失败`},N={generic:`出了点问题。请重试。`,busy:`智能体正忙。请稍后重试。`},P={kindAgent:`智能体任务`},F=`新任务`,I=`切换到任务中心`,L=`切换到看板`,R=`搜索`,z=`主页`,B=`收藏任务`,V=`未命名`,H={title:`工作区`,terminal:`终端`,files:`文件`,browser:`浏览器`,requiresProject:`请选择一个项目以使用此工具`,resizeCode:`调整代码面板`,closeFiles:`关闭代码`,browserConfirm:`添加到智能体`,browserCaptured:`已添加捕获`,uploadFailed:`上传失败`,requiresConversation:`启动任务后才能使用此工具`,jobs:`作业`,closeJobs:`关闭作业`,resizeJobs:`调整作业面板大小`,noJobs:`还没有作业——让智能体启动一个吧`},U=`附加文件`,W=`删除「{{title}}」`,G=`确认删除「{{title}}」`,K=`将「{{title}}」添加到收藏`,q=`从收藏中移除「{{title}}」`,J=`确认?`,Y=`该提供商暂不支持读取图片 — 请附加文本文件`,X={label:`推理强度`,minimal:`最小`,low:`低`,medium:`中`,high:`高`,xhigh:`极高`},Z={operation:{inProgress:`操作进行中…`,"create-pr":`正在创建 PR…`,publish:`正在发布…`,discard:`正在丢弃…`,dismiss:`正在关闭提示…`,"poll-merge":`正在检查合并…`,reopen:`正在重新打开…`,"merge-local":`正在本地集成…`,"acknowledge-no-changes":`正在标记完成…`},markDone:`标记为完成`,refine:`细化`,completedNote:`已确认 — spec 已移至完成`,partialSummary:`{{total}} 个中 {{succeeded}} 个完成,{{failed}} 个失败`,unit:{failed:`实现失败`,blocked:`交付受阻`,noChanges:`无更改`,succeeded:`已就绪`},rail:`Rail {{index}}`,specCount_one:`{{count}} 个 Spec`,specCount_other:`{{count}} 个 Spec`,base:`基础分支`,openPr:`打开 PR`,existingPr:`现有 PR`,title:{no_changes:`无需更改`,partial:`部分实现完成`,delivery_blocked:`实现完成 — 交付需要处理`,update_failed:`实现完成 — 更新失败`,pr_closed:`PR 已关闭但未合并`,superseded:`已被较新的运行取代`,existing_pr_updated:`现有 PR 已更新`,building:`正在隔离的 worktree 中实现…`,buildingExistingPr:`正在向现有 PR 应用更改…`,paused:`需要人工决策`,on_review:`实现已完成,待评审`,pr_draft:`已创建草稿 PR`,pr_draft_degraded:`PR 交付未完成`,pr_ready:`PR 已就绪,可合并`,implementation_failed:`实现失败`,pr_failed:`PR 创建失败`,merged:`PR 已合并`,discarded:`已丢弃`},buildingHint:`完成后会询问你是否创建 PR。`,buildingExistingPrHint:`Specrails 正在现有 PR 的分支上工作,并会把 review 更改推送回同一个 PR。`,paused:`实现已暂停`,pausedForRun:`在 {{ref}} 暂停`,resume:`继续`,stopExecution:`停止执行`,stopExecutionSent:`已发送停止信号`,stopExecutionFailed:`无法停止执行`,createPr:`创建 PR`,publish:`发布`,checkout:`Checkout`,checkoutTooltip:`在项目主目录检出 {{branch}}`,checkoutSuccess:`已检出 {{branch}}`,checkoutFailed:`无法检出 PR 分支`,retry:`重试`,retryPr:`重试 PR`,checkMerge:`检查合并`,discard:`丢弃`,confirmDiscard:`确认丢弃?`,mergedNote:`已合并 — Spec 已移至完成`,discardedNote:`已丢弃 — Spec 已退回待办`,implementationFailedNote:`实现运行在生成可交付内容前失败。请打开运行日志查看失败原因,然后在重新启动前丢弃此卡片。`,dismiss:`关闭提示`,discardLocalResult:`丢弃本地结果`,retryPush:`重试推送`,reopen:`重新打开`,createPartialPr:`用 {{count}} 个结果创建 PR`,supersededNote:`较新的实现运行已取代此卡片。`,noChangesExisting:`无需新的更改;现有 PR 保持不变。`,noChangesNote:`无需更改代码。请将 spec 标记为完成,或退回待办列表继续细化。`,deliveryNeedsAttention:`实现完成;交付需要处理`,deliveryBlockedNote:`实现已成功,但交付受阻。丢弃本地结果前,请查看阶段详情和运行日志。`,retryPushNote:`实现已成功,更改安全保存在本地。请仅重试推送。`,cleanupIncomplete_one:`清理未完成({{count}} 条警告)`,cleanupIncomplete_other:`清理未完成({{count}} 条警告)`,confirm:{noChangesDoneTitle:`将这些 spec 标记为完成?`,noChangesDoneBody:`实现已确认无需更改代码。spec 将移至完成,并清理无更改的 worktree。`,refineTitle:`细化这些 spec?`,refineBody:`无更改结果将被关闭,spec 会返回待办列表以便细化。运行日志仍可查看。`,mergeLocalTitle:`在本地集成?`,mergeLocalBody:`已交付的分支将合并到本地 checkout 的 {{base}}。checkout 必须位于 {{base}},且工作树干净。`,freshDiscardTitle:`丢弃此交付?`,freshDiscardBody:`此次运行的分支和 worktree 将被删除,spec 将返回待办列表。此操作无法撤销。`,implementationFailedDiscardTitle:`丢弃此失败的交付?`,implementationFailedDiscardBody:`卡片将被关闭,spec 会返回待办列表。本地工作和分支将保留以供检查。只有确认可安全清理的资源才可能被移除。`,dismissTitle:`关闭此后续任务?`,dismissBody:`只会清除此后续卡片及其 worktree。现有 PR、分支和审查状态不会改变。`,discardLocalTitle:`丢弃本地结果?`,discardLocalBody:`可恢复的本地迭代将被删除。任何现有 PR 及其分支都不会改变。此操作无法撤销。`},degraded:{pushed:`分支已推送,但无法创建 PR — 请重试以完成。`,localOnly:`更改已在本地组装但未推送 — 请重试以发布 PR。`},alreadyResolved:`已在其他地方处理`,actionFailed:`操作失败`,notMergedYet:`尚未合并`,viewLog:`查看 {{ref}} 的运行日志`,runElapsedAria:`已运行 {{elapsed}}`,runCostAria:`已花费 {{cost}}`,pinned:{label:`已固定`,marker:`实现卡片 — 已固定在上方`,collapse:`最小化固定卡片`,expand:`展开固定卡片`,expandCard:`展开此卡片`,collapseCard:`最小化此卡片`,collapsed_one:`实现卡片`,collapsed_other:`{{count}} 张实现卡片`,state:{completed:`已完成`,no_changes:`无更改`,pr_closed:`已关闭`,superseded:`已取代`,building:`构建中`,on_review:`待审阅`,pr_draft:`草稿 PR`,pr_ready:`已发布`,implementation_failed:`失败`,pr_failed:`失败`,merged:`已合并`,discarded:`已丢弃`}},mergeLocal:`本地集成`,mergeLocalTooltip:`将交付的分支合并到本地检出的 {{base}}(无需 GitHub)`,mergeLocalBlockedDirty:`无法集成:{{base}} 上的工作树有未提交的更改。请提交或暂存后重试。`,mergeLocalBlockedBranch:`无法集成:当前检出在 {{current}},而不是 {{base}}。请切换到 {{base}} 后重试。`,mergedLocally:`已在本地集成到 {{base}}`},Q={heading:`规格草稿`,drafting:`正在更新草稿…`,acceptanceCriteria:`验收标准`,untitled:`未命名规格`,expand:`显示完整描述`,collapse:`收起描述`},$={openTicket:`打开 Spec #{{id}}`,openPullRequest:`打开 PR #{{id}}`,openJob:`打开任务 {{id}}`,openLoop:`打开循环 {{id}}`,ticketNotFound:`未找到 Spec #{{id}} — 可能已被删除`,pullRequestUrlMissing:`PR #{{id}} 被引用但没有 URL`,pullRequestNotFound:`在此项目中找不到 PR #{{id}}`,jobNotFound:`未找到任务 — 可能已被删除`,loopNotFound:`未找到循环 — 可能已被删除`,lookupFailed:`无法验证该引用 — 请重试`},ee={untitled:`未命名任务`,menu:`任务菜单`,rename:`重命名`,renamePlaceholder:`任务名称`,renameHint:`双击重命名`,renameFailed:`无法重命名`,addFavorite:`添加到收藏`,removeFavorite:`从收藏中移除`,copyName:`复制任务名称`,copyId:`复制任务 ID`,copyProject:`复制项目名称`,copyProjectPath:`复制项目路径`,copyFailed:`无法复制`,copyTranscript:`复制转录`,copyTranscriptSuccess:`转录已复制`,copyTranscriptFailed:`无法复制转录`,exportTranscript:`导出转录 (.txt)`,exportTranscriptSuccess:`转录导出已开始`,exportTranscriptFailed:`无法导出转录`,delete:`删除任务`,deleteConfirm:`删除此任务?此操作无法撤销。`,deleteFailed:`无法删除任务`},te=`接下来要构建什么?`,ne={title:e,subtitle:t,trigger:n,composerPlaceholder:r,send:i,stop:a,copy:o,attachment:s,maximize:c,restore:l,minimize:u,close:d,newConversation:f,emptyTitle:p,emptyHint:m,thinking:h,connecting:g,consultingCode:_,size:v,model:y,history:b,queue:x,queueEdit:S,git:C,provider:w,tier:T,approval:E,project:D,palette:O,mission:k,noProvider:A,degraded:j,toolCard:M,error:N,chip:P,newAgent:F,switchToAgent:I,switchToKanban:L,search:R,home:z,favoriteMissions:B,untitled:V,workspace:H,attachFile:U,deleteConversation:W,confirmDeleteConversation:G,addFavoriteConversation:K,removeFavoriteConversation:q,confirmShort:J,imagesUnsupported:Y,effort:X,prCard:Z,specDraft:Q,refs:$,header:ee,emptyTitleCodeRain:te};export{K as addFavoriteConversation,E as approval,U as attachFile,s as attachment,P as chip,d as close,r as composerPlaceholder,G as confirmDeleteConversation,J as confirmShort,g as connecting,_ as consultingCode,o as copy,ne as default,j as degraded,W as deleteConversation,X as effort,m as emptyHint,p as emptyTitle,te as emptyTitleCodeRain,N as error,B as favoriteMissions,C as git,ee as header,b as history,z as home,Y as imagesUnsupported,c as maximize,u as minimize,k as mission,y as model,F as newAgent,f as newConversation,A as noProvider,O as palette,Z as prCard,D as project,w as provider,x as queue,S as queueEdit,$ as refs,q as removeFavoriteConversation,l as restore,R as search,i as send,v as size,Q as specDraft,a as stop,t as subtitle,I as switchToAgent,L as switchToKanban,h as thinking,T as tier,e as title,M as toolCard,n as trigger,V as untitled,H as workspace};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=`Control de misiones`,t=`Maneja Specrails conversando`,n=`Control de misiones`,r=`Pídele al agente lo que necesites…`,i=`Enviar`,a=`Detener`,o=`Copiar`,s={openPreview:`Previsualizar {{name}}`,openDownload:`Descargar {{name}}`,previewTitle:`Vista previa de {{name}}`,downloadTitle:`¿Descargar archivo?`,downloadPrompt:`Este archivo no se puede previsualizar aquí. ¿Quieres descargarlo?`,download:`Descargar`,cancelDownload:`Ahora no`,loading:`Preparando archivo…`,loadFailed:`No se pudo cargar el adjunto`,loadError:`No se pudo cargar el adjunto: {{error}}`},c=`Maximizar`,l=`Restaurar`,u=`Minimizar`,d=`Cerrar`,f=`Nueva misión`,p=`¿Cuál es la misión?`,m=`Elige un proyecto y luego pregunta. El tablero se actualiza en vivo mientras el agente trabaja.`,h=`Pensando…`,g=`Conectando…`,_=`Consultando la app…`,v={compact:`Compacto`,comfortable:`Cómodo`,max:`Maximizar`},y={label:`Modelo`,loading:`Cargando modelos…`,unavailable:`Modelos no disponibles`},b={hint:`Explorando historial de prompts — escribe para editar, ↑↓ para navegar`},x={queued:`En cola`,send:`Enviar a la cola`,sendHint:`El agente sigue trabajando — este mensaje se pondrá en cola y se ejecutará después`,placeholder:`Añade más mientras el agente trabaja — se pondrá en cola…`},S={editing:`Editando mensaje en cola {{n}} de {{m}}`,hint:`↑↓ para navegar · Enter guarda · Esc cancela`,save:`Guardar mensaje en cola`,cancel:`Cancelar edición`,dispatched:`Ese mensaje en cola ya se envió — tu texto se conserva como borrador`,saveFailed:`No se pudo guardar el mensaje en cola`},C={branch:`Rama`,detached:`(detached)`,dirty:`Cambios sin commitear`,switched:`Cambiado a {{branch}}`,switchFailed:`No se pudo cambiar de rama`,lockedWhileWorking:`Rama bloqueada mientras el agente trabaja`,searchPlaceholder:`Buscar ramas…`,noMatches:`Ninguna rama coincide`,worktrees:`Worktrees`,worktreePathCopied:`Ruta del worktree copiada`,copyWorktreePath:`Copiar ruta del worktree`},w={label:`Proveedor`,claude:`Claude`,codex:`Codex`,gemini:`Gemini`},T={cycleHint:`⇧⇥ para cambiar`,observe:{name:`Observa`,desc:`Solo lectura — nada cambia`},edit:{name:`Edita`,desc:`Crear y editar (reversible)`},operate:{name:`Opera`,desc:`Lanzar IA — tiene coste`},autonomous:{name:`Autónomo`,desc:`Borrar y detener — irreversible`},lockedTitle:`Necesita un nivel superior`,lockedBody:`Esa acción necesita el nivel «{{level}}». Estás en «{{current}}».`,raiseHint:`⇧⇥ para subir el nivel, o pídelo de otra forma.`},E={title:`Confirmar acción`,costAction:`{{action}} · ~{{cost}} · {{tier}}`,approve:`Aprobar`,cancel:`Cancelar`,dontAskAgain:`No volver a preguntar en esta sesión`,approved:`Aprobado`,cancelled:`Cancelado`},D={home:`Inicio`,searchPlaceholder:`Habla con Specrails…`,searchProjectsPlaceholder:`Buscar proyectos…`,recents:`Recientes`,allProjects:`Todos los proyectos`,searchAll:`Buscar en todos los proyectos`,addProject:`Añadir proyecto…`,homeHint:`Ningún proyecto seleccionado — operando en todos los proyectos.`,askCreateOrSearch:`No hay ningún proyecto seleccionado. ¿Quieres crear un proyecto nuevo o buscar en todos los proyectos?`},O={remove:`Quitar {{label}}`,addContextAction:`Añadir contexto o acción`,filtering:`Filtrando "{{query}}"`,keyboard:`↑↓ Enter Esc`,noMatches:`Sin resultados`,noMatchesFor:`Sin resultados para "{{query}}"`,mode:{reference:{title:`Referencia`,hint:`@ proyectos, especificaciones, misiones`},trace:{title:`Traza`,hint:`# jobs, ejecuciones, IDs`},action:{title:`Acción`,hint:`/ comandos para este contexto`}},plus:{reference:`Referencia`,referenceHint:`Proyectos, especificaciones, misiones`,trace:`Traza`,traceHint:`Jobs, ejecuciones, IDs`,action:`Acción`,actionHint:`Crear, lanzar, inspeccionar`,fileAttachment:`Archivo adjunto`,fileAttachmentHint:`Añadir docs, imágenes, logs`,browserCapture:`Captura del navegador`,browserCaptureHint:`Disponible desde el navegador del workspace`}},k={label:`Cambiar de misión`,untitled:`Nueva misión`,new:`Nueva misión`,searchPlaceholder:`Buscar misiones…`,noMatches:`Ninguna misión coincide`,working:`El agente está trabajando`,queuedBadge:`{{n}} en cola`,delete:`Eliminar misión "{{title}}"`,deleteConfirm:`¿Eliminar?`,deleteLiveConfirm:`El agente está trabajando — ¿eliminar igualmente?`,confirmDelete:`Confirmar eliminación`,cancelDelete:`Conservar misión`,deleteFailed:`No se pudo eliminar la misión`},A={title:`No hay ningún proveedor de IA instalado`,body:`El agente necesita Claude, Codex o Gemini en tu máquina. Instala uno y vuelve a abrir el agente para empezar a chatear.`,placeholder:`Instala un proveedor de IA para usar el agente…`},j={title:`El MCP de Specrails está apagado`,body:`El agente necesita el servidor MCP integrado para manejar la app.`,enable:`Activar el MCP de Specrails`,enabling:`Activando…`,enabled:`MCP activado`},M={live:`en vivo`,queued:`en cola`,running:`en curso`,done:`hecho`,failed:`fallido`},N={generic:`Algo salió mal. Inténtalo de nuevo.`,busy:`El agente está ocupado. Inténtalo de nuevo en un momento.`},P={kindAgent:`Misión del agente`},F=`Nueva misión`,I=`Cambiar a Control de misiones`,L=`Cambiar al tablero`,R=`Buscar`,z=`Inicio`,B=`Misiones favoritas`,V=`Sin título`,H={title:`En el workspace`,terminal:`Terminal`,files:`Archivos`,browser:`Navegador`,requiresProject:`Selecciona un proyecto para usar esta herramienta`,resizeCode:`Redimensionar panel de código`,closeFiles:`Cerrar código`,browserConfirm:`Añadir al agente`,browserCaptured:`Captura añadida`,uploadFailed:`Error al subir`,requiresConversation:`Inicia una misión para usar esta herramienta`,jobs:`Jobs`,closeJobs:`Cerrar jobs`,resizeJobs:`Redimensionar panel de jobs`,noJobs:`Aún no hay jobs — pide al agente que lance uno`},U=`Adjuntar archivo`,W=`Borrar «{{title}}»`,G=`Confirmar borrado de «{{title}}»`,K=`Añadir «{{title}}» a favoritas`,q=`Quitar «{{title}}» de favoritas`,J=`¿confirmar?`,Y=`Este proveedor aún no lee imágenes — adjunta archivos de texto`,X={label:`Esfuerzo`,minimal:`Mínimo`,low:`Bajo`,medium:`Medio`,high:`Alto`,xhigh:`Extra alto`},Z={operation:{inProgress:`Acción en curso…`,"create-pr":`Creando PR…`,publish:`Publicando…`,discard:`Descartando…`,dismiss:`Cerrando aviso…`,"poll-merge":`Comprobando merge…`,reopen:`Reabriendo…`,"merge-local":`Integrando en local…`,"acknowledge-no-changes":`Marcando como hecho…`},rail:`Rail {{index}}`,specCount_one:`{{count}} spec`,specCount_other:`{{count}} specs`,base:`Rama base`,openPr:`Abrir PR`,existingPr:`PR existente`,title:{building:`Implementando en un worktree aislado…`,buildingExistingPr:`Aplicando cambios sobre una PR existente…`,paused:`Necesita decisión humana`,on_review:`Implementación lista para revisar`,pr_draft:`PR en borrador creada`,pr_draft_degraded:`Entrega de la PR incompleta`,pr_ready:`PR lista para el merge`,no_changes:`No hacían falta cambios`,partial:`Implementación parcial`,delivery_blocked:`Implementación completa — la entrega requiere atención`,update_failed:`Implementación completa — falló la actualización`,pr_closed:`PR cerrada sin merge`,superseded:`Sustituida por una ejecución más reciente`,existing_pr_updated:`PR existente actualizada`,implementation_failed:`La implementación ha fallado`,pr_failed:`No se pudo crear la PR`,merged:`Merge de la PR completado`,discarded:`Descartada`},buildingHint:`Cuando termine, se te preguntará si crear la PR.`,buildingExistingPrHint:`Specrails está trabajando sobre la rama de la PR existente y subirá los cambios de revisión a esa misma PR.`,paused:`Implementación pausada`,pausedForRun:`Pausada en {{ref}}`,resume:`Reanudar`,stopExecution:`Detener ejecución`,stopExecutionSent:`Señal de parada enviada`,stopExecutionFailed:`No se pudo parar la ejecución`,partialSummary:`{{succeeded}} de {{total}} completadas; {{failed}} fallidas`,unit:{failed:`implementación fallida`,blocked:`entrega bloqueada`,noChanges:`sin cambios`,succeeded:`lista`},createPr:`Crear PR`,publish:`Publicar`,checkout:`Checkout`,checkoutTooltip:`Cambia la carpeta principal del proyecto a {{branch}}`,checkoutSuccess:`Checkout en {{branch}}`,checkoutFailed:`No se pudo hacer checkout de la rama de la PR`,retry:`Reintentar`,retryPr:`Reintentar PR`,checkMerge:`Comprobar merge`,discard:`Descartar`,dismiss:`Cerrar aviso`,discardLocalResult:`Descartar resultado local`,markDone:`Marcar como hecho`,refine:`Refinar`,retryPush:`Reintentar push`,reopen:`Reabrir`,createPartialPr:`Crear PR con {{count}}`,confirmDiscard:`¿Confirmar descarte?`,mergedNote:`Merge completado — las specs han pasado a Hecho`,discardedNote:`Descartada — las specs han vuelto al backlog`,supersededNote:`Una ejecución de implementación más reciente sustituyó esta tarjeta.`,completedNote:`Confirmado — las specs han pasado a Hecho`,noChangesExisting:`No hacían falta cambios nuevos; la PR existente no se ha modificado.`,noChangesNote:`No hacían falta cambios de código. Marca las specs como hechas o devuélvelas al backlog para refinarlas.`,deliveryNeedsAttention:`Implementación completa; la entrega requiere atención`,deliveryBlockedNote:`La implementación terminó correctamente, pero la entrega está bloqueada. Revisa la etapa y los registros antes de descartar el resultado local.`,retryPushNote:`La implementación terminó correctamente y los cambios están seguros en local. Reintenta solo el push.`,cleanupIncomplete_one:`La limpieza está incompleta ({{count}} aviso)`,cleanupIncomplete_other:`La limpieza está incompleta ({{count}} avisos)`,implementationFailedNote:`El run de implementación falló antes de generar algo entregable. Abre el log del run para revisar el fallo y descarta esta card antes de relanzar.`,degraded:{pushed:`La rama se subió pero no se pudo crear la PR — reintenta para terminar.`,localOnly:`Los cambios se ensamblaron en local pero no se subieron — reintenta para publicar la PR.`},alreadyResolved:`Ya resuelta en otro sitio`,actionFailed:`La acción falló`,notMergedYet:`Aún sin merge`,viewLog:`Ver el registro de ejecución de {{ref}}`,runElapsedAria:`{{elapsed}} transcurridos`,runCostAria:`{{cost}} gastados`,pinned:{label:`Fijada`,marker:`Tarjeta de implementación — fijada arriba`,collapse:`Minimizar tarjeta fijada`,expand:`Expandir tarjeta fijada`,expandCard:`Expandir esta tarjeta`,collapseCard:`Minimizar esta tarjeta`,collapsed_one:`Tarjeta de implementación`,collapsed_other:`{{count}} tarjetas de implementación`,state:{building:`En curso`,on_review:`Revisión`,pr_draft:`PR borrador`,pr_ready:`Publicada`,no_changes:`Sin cambios`,completed:`Completada`,pr_closed:`Cerrada`,superseded:`Sustituida`,implementation_failed:`Fallida`,pr_failed:`Fallida`,merged:`Fusionada`,discarded:`Descartada`}},mergeLocal:`Integrar en local`,mergeLocalTooltip:`Fusiona las ramas entregadas en {{base}} en tu checkout local (sin necesidad de GitHub)`,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.`,mergedLocally:`Integrado en {{base}} en local`,confirm:{mergeLocalTitle:`¿Integrar en local?`,mergeLocalBody:`Las ramas entregadas se fusionarán en {{base}} en tu checkout local. Debes estar en {{base}} y tener el árbol de trabajo limpio.`,freshDiscardTitle:`¿Descartar esta entrega?`,freshDiscardBody:`Se eliminarán las ramas y worktrees del lanzamiento y sus specs volverán al backlog. Esta acción no se puede deshacer.`,implementationFailedDiscardTitle:`¿Descartar esta entrega fallida?`,implementationFailedDiscardBody:`Se cerrará la tarjeta y sus specs volverán al backlog. El trabajo local y las ramas se conservarán para su inspección. Solo se podrán eliminar los recursos cuya limpieza sea segura.`,dismissTitle:`¿Cerrar este seguimiento?`,dismissBody:`Solo se eliminarán esta tarjeta de seguimiento y su worktree. La PR existente, su rama y su estado de revisión no cambiarán.`,discardLocalTitle:`¿Descartar el resultado local?`,discardLocalBody:`Se eliminará la iteración local recuperable. Cualquier PR existente y su rama no cambiarán. Esta acción no se puede deshacer.`,noChangesDoneTitle:`¿Marcar estas specs como hechas?`,noChangesDoneBody:`La implementación confirmó que no hacen falta cambios de código. Las specs pasarán a Hecho y se limpiará el worktree sin cambios.`,refineTitle:`¿Refinar estas specs?`,refineBody:`Se cerrará el resultado sin cambios y las specs volverán al backlog para que puedas refinarlas. Los registros de ejecución seguirán disponibles.`}},Q={heading:`Borrador de spec`,drafting:`Actualizando borrador…`,acceptanceCriteria:`Criterios de aceptación`,untitled:`Spec sin título`,expand:`Ver descripción completa`,collapse:`Contraer descripción`},$={openTicket:`Abrir spec #{{id}}`,openPullRequest:`Abrir PR #{{id}}`,openJob:`Abrir job {{id}}`,openLoop:`Abrir loop {{id}}`,ticketNotFound:`Spec #{{id}} no encontrada — puede haber sido eliminada`,pullRequestUrlMissing:`La PR #{{id}} se mencionó sin URL`,pullRequestNotFound:`No se pudo encontrar la PR #{{id}} en este proyecto`,jobNotFound:`Job no encontrado — puede haber sido eliminado`,loopNotFound:`Loop no encontrado — puede haber sido eliminado`,lookupFailed:`No se pudo verificar la referencia — inténtalo de nuevo`},ee={untitled:`Misión sin título`,menu:`Menú de la misión`,rename:`Renombrar`,renamePlaceholder:`Nombre de la misión`,renameHint:`Doble clic para renombrar`,renameFailed:`No se pudo renombrar`,addFavorite:`Añadir a favoritas`,removeFavorite:`Quitar de favoritas`,copyName:`Copiar nombre de la misión`,copyId:`Copiar ID de la misión`,copyProject:`Copiar nombre del proyecto`,copyProjectPath:`Copiar ruta del proyecto`,copyFailed:`No se pudo copiar`,copyTranscript:`Copiar transcripción`,copyTranscriptSuccess:`Transcripción copiada`,copyTranscriptFailed:`No se pudo copiar la transcripción`,exportTranscript:`Exportar transcripción (.txt)`,exportTranscriptSuccess:`Exportación de transcripción iniciada`,exportTranscriptFailed:`No se pudo exportar la transcripción`,delete:`Borrar misión`,deleteConfirm:`¿Borrar esta misión? No se puede deshacer.`,deleteFailed:`No se pudo borrar la misión`},te=`¿Qué construimos ahora?`,ne={title:e,subtitle:t,trigger:n,composerPlaceholder:r,send:i,stop:a,copy:o,attachment:s,maximize:c,restore:l,minimize:u,close:d,newConversation:f,emptyTitle:p,emptyHint:m,thinking:h,connecting:g,consultingCode:_,size:v,model:y,history:b,queue:x,queueEdit:S,git:C,provider:w,tier:T,approval:E,project:D,palette:O,mission:k,noProvider:A,degraded:j,toolCard:M,error:N,chip:P,newAgent:F,switchToAgent:I,switchToKanban:L,search:R,home:z,favoriteMissions:B,untitled:V,workspace:H,attachFile:U,deleteConversation:W,confirmDeleteConversation:G,addFavoriteConversation:K,removeFavoriteConversation:q,confirmShort:J,imagesUnsupported:Y,effort:X,prCard:Z,specDraft:Q,refs:$,header:ee,emptyTitleCodeRain:te};export{K as addFavoriteConversation,E as approval,U as attachFile,s as attachment,P as chip,d as close,r as composerPlaceholder,G as confirmDeleteConversation,J as confirmShort,g as connecting,_ as consultingCode,o as copy,ne as default,j as degraded,W as deleteConversation,X as effort,m as emptyHint,p as emptyTitle,te as emptyTitleCodeRain,N as error,B as favoriteMissions,C as git,ee as header,b as history,z as home,Y as imagesUnsupported,c as maximize,u as minimize,k as mission,y as model,F as newAgent,f as newConversation,A as noProvider,O as palette,Z as prCard,D as project,w as provider,x as queue,S as queueEdit,$ as refs,q as removeFavoriteConversation,l as restore,R as search,i as send,v as size,Q as specDraft,a as stop,t as subtitle,I as switchToAgent,L as switchToKanban,h as thinking,T as tier,e as title,M as toolCard,n as trigger,V as untitled,H as workspace};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=`Controle de missões`,t=`Opere o Specrails conversando`,n=`Controle de missões`,r=`Peça ao agente o que quiser…`,i=`Enviar`,a=`Parar`,o=`Copiar`,s={openPreview:`Pré-visualizar {{name}}`,openDownload:`Transferir {{name}}`,previewTitle:`Pré-visualização de {{name}}`,downloadTitle:`Transferir ficheiro?`,downloadPrompt:`Este ficheiro não pode ser pré-visualizado aqui. Queres transferi-lo?`,download:`Transferir`,cancelDownload:`Agora não`,loading:`A preparar ficheiro…`,loadFailed:`Não foi possível carregar o anexo`,loadError:`Não foi possível carregar o anexo: {{error}}`},c=`Maximizar`,l=`Restaurar`,u=`Minimizar`,d=`Fechar`,f=`Nova missão`,p=`Qual é a missão?`,m=`Escolha um projeto e depois pergunte. O quadro é atualizado ao vivo enquanto o agente trabalha.`,h=`Pensando…`,g=`Conectando…`,_=`Consultando o app…`,v={compact:`Compacto`,comfortable:`Confortável`,max:`Maximizar`},y={label:`Modelo`,loading:`Carregando modelos…`,unavailable:`Modelos indisponíveis`},b={hint:`Explorando histórico — escreva para editar, ↑↓ para navegar`},x={queued:`Na fila`,send:`Enviar para a fila`,sendHint:`O agente ainda está trabalhando — esta mensagem entrará na fila e será executada em seguida`,placeholder:`Adicione mais enquanto o agente trabalha — entrará na fila…`},S={editing:`Editando mensagem na fila {{n}} de {{m}}`,hint:`↑↓ para navegar · Enter salva · Esc cancela`,save:`Salvar mensagem na fila`,cancel:`Cancelar edição`,dispatched:`Essa mensagem na fila já foi enviada — seu texto foi mantido como rascunho`,saveFailed:`Não foi possível salvar a mensagem na fila`},C={branch:`Branch`,detached:`(detached)`,dirty:`Alterações sem commit`,switched:`Mudou para {{branch}}`,switchFailed:`Não foi possível trocar de branch`,lockedWhileWorking:`Branch bloqueada enquanto o agente trabalha`,searchPlaceholder:`Buscar branches…`,noMatches:`Nenhuma branch corresponde`,worktrees:`Worktrees`,worktreePathCopied:`Caminho do worktree copiado`,copyWorktreePath:`Copiar caminho do worktree`},w={label:`Provedor`,claude:`Claude`,codex:`Codex`,gemini:`Gemini`},T={cycleHint:`⇧⇥ para mudar`,observe:{name:`Observa`,desc:`Somente leitura — nada muda`},edit:{name:`Edita`,desc:`Criar e editar (reversível)`},operate:{name:`Opera`,desc:`Lançar IA — tem custo`},autonomous:{name:`Autônomo`,desc:`Excluir e encerrar — irreversível`},lockedTitle:`Precisa de um nível superior`,lockedBody:`Essa ação precisa do nível "{{level}}". Você está no "{{current}}".`,raiseHint:`⇧⇥ para aumentar o nível, ou peça de outra forma.`},E={title:`Confirmar ação`,costAction:`{{action}} · ~{{cost}} · {{tier}}`,approve:`Aprovar`,cancel:`Cancelar`,dontAskAgain:`Não perguntar de novo nesta sessão`,approved:`Aprovado`,cancelled:`Cancelado`},D={home:`Início`,searchPlaceholder:`Fale com o Specrails…`,searchProjectsPlaceholder:`Buscar projetos…`,recents:`Recentes`,allProjects:`Todos os projetos`,searchAll:`Buscar em todos os projetos`,addProject:`Adicionar projeto…`,homeHint:`Nenhum projeto selecionado — operando em todos os projetos.`,askCreateOrSearch:`Nenhum projeto está selecionado. Você quer criar um novo projeto ou buscar em todos os projetos?`},O={remove:`Remover {{label}}`,addContextAction:`Adicionar contexto ou ação`,filtering:`Filtrando "{{query}}"`,keyboard:`↑↓ Enter Esc`,noMatches:`Sem resultados`,noMatchesFor:`Sem resultados para "{{query}}"`,mode:{reference:{title:`Referência`,hint:`@ projetos, specs, missões`},trace:{title:`Traço`,hint:`# jobs, execuções, IDs`},action:{title:`Ação`,hint:`/ comandos para este contexto`}},plus:{reference:`Referência`,referenceHint:`Projetos, specs, missões`,trace:`Traço`,traceHint:`Jobs, execuções, IDs`,action:`Ação`,actionHint:`Criar, lançar, inspecionar`,fileAttachment:`Anexo de arquivo`,fileAttachmentHint:`Adicionar docs, imagens, logs`,browserCapture:`Captura do navegador`,browserCaptureHint:`Disponível no navegador do workspace`}},k={label:`Trocar de missão`,untitled:`Nova missão`,new:`Nova missão`,searchPlaceholder:`Pesquisar missões…`,noMatches:`Nenhuma missão corresponde`,working:`O agente está trabalhando`,queuedBadge:`{{n}} na fila`,delete:`Excluir missão "{{title}}"`,deleteConfirm:`Excluir?`,deleteLiveConfirm:`O agente está trabalhando — excluir mesmo assim?`,confirmDelete:`Confirmar exclusão`,cancelDelete:`Manter missão`,deleteFailed:`Não foi possível excluir a missão`},A={title:`Nenhum provedor de IA instalado`,body:`O agente precisa de Claude, Codex ou Gemini na sua máquina. Instale um e reabra o agente para começar a conversar.`,placeholder:`Instale um provedor de IA para usar o agente…`},j={title:`O MCP do Specrails está desligado`,body:`O agente precisa do servidor MCP integrado para operar o app.`,enable:`Ativar o MCP do Specrails`,enabling:`Ativando…`,enabled:`MCP ativado`},M={live:`ao vivo`,queued:`na fila`,running:`em execução`,done:`concluído`,failed:`falhou`},N={generic:`Algo deu errado. Tente novamente.`,busy:`O agente está ocupado. Tente novamente em um instante.`},P={kindAgent:`Missão do agente`},F=`Nova missão`,I=`Mudar para o Controle de missões`,L=`Mudar para o quadro`,R=`Buscar`,z=`Início`,B=`Missões favoritas`,V=`Sem título`,H={title:`No workspace`,terminal:`Terminal`,files:`Arquivos`,browser:`Navegador`,requiresProject:`Selecione um projeto para usar esta ferramenta`,resizeCode:`Redimensionar painel de código`,closeFiles:`Fechar código`,browserConfirm:`Adicionar ao agente`,browserCaptured:`Captura adicionada`,uploadFailed:`Falha no upload`,requiresConversation:`Inicie uma missão para usar esta ferramenta`,jobs:`Jobs`,closeJobs:`Fechar jobs`,resizeJobs:`Redimensionar painel de jobs`,noJobs:`Ainda não há jobs — peça ao agente para lançar um`},U=`Anexar arquivo`,W=`Excluir "{{title}}"`,G=`Confirmar exclusão de "{{title}}"`,K=`Adicionar "{{title}}" aos favoritos`,q=`Remover "{{title}}" dos favoritos`,J=`confirmar?`,Y=`Este provedor ainda não lê imagens — anexe arquivos de texto`,X={label:`Esforço`,minimal:`Mínimo`,low:`Baixo`,medium:`Médio`,high:`Alto`,xhigh:`Extra alto`},Z={operation:{inProgress:`Ação em andamento…`,"create-pr":`Criando PR…`,publish:`Publicando…`,discard:`Descartando…`,dismiss:`Dispensando…`,"poll-merge":`Verificando merge…`,reopen:`Reabrindo…`,"merge-local":`Integrando localmente…`,"acknowledge-no-changes":`Marcando como concluído…`},markDone:`Marcar como concluídas`,refine:`Refinar`,completedNote:`Confirmado — as specs foram movidas para Concluído`,partialSummary:`{{succeeded}} de {{total}} concluídas; {{failed}} falharam`,unit:{failed:`implementação falhou`,blocked:`entrega bloqueada`,noChanges:`sem alterações`,succeeded:`pronta`},rail:`Rail {{index}}`,specCount_one:`{{count}} spec`,specCount_other:`{{count}} specs`,base:`Ramo base`,openPr:`Abrir PR`,existingPr:`PR existente`,title:{no_changes:`Nenhuma alteração necessária`,partial:`Implementação parcial`,delivery_blocked:`Implementação concluída — a entrega requer atenção`,update_failed:`Implementação concluída — falha na atualização`,pr_closed:`PR fechada sem merge`,superseded:`Substituída por uma execução mais recente`,existing_pr_updated:`PR existente atualizada`,building:`A implementar num worktree isolado…`,buildingExistingPr:`A aplicar alterações numa PR existente…`,paused:`Precisa de decisão humana`,on_review:`Implementação pronta para revisão`,pr_draft:`PR em rascunho criada`,pr_draft_degraded:`Entrega da PR incompleta`,pr_ready:`PR pronta para merge`,implementation_failed:`Implementação falhou`,pr_failed:`Falha ao criar a PR`,merged:`Merge da PR concluído`,discarded:`Descartada`},buildingHint:`Quando terminar, ser-lhe-á perguntado se quer criar a PR.`,buildingExistingPrHint:`O Specrails está a trabalhar no ramo da PR existente e irá enviar as alterações de revisão para essa mesma PR.`,paused:`Implementação em pausa`,pausedForRun:`Em pausa em {{ref}}`,resume:`Retomar`,stopExecution:`Parar execução`,stopExecutionSent:`Sinal de paragem enviado`,stopExecutionFailed:`Não foi possível parar a execução`,createPr:`Criar PR`,publish:`Publicar`,checkout:`Checkout`,checkoutTooltip:`Fazer checkout de {{branch}} na pasta principal do projeto`,checkoutSuccess:`Checkout feito em {{branch}}`,checkoutFailed:`Não foi possível fazer checkout do ramo da PR`,retry:`Tentar novamente`,retryPr:`Tentar PR novamente`,checkMerge:`Verificar merge`,discard:`Descartar`,confirmDiscard:`Confirmar descarte?`,mergedNote:`Merge concluído — specs movidas para Concluído`,discardedNote:`Descartada — specs devolvidas ao backlog`,implementationFailedNote:`A execução de implementação falhou antes de produzir algo entregável. Abra o log da execução para inspecionar a falha e descarte este cartão antes de relançar.`,dismiss:`Dispensar`,discardLocalResult:`Descartar resultado local`,retryPush:`Tentar push novamente`,reopen:`Reabrir`,createPartialPr:`Criar PR com {{count}}`,supersededNote:`Uma execução de implementação mais recente substituiu este cartão.`,noChangesExisting:`Nenhuma nova alteração foi necessária; a PR existente permanece inalterada.`,noChangesNote:`Nenhuma alteração de código foi necessária. Marque as specs como concluídas ou devolva-as ao backlog para refinamento.`,deliveryNeedsAttention:`Implementação concluída; a entrega requer atenção`,deliveryBlockedNote:`A implementação foi concluída com sucesso, mas a entrega está bloqueada. Revise os detalhes da etapa e os logs antes de descartar o resultado local.`,retryPushNote:`A implementação foi concluída com sucesso e as alterações estão seguras localmente. Tente novamente apenas o push.`,cleanupIncomplete_one:`Limpeza incompleta ({{count}} aviso)`,cleanupIncomplete_other:`Limpeza incompleta ({{count}} avisos)`,confirm:{noChangesDoneTitle:`Marcar estas specs como concluídas?`,noChangesDoneBody:`A implementação confirmou que nenhuma alteração de código é necessária. As specs serão movidas para Concluído e o worktree sem alterações será limpo.`,refineTitle:`Refinar estas specs?`,refineBody:`O resultado sem alterações será fechado e as specs voltarão ao backlog para refinamento. Os logs de execução permanecerão disponíveis.`,mergeLocalTitle:`Integrar localmente?`,mergeLocalBody:`Os branches entregues serão mesclados em {{base}} no checkout local. O checkout deve estar em {{base}} com a árvore de trabalho limpa.`,freshDiscardTitle:`Descartar esta entrega?`,freshDiscardBody:`Os branches e worktrees da execução serão removidos e as specs voltarão ao backlog. Esta ação não pode ser desfeita.`,implementationFailedDiscardTitle:`Descartar esta entrega com falha?`,implementationFailedDiscardBody:`O cartão será fechado e as specs voltarão ao backlog. O trabalho local e os branches serão preservados para inspeção. Apenas recursos comprovadamente seguros para limpeza poderão ser removidos.`,dismissTitle:`Dispensar este acompanhamento?`,dismissBody:`Apenas este cartão de acompanhamento e seu worktree serão removidos. A PR existente, seu branch e o estado da revisão permanecerão inalterados.`,discardLocalTitle:`Descartar o resultado local?`,discardLocalBody:`A iteração local recuperável será removida. Qualquer PR existente e seu branch permanecerão inalterados. Esta ação não pode ser desfeita.`},degraded:{pushed:`O ramo foi enviado mas não foi possível criar a PR — tente novamente para concluir.`,localOnly:`As alterações foram montadas localmente mas não enviadas — tente novamente para publicar a PR.`},alreadyResolved:`Já resolvida noutro lugar`,actionFailed:`A ação falhou`,notMergedYet:`Ainda sem merge`,viewLog:`Ver o registro de execução de {{ref}}`,runElapsedAria:`{{elapsed}} decorridos`,runCostAria:`{{cost}} gastos`,pinned:{label:`Fixada`,marker:`Cartão de implementação — fixado acima`,collapse:`Minimizar cartão fixado`,expand:`Expandir cartão fixado`,expandCard:`Expandir este cartão`,collapseCard:`Minimizar este cartão`,collapsed_one:`Cartão de implementação`,collapsed_other:`{{count}} cartões de implementação`,state:{completed:`Concluída`,no_changes:`Sem alterações`,pr_closed:`Fechada`,superseded:`Substituída`,building:`Em curso`,on_review:`Revisão`,pr_draft:`PR rascunho`,pr_ready:`Publicada`,implementation_failed:`Falhou`,pr_failed:`Falhou`,merged:`Integrada`,discarded:`Descartada`}},mergeLocal:`Integrar localmente`,mergeLocalTooltip:`Faz merge dos branches entregues em {{base}} no seu checkout local (sem GitHub)`,mergeLocalBlockedDirty:`Não é possível integrar: sua árvore de trabalho em {{base}} tem mudanças sem commit. Faça commit ou stash e tente de novo.`,mergeLocalBlockedBranch:`Não é possível integrar: seu checkout está em {{current}}, não em {{base}}. Mude para {{base}} e tente de novo.`,mergedLocally:`Integrado em {{base}} localmente`},Q={heading:`Rascunho da spec`,drafting:`Atualizando rascunho…`,acceptanceCriteria:`Critérios de aceitação`,untitled:`Spec sem título`,expand:`Ver descrição completa`,collapse:`Recolher descrição`},$={openTicket:`Abrir spec #{{id}}`,openPullRequest:`Abrir PR #{{id}}`,openJob:`Abrir job {{id}}`,openLoop:`Abrir loop {{id}}`,ticketNotFound:`Spec #{{id}} não encontrada — pode ter sido excluída`,pullRequestUrlMissing:`A PR #{{id}} foi mencionada sem URL`,pullRequestNotFound:`A PR #{{id}} não foi encontrada neste projeto`,jobNotFound:`Job não encontrado — pode ter sido excluído`,loopNotFound:`Loop não encontrado — pode ter sido excluído`,lookupFailed:`Não foi possível verificar a referência — tente novamente`},ee={untitled:`Missão sem título`,menu:`Menu da missão`,rename:`Renomear`,renamePlaceholder:`Nome da missão`,renameHint:`Duplo clique para renomear`,renameFailed:`Não foi possível renomear`,addFavorite:`Adicionar aos favoritos`,removeFavorite:`Remover dos favoritos`,copyName:`Copiar nome da missão`,copyId:`Copiar ID da missão`,copyProject:`Copiar nome do projeto`,copyProjectPath:`Copiar caminho do projeto`,copyFailed:`Não foi possível copiar`,copyTranscript:`Copiar transcrição`,copyTranscriptSuccess:`Transcrição copiada`,copyTranscriptFailed:`Não foi possível copiar a transcrição`,exportTranscript:`Exportar transcrição (.txt)`,exportTranscriptSuccess:`Exportação da transcrição iniciada`,exportTranscriptFailed:`Não foi possível exportar a transcrição`,delete:`Excluir missão`,deleteConfirm:`Excluir esta missão? Não pode ser desfeito.`,deleteFailed:`Não foi possível excluir a missão`},te=`O que devemos construir agora?`,ne={title:e,subtitle:t,trigger:n,composerPlaceholder:r,send:i,stop:a,copy:o,attachment:s,maximize:c,restore:l,minimize:u,close:d,newConversation:f,emptyTitle:p,emptyHint:m,thinking:h,connecting:g,consultingCode:_,size:v,model:y,history:b,queue:x,queueEdit:S,git:C,provider:w,tier:T,approval:E,project:D,palette:O,mission:k,noProvider:A,degraded:j,toolCard:M,error:N,chip:P,newAgent:F,switchToAgent:I,switchToKanban:L,search:R,home:z,favoriteMissions:B,untitled:V,workspace:H,attachFile:U,deleteConversation:W,confirmDeleteConversation:G,addFavoriteConversation:K,removeFavoriteConversation:q,confirmShort:J,imagesUnsupported:Y,effort:X,prCard:Z,specDraft:Q,refs:$,header:ee,emptyTitleCodeRain:te};export{K as addFavoriteConversation,E as approval,U as attachFile,s as attachment,P as chip,d as close,r as composerPlaceholder,G as confirmDeleteConversation,J as confirmShort,g as connecting,_ as consultingCode,o as copy,ne as default,j as degraded,W as deleteConversation,X as effort,m as emptyHint,p as emptyTitle,te as emptyTitleCodeRain,N as error,B as favoriteMissions,C as git,ee as header,b as history,z as home,Y as imagesUnsupported,c as maximize,u as minimize,k as mission,y as model,F as newAgent,f as newConversation,A as noProvider,O as palette,Z as prCard,D as project,w as provider,x as queue,S as queueEdit,$ as refs,q as removeFavoriteConversation,l as restore,R as search,i as send,v as size,Q as specDraft,a as stop,t as subtitle,I as switchToAgent,L as switchToKanban,h as thinking,T as tier,e as title,M as toolCard,n as trigger,V as untitled,H as workspace};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=`Contrôle des missions`,t=`Pilotez Specrails en discutant`,n=`Contrôle des missions`,r=`Demandez à l'agent ce que vous voulez…`,i=`Envoyer`,a=`Arrêter`,o=`Copier`,s={openPreview:`Prévisualiser {{name}}`,openDownload:`Télécharger {{name}}`,previewTitle:`Aperçu de {{name}}`,downloadTitle:`Télécharger le fichier ?`,downloadPrompt:`Ce fichier ne peut pas être prévisualisé ici. Voulez-vous le télécharger ?`,download:`Télécharger`,cancelDownload:`Pas maintenant`,loading:`Préparation du fichier…`,loadFailed:`Impossible de charger la pièce jointe`,loadError:`Impossible de charger la pièce jointe : {{error}}`},c=`Agrandir`,l=`Restaurer`,u=`Réduire`,d=`Fermer`,f=`Nouvelle mission`,p=`Quelle est la mission ?`,m=`Choisissez un projet, puis demandez. Le tableau se met à jour en direct pendant que l'agent travaille.`,h=`Réflexion…`,g=`Connexion…`,_=`Consultation de l'app…`,v={compact:`Compact`,comfortable:`Confortable`,max:`Agrandir`},y={label:`Modèle`,loading:`Chargement des modèles…`,unavailable:`Modèles indisponibles`},b={hint:`Parcours de l'historique — tapez pour modifier, ↑↓ pour naviguer`},x={queued:`En file`,send:`Envoyer dans la file`,sendHint:`L'agent travaille encore — ce message sera mis en file puis traité`,placeholder:`Ajoutez-en pendant que l'agent travaille — mis en file…`},S={editing:`Modification du message en file {{n}} sur {{m}}`,hint:`↑↓ pour naviguer · Entrée enregistre · Échap annule`,save:`Enregistrer le message en file`,cancel:`Annuler la modification`,dispatched:`Ce message en file a déjà été envoyé — votre texte est conservé comme brouillon`,saveFailed:`Impossible d'enregistrer le message en file`},C={branch:`Branche`,detached:`(détaché)`,dirty:`Modifications non commitées`,switched:`Basculé sur {{branch}}`,switchFailed:`Impossible de changer de branche`,lockedWhileWorking:`Branche verrouillée pendant que l'agent travaille`,searchPlaceholder:`Rechercher des branches…`,noMatches:`Aucune branche ne correspond`,worktrees:`Worktrees`,worktreePathCopied:`Chemin du worktree copié`,copyWorktreePath:`Copier le chemin du worktree`},w={label:`Fournisseur`,claude:`Claude`,codex:`Codex`,gemini:`Gemini`},T={cycleHint:`⇧⇥ pour changer`,observe:{name:`Observer`,desc:`Lecture seule — rien ne change`},edit:{name:`Modifier`,desc:`Créer et modifier (réversible)`},operate:{name:`Opérer`,desc:`Lancer l'IA — c'est payant`},autonomous:{name:`Autonome`,desc:`Supprimer et arrêter — irréversible`},lockedTitle:`Nécessite un niveau supérieur`,lockedBody:`Cette action nécessite le niveau « {{level}} ». Vous êtes sur « {{current}} ».`,raiseHint:`⇧⇥ pour augmenter le niveau, ou demandez autrement.`},E={title:`Confirmer l'action`,costAction:`{{action}} · ~{{cost}} · {{tier}}`,approve:`Approuver`,cancel:`Annuler`,dontAskAgain:`Ne plus demander durant cette session`,approved:`Approuvé`,cancelled:`Annulé`},D={home:`Accueil`,searchPlaceholder:`Parlez à Specrails…`,searchProjectsPlaceholder:`Rechercher des projets…`,recents:`Récents`,allProjects:`Tous les projets`,searchAll:`Rechercher dans tous les projets`,addProject:`Ajouter un projet…`,homeHint:`Aucun projet sélectionné — opération sur tous les projets.`,askCreateOrSearch:`Aucun projet n'est sélectionné. Voulez-vous créer un nouveau projet ou rechercher dans tous les projets ?`},O={remove:`Retirer {{label}}`,addContextAction:`Ajouter un contexte ou une action`,filtering:`Filtrage de "{{query}}"`,keyboard:`↑↓ Enter Esc`,noMatches:`Aucun résultat`,noMatchesFor:`Aucun résultat pour "{{query}}"`,mode:{reference:{title:`Référence`,hint:`@ projets, specs, missions`},trace:{title:`Trace`,hint:`# jobs, exécutions, IDs`},action:{title:`Action`,hint:`/ commandes pour ce contexte`}},plus:{reference:`Référence`,referenceHint:`Projets, specs, missions`,trace:`Trace`,traceHint:`Jobs, exécutions, IDs`,action:`Action`,actionHint:`Créer, lancer, inspecter`,fileAttachment:`Pièce jointe`,fileAttachmentHint:`Ajouter docs, images, logs`,browserCapture:`Capture navigateur`,browserCaptureHint:`Disponible depuis le navigateur du workspace`}},k={label:`Changer de mission`,untitled:`Nouvelle mission`,new:`Nouvelle mission`,searchPlaceholder:`Rechercher des missions…`,noMatches:`Aucune mission ne correspond`,working:`L'agent travaille`,queuedBadge:`{{n}} en file`,delete:`Supprimer la mission "{{title}}"`,deleteConfirm:`Supprimer ?`,deleteLiveConfirm:`L'agent travaille — supprimer quand même ?`,confirmDelete:`Confirmer la suppression`,cancelDelete:`Garder la mission`,deleteFailed:`Impossible de supprimer la mission`},A={title:`Aucun fournisseur d'IA installé`,body:`L'agent a besoin de Claude, Codex ou Gemini sur votre machine. Installez-en un, puis rouvrez l'agent pour discuter.`,placeholder:`Installez un fournisseur d'IA pour utiliser l'agent…`},j={title:`Le MCP Specrails est désactivé`,body:`L'agent a besoin du serveur MCP intégré pour piloter l'app.`,enable:`Activer le MCP Specrails`,enabling:`Activation…`,enabled:`MCP activé`},M={live:`en direct`,queued:`en file`,running:`en cours`,done:`terminé`,failed:`échoué`},N={generic:`Une erreur est survenue. Réessayez.`,busy:`L'agent est occupé. Réessayez dans un instant.`},P={kindAgent:`Mission de l'agent`},F=`Nouvelle mission`,I=`Passer au Contrôle des missions`,L=`Passer au tableau`,R=`Rechercher`,z=`Accueil`,B=`Missions favorites`,V=`Sans titre`,H={title:`Espace de travail`,terminal:`Terminal`,files:`Fichiers`,browser:`Navigateur`,requiresProject:`Sélectionnez un projet pour utiliser cet outil`,resizeCode:`Redimensionner le volet de code`,closeFiles:`Fermer le code`,browserConfirm:`Ajouter à l'agent`,browserCaptured:`Capture ajoutée`,uploadFailed:`Échec du téléversement`,requiresConversation:`Lancez une mission pour utiliser cet outil`,jobs:`Jobs`,closeJobs:`Fermer les jobs`,resizeJobs:`Redimensionner le panneau des jobs`,noJobs:`Aucun job pour l'instant — demandez à l'agent d'en lancer un`},U=`Joindre un fichier`,W=`Supprimer «\xA0{{title}}\xA0»`,G=`Confirmer la suppression de «\xA0{{title}}\xA0»`,K=`Ajouter «\xA0{{title}}\xA0» aux favorites`,q=`Retirer «\xA0{{title}}\xA0» des favorites`,J=`confirmer\xA0?`,Y=`Ce fournisseur ne lit pas encore les images — joignez plutôt des fichiers texte`,X={label:`Effort`,minimal:`Minimal`,low:`Faible`,medium:`Moyen`,high:`Élevé`,xhigh:`Très élevé`},Z={operation:{inProgress:`Action en cours…`,"create-pr":`Création de la PR…`,publish:`Publication…`,discard:`Suppression…`,dismiss:`Masquage…`,"poll-merge":`Vérification de la fusion…`,reopen:`Réouverture…`,"merge-local":`Intégration locale…`,"acknowledge-no-changes":`Marquage comme terminé…`},markDone:`Marquer comme terminées`,refine:`Affiner`,completedNote:`Confirmé — les specs sont passées à Terminé`,partialSummary:`{{succeeded}} sur {{total}} terminées ; {{failed}} en échec`,unit:{failed:`échec de l’implémentation`,blocked:`livraison bloquée`,noChanges:`aucune modification`,succeeded:`prête`},rail:`Rail {{index}}`,specCount_one:`{{count}} spec`,specCount_other:`{{count}} specs`,base:`Branche de base`,openPr:`Ouvrir la PR`,existingPr:`PR existante`,title:{no_changes:`Aucune modification nécessaire`,partial:`Implémentation partielle`,delivery_blocked:`Implémentation terminée — la livraison requiert votre attention`,update_failed:`Implémentation terminée — échec de la mise à jour`,pr_closed:`PR fermée sans fusion`,superseded:`Remplacée par une exécution plus récente`,existing_pr_updated:`PR existante mise à jour`,building:`Implémentation dans un worktree isolé…`,buildingExistingPr:`Application des changements sur une PR existante…`,paused:`Décision humaine requise`,on_review:`Implémentation prête pour la revue`,pr_draft:`PR en brouillon créée`,pr_draft_degraded:`Livraison de la PR incomplète`,pr_ready:`PR prête à être fusionnée`,implementation_failed:`Échec de l’implémentation`,pr_failed:`Échec de la création de la PR`,merged:`PR fusionnée`,discarded:`Abandonnée`},buildingHint:`À la fin, il vous sera proposé de créer la PR.`,buildingExistingPrHint:`Specrails travaille sur la branche de la PR existante et poussera les changements de revue vers cette même PR.`,paused:`Implémentation en pause`,pausedForRun:`En pause sur {{ref}}`,resume:`Reprendre`,stopExecution:`Arrêter l’exécution`,stopExecutionSent:`Signal d’arrêt envoyé`,stopExecutionFailed:`Impossible d’arrêter l’exécution`,createPr:`Créer la PR`,publish:`Publier`,checkout:`Checkout`,checkoutTooltip:`Basculer le dossier principal du projet sur {{branch}}`,checkoutSuccess:`Checkout effectué sur {{branch}}`,checkoutFailed:`Impossible de faire le checkout de la branche de la PR`,retry:`Réessayer`,retryPr:`Réessayer la PR`,checkMerge:`Vérifier le merge`,discard:`Abandonner`,confirmDiscard:`Confirmer l'abandon ?`,mergedNote:`Fusionnée — specs passées en Terminé`,discardedNote:`Abandonnée — specs renvoyées vers le backlog`,implementationFailedNote:`Le run d’implémentation a échoué avant de produire quelque chose de livrable. Ouvrez le journal du run pour inspecter l’échec, puis abandonnez cette carte avant de relancer.`,dismiss:`Masquer`,discardLocalResult:`Supprimer le résultat local`,retryPush:`Réessayer le push`,reopen:`Rouvrir`,createPartialPr:`Créer une PR avec {{count}}`,supersededNote:`Une exécution d’implémentation plus récente a remplacé cette carte.`,noChangesExisting:`Aucune nouvelle modification n’était nécessaire ; la PR existante reste inchangée.`,noChangesNote:`Aucune modification de code n’était nécessaire. Marquez les specs comme terminées ou renvoyez-les dans le backlog pour les affiner.`,deliveryNeedsAttention:`Implémentation terminée ; la livraison requiert votre attention`,deliveryBlockedNote:`L’implémentation a réussi, mais la livraison est bloquée. Consultez le détail de l’étape et les journaux avant de supprimer le résultat local.`,retryPushNote:`L’implémentation a réussi et les modifications sont en sécurité localement. Réessayez uniquement le push.`,cleanupIncomplete_one:`Nettoyage incomplet ({{count}} avertissement)`,cleanupIncomplete_other:`Nettoyage incomplet ({{count}} avertissements)`,confirm:{noChangesDoneTitle:`Marquer ces specs comme terminées ?`,noChangesDoneBody:`L’implémentation a confirmé qu’aucune modification de code n’est nécessaire. Les specs passeront à Terminé et le worktree sans changement sera nettoyé.`,refineTitle:`Affiner ces specs ?`,refineBody:`Le résultat sans modification sera fermé et les specs retourneront dans le backlog pour être affinées. Les journaux d’exécution resteront disponibles.`,mergeLocalTitle:`Intégrer localement ?`,mergeLocalBody:`Les branches livrées seront fusionnées dans {{base}} dans votre checkout local. Celui-ci doit être sur {{base}} avec un arbre de travail propre.`,freshDiscardTitle:`Supprimer cette livraison ?`,freshDiscardBody:`Les branches et worktrees de cette exécution seront supprimés et ses specs retourneront dans le backlog. Cette action est irréversible.`,implementationFailedDiscardTitle:`Abandonner cette livraison en échec ?`,implementationFailedDiscardBody:`La carte sera fermée et ses specs retourneront dans le backlog. Le travail local et les branches seront conservés pour inspection. Seules les ressources dont le nettoyage est prouvé sûr pourront être supprimées.`,dismissTitle:`Masquer ce suivi ?`,dismissBody:`Seuls cette carte de suivi et son worktree seront supprimés. La PR existante, sa branche et son état de revue resteront inchangés.`,discardLocalTitle:`Supprimer le résultat local ?`,discardLocalBody:`L’itération locale récupérable sera supprimée. Toute PR existante et sa branche resteront inchangées. Cette action est irréversible.`},degraded:{pushed:`La branche a été poussée mais la PR n'a pas pu être créée — réessayez pour terminer.`,localOnly:`Les modifications ont été assemblées en local mais pas poussées — réessayez pour publier la PR.`},alreadyResolved:`Déjà résolue ailleurs`,actionFailed:`L'action a échoué`,notMergedYet:`Pas encore fusionnée`,viewLog:`Voir le journal d'exécution de {{ref}}`,runElapsedAria:`{{elapsed}} écoulées`,runCostAria:`{{cost}} dépensés`,pinned:{label:`Épinglée`,marker:`Carte d’implémentation — épinglée ci-dessus`,collapse:`Réduire la carte épinglée`,expand:`Déployer la carte épinglée`,expandCard:`Développer cette carte`,collapseCard:`Réduire cette carte`,collapsed_one:`Carte d’implémentation`,collapsed_other:`{{count}} cartes d’implémentation`,state:{completed:`Terminée`,no_changes:`Aucune modification`,pr_closed:`Fermée`,superseded:`Remplacée`,building:`En cours`,on_review:`Revue`,pr_draft:`PR brouillon`,pr_ready:`Publiée`,implementation_failed:`Échec`,pr_failed:`Échec`,merged:`Fusionnée`,discarded:`Abandonnée`}},mergeLocal:`Intégrer en local`,mergeLocalTooltip:`Fusionne les branches livrées dans {{base}} dans votre checkout local (sans GitHub)`,mergeLocalBlockedDirty:`Impossible d'intégrer : votre arbre de travail sur {{base}} contient des changements non commités. Commitez ou stashez-les, puis réessayez.`,mergeLocalBlockedBranch:`Impossible d'intégrer : votre checkout est sur {{current}}, pas sur {{base}}. Passez sur {{base}}, puis réessayez.`,mergedLocally:`Intégré dans {{base}} en local`},Q={heading:`Brouillon de spec`,drafting:`Mise à jour du brouillon…`,acceptanceCriteria:`Critères d'acceptation`,untitled:`Spec sans titre`,expand:`Afficher la description complète`,collapse:`Réduire la description`},$={openTicket:`Ouvrir la spec #{{id}}`,openPullRequest:`Ouvrir la PR #{{id}}`,openJob:`Ouvrir le job {{id}}`,openLoop:`Ouvrir la boucle {{id}}`,ticketNotFound:`Spec #{{id}} introuvable — elle a peut-être été supprimée`,pullRequestUrlMissing:`La PR #{{id}} est mentionnée sans URL`,pullRequestNotFound:`PR #{{id}} introuvable dans ce projet`,jobNotFound:`Job introuvable — il a peut-être été supprimé`,loopNotFound:`Boucle introuvable — elle a peut-être été supprimée`,lookupFailed:`Impossible de vérifier la référence — réessayez`},ee={untitled:`Mission sans titre`,menu:`Menu de la mission`,rename:`Renommer`,renamePlaceholder:`Nom de la mission`,renameHint:`Double-clic pour renommer`,renameFailed:`Renommage impossible`,addFavorite:`Ajouter aux favorites`,removeFavorite:`Retirer des favorites`,copyName:`Copier le nom de la mission`,copyId:`Copier l'ID de la mission`,copyProject:`Copier le nom du projet`,copyProjectPath:`Copier le chemin du projet`,copyFailed:`Copie impossible`,copyTranscript:`Copier la transcription`,copyTranscriptSuccess:`Transcription copiée`,copyTranscriptFailed:`Impossible de copier la transcription`,exportTranscript:`Exporter la transcription (.txt)`,exportTranscriptSuccess:`Export de la transcription lancé`,exportTranscriptFailed:`Impossible d'exporter la transcription`,delete:`Supprimer la mission`,deleteConfirm:`Supprimer cette mission ? Action irréversible.`,deleteFailed:`Impossible de supprimer la mission`},te=`Que doit-on construire maintenant ?`,ne={title:e,subtitle:t,trigger:n,composerPlaceholder:r,send:i,stop:a,copy:o,attachment:s,maximize:c,restore:l,minimize:u,close:d,newConversation:f,emptyTitle:p,emptyHint:m,thinking:h,connecting:g,consultingCode:_,size:v,model:y,history:b,queue:x,queueEdit:S,git:C,provider:w,tier:T,approval:E,project:D,palette:O,mission:k,noProvider:A,degraded:j,toolCard:M,error:N,chip:P,newAgent:F,switchToAgent:I,switchToKanban:L,search:R,home:z,favoriteMissions:B,untitled:V,workspace:H,attachFile:U,deleteConversation:W,confirmDeleteConversation:G,addFavoriteConversation:K,removeFavoriteConversation:q,confirmShort:J,imagesUnsupported:Y,effort:X,prCard:Z,specDraft:Q,refs:$,header:ee,emptyTitleCodeRain:te};export{K as addFavoriteConversation,E as approval,U as attachFile,s as attachment,P as chip,d as close,r as composerPlaceholder,G as confirmDeleteConversation,J as confirmShort,g as connecting,_ as consultingCode,o as copy,ne as default,j as degraded,W as deleteConversation,X as effort,m as emptyHint,p as emptyTitle,te as emptyTitleCodeRain,N as error,B as favoriteMissions,C as git,ee as header,b as history,z as home,Y as imagesUnsupported,c as maximize,u as minimize,k as mission,y as model,F as newAgent,f as newConversation,A as noProvider,O as palette,Z as prCard,D as project,w as provider,x as queue,S as queueEdit,$ as refs,q as removeFavoriteConversation,l as restore,R as search,i as send,v as size,Q as specDraft,a as stop,t as subtitle,I as switchToAgent,L as switchToKanban,h as thinking,T as tier,e as title,M as toolCard,n as trigger,V as untitled,H as workspace};
|