specrails-desktop 2.43.0 → 2.43.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/dist/assets/{ActivityFeedPage-DoEMumQS.js → ActivityFeedPage-C7XJ5-bJ.js} +1 -1
- package/client/dist/assets/{AgentBrowserCapture-DIh4K0gh.js → AgentBrowserCapture-C_WpXceT.js} +1 -1
- package/client/dist/assets/{AgentModeAnalyticsPane-mbq4WEoO.js → AgentModeAnalyticsPane-PEZKjyZS.js} +2 -2
- package/client/dist/assets/{AgentModeCodePane-CKh7zuA4.js → AgentModeCodePane-D_Xcq5t5.js} +2 -2
- package/client/dist/assets/{AgentModeJobsPane-BDokPiLJ.js → AgentModeJobsPane-CDSkOuNP.js} +1 -1
- package/client/dist/assets/{AgentsPage-BFVAZbBj.js → AgentsPage-D577NzIM.js} +1 -1
- package/client/dist/assets/{AnalyticsPage-3Y9LuWwz.js → AnalyticsPage-C6ZZI_zg.js} +1 -1
- package/client/dist/assets/{CodePage-C9KyuV_C.js → CodePage-B5z5oLnP.js} +1 -1
- package/client/dist/assets/{DesktopAnalyticsPage-Bhi54bXQ.js → DesktopAnalyticsPage-D_V9RuGg.js} +1 -1
- package/client/dist/assets/{DocsDialog-Dj6mt4ga.js → DocsDialog-Beg82MEe.js} +1 -1
- package/client/dist/assets/{DocsPage-24yWglNI.js → DocsPage-BkE4m4wp.js} +1 -1
- package/client/dist/assets/{InteractiveJobComposer-C1ucmxQh.js → InteractiveJobComposer-wBBBNaJn.js} +1 -1
- package/client/dist/assets/JobDetailModal-BCxue_Do.js +1 -0
- package/client/dist/assets/{JobDetailPage-BcajZyuu.js → JobDetailPage-_rIDpNfo.js} +1 -1
- package/client/dist/assets/{JobsPage-B9nTZw6e.js → JobsPage-C6xcijbs.js} +1 -1
- package/client/dist/assets/{LoopBuilderPage-Oc48iOFW.js → LoopBuilderPage-A-Mt6EjT.js} +1 -1
- package/client/dist/assets/{LoopPreviewModal-ae0Fr6SU.js → LoopPreviewModal-DqHiG4Dt.js} +1 -1
- package/client/dist/assets/{LoopsPage-CUEqzUBI.js → LoopsPage-B-ketPET.js} +1 -1
- package/client/dist/assets/{PluginsPage-C1xtARIx.js → PluginsPage-Dn2jPvJL.js} +1 -1
- package/client/dist/assets/{ProjectSettingsDialog-JZzrXFBN.js → ProjectSettingsDialog-CVTj4VLt.js} +1 -1
- package/client/dist/assets/{RepositoryDeliveries-CSDsiVUz.js → RepositoryDeliveries-IiQCcndQ.js} +1 -1
- package/client/dist/assets/{ReviewPacketPage-x5EfGTiL.js → ReviewPacketPage-BBd617OM.js} +1 -1
- package/client/dist/assets/{TemplatePreviewModal-BSyuZxGq.js → TemplatePreviewModal-COHFkUS4.js} +1 -1
- package/client/dist/assets/{TicketDetailModalContext-DqyF0so-.js → TicketDetailModalContext-BNa1mdXq.js} +3 -3
- package/client/dist/assets/{button-DCBqEaZl.js → button-Ccc9Dc-D.js} +1 -1
- package/client/dist/assets/dialog-xXB2q5HJ.js +45 -0
- package/client/dist/assets/index-D5n_jg_I.css +2 -0
- package/client/dist/assets/index-m5pKr1T6.js +76 -0
- package/client/dist/index.html +6 -6
- package/docs/guide/en/pipeline/3-batch-implement-and-multi-feature.md +11 -0
- package/docs/internals/core-runtime-updates.md +7 -0
- package/docs/internals/interactive-jobs.md +53 -0
- package/package.json +1 -1
- package/server/dist/loop-executors.js +14 -1
- package/server/dist/loop-factory.js +24 -5
- package/server/dist/loop-run-manager.js +12 -0
- package/server/dist/loop-templates.js +14 -33
- package/server/dist/rails-router.js +2 -2
- package/server/dist/workspace-manager.js +54 -3
- package/client/dist/assets/JobDetailModal-DNWmgVHD.js +0 -1
- package/client/dist/assets/dialog-SRw01_QU.js +0 -45
- package/client/dist/assets/index-DwAmL7m5.css +0 -2
- package/client/dist/assets/index-EzrkUb8B.js +0 -76
package/client/dist/index.html
CHANGED
|
@@ -204,7 +204,7 @@
|
|
|
204
204
|
.specrails-splash__mark .pill { opacity: 1; }
|
|
205
205
|
}
|
|
206
206
|
</style>
|
|
207
|
-
<script type="module" crossorigin src="/assets/index-
|
|
207
|
+
<script type="module" crossorigin src="/assets/index-m5pKr1T6.js"></script>
|
|
208
208
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-CNC7AqOf.js">
|
|
209
209
|
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-zu2_FqZY.js">
|
|
210
210
|
<link rel="modulepreload" crossorigin href="/assets/react-dom-DiWzBDP9.js">
|
|
@@ -263,19 +263,19 @@
|
|
|
263
263
|
<link rel="modulepreload" crossorigin href="/assets/zap-CHo3aCD1.js">
|
|
264
264
|
<link rel="modulepreload" crossorigin href="/assets/clsx-CjueKrWZ.js">
|
|
265
265
|
<link rel="modulepreload" crossorigin href="/assets/utils-BC4DHlz2.js">
|
|
266
|
-
<link rel="modulepreload" crossorigin href="/assets/dialog-
|
|
266
|
+
<link rel="modulepreload" crossorigin href="/assets/dialog-xXB2q5HJ.js">
|
|
267
267
|
<link rel="modulepreload" crossorigin href="/assets/lib-CGdyxIWg.js">
|
|
268
268
|
<link rel="modulepreload" crossorigin href="/assets/getTimezoneOffsetInMilliseconds-YhD8rIEs.js">
|
|
269
269
|
<link rel="modulepreload" crossorigin href="/assets/formatDistanceToNow-DSj5DprF.js">
|
|
270
|
-
<link rel="modulepreload" crossorigin href="/assets/button-
|
|
270
|
+
<link rel="modulepreload" crossorigin href="/assets/button-Ccc9Dc-D.js">
|
|
271
271
|
<link rel="modulepreload" crossorigin href="/assets/project-repositories-DYhTvwQ1.js">
|
|
272
272
|
<link rel="modulepreload" crossorigin href="/assets/RepositoryScopeSelector-D-RCaknl.js">
|
|
273
273
|
<link rel="modulepreload" crossorigin href="/assets/provider-capabilities-B-wOHfLP.js">
|
|
274
|
-
<link rel="modulepreload" crossorigin href="/assets/TicketDetailModalContext-
|
|
274
|
+
<link rel="modulepreload" crossorigin href="/assets/TicketDetailModalContext-BNa1mdXq.js">
|
|
275
275
|
<link rel="modulepreload" crossorigin href="/assets/core-B3mKBIh5.js">
|
|
276
|
-
<link rel="modulepreload" crossorigin href="/assets/RepositoryDeliveries-
|
|
276
|
+
<link rel="modulepreload" crossorigin href="/assets/RepositoryDeliveries-IiQCcndQ.js">
|
|
277
277
|
<link rel="modulepreload" crossorigin href="/assets/event-Bt7f3wXe.js">
|
|
278
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
278
|
+
<link rel="stylesheet" crossorigin href="/assets/index-D5n_jg_I.css">
|
|
279
279
|
</head>
|
|
280
280
|
<body>
|
|
281
281
|
<div id="specrails-splash" aria-hidden="false" role="status" aria-label="Loading Specrails">
|
|
@@ -12,6 +12,17 @@ The simplest way to run a pile of specs from one rail is **Batch** mode:
|
|
|
12
12
|
|
|
13
13
|
The rail launches **one** `/specrails:batch-implement` job that works through every assigned spec. Monitor it like any other job on the Jobs page — it's a single job covering the whole set, not one job per spec.
|
|
14
14
|
|
|
15
|
+
The built-in Implement and Batch Implement graphs are **Start → Core command → End**.
|
|
16
|
+
Core owns implementation, review, verification and corrections; Desktop does not
|
|
17
|
+
append another Verify, Loop Decider or Fix cycle. Existing custom forks keep
|
|
18
|
+
their saved steps. Freestyle and Revision retain their own verification cycles.
|
|
19
|
+
|
|
20
|
+
SDD Quick (OpenSpec) uses **Start → prepare artifacts → apply and test → CLI
|
|
21
|
+
validate → CLI archive → End**. Apply handles code checks and corrections;
|
|
22
|
+
`openspec validate` checks the change artifacts before archiving. There is no
|
|
23
|
+
separate AI Verify or Loop Decider. Failed implementation checks or CLI validation
|
|
24
|
+
stop the run before archive. This lightweight path has no independent AI review.
|
|
25
|
+
|
|
15
26
|
Batch mode is still the cleanest way to *sequence* related specs because it keeps their dependency order inside one rail. If the specs are independent, you can also spread them across several rails: git-backed rails run in parallel and each one gets its own isolated worktree.
|
|
16
27
|
|
|
17
28
|
### Implement vs Batch — which mode?
|
|
@@ -25,6 +25,13 @@ Previous framework versions are retained. Windows repair reads the activated
|
|
|
25
25
|
version instead of choosing the highest directory, which could be an unfinished
|
|
26
26
|
stage.
|
|
27
27
|
|
|
28
|
+
Before a Windows rail starts, command repair also checks the `specrails`
|
|
29
|
+
namespace inside populated, real command directories. Missing command files and
|
|
30
|
+
dangling links are filled from that activated version even when OpenSpec or
|
|
31
|
+
custom commands are already present. Existing files and live links are preserved;
|
|
32
|
+
the repair does not write through a live link into another tree. This repair is
|
|
33
|
+
disabled on macOS and Linux.
|
|
34
|
+
|
|
28
35
|
Changing the shared pointer does not update copied project files. The update
|
|
29
36
|
therefore waits for all affected workspaces to be assembled again. Existing
|
|
30
37
|
provider installation configuration and MCP configuration are preserved. A
|
|
@@ -314,3 +314,56 @@ delivery row — stranded uncommitted work. Loops disabled ⇒ the legacy QueueM
|
|
|
314
314
|
unchanged. Relatedly, the agent-chat operator prompt gained the ask-confirmation-once
|
|
315
315
|
turn-discipline rule (`server/agent-operator-prompt.ts`): a confirmation question is asked
|
|
316
316
|
exactly once and ends the reply — the answer arrives as the next user message.
|
|
317
|
+
|
|
318
|
+
## Decider starved by its own tool budget (2026-09-07)
|
|
319
|
+
|
|
320
|
+
A two-repo `factory:implement` run (pipeline run `47b9a423`) finished its work, and the
|
|
321
|
+
verify step answered `VERIFICATION: PASS` with a freshly re-run receipt across both
|
|
322
|
+
repositories. The loop continued anyway. The Decider step's log line was the tell:
|
|
323
|
+
|
|
324
|
+
```
|
|
325
|
+
Decision: continue — error_max_turns: Reached maximum number of turns (1)
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
That is not a verdict. The Decider never emitted one — it died before answering, and the
|
|
329
|
+
executor's fail-open default did the rest.
|
|
330
|
+
|
|
331
|
+
- **The starvation.** `runDecider` spawned with `maxTurns: 1` *and* `toolPolicy:
|
|
332
|
+
'read-only'`, which on claude is `--tools Read,Grep,Glob` **plus `--permission-mode plan
|
|
333
|
+
--safe-mode`**. One tool call — a repo read, or plan mode's own exit call — consumes the
|
|
334
|
+
single allowed turn, so the run ends `error_max_turns` **before** the JSON verdict is
|
|
335
|
+
produced. Nothing about it is intermittent: a Decider that touches any tool can never
|
|
336
|
+
answer. The step burned 2 turns and ~$0.09 to say nothing.
|
|
337
|
+
- **Reproduced across loops and tiers.** A `SDD Quick (OpenSpec)` run on claude/**sonnet**
|
|
338
|
+
showed the identical signature — every Decider step `2 turns`, ~7 s, `Decision: continue
|
|
339
|
+
— error_max_turns`. Its verify step reported `VERIFICATION: PASS` twice, and the loop
|
|
340
|
+
still cycled `opsx:ff → opsx:apply → opsx:verify` for two full iterations (the fix steps
|
|
341
|
+
correctly finding nothing to do and saying so) until the user cancelled it. So the bug is
|
|
342
|
+
not model-, tier- or loop-specific: it is every Decider on claude.
|
|
343
|
+
- **Why it became a `continue`.** A failed Decider invocation is deliberately forced to
|
|
344
|
+
`{ continue: true, parsed: false }` — a streamed verdict from an interrupted run is not
|
|
345
|
+
an authoritative completion gate, and `maxIterations`/`timeout` are the hard stop. Sound
|
|
346
|
+
in isolation, but combined with the starvation above it meant *every* such run silently
|
|
347
|
+
discarded a real STOP and paid for another iteration: here a fix step that invented work
|
|
348
|
+
(tautological cascade tests, a mutation probe, a wrong conclusion, then a full revert)
|
|
349
|
+
plus a second full re-verification, for no change to the delivered candidate.
|
|
350
|
+
- **The fix.** The Decider judges from the prompt it is GIVEN (goal + spec + iteration
|
|
351
|
+
history) and must answer with one JSON object, so it needs no tools at all.
|
|
352
|
+
`runDecider` now picks the tightest boundary the CLI enforces via
|
|
353
|
+
`pureOutputToolPolicy(adapter)`: `'none'` on claude (`--tools __none__`, no approval
|
|
354
|
+
bypass needed), `'read-only'` on codex/gemini — byte-identical there, since neither has
|
|
355
|
+
a native no-tools mode. The null case is unreachable: `LoopRunManager.run` already
|
|
356
|
+
rejects a decider-bearing graph whose provider cannot enforce `read-only` natively
|
|
357
|
+
(kimi), before allocating or persisting the run. `'none'` also drops the plan-mode flags
|
|
358
|
+
(the adapter attaches them only to `read-only`), removing the second way the single turn
|
|
359
|
+
could be consumed. This aligns the Decider with the repo's other single-turn spawns —
|
|
360
|
+
`file-summary-generator.ts` and both `contract-refine-runner.ts` invocations already
|
|
361
|
+
resolve a pure-output policy rather than hardcoding `read-only`; the Decider was the last
|
|
362
|
+
one left with tools it could not afford to use.
|
|
363
|
+
- **Deliberately NOT changed:** the fail-open `continue` on a genuinely failed Decider
|
|
364
|
+
(timeout, spawn failure, non-zero exit, provider limit). The starvation was the bug; the
|
|
365
|
+
default is the safety net, and with tools gone it stops firing on every healthy run.
|
|
366
|
+
- **Adjacent, still open:** the verify step re-ran the full cross-repository suite each
|
|
367
|
+
iteration because the Core receipt is invalidated per session (*"Verification environment
|
|
368
|
+
changed: ./mvnw / npm"*) even when the candidate hash is identical. That is a receipt
|
|
369
|
+
env-hash question in specrails-core, not a desktop one.
|
package/package.json
CHANGED
|
@@ -488,7 +488,20 @@ function createLoopExecutors(opts = {}) {
|
|
|
488
488
|
const decEnv = aiStepEnv(baseEnv, repoDir, executionManifest);
|
|
489
489
|
// spec-gen is a one-shot, system-prompted invocation (workspace-write on
|
|
490
490
|
// codex, not full-access) — appropriate for a read-only judgment.
|
|
491
|
-
|
|
491
|
+
//
|
|
492
|
+
// The Decider judges the goal from the prompt it is GIVEN (goal + spec +
|
|
493
|
+
// iteration history) and must answer with a single JSON object, so it
|
|
494
|
+
// needs no tools. Granting them was actively harmful on claude: with
|
|
495
|
+
// `--max-turns 1`, one Read/Grep call consumes the whole turn budget and
|
|
496
|
+
// the run ends `error_max_turns` BEFORE the verdict is emitted. A failed
|
|
497
|
+
// Decider invocation is forced to `continue` below, so every such run
|
|
498
|
+
// silently discarded a real STOP verdict and burned another iteration.
|
|
499
|
+
// `pureOutputToolPolicy` picks the tightest boundary the CLI enforces:
|
|
500
|
+
// 'none' on claude, 'read-only' on codex/gemini (byte-identical to the
|
|
501
|
+
// previous behaviour there). The null case is unreachable — `run()`
|
|
502
|
+
// rejects a decider graph whose provider cannot enforce 'read-only'.
|
|
503
|
+
const toolPolicy = (0, runtime_1.pureOutputToolPolicy)(adapter) ?? 'read-only';
|
|
504
|
+
const buildOpts = { prompt: userPrompt, systemPrompt, model, maxTurns: 1, reasoning_effort: effort, toolPolicy, ...(executionManifest ? { extraArgs: aiStepExtraArgs(adapter, cwd, repoDir, executionManifest) } : {}) };
|
|
492
505
|
const wallStartedAt = Date.now();
|
|
493
506
|
const res = await (0, spawn_lifecycle_1.runAiCliInvocation)({
|
|
494
507
|
adapter,
|
|
@@ -16,10 +16,29 @@ const GREEN_GOAL = 'Stop only when the latest verification step reports {{const:
|
|
|
16
16
|
const FACTORY_MAX_ITERATIONS = 12;
|
|
17
17
|
const FACTORY_LOOP_TIMEOUT_MIN = 0;
|
|
18
18
|
const FACTORY_AI_STEP_TIMEOUT_MIN = 0;
|
|
19
|
+
/** Core owns the complete implementation/review cycle. Desktop runs it once. */
|
|
20
|
+
function coreImplementationGraph(command) {
|
|
21
|
+
return {
|
|
22
|
+
nodes: [
|
|
23
|
+
{ id: 'start', type: 'start', position: { x: 0, y: 0 } },
|
|
24
|
+
{ id: 'main-1', type: 'ai-step', position: { x: 0, y: 110 }, data: { prompt: `{{cmd:${command}}}` } },
|
|
25
|
+
{ id: 'done', type: 'end', position: { x: 0, y: 220 }, data: { outcome: 'success' } },
|
|
26
|
+
],
|
|
27
|
+
edges: [
|
|
28
|
+
{ id: 'e-start', source: 'start', target: 'main-1' },
|
|
29
|
+
{ id: 'e-main-1', source: 'main-1', target: 'done' },
|
|
30
|
+
],
|
|
31
|
+
config: {
|
|
32
|
+
maxIterations: FACTORY_MAX_ITERATIONS,
|
|
33
|
+
timeoutMinutes: FACTORY_LOOP_TIMEOUT_MIN,
|
|
34
|
+
aiStepTimeoutMinutes: FACTORY_AI_STEP_TIMEOUT_MIN,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
19
38
|
const SDD_QUICK_OPENSPEC_FACTORY = {
|
|
20
39
|
id: 'factory:sdd-quick-openspec',
|
|
21
40
|
name: 'SDD Quick (OpenSpec)',
|
|
22
|
-
description: 'Quick spec-driven OpenSpec lifecycle for small contract-governed changes:
|
|
41
|
+
description: 'Quick spec-driven OpenSpec lifecycle for small contract-governed changes: prepare artifacts, apply and test, validate through the CLI, then archive.',
|
|
23
42
|
mode: 'loop',
|
|
24
43
|
graph: (0, loop_templates_1.opsxLifecycleGraph)(),
|
|
25
44
|
};
|
|
@@ -29,16 +48,16 @@ exports.FACTORY_LOOPS = [
|
|
|
29
48
|
{
|
|
30
49
|
id: 'factory:implement',
|
|
31
50
|
name: 'Implement',
|
|
32
|
-
description: '
|
|
51
|
+
description: 'Run the Core implementation pipeline for the spec. Core owns implementation, review, verification and corrections.',
|
|
33
52
|
mode: 'implement',
|
|
34
|
-
graph: (
|
|
53
|
+
graph: coreImplementationGraph('implement'),
|
|
35
54
|
},
|
|
36
55
|
{
|
|
37
56
|
id: 'factory:batch',
|
|
38
57
|
name: 'Batch Implement',
|
|
39
|
-
description: '
|
|
58
|
+
description: 'Run the Core batch implementation pipeline for all the rail\'s tickets. Core owns implementation, review, verification and corrections across the batch.',
|
|
40
59
|
mode: 'batch-implement',
|
|
41
|
-
graph: (
|
|
60
|
+
graph: coreImplementationGraph('batch'),
|
|
42
61
|
},
|
|
43
62
|
{
|
|
44
63
|
id: 'factory:freestyle',
|
|
@@ -1251,6 +1251,13 @@ class LoopRunManager {
|
|
|
1251
1251
|
// session — plus zero-work); no exit code is exposed by the AI
|
|
1252
1252
|
// executors → null.
|
|
1253
1253
|
emitStepEnd({ status: stepFailed ? 'failed' : 'ok', durationMs: res.durationMs });
|
|
1254
|
+
// Linear workflows may forbid later actions (such as archive) after
|
|
1255
|
+
// a failed step. Verify/fix loops keep their existing recovery path.
|
|
1256
|
+
if (node.data?.stopOnFailure === true && stepFailed) {
|
|
1257
|
+
outcome = 'failed';
|
|
1258
|
+
settled = true;
|
|
1259
|
+
break;
|
|
1260
|
+
}
|
|
1254
1261
|
// Only carry forward the session of a step that actually ran — a
|
|
1255
1262
|
// hard-failed turn (codex still emits thread.started before its error)
|
|
1256
1263
|
// would otherwise make the next step `--resume` a dead session.
|
|
@@ -1349,6 +1356,11 @@ class LoopRunManager {
|
|
|
1349
1356
|
totalDurationMs: totalDuration,
|
|
1350
1357
|
});
|
|
1351
1358
|
history.push(`Shell \`${command}\` exit=${sh.exitCode}: ${truncate(sh.stdout || sh.stderr)}`);
|
|
1359
|
+
if (node.data?.stopOnFailure === true && sh.exitCode !== 0) {
|
|
1360
|
+
outcome = 'failed';
|
|
1361
|
+
settled = true;
|
|
1362
|
+
break;
|
|
1363
|
+
}
|
|
1352
1364
|
nodeId = succs[0]?.id;
|
|
1353
1365
|
break;
|
|
1354
1366
|
}
|
|
@@ -128,13 +128,8 @@ function fixLoopGraph(mainPrompts, deciderGoal, maxIterations = 12, timeoutMinut
|
|
|
128
128
|
return { nodes, edges, config: { maxIterations, timeoutMinutes, ...(aiStepTimeoutMinutes != null ? { aiStepTimeoutMinutes } : {}) } };
|
|
129
129
|
}
|
|
130
130
|
// ── OpenSpec lifecycle loop ──────────────────────────────────────────────────
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
// branch — a shape the stock aiLoopGraph/fixLoopGraph builders do not produce.
|
|
134
|
-
// Per iteration: opsx:ff → opsx:apply → opsx:verify → Decider. The Decider stops
|
|
135
|
-
// when verify reports PASS (→ unattended `openspec archive <id> -y` shell node);
|
|
136
|
-
// otherwise it loops back to opsx:ff, which AMENDS the same change ({{run.changeId}}
|
|
137
|
-
// captured by the engine from ff's first-pass output) using the gaps verify found.
|
|
131
|
+
// Lightweight lifecycle: prepare → apply/test → validate artifacts → archive.
|
|
132
|
+
// CLI validation checks OpenSpec artifacts; Apply owns code tests and corrections.
|
|
138
133
|
const OPSX_FF_PROMPT = [
|
|
139
134
|
'{{cmd:opsx:ff}} {{spec.title}}',
|
|
140
135
|
'',
|
|
@@ -142,7 +137,7 @@ const OPSX_FF_PROMPT = [
|
|
|
142
137
|
'',
|
|
143
138
|
'Structured OpenSpec target from the local ticket metadata: "{{spec.openspecChangeName}}". If this value is non-blank, CONTINUE that exact OpenSpec change and do NOT create a duplicate change for the same follow-up. If it is blank and no run change id exists, create a new OpenSpec change from this ticket and generate all required artifacts.',
|
|
144
139
|
'',
|
|
145
|
-
'If a run change id appears here — "{{run.changeId}}" — an OpenSpec change for this ticket already exists: CONTINUE that change (do NOT create a new one) and
|
|
140
|
+
'If a run change id appears here — "{{run.changeId}}" — an OpenSpec change for this ticket already exists: CONTINUE that change (do NOT create a new one) and complete its remaining work.',
|
|
146
141
|
'',
|
|
147
142
|
'OpenSpec artifacts are authoritative. If the requested implementation changes requirements, acceptance criteria, design decisions, APIs, states, data models, or invariants, amend the relevant OpenSpec artifacts before any code changes.',
|
|
148
143
|
'',
|
|
@@ -155,47 +150,33 @@ const OPSX_APPLY_PROMPT = [
|
|
|
155
150
|
'',
|
|
156
151
|
'Before editing code, confirm the active OpenSpec artifacts already describe the contract being implemented. If implementation requires changing requirements, acceptance criteria, design decisions, APIs, states, data models, or invariants, stop code work and amend the OpenSpec artifacts first.',
|
|
157
152
|
'',
|
|
153
|
+
'Run the relevant tests and configured checks for the changed behavior, correct failures, and confirm every required task and acceptance criterion is implemented. This step owns code verification; the later CLI validate only checks OpenSpec artifacts. Do not archive here.',
|
|
154
|
+
'Finish with exactly `{{const:VERIFICATION_PASS}}` only after implementation and relevant checks succeed. Otherwise finish with `{{const:VERIFICATION_FAIL}} — <remaining work or failed checks>`.',
|
|
158
155
|
'Run fully unattended: decide and keep momentum, never pause to ask. If you hit an ambiguity or blocker, make the most reasonable choice, implement it, and continue.',
|
|
159
156
|
].join('\n');
|
|
160
|
-
const OPSX_VERIFY_PROMPT = [
|
|
161
|
-
'{{cmd:opsx:verify}}',
|
|
162
|
-
'',
|
|
163
|
-
'Verify the active OpenSpec change against its specs, design, and tasks for ticket "{{spec.title}}". Be strict and honest — inspect the REAL code and tests, not any step\'s self-report.',
|
|
164
|
-
'',
|
|
165
|
-
'Report FAIL if the implementation diverges from the active OpenSpec artifacts, or if code changed requirements, acceptance criteria, design decisions, APIs, states, data models, or invariants without corresponding artifact amendments.',
|
|
166
|
-
'',
|
|
167
|
-
'Finish with a clear final line: exactly `{{const:VERIFICATION_PASS}}` when the change fully matches the ticket with nothing required missing, or `{{const:VERIFICATION_FAIL}} — <what is still missing>` otherwise.',
|
|
168
|
-
].join('\n');
|
|
169
|
-
const OPSX_DECIDER_GOAL = 'Stop only when the latest verify step reports {{const:VERIFICATION_PASS}} and evidence shows the implementation fully matches the active OpenSpec artifacts for ticket "{{spec.title}}" across every required repository, with nothing required missing. Green baseline checks or completed design artifacts alone do not prove implementation.';
|
|
170
157
|
/** The OpenSpec-lifecycle graph (see comment above). Exported for unit testing. */
|
|
171
158
|
function opsxLifecycleGraph() {
|
|
172
159
|
return {
|
|
173
160
|
nodes: [
|
|
174
161
|
{ id: 'start', type: 'start', position: { x: COL_X, y: 0 } },
|
|
175
162
|
{ id: 'ff', type: 'ai-step', position: { x: COL_X, y: ROW_GAP * 1 }, data: { label: 'opsx:ff', prompt: OPSX_FF_PROMPT } },
|
|
176
|
-
{ id: 'apply', type: 'ai-step', position: { x: COL_X, y: ROW_GAP * 2 }, data: { label: 'opsx:apply', prompt: OPSX_APPLY_PROMPT } },
|
|
177
|
-
{ id: '
|
|
178
|
-
{ id: 'decide', type: 'decider', position: { x: COL_X, y: ROW_GAP * 4 }, data: { goal: OPSX_DECIDER_GOAL } },
|
|
163
|
+
{ id: 'apply', type: 'ai-step', position: { x: COL_X, y: ROW_GAP * 2 }, data: { label: 'opsx:apply', prompt: OPSX_APPLY_PROMPT, requireVerificationPass: true, stopOnFailure: true } },
|
|
164
|
+
{ id: 'validate', type: 'shell', position: { x: COL_X, y: ROW_GAP * 3 }, data: { label: 'validate', stopOnFailure: true, command: 'openspec validate {{run.changeId}} --type change --strict --no-interactive', requireRunVars: ['changeId'] } },
|
|
179
165
|
// Unattended archive: deterministic CLI, no AI, no prompt. `requireRunVars`
|
|
180
166
|
// makes the engine REFUSE to run if no change id was captured (never archive
|
|
181
167
|
// an unknown change); `openspec archive -y` syncs the main specs by default.
|
|
182
|
-
{ id: 'archive', type: 'shell', position: { x: COL_X, y: ROW_GAP *
|
|
183
|
-
{ id: 'done', type: 'end', position: { x: COL_X, y: ROW_GAP *
|
|
168
|
+
{ id: 'archive', type: 'shell', position: { x: COL_X, y: ROW_GAP * 4 }, data: { label: 'archive', command: 'openspec archive {{run.changeId}} -y', requireRunVars: ['changeId'] } },
|
|
169
|
+
{ id: 'done', type: 'end', position: { x: COL_X, y: ROW_GAP * 5 }, data: { outcome: 'success' } },
|
|
184
170
|
],
|
|
185
171
|
edges: [
|
|
186
172
|
{ id: 'e-start', source: 'start', target: 'ff' },
|
|
187
173
|
{ id: 'e-ff', source: 'ff', target: 'apply' },
|
|
188
|
-
{ id: 'e-apply', source: 'apply', target: '
|
|
189
|
-
{ id: 'e-
|
|
190
|
-
// not-done (verify FAIL) → loop back to ff (firstStepId ⇒ session resets, the
|
|
191
|
-
// pass re-reads disk; verify's gaps ride in the injected history).
|
|
192
|
-
{ id: 'e-continue', source: 'decide', target: 'ff', branch: 'continue' },
|
|
193
|
-
// done (verify PASS) → archive then end.
|
|
194
|
-
{ id: 'e-stop', source: 'decide', target: 'archive', branch: 'stop' },
|
|
174
|
+
{ id: 'e-apply', source: 'apply', target: 'validate' },
|
|
175
|
+
{ id: 'e-validate', source: 'validate', target: 'archive' },
|
|
195
176
|
{ id: 'e-archive', source: 'archive', target: 'done' },
|
|
196
177
|
],
|
|
197
|
-
//
|
|
198
|
-
//
|
|
178
|
+
// This linear lifecycle has no retry cycle. Like the other built-ins,
|
|
179
|
+
// the run is UNTIMED (0 = no timeout) — apply can
|
|
199
180
|
// implement a whole change and must never be killed mid-flight.
|
|
200
181
|
config: { maxIterations: 3, timeoutMinutes: 0, aiStepTimeoutMinutes: 0 },
|
|
201
182
|
};
|
|
@@ -204,7 +185,7 @@ exports.LOOP_TEMPLATES = [
|
|
|
204
185
|
{
|
|
205
186
|
id: 'opsx-lifecycle',
|
|
206
187
|
name: 'OpenSpec Lifecycle',
|
|
207
|
-
description: '
|
|
188
|
+
description: 'Lightweight ticket-to-archive OpenSpec lifecycle: generate artifacts, implement and test, validate the change through the CLI, then archive it unattended. The artifact-centric counterpart to the implement pipeline. Claude-first — codex/gemini fall back to a generic prompt until OpenSpec ships their native opsx commands.',
|
|
208
189
|
category: 'Automation',
|
|
209
190
|
tags: ['Automation', 'openspec', 'lifecycle'],
|
|
210
191
|
graph: opsxLifecycleGraph(),
|
|
@@ -681,8 +681,8 @@ function createRailsRouter() {
|
|
|
681
681
|
// one app-driven LoopRun per ticket (mirrors freestyle's per-ticket model).
|
|
682
682
|
// Drives raw prompts via the LoopRunManager — NO queue job, NO slash command.
|
|
683
683
|
// rails-as-loops: a chosen loop (factory OR custom) runs through the
|
|
684
|
-
// LoopRunManager when Loops are enabled
|
|
685
|
-
//
|
|
684
|
+
// LoopRunManager when Loops are enabled, using the current factory graph.
|
|
685
|
+
// Implement/batch delegate their complete cycle to Core. (Loops off / no loopId → the legacy
|
|
686
686
|
// bare-mode QueueManager path below; `mode` is the derived factory mode.)
|
|
687
687
|
if ((0, feature_flags_1.isLoopsEnabled)() && typeof loopId === 'string' && loopId) {
|
|
688
688
|
let loopGraph;
|
|
@@ -124,6 +124,53 @@ function hasReadableFrameworkContent(dest) {
|
|
|
124
124
|
return false;
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
+
/** Fill only missing framework command entries in a merged, real directory.
|
|
128
|
+
* Never overwrite user files or write through a live link into another tree. */
|
|
129
|
+
function repairMissingCommands(src, dest) {
|
|
130
|
+
try {
|
|
131
|
+
const source = fs_1.default.lstatSync(src);
|
|
132
|
+
if (source.isSymbolicLink() || (!source.isDirectory() && !source.isFile()))
|
|
133
|
+
return false;
|
|
134
|
+
let target;
|
|
135
|
+
try {
|
|
136
|
+
target = fs_1.default.lstatSync(dest);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (error.code !== 'ENOENT')
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
if (target?.isSymbolicLink()) {
|
|
143
|
+
try {
|
|
144
|
+
fs_1.default.statSync(dest);
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
if (error.code !== 'ENOENT')
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
fs_1.default.unlinkSync(dest);
|
|
152
|
+
target = undefined;
|
|
153
|
+
}
|
|
154
|
+
if (source.isFile()) {
|
|
155
|
+
if (target)
|
|
156
|
+
return false;
|
|
157
|
+
fs_1.default.copyFileSync(src, dest, fs_1.default.constants.COPYFILE_EXCL);
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
if (target && !target.isDirectory())
|
|
161
|
+
return false;
|
|
162
|
+
if (!target)
|
|
163
|
+
fs_1.default.mkdirSync(dest, { recursive: true });
|
|
164
|
+
let repaired = false;
|
|
165
|
+
for (const name of fs_1.default.readdirSync(src)) {
|
|
166
|
+
repaired = repairMissingCommands(path_1.default.join(src, name), path_1.default.join(dest, name)) || repaired;
|
|
167
|
+
}
|
|
168
|
+
return repaired;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return false; /* one inaccessible entry must not prevent other repairs */
|
|
172
|
+
}
|
|
173
|
+
}
|
|
127
174
|
/**
|
|
128
175
|
* Windows repair for provider-owned framework links — the sibling of
|
|
129
176
|
* `ensureFrameworkAgents`.
|
|
@@ -144,8 +191,8 @@ function hasReadableFrameworkContent(dest) {
|
|
|
144
191
|
* removed.
|
|
145
192
|
*
|
|
146
193
|
* SAFETY: only heals a managed destination when it is missing, unreadable, or
|
|
147
|
-
* empty.
|
|
148
|
-
*
|
|
194
|
+
* empty. In a populated real commands directory, missing specrails entries are
|
|
195
|
+
* filled individually; existing files and live links stay untouched. NO-OP on POSIX. Best-effort +
|
|
149
196
|
* idempotent. Returns the number of repaired subtrees/managed skill children.
|
|
150
197
|
*/
|
|
151
198
|
function ensureFrameworkCommandSubtrees(workspaceDir, providerDir, home) {
|
|
@@ -171,8 +218,12 @@ function ensureFrameworkCommandSubtrees(workspaceDir, providerDir, home) {
|
|
|
171
218
|
if (srcEntries.length === 0)
|
|
172
219
|
continue;
|
|
173
220
|
const dest = path_1.default.join(workspaceDir, providerDir, subtree);
|
|
174
|
-
if (hasReadableFrameworkContent(dest))
|
|
221
|
+
if (hasReadableFrameworkContent(dest)) {
|
|
222
|
+
if (subtree === 'commands' && !fs_1.default.lstatSync(dest).isSymbolicLink()
|
|
223
|
+
&& repairMissingCommands(path_1.default.join(src, 'specrails'), path_1.default.join(dest, 'specrails')))
|
|
224
|
+
healed += 1;
|
|
175
225
|
continue;
|
|
226
|
+
}
|
|
176
227
|
removeBrokenFrameworkDestination(dest);
|
|
177
228
|
try {
|
|
178
229
|
fs_1.default.mkdirSync(path_1.default.dirname(dest), { recursive: true });
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{t as r}from"./react-dom-DiWzBDP9.js";import{ct as i,it as a}from"./TicketDetailModalContext-DqyF0so-.js";import{a as o,c as s,l as c,m as l}from"./useSharedWebSocket-BOdS5_Iz.js";import{n as u}from"./createLucideIcon-Bjbbp_KS.js";import{a as d,s as f}from"./useDesktop-RSMTyy7V.js";import{a as p,i as m,n as h,o as g,r as _,s as ee,t as te}from"./InteractiveJobComposer-C1ucmxQh.js";import{t as ne}from"./loader-circle-DcygOQpC.js";import{t as re}from"./x-CBMI9ejn.js";import{M as ie,j as ae}from"./dialog-SRw01_QU.js";import{t as oe}from"./formatDistanceToNow-DSj5DprF.js";import{t as v}from"./button-DCBqEaZl.js";import{B as y,I as se,L as b,R as x,V as ce,x as S,z as le}from"./index-EzrkUb8B.js";import{n as C,t as ue}from"./job-time-BCL7wee9.js";var de=e(r(),1),w=e(t(),1),T=[1e3,2e3,4e3,8e3,16e3];function E(e,t){let[n,r]=(0,w.useState)(`connecting`),i=(0,w.useRef)(t);return i.current=t,(0,w.useEffect)(()=>{let t=!1,n=!1,a=null,c=0,l=null;async function u(){if(!(t||n||a)){n=!0;try{await s()}catch{}finally{n=!1}!t&&!a&&f()}}function d(){if(t)return;l!==null&&clearTimeout(l),r(`connecting`);let e=T[c++]??3e4;l=setTimeout(()=>{l=null,u()},e)}function f(){if(t||a)return;let n=o(),s;try{s=n?new WebSocket(e,[`specrails-desktop`,n]):new WebSocket(e)}catch{d();return}a=s,r(`connecting`),s.onopen=()=>{t||a!==s||(c=0,r(`connected`))},s.onmessage=e=>{if(!(t||a!==s))try{i.current(JSON.parse(e.data))}catch{}},s.onclose=()=>{t||a!==s||(a=null,d())}}let p=()=>{t||a||(l!==null&&clearTimeout(l),l=null,u())};return window.addEventListener(`online`,p),window.addEventListener(`focus`,p),f(),()=>{t=!0,window.removeEventListener(`online`,p),window.removeEventListener(`focus`,p),l!==null&&clearTimeout(l);let e=a;if(a=null,e){e.onopen=null,e.onmessage=null,e.onclose=null,e.onerror=null;try{e.close()}catch{}}}},[e]),{connectionStatus:n}}var D=n();function fe(e,t){let n=C(e),r=C(t);if(!n||!r)return`—`;let i=r.getTime()-n.getTime();if(i<0)return`—`;let a=Math.round(i/1e3);if(a<60)return`${a}s`;let o=Math.floor(a/60),s=a%60;return o<60?`${o}m ${s}s`:`${Math.floor(o/60)}h ${o%60}m`}var O={running:{variant:`running`,labelKey:`statusLabel.running`,tooltipKey:`statusTooltip.running`},completed:{variant:`success`,labelKey:`statusLabel.completed`,tooltipKey:`statusTooltip.completed`},failed:{variant:`failed`,labelKey:`statusLabel.failed`,tooltipKey:`statusTooltip.failed`},canceled:{variant:`canceled`,labelKey:`statusLabel.canceled`,tooltipKey:`statusTooltip.canceled`},queued:{variant:`queued`,labelKey:`statusLabel.queued`,tooltipKey:`statusTooltip.queued`},zombie_terminated:{variant:`failed`,labelKey:`statusLabel.zombie`,tooltipKey:`statusTooltip.zombie`}};function k({jobId:e,onClose:t,projectId:n}){let{t:r}=u(`jobs`),{t:o}=u(`narration`),s=(0,w.useCallback)(()=>n?`${c}/api/projects/${n}`:d(),[n]),[T,k]=(0,w.useState)(h),pe=(0,w.useCallback)(e=>{k(e),_(e)},[]),[A,j]=(0,w.useState)(null),[M,N]=(0,w.useState)([]),[P,F]=(0,w.useState)([]),[I,L]=(0,w.useState)({}),[R,z]=(0,w.useState)(!0),[B,V]=(0,w.useState)(!1),[H,U]=(0,w.useState)(!1),[W,G]=(0,w.useState)(!1);(0,w.useEffect)(()=>{async function t(){try{let t=await fetch(`${s()}/jobs/${e}`);if(t.status===404){V(!0);return}if(!t.ok)throw Error(`Failed to fetch job`);let n=await t.json();if(j(n.job),N(n.events),n.phaseDefinitions){F(n.phaseDefinitions);let e={};for(let t of n.phaseDefinitions)e[t.key]=`idle`;L(e)}}catch{V(!0)}finally{z(!1)}}t()},[e,s]);let K=(0,w.useCallback)(()=>{fetch(`${s()}/jobs/${e}`).then(e=>e.ok?e.json():null).then(e=>{e?.job&&j(e.job)}).catch(()=>{})},[e,s]),q=(0,w.useRef)([]),J=(0,w.useRef)(null),Y=(0,w.useCallback)(()=>{J.current=null;let e=q.current;e.length!==0&&(q.current=[],N(t=>{let n=[...t,...e];return n.length>1e4?n.slice(n.length-8e3):n}))},[]);(0,w.useEffect)(()=>()=>{J.current&&cancelAnimationFrame(J.current)},[]),E(i,(0,w.useCallback)(t=>{let n=t;if(n.type===`event`&&n.jobId===e){let t={id:Date.now(),job_id:e,seq:0,event_type:n.event_type,source:n.source,payload:n.payload,timestamp:n.timestamp};q.current.push(t),J.current||=requestAnimationFrame(Y)}else if(n.type===`log`&&n.processId===e){let t={id:Date.now(),job_id:e,seq:0,event_type:`log`,source:n.source,payload:JSON.stringify({line:n.line}),timestamp:n.timestamp};q.current.push(t),J.current||=requestAnimationFrame(Y)}else if(n.type===`job.finalized`&&n.jobId===e||n.type===`job.interactive`&&n.jobId===e||(n.type===`loop.run_paused`||n.type===`loop.run_resumed`)&&n.loopRunId===e)K();else if(n.type===`phase`){let e=n.phase,t=n.state;L(n=>({...n,[e]:t}))}else if(n.type===`queue`){let t=n.jobs?.find(t=>t.id===e);t&&A&&j(e=>e&&{...e,status:t.status})}},[e,A,Y,K])),(0,w.useEffect)(()=>{function e(e){if(e.key===`Escape`){if(H){U(!1);return}t()}}return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t,H]);let X=A?b(A):`job`,Z=X===`loop-run`;async function me(){G(!0);try{let t=await se({projectId:n??null,jobId:e,kind:X});t.ok?(f.success(r(Z?`modal.toast.stopSignalSent`:`modal.toast.cancelSignalSent`),{description:r(Z?`modal.toast.stopSignalSentDescription`:`modal.toast.cancelSignalSentDescription`)}),K()):f.error(r(`modal.toast.cancelFailed`),{description:t.error})}finally{G(!1)}}let Q=A?O[A.status]??O.queued:O.queued,he=A?.status===`running`,$=A?C(ue(A)):null,{panelRef:ge,panelStyle:_e,headerHandleProps:ve,resizeHandles:ye,isFloating:be,guardBackdrop:xe}=ie();return(0,de.createPortal)((0,D.jsx)(y,{delayDuration:400,children:(0,D.jsxs)(`div`,{className:`fixed inset-0 z-[65] flex items-stretch justify-center`,children:[(0,D.jsx)(`div`,{className:`absolute inset-0 bg-black/50 backdrop-blur-sm`,onClick:xe(t)}),(0,D.jsxs)(`div`,{ref:ge,className:`relative w-full m-3 rounded-xl glass-card border border-border/30 flex flex-col animate-in fade-in zoom-in-95 duration-200 overflow-hidden`,style:_e,children:[(0,D.jsxs)(`div`,{...ve,className:`flex items-center justify-between px-4 py-3 border-b border-border/30${be?` cursor-grab active:cursor-grabbing`:``}`,children:[(0,D.jsxs)(`div`,{className:`flex items-center gap-3 min-w-0`,children:[A&&(0,D.jsxs)(D.Fragment,{children:[(0,D.jsxs)(x,{children:[(0,D.jsx)(ce,{asChild:!0,children:(0,D.jsx)(`div`,{children:(0,D.jsx)(S,{variant:Q.variant,children:r(Q.labelKey)})})}),(0,D.jsx)(le,{children:r(Q.tooltipKey)})]}),(0,D.jsx)(`code`,{className:`text-xs font-mono text-foreground/80 truncate`,children:A.command}),(0,D.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:$?oe($,{addSuffix:!0,locale:l()}):`—`}),A.total_cost_usd!=null&&A.total_cost_usd>0&&(0,D.jsxs)(`span`,{className:`text-[10px] text-muted-foreground`,children:[`$`,A.total_cost_usd.toFixed(4)]}),A.started_at&&A.finished_at&&(0,D.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:fe(A.started_at,A.finished_at)})]}),R&&(0,D.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:r(`common:states.loading`)})]}),(0,D.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[P.length>0&&(0,D.jsx)(`div`,{className:`mr-3`,children:(0,D.jsx)(ee,{phases:I,phaseDefinitions:P})}),he&&(0,D.jsxs)(v,{variant:`ghost`,size:`sm`,onClick:()=>U(!0),disabled:W,className:`h-7 text-destructive hover:text-destructive hover:bg-destructive/10`,children:[W&&(0,D.jsx)(ne,{className:`w-3.5 h-3.5 mr-1.5 animate-spin`,"aria-hidden":!0}),r(Z?`dashboard:railControls.stop`:X===`interactive`?`common:actions.discard`:`common:actions.cancel`)]}),(0,D.jsx)(`button`,{onClick:t,className:`h-7 w-7 flex items-center justify-center rounded-md text-muted-foreground hover:text-foreground hover:bg-surface/50 transition-colors cursor-pointer`,children:(0,D.jsx)(re,{className:`w-4 h-4`})})]})]}),(0,D.jsx)(`div`,{className:`flex-1 overflow-hidden relative`,children:B?(0,D.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,D.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:r(`modal.notFound`)})}):a&&A?(0,D.jsxs)(`div`,{className:`flex h-full flex-col`,children:[(0,D.jsx)(`div`,{className:`flex items-center gap-1 border-b border-border/40 px-3 py-1.5`,children:[`narrated`,`log`].map(e=>(0,D.jsx)(`button`,{type:`button`,onClick:()=>pe(e),"aria-pressed":T===e,"data-testid":`modal-narration-mode-${e}`,className:`rounded-md px-2 py-0.5 text-[11px] font-medium transition-colors ${T===e?`bg-accent-primary/15 text-accent-primary`:`text-muted-foreground hover:bg-surface/60`}`,children:o(e===`narrated`?`modeNarrated`:`modeLog`)},e))}),(0,D.jsx)(`div`,{className:`flex-1 overflow-hidden`,children:T===`narrated`?(0,D.jsx)(m,{events:M,settled:A.status!==`running`&&A.status!==`queued`,elapsedMs:A.duration_ms??null,variant:`glass`}):A.command.startsWith(`loop:`)?(0,D.jsx)(p,{events:M,jobStatus:A.status,isLoading:R,variant:`glass`,projectId:n}):(0,D.jsx)(g,{events:M,isLoading:R,projectId:n})})]}):A?.command.startsWith(`loop:`)?(0,D.jsx)(p,{events:M,jobStatus:A.status,isLoading:R,variant:`glass`,projectId:n}):(0,D.jsx)(g,{events:M,isLoading:R,projectId:n})}),!!A?.interactive&&A.status===`running`&&(0,D.jsx)(te,{jobId:e,projectId:n,settleMode:A.interactiveSettleMode,initialAcceptingTurns:A.interactiveAcceptingTurns,kind:A.command.startsWith(`loop:`)?`loop-step`:`job`,variant:`glass`,onFinalized:K})]}),(0,D.jsx)(ae,{handles:ye}),H&&(0,D.jsxs)(`div`,{"data-testid":`job-cancel-confirm`,className:`absolute inset-0 z-10 flex items-center justify-center p-4`,children:[(0,D.jsx)(`div`,{className:`absolute inset-0 bg-black/60 backdrop-blur-sm`,onClick:()=>U(!1)}),(0,D.jsxs)(`div`,{className:`relative w-full max-w-sm rounded-xl glass-card border border-border/30 p-5 shadow-xl animate-in fade-in zoom-in-95 duration-150`,children:[(0,D.jsx)(`h3`,{className:`text-base font-semibold text-foreground`,children:r(Z?`modal.stopRunConfirmTitle`:`modal.cancelConfirmTitle`)}),(0,D.jsx)(`p`,{className:`mt-1.5 text-sm text-muted-foreground`,children:r(Z?`modal.stopRunConfirmDescription`:`modal.cancelConfirmDescription`)}),(0,D.jsxs)(`div`,{className:`mt-4 flex justify-end gap-2`,children:[(0,D.jsx)(v,{variant:`ghost`,size:`sm`,onClick:()=>U(!1),children:r(`modal.keepRunning`)}),(0,D.jsx)(v,{variant:`destructive`,size:`sm`,onClick:()=>{U(!1),me()},children:r(Z?`modal.stopRun`:X===`interactive`?`common:actions.discard`:`modal.cancelJob`)})]})]})]})]})}),document.body)}export{k as JobDetailModal};
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{t as r}from"./react-dom-DiWzBDP9.js";import{n as i}from"./createLucideIcon-Bjbbp_KS.js";import{t as a}from"./x-CBMI9ejn.js";import{t as o}from"./utils-BC4DHlz2.js";var s=e(t(),1),c=e(r(),1),l=n(),u=[`nw`,`n`,`ne`,`e`,`se`,`s`,`sw`,`w`],d={nw:{left:!0,top:!0},n:{top:!0},ne:{right:!0,top:!0},e:{right:!0},se:{right:!0,bottom:!0},s:{bottom:!0},sw:{left:!0,bottom:!0},w:{left:!0}};function f(e){return e===`n`||e===`s`?`horizontal`:`vertical`}function p(e,t,n){return Math.min(Math.max(e,t),Math.max(t,n))}function m(e,t,n,r){return{w:p(e,r.minWidth,n.width-16),h:p(t,r.minHeight,n.height-16)}}function h(e,t){let n=p(e.x,120-e.w,t.width-e.w),r=p(e.y,0,Math.max(0,t.height-48));return{...e,x:n,y:r}}function g(e,t,n,r){return h({...e,x:e.x+t,y:e.y+n},r)}function _(e,t,n,r,i,a){let o=d[t],s=e.x+e.w,c=e.y+e.h,l=e.w,u=e.h;o.right&&(l=e.w+n),o.left&&(l=e.w-n),o.bottom&&(u=e.h+r),o.top&&(u=e.h-r);let f=m(l,u,i,a),p=e.x,g=e.y;return o.left&&(p=s-f.w),o.top&&(g=c-f.h),h({x:p,y:g,w:f.w,h:f.h},i)}function v(e,t,n,r,i){let a=d[t],o=a.left||a.right,s=a.top||a.bottom,c=o?n===`min`?i.minWidth:r.width-16:e.w,l=s?n===`min`?i.minHeight:r.height-16:e.h,u=e.x+e.w,f=e.y+e.h,p=m(c,l,r,i);return h({x:a.left?u-p.w:e.x,y:a.top?f-p.h:e.y,w:p.w,h:p.h},r)}function y(e){return{x:e.left,y:e.top,w:e.width,h:e.height}}function b(e,t){return{w:e.width,h:e.height,x:Math.round((t.width-e.width)/2),y:Math.round((t.height-e.height)/2)}}function ee(e,t){let{x:n,y:r,w:i,h:a}=t,o=Math.max(0,i-24),s=Math.max(0,a-24);switch(e){case`nw`:return{left:n-14/2,top:r-14/2,width:14,height:14};case`ne`:return{left:n+i-14/2,top:r-14/2,width:14,height:14};case`se`:return{left:n+i-14/2,top:r+a-14/2,width:14,height:14};case`sw`:return{left:n-14/2,top:r+a-14/2,width:14,height:14};case`n`:return{left:n+12,top:r-8/2,width:o,height:8};case`s`:return{left:n+12,top:r+a-8/2,width:o,height:8};case`e`:return{left:n+i-8/2,top:r+12,width:8,height:s};case`w`:return{left:n-8/2,top:r+12,width:8,height:s}}}function te(e,t,n){let r=d[e],i=r.left||r.right,a=r.top||r.bottom;switch(t){case`ArrowRight`:return i?{dx:n,dy:0}:null;case`ArrowLeft`:return i?{dx:-n,dy:0}:null;case`ArrowDown`:return a?{dx:0,dy:n}:null;case`ArrowUp`:return a?{dx:0,dy:-n}:null;default:return null}}var ne=64;function x(){return typeof window>`u`?{width:0,height:0}:{width:window.innerWidth,height:window.innerHeight}}var re=`button, input, textarea, select, a, [role="button"], [contenteditable="true"]`;function S(e={}){let{enabled:t=!0,allowMove:n=!0,minWidth:r=320,minHeight:i=200,anchorFromCurrentRect:a=!1,persistKey:o}=e,c=(0,s.useRef)(null),[l,d]=(0,s.useState)(null),p=(0,s.useCallback)(e=>{c.current=e,d(e)},[]),[m,S]=(0,s.useState)(()=>{if(!o||typeof window>`u`)return null;try{let e=window.localStorage.getItem(o);if(!e)return null;let t=JSON.parse(e);if([t?.x,t?.y,t?.w,t?.h].every(e=>typeof e==`number`&&Number.isFinite(e))&&t.w>0&&t.h>0)return h(t,x())}catch{}return null}),[ie,C]=(0,s.useState)(null),[w,T]=(0,s.useState)(()=>typeof window>`u`||window.innerWidth>=900),E=(0,s.useRef)(null),D=(0,s.useRef)(null),ae=(0,s.useRef)(!1),O=(0,s.useRef)(null),oe=(0,s.useRef)(!1);D.current=m;let k={minWidth:r,minHeight:i},A=t&&w;(0,s.useEffect)(()=>{function e(){let e=window.innerWidth>=900;T(e),e||S(null)}return window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[]),(0,s.useEffect)(()=>{t||S(null)},[t]),(0,s.useEffect)(()=>{if(!(!o||typeof window>`u`||!m))try{window.localStorage.setItem(o,JSON.stringify(m))}catch{}},[m,o]),(0,s.useEffect)(()=>{if(!A||m!==null){C(null);return}let e=c.current;if(!e)return;let t=()=>C(y(e.getBoundingClientRect()));t();let n;return typeof ResizeObserver<`u`&&(n=new ResizeObserver(t),n.observe(e)),window.addEventListener(`resize`,t),window.addEventListener(`scroll`,t,!0),()=>{n?.disconnect(),window.removeEventListener(`resize`,t),window.removeEventListener(`scroll`,t,!0)}},[A,m,l]);let se=(0,s.useCallback)(e=>{O.current=e,!ae.current&&(ae.current=!0,requestAnimationFrame(()=>{ae.current=!1,O.current&&S(O.current)}))},[]),j=(0,s.useCallback)(e=>{let t=E.current;if(!t)return;let n=x(),r=e.clientX-t.startX,i=e.clientY-t.startY,a=t.mode===`move`?g(t.startGeom,r,i,n):_(t.startGeom,t.position,r,i,n,k);se(a)},[se,k.minWidth,k.minHeight]),M=(0,s.useCallback)(()=>{let e=E.current;if(e){try{e.element.releasePointerCapture(e.pointerId)}catch{}E.current=null,oe.current=!0,setTimeout(()=>{oe.current=!1},0),O.current&&S(O.current),window.removeEventListener(`pointermove`,j),window.removeEventListener(`pointerup`,M),window.removeEventListener(`pointercancel`,M)}},[j]),N=(0,s.useCallback)((e,t)=>{if(!A||e.button!==0)return;let n=c.current;if(!n)return;let r=D.current;if(!r){let e=n.getBoundingClientRect();if(e.width<=0||e.height<=0)return;r=h(a?y(e):b(e,x()),x())}D.current=r,O.current=r;let i=t(r);E.current=i;try{i.element.setPointerCapture(i.pointerId)}catch{}S(r),window.addEventListener(`pointermove`,j),window.addEventListener(`pointerup`,M),window.addEventListener(`pointercancel`,M)},[A,j,M,a]),ce=(0,s.useCallback)(e=>{if(!n||e.target.closest(re))return;let t=c.current;t&&e.clientY-t.getBoundingClientRect().top>ne||N(e,t=>({mode:`move`,startX:e.clientX,startY:e.clientY,startGeom:t,pointerId:e.pointerId,element:e.currentTarget}))},[n,N]),le=(0,s.useCallback)(e=>t=>{t.stopPropagation(),N(t,n=>({mode:`resize`,position:e,startX:t.clientX,startY:t.clientY,startGeom:n,pointerId:t.pointerId,element:t.currentTarget}))},[N]),P=(0,s.useCallback)(()=>S(null),[]),ue=(0,s.useCallback)(e=>(...t)=>{oe.current||e(...t)},[]),de=(0,s.useCallback)(e=>t=>{if(!A)return;if(t.key===`0`){t.preventDefault(),P();return}let n=c.current;if(!n)return;let r=x(),i=D.current??y(n.getBoundingClientRect());if(t.key===`Home`||t.key===`End`){t.preventDefault(),S(v(i,e,t.key===`Home`?`min`:`max`,r,k));return}let a=t.shiftKey?64:16,o=te(e,t.key,a);o&&(t.preventDefault(),S(_(i,e,o.dx,o.dy,r,k)))},[A,P,k.minWidth,k.minHeight]);(0,s.useEffect)(()=>{if(!m||!w)return;function e(){let e=D.current;e&&S(h(e,x()))}return window.addEventListener(`resize`,e),()=>window.removeEventListener(`resize`,e)},[m,w]),(0,s.useEffect)(()=>()=>{window.removeEventListener(`pointermove`,j),window.removeEventListener(`pointerup`,M),window.removeEventListener(`pointercancel`,M);let e=E.current;if(e){try{e.element.releasePointerCapture(e.pointerId)}catch{}E.current=null}},[j,M]);let F=A&&m!==null,fe=F&&m?{position:`fixed`,left:m.x,top:m.y,width:m.w,height:m.h,maxWidth:`none`,maxHeight:`none`,margin:0,transform:`none`,animation:`none`}:{},pe=F?m:ie,I=A&&pe?u.map(e=>({position:e,role:`separator`,"aria-orientation":f(e),tabIndex:0,style:{position:`fixed`,...ee(e,pe)},onPointerDown:le(e),onKeyDown:de(e)})):[];return{panelRef:p,panelStyle:fe,headerHandleProps:{onPointerDown:ce},resizeHandles:I,isFloating:F,enabled:A,reset:P,guardBackdrop:ue}}var ie={nw:`cursor-nwse-resize`,n:`cursor-ns-resize`,ne:`cursor-nesw-resize`,e:`cursor-ew-resize`,se:`cursor-nwse-resize`,s:`cursor-ns-resize`,sw:`cursor-nesw-resize`,w:`cursor-ew-resize`};function C({handles:e}){let{t}=i(`common`);return e.length===0?null:(0,l.jsx)(l.Fragment,{children:e.map(e=>(0,l.jsx)(`div`,{"data-testid":`modal-resize-${e.position}`,role:e.role,"aria-orientation":e[`aria-orientation`],"aria-label":t(`modal.resize.${e.position}`),tabIndex:e.tabIndex,style:e.style,onPointerDown:e.onPointerDown,onKeyDown:e.onKeyDown,className:o(`z-[51] rounded-full bg-transparent transition-colors duration-150`,`hover:bg-accent-primary/20 focus:outline-none focus-visible:bg-accent-primary/30`,ie[e.position])},e.position))})}function w(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}function T(...e){return t=>{let n=!1,r=e.map(e=>{let r=w(e,t);return!n&&typeof r==`function`&&(n=!0),r});if(n)return()=>{for(let t=0;t<r.length;t++){let n=r[t];typeof n==`function`?n():w(e[t],null)}}}}function E(...e){return s.useCallback(T(...e),e)}typeof window<`u`&&window.document&&window.document.createElement;function D(e,t,{checkForDefaultPrevented:n=!0}={}){return function(r){if(e?.(r),n===!1||!r.defaultPrevented)return t?.(r)}}function ae(e,t){let n=s.createContext(t),r=e=>{let{children:t,...r}=e,i=s.useMemo(()=>r,Object.values(r));return(0,l.jsx)(n.Provider,{value:i,children:t})};r.displayName=e+`Provider`;function i(r){let i=s.useContext(n);if(i)return i;if(t!==void 0)return t;throw Error(`\`${r}\` must be used within \`${e}\``)}return[r,i]}function O(e,t=[]){let n=[];function r(t,r){let i=s.createContext(r),a=n.length;n=[...n,r];let o=t=>{let{scope:n,children:r,...o}=t,c=n?.[e]?.[a]||i,u=s.useMemo(()=>o,Object.values(o));return(0,l.jsx)(c.Provider,{value:u,children:r})};o.displayName=t+`Provider`;function c(n,o){let c=o?.[e]?.[a]||i,l=s.useContext(c);if(l)return l;if(r!==void 0)return r;throw Error(`\`${n}\` must be used within \`${t}\``)}return[o,c]}let i=()=>{let t=n.map(e=>s.createContext(e));return function(n){let r=n?.[e]||t;return s.useMemo(()=>({[`__scope${e}`]:{...n,[e]:r}}),[n,r])}};return i.scopeName=e,[r,oe(i,...t)]}function oe(...e){let t=e[0];if(e.length===1)return t;let n=()=>{let n=e.map(e=>({useScope:e(),scopeName:e.scopeName}));return function(e){let r=n.reduce((t,{useScope:n,scopeName:r})=>{let i=n(e)[`__scope${r}`];return{...t,...i}},{});return s.useMemo(()=>({[`__scope${t.scopeName}`]:r}),[r])}};return n.scopeName=t.scopeName,n}var k=globalThis?.document?s.useLayoutEffect:()=>{},A=s.useId||(()=>void 0),se=0;function j(e){let[t,n]=s.useState(A());return k(()=>{e||n(e=>e??String(se++))},[e]),e||(t?`radix-${t}`:``)}var M=s.useInsertionEffect||k;function N({prop:e,defaultProp:t,onChange:n=()=>{},caller:r}){let[i,a,o]=ce({defaultProp:t,onChange:n}),c=e!==void 0,l=c?e:i;{let t=s.useRef(e!==void 0);s.useEffect(()=>{let e=t.current;e!==c&&console.warn(`${r} is changing from ${e?`controlled`:`uncontrolled`} to ${c?`controlled`:`uncontrolled`}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),t.current=c},[c,r])}return[l,s.useCallback(t=>{if(c){let n=le(t)?t(e):t;n!==e&&o.current?.(n)}else a(t)},[c,e,a,o])]}function ce({defaultProp:e,onChange:t}){let[n,r]=s.useState(e),i=s.useRef(n),a=s.useRef(t);return M(()=>{a.current=t},[t]),s.useEffect(()=>{i.current!==n&&(a.current?.(n),i.current=n)},[n,i]),[n,r,a]}function le(e){return typeof e==`function`}function P(e){let t=ue(e),n=s.forwardRef((e,n)=>{let{children:r,...i}=e,a=s.Children.toArray(r),o=a.find(F);if(o){let e=o.props.children,r=a.map(t=>t===o?s.Children.count(e)>1?s.Children.only(null):s.isValidElement(e)?e.props.children:null:t);return(0,l.jsx)(t,{...i,ref:n,children:s.isValidElement(e)?s.cloneElement(e,void 0,r):null})}return(0,l.jsx)(t,{...i,ref:n,children:r})});return n.displayName=`${e}.Slot`,n}function ue(e){let t=s.forwardRef((e,t)=>{let{children:n,...r}=e;if(s.isValidElement(n)){let e=pe(n),i=fe(r,n.props);return n.type!==s.Fragment&&(i.ref=t?T(t,e):e),s.cloneElement(n,i)}return s.Children.count(n)>1?s.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var de=Symbol(`radix.slottable`);function F(e){return s.isValidElement(e)&&typeof e.type==`function`&&`__radixId`in e.type&&e.type.__radixId===de}function fe(e,t){let n={...t};for(let r in t){let i=e[r],a=t[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...e)=>{let t=a(...e);return i(...e),t}:i&&(n[r]=i):r===`style`?n[r]={...i,...a}:r===`className`&&(n[r]=[i,a].filter(Boolean).join(` `))}return{...e,...n}}function pe(e){let t=Object.getOwnPropertyDescriptor(e.props,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var I=[`a`,`button`,`div`,`form`,`h2`,`h3`,`img`,`input`,`label`,`li`,`nav`,`ol`,`p`,`select`,`span`,`svg`,`ul`].reduce((e,t)=>{let n=P(`Primitive.${t}`),r=s.forwardRef((e,r)=>{let{asChild:i,...a}=e,o=i?n:t;return typeof window<`u`&&(window[Symbol.for(`radix-ui`)]=!0),(0,l.jsx)(o,{...a,ref:r})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{});function me(e,t){e&&c.flushSync(()=>e.dispatchEvent(t))}function L(e){let t=s.useRef(e);return s.useEffect(()=>{t.current=e}),s.useMemo(()=>(...e)=>t.current?.(...e),[])}function he(e,t=globalThis?.document){let n=L(e);s.useEffect(()=>{let e=e=>{e.key===`Escape`&&n(e)};return t.addEventListener(`keydown`,e,{capture:!0}),()=>t.removeEventListener(`keydown`,e,{capture:!0})},[n,t])}var ge=`DismissableLayer`,_e=`dismissableLayer.update`,ve=`dismissableLayer.pointerDownOutside`,ye=`dismissableLayer.focusOutside`,be,xe=s.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),Se=s.forwardRef((e,t)=>{let{disableOutsidePointerEvents:n=!1,onEscapeKeyDown:r,onPointerDownOutside:i,onFocusOutside:a,onInteractOutside:o,onDismiss:c,...u}=e,d=s.useContext(xe),[f,p]=s.useState(null),m=f?.ownerDocument??globalThis?.document,[,h]=s.useState({}),g=E(t,e=>p(e)),_=Array.from(d.layers),[v]=[...d.layersWithOutsidePointerEventsDisabled].slice(-1),y=_.indexOf(v),b=f?_.indexOf(f):-1,ee=d.layersWithOutsidePointerEventsDisabled.size>0,te=b>=y,ne=Te(e=>{let t=e.target,n=[...d.branches].some(e=>e.contains(t));!te||n||(i?.(e),o?.(e),e.defaultPrevented||c?.())},m),x=Ee(e=>{let t=e.target;[...d.branches].some(e=>e.contains(t))||(a?.(e),o?.(e),e.defaultPrevented||c?.())},m);return he(e=>{b===d.layers.size-1&&(r?.(e),!e.defaultPrevented&&c&&(e.preventDefault(),c()))},m),s.useEffect(()=>{if(f)return n&&(d.layersWithOutsidePointerEventsDisabled.size===0&&(be=m.body.style.pointerEvents,m.body.style.pointerEvents=`none`),d.layersWithOutsidePointerEventsDisabled.add(f)),d.layers.add(f),De(),()=>{n&&d.layersWithOutsidePointerEventsDisabled.size===1&&(m.body.style.pointerEvents=be)}},[f,m,n,d]),s.useEffect(()=>()=>{f&&(d.layers.delete(f),d.layersWithOutsidePointerEventsDisabled.delete(f),De())},[f,d]),s.useEffect(()=>{let e=()=>h({});return document.addEventListener(_e,e),()=>document.removeEventListener(_e,e)},[]),(0,l.jsx)(I.div,{...u,ref:g,style:{pointerEvents:ee?te?`auto`:`none`:void 0,...e.style},onFocusCapture:D(e.onFocusCapture,x.onFocusCapture),onBlurCapture:D(e.onBlurCapture,x.onBlurCapture),onPointerDownCapture:D(e.onPointerDownCapture,ne.onPointerDownCapture)})});Se.displayName=ge;var Ce=`DismissableLayerBranch`,we=s.forwardRef((e,t)=>{let n=s.useContext(xe),r=s.useRef(null),i=E(t,r);return s.useEffect(()=>{let e=r.current;if(e)return n.branches.add(e),()=>{n.branches.delete(e)}},[n.branches]),(0,l.jsx)(I.div,{...e,ref:i})});we.displayName=Ce;function Te(e,t=globalThis?.document){let n=L(e),r=s.useRef(!1),i=s.useRef(()=>{});return s.useEffect(()=>{let e=e=>{if(e.target&&!r.current){let r=function(){Oe(ve,n,a,{discrete:!0})},a={originalEvent:e};e.pointerType===`touch`?(t.removeEventListener(`click`,i.current),i.current=r,t.addEventListener(`click`,i.current,{once:!0})):r()}else t.removeEventListener(`click`,i.current);r.current=!1},a=window.setTimeout(()=>{t.addEventListener(`pointerdown`,e)},0);return()=>{window.clearTimeout(a),t.removeEventListener(`pointerdown`,e),t.removeEventListener(`click`,i.current)}},[t,n]),{onPointerDownCapture:()=>r.current=!0}}function Ee(e,t=globalThis?.document){let n=L(e),r=s.useRef(!1);return s.useEffect(()=>{let e=e=>{e.target&&!r.current&&Oe(ye,n,{originalEvent:e},{discrete:!1})};return t.addEventListener(`focusin`,e),()=>t.removeEventListener(`focusin`,e)},[t,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function De(){let e=new CustomEvent(_e);document.dispatchEvent(e)}function Oe(e,t,n,{discrete:r}){let i=n.originalEvent.target,a=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&i.addEventListener(e,t,{once:!0}),r?me(i,a):i.dispatchEvent(a)}var ke=`focusScope.autoFocusOnMount`,Ae=`focusScope.autoFocusOnUnmount`,je={bubbles:!1,cancelable:!0},Me=`FocusScope`,Ne=s.forwardRef((e,t)=>{let{loop:n=!1,trapped:r=!1,onMountAutoFocus:i,onUnmountAutoFocus:a,...o}=e,[c,u]=s.useState(null),d=L(i),f=L(a),p=s.useRef(null),m=E(t,e=>u(e)),h=s.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;s.useEffect(()=>{if(r){let e=function(e){if(h.paused||!c)return;let t=e.target;c.contains(t)?p.current=t:R(p.current,{select:!0})},t=function(e){if(h.paused||!c)return;let t=e.relatedTarget;t!==null&&(c.contains(t)||R(p.current,{select:!0}))},n=function(e){if(document.activeElement===document.body)for(let t of e)t.removedNodes.length>0&&R(c)};document.addEventListener(`focusin`,e),document.addEventListener(`focusout`,t);let r=new MutationObserver(n);return c&&r.observe(c,{childList:!0,subtree:!0}),()=>{document.removeEventListener(`focusin`,e),document.removeEventListener(`focusout`,t),r.disconnect()}}},[r,c,h.paused]),s.useEffect(()=>{if(c){Be.add(h);let e=document.activeElement;if(!c.contains(e)){let t=new CustomEvent(ke,je);c.addEventListener(ke,d),c.dispatchEvent(t),t.defaultPrevented||(Pe(Ue(Ie(c)),{select:!0}),document.activeElement===e&&R(c))}return()=>{c.removeEventListener(ke,d),setTimeout(()=>{let t=new CustomEvent(Ae,je);c.addEventListener(Ae,f),c.dispatchEvent(t),t.defaultPrevented||R(e??document.body,{select:!0}),c.removeEventListener(Ae,f),Be.remove(h)},0)}}},[c,d,f,h]);let g=s.useCallback(e=>{if(!n&&!r||h.paused)return;let t=e.key===`Tab`&&!e.altKey&&!e.ctrlKey&&!e.metaKey,i=document.activeElement;if(t&&i){let t=e.currentTarget,[r,a]=Fe(t);r&&a?!e.shiftKey&&i===a?(e.preventDefault(),n&&R(r,{select:!0})):e.shiftKey&&i===r&&(e.preventDefault(),n&&R(a,{select:!0})):i===t&&e.preventDefault()}},[n,r,h.paused]);return(0,l.jsx)(I.div,{tabIndex:-1,...o,ref:m,onKeyDown:g})});Ne.displayName=Me;function Pe(e,{select:t=!1}={}){let n=document.activeElement;for(let r of e)if(R(r,{select:t}),document.activeElement!==n)return}function Fe(e){let t=Ie(e);return[Le(t,e),Le(t.reverse(),e)]}function Ie(e){let t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:e=>{let t=e.tagName===`INPUT`&&e.type===`hidden`;return e.disabled||e.hidden||t?NodeFilter.FILTER_SKIP:e.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function Le(e,t){for(let n of e)if(!Re(n,{upTo:t}))return n}function Re(e,{upTo:t}){if(getComputedStyle(e).visibility===`hidden`)return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display===`none`)return!0;e=e.parentElement}return!1}function ze(e){return e instanceof HTMLInputElement&&`select`in e}function R(e,{select:t=!1}={}){if(e&&e.focus){let n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&ze(e)&&t&&e.select()}}var Be=Ve();function Ve(){let e=[];return{add(t){let n=e[0];t!==n&&n?.pause(),e=He(e,t),e.unshift(t)},remove(t){e=He(e,t),e[0]?.resume()}}}function He(e,t){let n=[...e],r=n.indexOf(t);return r!==-1&&n.splice(r,1),n}function Ue(e){return e.filter(e=>e.tagName!==`A`)}var We=`Portal`,Ge=s.forwardRef((e,t)=>{let{container:n,...r}=e,[i,a]=s.useState(!1);k(()=>a(!0),[]);let o=n||i&&globalThis?.document?.body;return o?c.createPortal((0,l.jsx)(I.div,{...r,ref:t}),o):null});Ge.displayName=We;function Ke(e,t){return s.useReducer((e,n)=>t[e][n]??e,e)}var z=e=>{let{present:t,children:n}=e,r=qe(t),i=typeof n==`function`?n({present:r.isPresent}):s.Children.only(n),a=E(r.ref,Je(i));return typeof n==`function`||r.isPresent?s.cloneElement(i,{ref:a}):null};z.displayName=`Presence`;function qe(e){let[t,n]=s.useState(),r=s.useRef(null),i=s.useRef(e),a=s.useRef(`none`),[o,c]=Ke(e?`mounted`:`unmounted`,{mounted:{UNMOUNT:`unmounted`,ANIMATION_OUT:`unmountSuspended`},unmountSuspended:{MOUNT:`mounted`,ANIMATION_END:`unmounted`},unmounted:{MOUNT:`mounted`}});return s.useEffect(()=>{let e=B(r.current);a.current=o===`mounted`?e:`none`},[o]),k(()=>{let t=r.current,n=i.current;if(n!==e){let r=a.current,o=B(t);e?c(`MOUNT`):o===`none`||t?.display===`none`?c(`UNMOUNT`):c(n&&r!==o?`ANIMATION_OUT`:`UNMOUNT`),i.current=e}},[e,c]),k(()=>{if(t){let e,n=t.ownerDocument.defaultView??window,o=a=>{let o=B(r.current).includes(CSS.escape(a.animationName));if(a.target===t&&o&&(c(`ANIMATION_END`),!i.current)){let r=t.style.animationFillMode;t.style.animationFillMode=`forwards`,e=n.setTimeout(()=>{t.style.animationFillMode===`forwards`&&(t.style.animationFillMode=r)})}},s=e=>{e.target===t&&(a.current=B(r.current))};return t.addEventListener(`animationstart`,s),t.addEventListener(`animationcancel`,o),t.addEventListener(`animationend`,o),()=>{n.clearTimeout(e),t.removeEventListener(`animationstart`,s),t.removeEventListener(`animationcancel`,o),t.removeEventListener(`animationend`,o)}}else c(`ANIMATION_END`)},[t,c]),{isPresent:[`mounted`,`unmountSuspended`].includes(o),ref:s.useCallback(e=>{r.current=e?getComputedStyle(e):null,n(e)},[])}}function B(e){return e?.animationName||`none`}function Je(e){let t=Object.getOwnPropertyDescriptor(e.props,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var Ye=0;function Xe(){s.useEffect(()=>{let e=document.querySelectorAll(`[data-radix-focus-guard]`);return document.body.insertAdjacentElement(`afterbegin`,e[0]??Ze()),document.body.insertAdjacentElement(`beforeend`,e[1]??Ze()),Ye++,()=>{Ye===1&&document.querySelectorAll(`[data-radix-focus-guard]`).forEach(e=>e.remove()),Ye--}},[])}function Ze(){let e=document.createElement(`span`);return e.setAttribute(`data-radix-focus-guard`,``),e.tabIndex=0,e.style.outline=`none`,e.style.opacity=`0`,e.style.position=`fixed`,e.style.pointerEvents=`none`,e}var V=function(){return V=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var i in t=arguments[n],t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e},V.apply(this,arguments)};function Qe(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols==`function`)for(var i=0,r=Object.getOwnPropertySymbols(e);i<r.length;i++)t.indexOf(r[i])<0&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function $e(e,t,n){if(n||arguments.length===2)for(var r=0,i=t.length,a;r<i;r++)(a||!(r in t))&&(a||=Array.prototype.slice.call(t,0,r),a[r]=t[r]);return e.concat(a||Array.prototype.slice.call(t))}var H=`right-scroll-bar-position`,U=`width-before-scroll-bar`,et=`with-scroll-bars-hidden`,tt=`--removed-body-scroll-bar-size`;function nt(e,t){return typeof e==`function`?e(t):e&&(e.current=t),e}function rt(e,t){var n=(0,s.useState)(function(){return{value:e,callback:t,facade:{get current(){return n.value},set current(e){var t=n.value;t!==e&&(n.value=e,n.callback(e,t))}}}})[0];return n.callback=t,n.facade}var it=typeof window<`u`?s.useLayoutEffect:s.useEffect,at=new WeakMap;function ot(e,t){var n=rt(t||null,function(t){return e.forEach(function(e){return nt(e,t)})});return it(function(){var t=at.get(n);if(t){var r=new Set(t),i=new Set(e),a=n.current;r.forEach(function(e){i.has(e)||nt(e,null)}),i.forEach(function(e){r.has(e)||nt(e,a)})}at.set(n,e)},[e]),n}function st(e){return e}function ct(e,t){t===void 0&&(t=st);var n=[],r=!1;return{read:function(){if(r)throw Error("Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`.");return n.length?n[n.length-1]:e},useMedium:function(e){var i=t(e,r);return n.push(i),function(){n=n.filter(function(e){return e!==i})}},assignSyncMedium:function(e){for(r=!0;n.length;){var t=n;n=[],t.forEach(e)}n={push:function(t){return e(t)},filter:function(){return n}}},assignMedium:function(e){r=!0;var t=[];if(n.length){var i=n;n=[],i.forEach(e),t=n}var a=function(){var n=t;t=[],n.forEach(e)},o=function(){return Promise.resolve().then(a)};o(),n={push:function(e){t.push(e),o()},filter:function(e){return t=t.filter(e),n}}}}}function lt(e){e===void 0&&(e={});var t=ct(null);return t.options=V({async:!0,ssr:!1},e),t}var ut=function(e){var t=e.sideCar,n=Qe(e,[`sideCar`]);if(!t)throw Error("Sidecar: please provide `sideCar` property to import the right car");var r=t.read();if(!r)throw Error(`Sidecar medium not found`);return s.createElement(r,V({},n))};ut.isSideCarExport=!0;function dt(e,t){return e.useMedium(t),ut}var ft=lt(),pt=function(){},W=s.forwardRef(function(e,t){var n=s.useRef(null),r=s.useState({onScrollCapture:pt,onWheelCapture:pt,onTouchMoveCapture:pt}),i=r[0],a=r[1],o=e.forwardProps,c=e.children,l=e.className,u=e.removeScrollBar,d=e.enabled,f=e.shards,p=e.sideCar,m=e.noRelative,h=e.noIsolation,g=e.inert,_=e.allowPinchZoom,v=e.as,y=v===void 0?`div`:v,b=e.gapMode,ee=Qe(e,[`forwardProps`,`children`,`className`,`removeScrollBar`,`enabled`,`shards`,`sideCar`,`noRelative`,`noIsolation`,`inert`,`allowPinchZoom`,`as`,`gapMode`]),te=p,ne=ot([n,t]),x=V(V({},ee),i);return s.createElement(s.Fragment,null,d&&s.createElement(te,{sideCar:ft,removeScrollBar:u,shards:f,noRelative:m,noIsolation:h,inert:g,setCallbacks:a,allowPinchZoom:!!_,lockRef:n,gapMode:b}),o?s.cloneElement(s.Children.only(c),V(V({},x),{ref:ne})):s.createElement(y,V({},x,{className:l,ref:ne}),c))});W.defaultProps={enabled:!0,removeScrollBar:!0,inert:!1},W.classNames={fullWidth:U,zeroRight:H};var mt,ht=function(){if(mt)return mt;if(typeof __webpack_nonce__<`u`)return __webpack_nonce__};function gt(){if(!document)return null;var e=document.createElement(`style`);e.type=`text/css`;var t=ht();return t&&e.setAttribute(`nonce`,t),e}function _t(e,t){e.styleSheet?e.styleSheet.cssText=t:e.appendChild(document.createTextNode(t))}function vt(e){(document.head||document.getElementsByTagName(`head`)[0]).appendChild(e)}var yt=function(){var e=0,t=null;return{add:function(n){e==0&&(t=gt())&&(_t(t,n),vt(t)),e++},remove:function(){e--,!e&&t&&(t.parentNode&&t.parentNode.removeChild(t),t=null)}}},bt=function(){var e=yt();return function(t,n){s.useEffect(function(){return e.add(t),function(){e.remove()}},[t&&n])}},xt=function(){var e=bt();return function(t){var n=t.styles,r=t.dynamic;return e(n,r),null}},St={left:0,top:0,right:0,gap:0},Ct=function(e){return parseInt(e||``,10)||0},wt=function(e){var t=window.getComputedStyle(document.body),n=t[e===`padding`?`paddingLeft`:`marginLeft`],r=t[e===`padding`?`paddingTop`:`marginTop`],i=t[e===`padding`?`paddingRight`:`marginRight`];return[Ct(n),Ct(r),Ct(i)]},Tt=function(e){if(e===void 0&&(e=`margin`),typeof window>`u`)return St;var t=wt(e),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,r-n+t[2]-t[0])}},Et=xt(),G=`data-scroll-locked`,Dt=function(e,t,n,r){var i=e.left,a=e.top,o=e.right,s=e.gap;return n===void 0&&(n=`margin`),`
|
|
2
|
-
.${et} {
|
|
3
|
-
overflow: hidden ${r};
|
|
4
|
-
padding-right: ${s}px ${r};
|
|
5
|
-
}
|
|
6
|
-
body[${G}] {
|
|
7
|
-
overflow: hidden ${r};
|
|
8
|
-
overscroll-behavior: contain;
|
|
9
|
-
${[t&&`position: relative ${r};`,n===`margin`&&`
|
|
10
|
-
padding-left: ${i}px;
|
|
11
|
-
padding-top: ${a}px;
|
|
12
|
-
padding-right: ${o}px;
|
|
13
|
-
margin-left:0;
|
|
14
|
-
margin-top:0;
|
|
15
|
-
margin-right: ${s}px ${r};
|
|
16
|
-
`,n===`padding`&&`padding-right: ${s}px ${r};`].filter(Boolean).join(``)}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.${H} {
|
|
20
|
-
right: ${s}px ${r};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.${U} {
|
|
24
|
-
margin-right: ${s}px ${r};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.${H} .${H} {
|
|
28
|
-
right: 0 ${r};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.${U} .${U} {
|
|
32
|
-
margin-right: 0 ${r};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
body[${G}] {
|
|
36
|
-
${tt}: ${s}px;
|
|
37
|
-
}
|
|
38
|
-
`},Ot=function(){var e=parseInt(document.body.getAttribute(`data-scroll-locked`)||`0`,10);return isFinite(e)?e:0},kt=function(){s.useEffect(function(){return document.body.setAttribute(G,(Ot()+1).toString()),function(){var e=Ot()-1;e<=0?document.body.removeAttribute(G):document.body.setAttribute(G,e.toString())}},[])},At=function(e){var t=e.noRelative,n=e.noImportant,r=e.gapMode,i=r===void 0?`margin`:r;kt();var a=s.useMemo(function(){return Tt(i)},[i]);return s.createElement(Et,{styles:Dt(a,!t,i,n?``:`!important`)})},jt=!1;if(typeof window<`u`)try{var K=Object.defineProperty({},"passive",{get:function(){return jt=!0,!0}});window.addEventListener(`test`,K,K),window.removeEventListener(`test`,K,K)}catch{jt=!1}var q=jt?{passive:!1}:!1,Mt=function(e){return e.tagName===`TEXTAREA`},Nt=function(e,t){if(!(e instanceof Element))return!1;var n=window.getComputedStyle(e);return n[t]!==`hidden`&&!(n.overflowY===n.overflowX&&!Mt(e)&&n[t]===`visible`)},Pt=function(e){return Nt(e,`overflowY`)},Ft=function(e){return Nt(e,`overflowX`)},It=function(e,t){var n=t.ownerDocument,r=t;do{if(typeof ShadowRoot<`u`&&r instanceof ShadowRoot&&(r=r.host),zt(e,r)){var i=Bt(e,r);if(i[1]>i[2])return!0}r=r.parentNode}while(r&&r!==n.body);return!1},Lt=function(e){return[e.scrollTop,e.scrollHeight,e.clientHeight]},Rt=function(e){return[e.scrollLeft,e.scrollWidth,e.clientWidth]},zt=function(e,t){return e===`v`?Pt(t):Ft(t)},Bt=function(e,t){return e===`v`?Lt(t):Rt(t)},Vt=function(e,t){return e===`h`&&t===`rtl`?-1:1},Ht=function(e,t,n,r,i){var a=Vt(e,window.getComputedStyle(t).direction),o=a*r,s=n.target,c=t.contains(s),l=!1,u=o>0,d=0,f=0;do{if(!s)break;var p=Bt(e,s),m=p[0],h=p[1]-p[2]-a*m;(m||h)&&zt(e,s)&&(d+=h,f+=m);var g=s.parentNode;s=g&&g.nodeType===Node.DOCUMENT_FRAGMENT_NODE?g.host:g}while(!c&&s!==document.body||c&&(t.contains(s)||t===s));return(u&&(i&&Math.abs(d)<1||!i&&o>d)||!u&&(i&&Math.abs(f)<1||!i&&-o>f))&&(l=!0),l},J=function(e){return`changedTouches`in e?[e.changedTouches[0].clientX,e.changedTouches[0].clientY]:[0,0]},Ut=function(e){return[e.deltaX,e.deltaY]},Wt=function(e){return e&&`current`in e?e.current:e},Gt=function(e,t){return e[0]===t[0]&&e[1]===t[1]},Kt=function(e){return`
|
|
39
|
-
.block-interactivity-${e} {pointer-events: none;}
|
|
40
|
-
.allow-interactivity-${e} {pointer-events: all;}
|
|
41
|
-
`},qt=0,Y=[];function Jt(e){var t=s.useRef([]),n=s.useRef([0,0]),r=s.useRef(),i=s.useState(qt++)[0],a=s.useState(xt)[0],o=s.useRef(e);s.useEffect(function(){o.current=e},[e]),s.useEffect(function(){if(e.inert){document.body.classList.add(`block-interactivity-${i}`);var t=$e([e.lockRef.current],(e.shards||[]).map(Wt),!0).filter(Boolean);return t.forEach(function(e){return e.classList.add(`allow-interactivity-${i}`)}),function(){document.body.classList.remove(`block-interactivity-${i}`),t.forEach(function(e){return e.classList.remove(`allow-interactivity-${i}`)})}}},[e.inert,e.lockRef.current,e.shards]);var c=s.useCallback(function(e,t){if(`touches`in e&&e.touches.length===2||e.type===`wheel`&&e.ctrlKey)return!o.current.allowPinchZoom;var i=J(e),a=n.current,s=`deltaX`in e?e.deltaX:a[0]-i[0],c=`deltaY`in e?e.deltaY:a[1]-i[1],l,u=e.target,d=Math.abs(s)>Math.abs(c)?`h`:`v`;if(`touches`in e&&d===`h`&&u.type===`range`)return!1;var f=window.getSelection(),p=f&&f.anchorNode;if(p&&(p===u||p.contains(u)))return!1;var m=It(d,u);if(!m)return!0;if(m?l=d:(l=d===`v`?`h`:`v`,m=It(d,u)),!m)return!1;if(!r.current&&`changedTouches`in e&&(s||c)&&(r.current=l),!l)return!0;var h=r.current||l;return Ht(h,t,e,h===`h`?s:c,!0)},[]),l=s.useCallback(function(e){var n=e;if(!(!Y.length||Y[Y.length-1]!==a)){var r=`deltaY`in n?Ut(n):J(n),i=t.current.filter(function(e){return e.name===n.type&&(e.target===n.target||n.target===e.shadowParent)&&Gt(e.delta,r)})[0];if(i&&i.should){n.cancelable&&n.preventDefault();return}if(!i){var s=(o.current.shards||[]).map(Wt).filter(Boolean).filter(function(e){return e.contains(n.target)});(s.length>0?c(n,s[0]):!o.current.noIsolation)&&n.cancelable&&n.preventDefault()}}},[]),u=s.useCallback(function(e,n,r,i){var a={name:e,delta:n,target:r,should:i,shadowParent:Yt(r)};t.current.push(a),setTimeout(function(){t.current=t.current.filter(function(e){return e!==a})},1)},[]),d=s.useCallback(function(e){n.current=J(e),r.current=void 0},[]),f=s.useCallback(function(t){u(t.type,Ut(t),t.target,c(t,e.lockRef.current))},[]),p=s.useCallback(function(t){u(t.type,J(t),t.target,c(t,e.lockRef.current))},[]);s.useEffect(function(){return Y.push(a),e.setCallbacks({onScrollCapture:f,onWheelCapture:f,onTouchMoveCapture:p}),document.addEventListener(`wheel`,l,q),document.addEventListener(`touchmove`,l,q),document.addEventListener(`touchstart`,d,q),function(){Y=Y.filter(function(e){return e!==a}),document.removeEventListener(`wheel`,l,q),document.removeEventListener(`touchmove`,l,q),document.removeEventListener(`touchstart`,d,q)}},[]);var m=e.removeScrollBar,h=e.inert;return s.createElement(s.Fragment,null,h?s.createElement(a,{styles:Kt(i)}):null,m?s.createElement(At,{noRelative:e.noRelative,gapMode:e.gapMode}):null)}function Yt(e){for(var t=null;e!==null;)e instanceof ShadowRoot&&(t=e.host,e=e.host),e=e.parentNode;return t}var Xt=dt(ft,Jt),Zt=s.forwardRef(function(e,t){return s.createElement(W,V({},e,{ref:t,sideCar:Xt}))});Zt.classNames=W.classNames;var Qt=function(e){return typeof document>`u`?null:(Array.isArray(e)?e[0]:e).ownerDocument.body},X=new WeakMap,Z=new WeakMap,$t={},en=0,tn=function(e){return e&&(e.host||tn(e.parentNode))},nn=function(e,t){return t.map(function(t){if(e.contains(t))return t;var n=tn(t);return n&&e.contains(n)?n:(console.error(`aria-hidden`,t,`in not contained inside`,e,`. Doing nothing`),null)}).filter(function(e){return!!e})},rn=function(e,t,n,r){var i=nn(t,Array.isArray(e)?e:[e]);$t[n]||($t[n]=new WeakMap);var a=$t[n],o=[],s=new Set,c=new Set(i),l=function(e){!e||s.has(e)||(s.add(e),l(e.parentNode))};i.forEach(l);var u=function(e){!e||c.has(e)||Array.prototype.forEach.call(e.children,function(e){if(s.has(e))u(e);else try{var t=e.getAttribute(r),i=t!==null&&t!==`false`,c=(X.get(e)||0)+1,l=(a.get(e)||0)+1;X.set(e,c),a.set(e,l),o.push(e),c===1&&i&&Z.set(e,!0),l===1&&e.setAttribute(n,`true`),i||e.setAttribute(r,`true`)}catch(t){console.error(`aria-hidden: cannot operate on `,e,t)}})};return u(t),s.clear(),en++,function(){o.forEach(function(e){var t=X.get(e)-1,i=a.get(e)-1;X.set(e,t),a.set(e,i),t||(Z.has(e)||e.removeAttribute(r),Z.delete(e)),i||e.removeAttribute(n)}),en--,en||(X=new WeakMap,X=new WeakMap,Z=new WeakMap,$t={})}},an=function(e,t,n){n===void 0&&(n=`data-aria-hidden`);var r=Array.from(Array.isArray(e)?e:[e]),i=t||Qt(e);return i?(r.push.apply(r,Array.from(i.querySelectorAll(`[aria-live], script`))),rn(r,i,n,`aria-hidden`)):function(){return null}};function on(e){let t=sn(e),n=s.forwardRef((e,n)=>{let{children:r,...i}=e,a=s.Children.toArray(r),o=a.find(ln);if(o){let e=o.props.children,r=a.map(t=>t===o?s.Children.count(e)>1?s.Children.only(null):s.isValidElement(e)?e.props.children:null:t);return(0,l.jsx)(t,{...i,ref:n,children:s.isValidElement(e)?s.cloneElement(e,void 0,r):null})}return(0,l.jsx)(t,{...i,ref:n,children:r})});return n.displayName=`${e}.Slot`,n}function sn(e){let t=s.forwardRef((e,t)=>{let{children:n,...r}=e;if(s.isValidElement(n)){let e=dn(n),i=un(r,n.props);return n.type!==s.Fragment&&(i.ref=t?T(t,e):e),s.cloneElement(n,i)}return s.Children.count(n)>1?s.Children.only(null):null});return t.displayName=`${e}.SlotClone`,t}var cn=Symbol(`radix.slottable`);function ln(e){return s.isValidElement(e)&&typeof e.type==`function`&&`__radixId`in e.type&&e.type.__radixId===cn}function un(e,t){let n={...t};for(let r in t){let i=e[r],a=t[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...e)=>{let t=a(...e);return i(...e),t}:i&&(n[r]=i):r===`style`?n[r]={...i,...a}:r===`className`&&(n[r]=[i,a].filter(Boolean).join(` `))}return{...e,...n}}function dn(e){let t=Object.getOwnPropertyDescriptor(e.props,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var fn=`Dialog`,[pn,mn]=O(fn),[hn,Q]=pn(fn),gn=e=>{let{__scopeDialog:t,children:n,open:r,defaultOpen:i,onOpenChange:a,modal:o=!0}=e,c=s.useRef(null),u=s.useRef(null),[d,f]=N({prop:r,defaultProp:i??!1,onChange:a,caller:fn});return(0,l.jsx)(hn,{scope:t,triggerRef:c,contentRef:u,contentId:j(),titleId:j(),descriptionId:j(),open:d,onOpenChange:f,onOpenToggle:s.useCallback(()=>f(e=>!e),[f]),modal:o,children:n})};gn.displayName=fn;var _n=`DialogTrigger`,vn=s.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=Q(_n,n),a=E(t,i.triggerRef);return(0,l.jsx)(I.button,{type:`button`,"aria-haspopup":`dialog`,"aria-expanded":i.open,"aria-controls":i.contentId,"data-state":Ln(i.open),...r,ref:a,onClick:D(e.onClick,i.onOpenToggle)})});vn.displayName=_n;var yn=`DialogPortal`,[bn,xn]=pn(yn,{forceMount:void 0}),Sn=e=>{let{__scopeDialog:t,forceMount:n,children:r,container:i}=e,a=Q(yn,t);return(0,l.jsx)(bn,{scope:t,forceMount:n,children:s.Children.map(r,e=>(0,l.jsx)(z,{present:n||a.open,children:(0,l.jsx)(Ge,{asChild:!0,container:i,children:e})}))})};Sn.displayName=yn;var Cn=`DialogOverlay`,wn=s.forwardRef((e,t)=>{let n=xn(Cn,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=Q(Cn,e.__scopeDialog);return a.modal?(0,l.jsx)(z,{present:r||a.open,children:(0,l.jsx)(En,{...i,ref:t})}):null});wn.displayName=Cn;var Tn=on(`DialogOverlay.RemoveScroll`),En=s.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=Q(Cn,n);return(0,l.jsx)(Zt,{as:Tn,allowPinchZoom:!0,shards:[i.contentRef],children:(0,l.jsx)(I.div,{"data-state":Ln(i.open),...r,ref:t,style:{pointerEvents:`auto`,...r.style}})})}),$=`DialogContent`,Dn=s.forwardRef((e,t)=>{let n=xn($,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=Q($,e.__scopeDialog);return(0,l.jsx)(z,{present:r||a.open,children:a.modal?(0,l.jsx)(On,{...i,ref:t}):(0,l.jsx)(kn,{...i,ref:t})})});Dn.displayName=$;var On=s.forwardRef((e,t)=>{let n=Q($,e.__scopeDialog),r=s.useRef(null),i=E(t,n.contentRef,r);return s.useEffect(()=>{let e=r.current;if(e)return an(e)},[]),(0,l.jsx)(An,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:D(e.onCloseAutoFocus,e=>{e.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:D(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0;(t.button===2||n)&&e.preventDefault()}),onFocusOutside:D(e.onFocusOutside,e=>e.preventDefault())})}),kn=s.forwardRef((e,t)=>{let n=Q($,e.__scopeDialog),r=s.useRef(!1),i=s.useRef(!1);return(0,l.jsx)(An,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(r.current||n.triggerRef.current?.focus(),t.preventDefault()),r.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(r.current=!0,t.detail.originalEvent.type===`pointerdown`&&(i.current=!0));let a=t.target;n.triggerRef.current?.contains(a)&&t.preventDefault(),t.detail.originalEvent.type===`focusin`&&i.current&&t.preventDefault()}})}),An=s.forwardRef((e,t)=>{let{__scopeDialog:n,trapFocus:r,onOpenAutoFocus:i,onCloseAutoFocus:a,...o}=e,c=Q($,n),u=s.useRef(null),d=E(t,u);return Xe(),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(Ne,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,l.jsx)(Se,{role:`dialog`,id:c.contentId,"aria-describedby":c.descriptionId,"aria-labelledby":c.titleId,"data-state":Ln(c.open),...o,ref:d,onDismiss:()=>c.onOpenChange(!1)})}),(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(Vn,{titleId:c.titleId}),(0,l.jsx)(Un,{contentRef:u,descriptionId:c.descriptionId})]})]})}),jn=`DialogTitle`,Mn=s.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=Q(jn,n);return(0,l.jsx)(I.h2,{id:i.titleId,...r,ref:t})});Mn.displayName=jn;var Nn=`DialogDescription`,Pn=s.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=Q(Nn,n);return(0,l.jsx)(I.p,{id:i.descriptionId,...r,ref:t})});Pn.displayName=Nn;var Fn=`DialogClose`,In=s.forwardRef((e,t)=>{let{__scopeDialog:n,...r}=e,i=Q(Fn,n);return(0,l.jsx)(I.button,{type:`button`,...r,ref:t,onClick:D(e.onClick,()=>i.onOpenChange(!1))})});In.displayName=Fn;function Ln(e){return e?`open`:`closed`}var Rn=`DialogTitleWarning`,[zn,Bn]=ae(Rn,{contentName:$,titleName:jn,docsSlug:`dialog`}),Vn=({titleId:e})=>{let t=Bn(Rn),n=`\`${t.contentName}\` requires a \`${t.titleName}\` for the component to be accessible for screen reader users.
|
|
42
|
-
|
|
43
|
-
If you want to hide the \`${t.titleName}\`, you can wrap it with our VisuallyHidden component.
|
|
44
|
-
|
|
45
|
-
For more information, see https://radix-ui.com/primitives/docs/components/${t.docsSlug}`;return s.useEffect(()=>{e&&(document.getElementById(e)||console.error(n))},[n,e]),null},Hn=`DialogDescriptionWarning`,Un=({contentRef:e,descriptionId:t})=>{let n=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${Bn(Hn).contentName}}.`;return s.useEffect(()=>{let r=e.current?.getAttribute(`aria-describedby`);t&&r&&(document.getElementById(t)||console.warn(n))},[n,e,t]),null},Wn=gn,Gn=Sn,Kn=wn,qn=Dn,Jn=Mn,Yn=Pn,Xn=In;function Zn(...e){return s.useCallback(t=>{for(let n of e)n&&(typeof n==`function`?n(t):n.current=t)},e)}var Qn=Wn,$n=Gn,er=Xn,tr=s.forwardRef(({className:e,...t},n)=>(0,l.jsx)(Kn,{ref:n,className:o(`fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0`,e),...t}));tr.displayName=Kn.displayName;var nr=()=>{let{t:e}=i(`common`);return(0,l.jsxs)(Xn,{className:`absolute right-4 top-4 z-20 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground`,children:[(0,l.jsx)(a,{className:`h-4 w-4`}),(0,l.jsx)(`span`,{className:`sr-only`,children:e(`actions.close`)})]})},rr=s.forwardRef(({className:e,children:t,showCloseButton:n=!0,movableResizable:r=!1,style:i,...a},s)=>{let{panelRef:c,panelStyle:u,resizeHandles:d}=S({enabled:r,allowMove:!1}),f=Zn(s,c);return r?(0,l.jsxs)($n,{children:[(0,l.jsx)(tr,{}),(0,l.jsxs)(qn,{ref:f,style:{...i,...u},className:o(`fixed left-[50%] top-[50%] z-50 grid w-full max-w-2xl max-h-[85vh] translate-x-[-50%] translate-y-[-50%] gap-4 border border-border/30 bg-popover p-6 shadow-xl backdrop-blur-md duration-200 overflow-y-auto data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-xl`,e),...a,children:[t,n&&(0,l.jsx)(nr,{})]}),(0,l.jsx)(C,{handles:d})]}):(0,l.jsxs)($n,{children:[(0,l.jsx)(tr,{}),(0,l.jsxs)(qn,{ref:s,style:i,className:o(`fixed left-[50%] top-[50%] z-50 grid w-full max-w-2xl max-h-[85vh] translate-x-[-50%] translate-y-[-50%] gap-4 border border-border/30 bg-popover p-6 shadow-xl backdrop-blur-md duration-200 overflow-y-auto data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-xl`,e),...a,children:[t,n&&(0,l.jsx)(nr,{})]})]})});rr.displayName=qn.displayName;var ir=({className:e,...t})=>(0,l.jsx)(`div`,{className:o(`flex flex-col space-y-1.5 text-center sm:text-left`,e),...t});ir.displayName=`DialogHeader`;var ar=({className:e,...t})=>(0,l.jsx)(`div`,{className:o(`flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2`,e),...t});ar.displayName=`DialogFooter`;var or=s.forwardRef(({className:e,...t},n)=>(0,l.jsx)(Jn,{ref:n,className:o(`text-lg font-semibold leading-none tracking-tight`,e),...t}));or.displayName=Jn.displayName;var sr=s.forwardRef(({className:e,...t},n)=>(0,l.jsx)(Yn,{ref:n,className:o(`text-xs text-muted-foreground`,e),...t}));sr.displayName=Yn.displayName;export{E as A,I as C,O as D,k as E,S as M,D as O,L as S,j as T,Xe as _,ar as a,Ne as b,$n as c,Kn as d,Gn as f,Zt as g,an as h,sr as i,C as j,T as k,or as l,Jn as m,er as n,ir as o,Wn as p,rr as r,tr as s,Qn as t,qn as u,z as v,N as w,Se as x,Ge as y};
|