@cat-factory/app 0.54.4 → 0.55.0
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/app/app.vue +14 -0
- package/app/components/auth/UserMenu.vue +1 -1
- package/app/components/board/AddTaskModal.vue +5 -4
- package/app/components/board/nodes/AgentChip.vue +2 -2
- package/app/components/board/nodes/BlockNode.vue +12 -8
- package/app/components/board/nodes/DraggableTask.vue +1 -1
- package/app/components/board/nodes/EpicNode.vue +1 -1
- package/app/components/board/nodes/ModuleFrame.vue +7 -4
- package/app/components/board/nodes/TaskCard.vue +2 -2
- package/app/components/board/nodes/TaskPipelineMini.vue +3 -3
- package/app/components/brainstorm/BrainstormWindow.vue +8 -7
- package/app/components/clarity/ClarityReviewWindow.vue +8 -7
- package/app/components/consensus/ConsensusSessionWindow.vue +2 -2
- package/app/components/documents/ContextDocumentPicker.vue +4 -4
- package/app/components/documents/SpawnPreviewModal.vue +4 -4
- package/app/components/focus/BlockFocusView.vue +11 -4
- package/app/components/fragments/FragmentLibraryManager.vue +5 -5
- package/app/components/gates/GateResultView.vue +3 -3
- package/app/components/github/GitHubPanel.vue +5 -2
- package/app/components/humanTest/HumanTestWindow.vue +1 -1
- package/app/components/kaizen/KaizenPanel.vue +5 -5
- package/app/components/kaizen/KaizenStepStatus.vue +2 -2
- package/app/components/layout/BoardSwitcher.vue +4 -4
- package/app/components/layout/CommandBar.vue +1 -1
- package/app/components/layout/IntegrationBackTitle.vue +2 -1
- package/app/components/layout/IntegrationsHub.vue +10 -4
- package/app/components/layout/LanguageSwitcher.vue +1 -1
- package/app/components/layout/NotificationsInbox.vue +1 -1
- package/app/components/layout/PersonalSetupModal.vue +5 -2
- package/app/components/layout/SideBar.vue +5 -3
- package/app/components/media/ArtifactLightbox.vue +5 -5
- package/app/components/media/ImageCompare.vue +6 -1
- package/app/components/observability/StepMetricsBar.vue +6 -2
- package/app/components/palettes/AgentPalette.vue +4 -4
- package/app/components/panels/AgentStepDetail.vue +12 -12
- package/app/components/panels/GenericStructuredResultView.vue +1 -1
- package/app/components/panels/InspectorPanel.vue +2 -2
- package/app/components/panels/ObservabilityPanel.vue +6 -6
- package/app/components/panels/StepMetadataCard.vue +1 -1
- package/app/components/panels/inspector/ContainerSummary.vue +2 -2
- package/app/components/panels/inspector/EpicChildren.vue +3 -3
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +1 -1
- package/app/components/panels/inspector/ServiceFragments.vue +1 -1
- package/app/components/panels/inspector/ServiceTestConfig.vue +1 -1
- package/app/components/panels/inspector/TaskDependencies.vue +1 -1
- package/app/components/panels/inspector/TaskEstimateBadge.vue +1 -1
- package/app/components/panels/inspector/TaskExecution.vue +9 -9
- package/app/components/panels/inspector/TaskRunSettings.vue +2 -2
- package/app/components/panels/inspector/TaskStructure.vue +1 -1
- package/app/components/pipeline/IterationCapPrompt.vue +1 -0
- package/app/components/pipeline/PipelineBuilder.vue +8 -8
- package/app/components/pipeline/PipelineProgress.vue +4 -4
- package/app/components/providers/ApiKeysSection.vue +2 -2
- package/app/components/providers/PersonalSubscriptionSection.vue +2 -2
- package/app/components/providers/VendorCredentialsModal.vue +2 -2
- package/app/components/provisioning/ProvisioningLogsDrawer.vue +1 -1
- package/app/components/requirements/RequirementsReviewWindow.vue +9 -8
- package/app/components/sandbox/SandboxPanel.vue +17 -17
- package/app/components/settings/LocalModelEndpointsPanel.vue +1 -1
- package/app/components/settings/ModelConfigurationPanel.vue +4 -3
- package/app/components/settings/OpenRouterCatalogPanel.vue +3 -3
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +1 -1
- package/app/components/spec/ServiceSpecWindow.vue +3 -3
- package/app/components/tasks/ContextIssuePicker.vue +5 -5
- package/app/components/tasks/TaskContextIssues.vue +1 -1
- package/app/components/tasks/TaskImportModal.vue +1 -1
- package/app/components/testing/TestReportWindow.vue +5 -5
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +2 -2
- package/app/pages/index.vue +1 -1
- package/i18n/i18n.config.ts +9 -0
- package/i18n/locales/he.json +3385 -0
- package/nuxt.config.ts +1 -0
- package/package.json +1 -1
|
@@ -190,7 +190,7 @@ async function resetRun() {
|
|
|
190
190
|
model, subtasks + the prose output when there is one). -->
|
|
191
191
|
<button
|
|
192
192
|
type="button"
|
|
193
|
-
class="flex min-w-0 cursor-pointer items-center gap-2 text-
|
|
193
|
+
class="flex min-w-0 cursor-pointer items-center gap-2 text-start transition hover:text-white"
|
|
194
194
|
:title="
|
|
195
195
|
s.output
|
|
196
196
|
? t('inspector.execution.viewDetailsOutput')
|
|
@@ -220,7 +220,7 @@ async function resetRun() {
|
|
|
220
220
|
</button>
|
|
221
221
|
<span
|
|
222
222
|
v-if="s.subtasks && s.subtasks.total > 0"
|
|
223
|
-
class="
|
|
223
|
+
class="ms-auto font-mono text-[10px] tabular-nums text-slate-300"
|
|
224
224
|
:title="
|
|
225
225
|
s.subtasks.inProgress > 0
|
|
226
226
|
? t('inspector.execution.subtasksProgress', {
|
|
@@ -240,7 +240,7 @@ async function resetRun() {
|
|
|
240
240
|
class="inline-flex items-center gap-1 text-[10px]"
|
|
241
241
|
:class="[
|
|
242
242
|
stepFailed(s) ? 'text-rose-400' : 'text-slate-400',
|
|
243
|
-
{ '
|
|
243
|
+
{ 'ms-auto': !s.subtasks },
|
|
244
244
|
]"
|
|
245
245
|
>
|
|
246
246
|
<UIcon v-if="stepFailed(s)" name="i-lucide-circle-x" class="h-3 w-3 shrink-0" />
|
|
@@ -300,7 +300,7 @@ async function resetRun() {
|
|
|
300
300
|
</div>
|
|
301
301
|
<div
|
|
302
302
|
v-if="s.subtasks && s.subtasks.total > 0"
|
|
303
|
-
class="mt-1
|
|
303
|
+
class="mt-1 ms-6 h-1 overflow-hidden rounded-full bg-slate-700/60"
|
|
304
304
|
>
|
|
305
305
|
<div
|
|
306
306
|
class="h-full rounded-full bg-indigo-400 transition-all duration-500"
|
|
@@ -309,7 +309,7 @@ async function resetRun() {
|
|
|
309
309
|
</div>
|
|
310
310
|
<div
|
|
311
311
|
v-if="s.model"
|
|
312
|
-
class="mt-0.5 flex items-center gap-1
|
|
312
|
+
class="mt-0.5 flex items-center gap-1 ps-6 text-[10px] text-slate-500"
|
|
313
313
|
:title="s.model"
|
|
314
314
|
>
|
|
315
315
|
<UIcon name="i-lucide-cpu" class="h-3 w-3" />
|
|
@@ -318,7 +318,7 @@ async function resetRun() {
|
|
|
318
318
|
<!-- Prompt-fragment standards the library selected for this step. -->
|
|
319
319
|
<div
|
|
320
320
|
v-if="s.selectedFragmentIds && s.selectedFragmentIds.length"
|
|
321
|
-
class="mt-0.5 flex flex-wrap items-center gap-1
|
|
321
|
+
class="mt-0.5 flex flex-wrap items-center gap-1 ps-6 text-[10px] text-slate-500"
|
|
322
322
|
:title="
|
|
323
323
|
t('inspector.execution.fragmentsTooltip', {
|
|
324
324
|
fragments: s.selectedFragmentIds.join(', '),
|
|
@@ -338,7 +338,7 @@ async function resetRun() {
|
|
|
338
338
|
completed/skipped, so it's clear whether a fix pass ran. -->
|
|
339
339
|
<div
|
|
340
340
|
v-if="gateCompanionFor(s, runFailed)"
|
|
341
|
-
class="mt-0.5 flex items-center gap-1.5
|
|
341
|
+
class="mt-0.5 flex items-center gap-1.5 ps-6 text-[10px]"
|
|
342
342
|
>
|
|
343
343
|
<UIcon
|
|
344
344
|
:name="agentKindMeta(gateCompanionFor(s, runFailed)!.kind).icon"
|
|
@@ -356,7 +356,7 @@ async function resetRun() {
|
|
|
356
356
|
}}
|
|
357
357
|
</span>
|
|
358
358
|
<span
|
|
359
|
-
class="
|
|
359
|
+
class="ms-auto"
|
|
360
360
|
:class="COMPANION_STATE_META[gateCompanionFor(s, runFailed)!.state].text"
|
|
361
361
|
>
|
|
362
362
|
{{ COMPANION_STATE_META[gateCompanionFor(s, runFailed)!.state].label }}
|
|
@@ -388,7 +388,7 @@ async function resetRun() {
|
|
|
388
388
|
>
|
|
389
389
|
<span class="flex w-full items-center gap-2">
|
|
390
390
|
{{ prLabel }}
|
|
391
|
-
<UBadge :color="prMerged ? 'success' : 'info'" variant="subtle" size="sm" class="
|
|
391
|
+
<UBadge :color="prMerged ? 'success' : 'info'" variant="subtle" size="sm" class="ms-auto">
|
|
392
392
|
{{ prMerged ? t('inspector.execution.merged') : t('inspector.execution.open') }}
|
|
393
393
|
</UBadge>
|
|
394
394
|
</span>
|
|
@@ -246,7 +246,7 @@ const technicalLabel = computed(() => {
|
|
|
246
246
|
class="cursor-pointer"
|
|
247
247
|
@click="setPipeline('')"
|
|
248
248
|
>
|
|
249
|
-
{{ selectedPipeline.name }}<UIcon name="i-lucide-x" class="
|
|
249
|
+
{{ selectedPipeline.name }}<UIcon name="i-lucide-x" class="ms-0.5 h-3 w-3" />
|
|
250
250
|
</UBadge>
|
|
251
251
|
</div>
|
|
252
252
|
<div v-else class="text-[11px] text-slate-500">
|
|
@@ -461,7 +461,7 @@ const technicalLabel = computed(() => {
|
|
|
461
461
|
class="cursor-pointer"
|
|
462
462
|
@click="setResponsible('')"
|
|
463
463
|
>
|
|
464
|
-
{{ responsibleLabel }}<UIcon name="i-lucide-x" class="
|
|
464
|
+
{{ responsibleLabel }}<UIcon name="i-lucide-x" class="ms-0.5 h-3 w-3" />
|
|
465
465
|
</UBadge>
|
|
466
466
|
</div>
|
|
467
467
|
<div v-else class="text-[11px] text-slate-500">
|
|
@@ -112,7 +112,7 @@ function removeFragment(id: string) {
|
|
|
112
112
|
:title="f.summary"
|
|
113
113
|
@click="removeFragment(f.id)"
|
|
114
114
|
>
|
|
115
|
-
{{ f.title }}<UIcon name="i-lucide-x" class="
|
|
115
|
+
{{ f.title }}<UIcon name="i-lucide-x" class="ms-0.5 h-3 w-3" />
|
|
116
116
|
</UBadge>
|
|
117
117
|
</div>
|
|
118
118
|
<div v-else class="text-[11px] text-slate-500">
|
|
@@ -53,6 +53,7 @@ const emit = defineEmits<{ resolve: [choice: IterationCapChoice] }>()
|
|
|
53
53
|
variant="soft"
|
|
54
54
|
size="xs"
|
|
55
55
|
icon="i-lucide-arrow-right"
|
|
56
|
+
:ui="{ leadingIcon: 'rtl:-scale-x-100', trailingIcon: 'rtl:-scale-x-100' }"
|
|
56
57
|
:loading="loading"
|
|
57
58
|
@click="emit('resolve', 'proceed')"
|
|
58
59
|
>
|
|
@@ -241,7 +241,7 @@ async function clone(p: Pipeline) {
|
|
|
241
241
|
{{ t('pipeline.builder.addAgent') }}
|
|
242
242
|
</UButton>
|
|
243
243
|
</div>
|
|
244
|
-
<div class="flex-1
|
|
244
|
+
<div class="flex-1 pe-1 lg:min-h-0 lg:overflow-y-auto">
|
|
245
245
|
<AgentPalette @add="add" />
|
|
246
246
|
</div>
|
|
247
247
|
</div>
|
|
@@ -309,7 +309,7 @@ async function clone(p: Pipeline) {
|
|
|
309
309
|
{{ t('pipeline.builder.emptyDraft') }}
|
|
310
310
|
</div>
|
|
311
311
|
|
|
312
|
-
<ol v-else class="flex-1 space-y-2
|
|
312
|
+
<ol v-else class="flex-1 space-y-2 pe-1 lg:min-h-0 lg:overflow-y-auto">
|
|
313
313
|
<li
|
|
314
314
|
v-for="(unit, vi) in pipelines.units"
|
|
315
315
|
:key="unit.index"
|
|
@@ -455,7 +455,7 @@ async function clone(p: Pipeline) {
|
|
|
455
455
|
gated on the task estimate. -->
|
|
456
456
|
<div
|
|
457
457
|
v-if="unit.companionIndex !== null"
|
|
458
|
-
class="
|
|
458
|
+
class="ms-6 space-y-2 rounded-md border border-fuchsia-800/40 bg-fuchsia-950/20 p-2 text-xs"
|
|
459
459
|
>
|
|
460
460
|
<div class="flex items-center gap-1.5">
|
|
461
461
|
<UIcon name="i-lucide-corner-down-right" class="h-3.5 w-3.5 text-slate-500" />
|
|
@@ -524,7 +524,7 @@ async function clone(p: Pipeline) {
|
|
|
524
524
|
<!-- Consensus config (shown when the step is consensus-enabled). -->
|
|
525
525
|
<div
|
|
526
526
|
v-if="pipelines.draftConsensus[unit.index]?.enabled"
|
|
527
|
-
class="
|
|
527
|
+
class="ms-6 space-y-2 rounded-md border border-emerald-800/40 bg-emerald-950/20 p-2 text-xs"
|
|
528
528
|
>
|
|
529
529
|
<div class="flex items-center gap-2">
|
|
530
530
|
<label class="text-slate-400">{{ t('pipeline.builder.strategy') }}</label>
|
|
@@ -538,7 +538,7 @@ async function clone(p: Pipeline) {
|
|
|
538
538
|
</select>
|
|
539
539
|
<label
|
|
540
540
|
v-if="pipelines.draftConsensus[unit.index]!.strategy === 'debate'"
|
|
541
|
-
class="
|
|
541
|
+
class="ms-2 text-slate-400"
|
|
542
542
|
>{{ t('pipeline.builder.rounds') }}</label
|
|
543
543
|
>
|
|
544
544
|
<input
|
|
@@ -681,7 +681,7 @@ async function clone(p: Pipeline) {
|
|
|
681
681
|
</UBadge>
|
|
682
682
|
</div>
|
|
683
683
|
|
|
684
|
-
<ul class="flex-1 space-y-1.5
|
|
684
|
+
<ul class="flex-1 space-y-1.5 pe-1 lg:min-h-0 lg:overflow-y-auto">
|
|
685
685
|
<li
|
|
686
686
|
v-for="p in visiblePipelines"
|
|
687
687
|
:key="p.id"
|
|
@@ -691,7 +691,7 @@ async function clone(p: Pipeline) {
|
|
|
691
691
|
<div class="flex items-center gap-2 px-2 py-1.5">
|
|
692
692
|
<button
|
|
693
693
|
type="button"
|
|
694
|
-
class="flex min-w-0 flex-1 items-center gap-2 text-
|
|
694
|
+
class="flex min-w-0 flex-1 items-center gap-2 text-start"
|
|
695
695
|
@click="toggleSaved(p.id)"
|
|
696
696
|
>
|
|
697
697
|
<UIcon
|
|
@@ -784,7 +784,7 @@ async function clone(p: Pipeline) {
|
|
|
784
784
|
<!-- Full ordered step list, revealed on click. -->
|
|
785
785
|
<ol
|
|
786
786
|
v-if="expandedSaved.has(p.id)"
|
|
787
|
-
class="space-y-1 border-t border-slate-800 px-2 py-2
|
|
787
|
+
class="space-y-1 border-t border-slate-800 px-2 py-2 ps-7"
|
|
788
788
|
>
|
|
789
789
|
<li
|
|
790
790
|
v-for="(k, i) in p.agentKinds"
|
|
@@ -213,7 +213,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
213
213
|
<span v-if="currentAgent && instance.status === 'running'" class="text-xs text-slate-500">
|
|
214
214
|
· {{ t('pipeline.progress.currently', { agent: currentAgent }) }}
|
|
215
215
|
</span>
|
|
216
|
-
<span class="
|
|
216
|
+
<span class="ms-auto font-mono text-sm tabular-nums text-slate-200">{{
|
|
217
217
|
t('pipeline.progress.percent', { value: overallPct })
|
|
218
218
|
}}</span>
|
|
219
219
|
</div>
|
|
@@ -241,7 +241,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
241
241
|
<!-- connector line to the next step -->
|
|
242
242
|
<span
|
|
243
243
|
v-if="i < steps.length - 1"
|
|
244
|
-
class="absolute top-9 bottom-0
|
|
244
|
+
class="absolute top-9 bottom-0 start-[17px] w-0.5 -translate-x-1/2"
|
|
245
245
|
:class="connectorDone(i) ? 'bg-emerald-500/60' : 'bg-slate-700'"
|
|
246
246
|
/>
|
|
247
247
|
|
|
@@ -306,7 +306,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
306
306
|
</div>
|
|
307
307
|
</div>
|
|
308
308
|
<span
|
|
309
|
-
class="
|
|
309
|
+
class="ms-auto shrink-0 text-[11px] font-medium"
|
|
310
310
|
:style="{ color: stepVisual(s.state).color }"
|
|
311
311
|
>
|
|
312
312
|
{{ stepVisual(s.state).label }}
|
|
@@ -495,7 +495,7 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
495
495
|
<button
|
|
496
496
|
v-if="s.followUps?.enabled"
|
|
497
497
|
type="button"
|
|
498
|
-
class="mt-3 flex w-full items-center gap-2 rounded-lg border border-dashed px-2.5 py-1.5 text-
|
|
498
|
+
class="mt-3 flex w-full items-center gap-2 rounded-lg border border-dashed px-2.5 py-1.5 text-start transition hover:border-pink-400/60"
|
|
499
499
|
:class="
|
|
500
500
|
followUpPending(s) > 0
|
|
501
501
|
? 'border-pink-500/50 bg-pink-500/10 followup-blink'
|
|
@@ -287,7 +287,7 @@ async function remove(k: ApiKey) {
|
|
|
287
287
|
|
|
288
288
|
<!-- where to get the key -->
|
|
289
289
|
<ol
|
|
290
|
-
class="list-decimal space-y-1.5 rounded-lg border border-slate-700 bg-slate-900/60 p-4
|
|
290
|
+
class="list-decimal space-y-1.5 rounded-lg border border-slate-700 bg-slate-900/60 p-4 ps-8 text-sm text-slate-300"
|
|
291
291
|
>
|
|
292
292
|
<li v-for="(step, i) in selected.steps" :key="i">{{ step }}</li>
|
|
293
293
|
<li>
|
|
@@ -351,7 +351,7 @@ async function remove(k: ApiKey) {
|
|
|
351
351
|
>
|
|
352
352
|
<div>
|
|
353
353
|
<span class="font-medium text-slate-200">{{ k.label }}</span>
|
|
354
|
-
<span class="
|
|
354
|
+
<span class="ms-2 text-xs text-slate-500">{{ providerLabel(k.provider) }}</span>
|
|
355
355
|
<div class="text-[11px] tabular-nums text-slate-500">
|
|
356
356
|
{{
|
|
357
357
|
t(
|
|
@@ -179,7 +179,7 @@ async function disconnect(v: SubscriptionVendor) {
|
|
|
179
179
|
>
|
|
180
180
|
<div>
|
|
181
181
|
<span class="font-medium text-slate-200">{{ sub.label }}</span>
|
|
182
|
-
<span class="
|
|
182
|
+
<span class="ms-2 text-xs text-slate-500">{{ vendorLabel(sub.vendor) }}</span>
|
|
183
183
|
<div class="text-[11px] text-slate-500">
|
|
184
184
|
<template v-if="sub.expiresAt">
|
|
185
185
|
{{ t('personalSubscriptions.expires', { date: d(new Date(sub.expiresAt), 'short') }) }}
|
|
@@ -210,7 +210,7 @@ async function disconnect(v: SubscriptionVendor) {
|
|
|
210
210
|
|
|
211
211
|
<!-- connect / replace form -->
|
|
212
212
|
<ol
|
|
213
|
-
class="list-decimal space-y-1.5 rounded-lg border border-slate-700 bg-slate-900/60 p-4
|
|
213
|
+
class="list-decimal space-y-1.5 rounded-lg border border-slate-700 bg-slate-900/60 p-4 ps-8 text-sm text-slate-300"
|
|
214
214
|
>
|
|
215
215
|
<li v-for="(step, i) in selectedMeta.steps" :key="i">{{ step }}</li>
|
|
216
216
|
</ol>
|
|
@@ -192,7 +192,7 @@ function vendorLabel(v: SubscriptionVendor): string {
|
|
|
192
192
|
|
|
193
193
|
<!-- guided steps -->
|
|
194
194
|
<ol
|
|
195
|
-
class="list-decimal space-y-1.5 rounded-lg border border-slate-700 bg-slate-900/60 p-4
|
|
195
|
+
class="list-decimal space-y-1.5 rounded-lg border border-slate-700 bg-slate-900/60 p-4 ps-8 text-sm text-slate-300"
|
|
196
196
|
>
|
|
197
197
|
<li v-for="(step, i) in steps" :key="i">{{ step }}</li>
|
|
198
198
|
</ol>
|
|
@@ -239,7 +239,7 @@ function vendorLabel(v: SubscriptionVendor): string {
|
|
|
239
239
|
>
|
|
240
240
|
<div>
|
|
241
241
|
<span class="font-medium text-slate-200">{{ c.label }}</span>
|
|
242
|
-
<span class="
|
|
242
|
+
<span class="ms-2 text-xs text-slate-500">{{ vendorLabel(c.vendor) }}</span>
|
|
243
243
|
<div class="text-[11px] tabular-nums text-slate-500">
|
|
244
244
|
{{
|
|
245
245
|
t(
|
|
@@ -94,7 +94,7 @@ function when(epochMs: number): string {
|
|
|
94
94
|
"
|
|
95
95
|
>{{ OUTCOME_LABEL[entry.outcome] }}</span
|
|
96
96
|
>
|
|
97
|
-
<span class="
|
|
97
|
+
<span class="ms-auto text-[11px] text-slate-500">{{ when(entry.createdAt) }}</span>
|
|
98
98
|
</div>
|
|
99
99
|
<div v-if="entry.targetId" class="mt-0.5 text-[11px] text-slate-500">
|
|
100
100
|
{{ entry.providerId ? `${entry.providerId} · ` : '' }}{{ entry.targetId }}
|
|
@@ -428,7 +428,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
428
428
|
</h1>
|
|
429
429
|
<p v-if="block" class="truncate text-xs text-slate-500">{{ block.title }}</p>
|
|
430
430
|
</div>
|
|
431
|
-
<div class="
|
|
431
|
+
<div class="ms-auto flex items-center gap-1.5">
|
|
432
432
|
<UBadge v-if="review" color="neutral" variant="subtle" size="sm">
|
|
433
433
|
{{ t('requirements.iteration', { current: iteration, max: maxIterations }) }}
|
|
434
434
|
</UBadge>
|
|
@@ -538,7 +538,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
538
538
|
size="xs"
|
|
539
539
|
variant="soft"
|
|
540
540
|
:color="STATUS_COLOR[item.status]"
|
|
541
|
-
class="
|
|
541
|
+
class="ms-auto"
|
|
542
542
|
>
|
|
543
543
|
{{ STATUS_LABELS[item.status] }}
|
|
544
544
|
</UBadge>
|
|
@@ -551,7 +551,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
551
551
|
ones the answer lives in the textarea below, seeded from the reply) -->
|
|
552
552
|
<div
|
|
553
553
|
v-if="item.reply && item.status !== 'open' && item.status !== 'answered'"
|
|
554
|
-
class="mt-2 rounded-md border-
|
|
554
|
+
class="mt-2 rounded-md border-s-2 border-slate-700 bg-slate-950/40 px-3 py-1.5 text-sm text-slate-300"
|
|
555
555
|
>
|
|
556
556
|
<span class="text-[10px] uppercase tracking-wide text-slate-500">
|
|
557
557
|
{{ t('requirements.answerLabel') }}
|
|
@@ -641,7 +641,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
641
641
|
}}</span>
|
|
642
642
|
<span
|
|
643
643
|
v-if="recommendationProgress"
|
|
644
|
-
class="
|
|
644
|
+
class="ms-auto flex items-center gap-1.5 normal-case text-indigo-300/80"
|
|
645
645
|
>
|
|
646
646
|
<UIcon name="i-lucide-loader-circle" class="h-3.5 w-3.5 animate-spin" />
|
|
647
647
|
{{
|
|
@@ -764,7 +764,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
764
764
|
<div v-for="s in outline.sections" :key="s.id" class="mb-2">
|
|
765
765
|
<button
|
|
766
766
|
v-if="s.title"
|
|
767
|
-
class="group flex w-full items-center gap-2 text-
|
|
767
|
+
class="group flex w-full items-center gap-2 text-start"
|
|
768
768
|
@click="toggle(s.id)"
|
|
769
769
|
>
|
|
770
770
|
<UIcon
|
|
@@ -780,7 +780,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
780
780
|
</button>
|
|
781
781
|
<div
|
|
782
782
|
v-show="!s.title || !collapsed[s.id]"
|
|
783
|
-
class="reader-prose mt-1
|
|
783
|
+
class="reader-prose mt-1 ps-5.5 text-[13px] leading-relaxed text-slate-300"
|
|
784
784
|
v-html="s.bodyHtml"
|
|
785
785
|
/>
|
|
786
786
|
</div>
|
|
@@ -789,7 +789,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
789
789
|
</div>
|
|
790
790
|
|
|
791
791
|
<!-- right action rail -->
|
|
792
|
-
<aside class="hidden w-72 shrink-0 flex-col border-
|
|
792
|
+
<aside class="hidden w-72 shrink-0 flex-col border-s border-slate-800 lg:flex">
|
|
793
793
|
<div class="flex flex-col gap-4 px-4 py-5">
|
|
794
794
|
<div v-if="review" class="space-y-2 text-xs text-slate-400">
|
|
795
795
|
<div class="flex items-center justify-between">
|
|
@@ -806,7 +806,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
806
806
|
</div>
|
|
807
807
|
<div v-if="review.model" class="flex items-center justify-between">
|
|
808
808
|
<span>{{ t('requirements.stats.model') }}</span>
|
|
809
|
-
<span class="truncate
|
|
809
|
+
<span class="truncate ps-2 text-slate-500">{{ review.model }}</span>
|
|
810
810
|
</div>
|
|
811
811
|
</div>
|
|
812
812
|
|
|
@@ -821,6 +821,7 @@ async function resolveExceeded(choice: 'extra-round' | 'proceed' | 'stop-reset')
|
|
|
821
821
|
size="sm"
|
|
822
822
|
block
|
|
823
823
|
icon="i-lucide-arrow-right"
|
|
824
|
+
:ui="{ leadingIcon: 'rtl:-scale-x-100', trailingIcon: 'rtl:-scale-x-100' }"
|
|
824
825
|
:loading="acting"
|
|
825
826
|
@click="proceed"
|
|
826
827
|
>
|
|
@@ -279,7 +279,7 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
279
279
|
<span class="mb-1 block text-[10px] uppercase tracking-wide text-slate-500">
|
|
280
280
|
{{ t('sandbox.builder.promptVersions') }}
|
|
281
281
|
</span>
|
|
282
|
-
<div class="max-h-28 space-y-1 overflow-auto
|
|
282
|
+
<div class="max-h-28 space-y-1 overflow-auto pe-1">
|
|
283
283
|
<label
|
|
284
284
|
v-for="p in kindPrompts"
|
|
285
285
|
:key="p.id"
|
|
@@ -311,7 +311,7 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
311
311
|
<span class="mb-1 block text-[10px] uppercase tracking-wide text-slate-500">
|
|
312
312
|
{{ t('sandbox.builder.models') }}
|
|
313
313
|
</span>
|
|
314
|
-
<div class="max-h-28 space-y-1 overflow-auto
|
|
314
|
+
<div class="max-h-28 space-y-1 overflow-auto pe-1">
|
|
315
315
|
<label
|
|
316
316
|
v-for="m in store.selectableModels"
|
|
317
317
|
:key="m.id"
|
|
@@ -335,7 +335,7 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
335
335
|
<span class="mb-1 block text-[10px] uppercase tracking-wide text-slate-500">
|
|
336
336
|
{{ t('sandbox.builder.fixtures') }}
|
|
337
337
|
</span>
|
|
338
|
-
<div class="max-h-28 space-y-1 overflow-auto
|
|
338
|
+
<div class="max-h-28 space-y-1 overflow-auto pe-1">
|
|
339
339
|
<label
|
|
340
340
|
v-for="f in kindFixtures"
|
|
341
341
|
:key="f.id"
|
|
@@ -401,13 +401,13 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
401
401
|
}}</UBadge>
|
|
402
402
|
</div>
|
|
403
403
|
<div class="overflow-auto">
|
|
404
|
-
<table class="w-full text-
|
|
404
|
+
<table class="w-full text-start text-xs">
|
|
405
405
|
<thead class="text-slate-500">
|
|
406
406
|
<tr>
|
|
407
|
-
<th class="py-1
|
|
408
|
-
<th class="py-1
|
|
409
|
-
<th class="py-1
|
|
410
|
-
<th class="py-1
|
|
407
|
+
<th class="py-1 pe-2 font-medium">{{ t('sandbox.results.col.prompt') }}</th>
|
|
408
|
+
<th class="py-1 pe-2 font-medium">{{ t('sandbox.results.col.model') }}</th>
|
|
409
|
+
<th class="py-1 pe-2 font-medium">{{ t('sandbox.results.col.fixture') }}</th>
|
|
410
|
+
<th class="py-1 pe-2 font-medium">{{ t('sandbox.results.col.score') }}</th>
|
|
411
411
|
<th class="py-1 font-medium">{{ t('sandbox.results.col.objective') }}</th>
|
|
412
412
|
</tr>
|
|
413
413
|
</thead>
|
|
@@ -418,12 +418,12 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
418
418
|
class="cursor-pointer border-t border-slate-800 hover:bg-slate-800/40"
|
|
419
419
|
@click="selectedRun = run"
|
|
420
420
|
>
|
|
421
|
-
<td class="py-1
|
|
422
|
-
<td class="py-1
|
|
421
|
+
<td class="py-1 pe-2 text-slate-300">{{ run.promptLabel }}</td>
|
|
422
|
+
<td class="py-1 pe-2 font-mono text-[11px] text-slate-400">
|
|
423
423
|
{{ run.model }}
|
|
424
424
|
</td>
|
|
425
|
-
<td class="py-1
|
|
426
|
-
<td class="py-1
|
|
425
|
+
<td class="py-1 pe-2 text-slate-400">{{ fixtureName }}</td>
|
|
426
|
+
<td class="py-1 pe-2">
|
|
427
427
|
<span
|
|
428
428
|
v-if="grade"
|
|
429
429
|
:class="scoreColor(grade.weightedTotal)"
|
|
@@ -470,8 +470,8 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
470
470
|
class="text-[11px] text-slate-400"
|
|
471
471
|
>
|
|
472
472
|
<span :class="scoreColor(d.score)" class="font-semibold">{{ d.score }}</span>
|
|
473
|
-
<span class="
|
|
474
|
-
<span v-if="d.rationale" class="
|
|
473
|
+
<span class="ms-1 text-slate-300">{{ d.key }}</span>
|
|
474
|
+
<span v-if="d.rationale" class="ms-1 text-slate-500">— {{ d.rationale }}</span>
|
|
475
475
|
</p>
|
|
476
476
|
</div>
|
|
477
477
|
</div>
|
|
@@ -484,7 +484,7 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
484
484
|
<button
|
|
485
485
|
v-for="x in store.experiments"
|
|
486
486
|
:key="x.id"
|
|
487
|
-
class="flex w-full items-center justify-between rounded-md border border-slate-800 bg-slate-900/40 px-2 py-1.5 text-
|
|
487
|
+
class="flex w-full items-center justify-between rounded-md border border-slate-800 bg-slate-900/40 px-2 py-1.5 text-start text-sm hover:bg-slate-800/50"
|
|
488
488
|
@click="store.openExperiment(x.id)"
|
|
489
489
|
>
|
|
490
490
|
<span class="truncate text-slate-300">{{ x.name }}</span>
|
|
@@ -499,7 +499,7 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
499
499
|
|
|
500
500
|
<!-- ============================== PROMPTS ============================== -->
|
|
501
501
|
<div v-else-if="tab === 'prompts'" class="grid gap-4 lg:grid-cols-2">
|
|
502
|
-
<div class="max-h-[28rem] space-y-1.5 overflow-auto
|
|
502
|
+
<div class="max-h-[28rem] space-y-1.5 overflow-auto pe-1">
|
|
503
503
|
<div
|
|
504
504
|
v-for="p in store.prompts"
|
|
505
505
|
:key="p.id"
|
|
@@ -581,7 +581,7 @@ async function archive(prompt: SandboxPromptVersion) {
|
|
|
581
581
|
</div>
|
|
582
582
|
|
|
583
583
|
<!-- ============================== FIXTURES ============================== -->
|
|
584
|
-
<div v-else class="max-h-[28rem] space-y-1.5 overflow-auto
|
|
584
|
+
<div v-else class="max-h-[28rem] space-y-1.5 overflow-auto pe-1">
|
|
585
585
|
<div
|
|
586
586
|
v-for="f in store.fixtures"
|
|
587
587
|
:key="f.id"
|
|
@@ -191,7 +191,7 @@ async function remove(p: LocalRunner) {
|
|
|
191
191
|
>
|
|
192
192
|
<div>
|
|
193
193
|
<span class="font-medium text-slate-200">{{ e.label }}</span>
|
|
194
|
-
<span class="
|
|
194
|
+
<span class="ms-2 text-xs text-slate-500">{{ LOCAL_RUNNER_LABELS[e.provider] }}</span>
|
|
195
195
|
<div class="text-[11px] text-slate-500">
|
|
196
196
|
{{ e.baseUrl }} ·
|
|
197
197
|
{{
|
|
@@ -267,10 +267,11 @@ function fail(title: string, e: unknown) {
|
|
|
267
267
|
<UButton
|
|
268
268
|
v-if="editor"
|
|
269
269
|
icon="i-lucide-arrow-left"
|
|
270
|
+
:ui="{ leadingIcon: 'rtl:-scale-x-100', trailingIcon: 'rtl:-scale-x-100' }"
|
|
270
271
|
color="neutral"
|
|
271
272
|
variant="ghost"
|
|
272
273
|
size="sm"
|
|
273
|
-
class="
|
|
274
|
+
class="ms-auto"
|
|
274
275
|
@click="editor = null"
|
|
275
276
|
>
|
|
276
277
|
{{ t('settings.modelConfiguration.back') }}
|
|
@@ -280,7 +281,7 @@ function fail(title: string, e: unknown) {
|
|
|
280
281
|
color="neutral"
|
|
281
282
|
variant="ghost"
|
|
282
283
|
size="sm"
|
|
283
|
-
:class="editor ? '' : '
|
|
284
|
+
:class="editor ? '' : 'ms-auto'"
|
|
284
285
|
:title="t('settings.modelConfiguration.closeEsc')"
|
|
285
286
|
@click="open = false"
|
|
286
287
|
/>
|
|
@@ -330,7 +331,7 @@ function fail(title: string, e: unknown) {
|
|
|
330
331
|
<UBadge v-if="p.isDefault" color="primary" variant="subtle" size="xs">
|
|
331
332
|
{{ t('settings.modelConfiguration.list.default') }}
|
|
332
333
|
</UBadge>
|
|
333
|
-
<div class="
|
|
334
|
+
<div class="ms-auto flex items-center gap-1">
|
|
334
335
|
<UButton
|
|
335
336
|
v-if="!p.isDefault"
|
|
336
337
|
size="xs"
|
|
@@ -235,7 +235,7 @@ function manageKeys() {
|
|
|
235
235
|
<h4 class="text-xs font-semibold uppercase tracking-wide text-slate-500">
|
|
236
236
|
{{ t('settings.openRouterCatalog.connectHeading') }}
|
|
237
237
|
</h4>
|
|
238
|
-
<ol class="list-decimal space-y-1
|
|
238
|
+
<ol class="list-decimal space-y-1 ps-5 text-sm text-slate-300">
|
|
239
239
|
<li>
|
|
240
240
|
<i18n-t keypath="settings.openRouterCatalog.step1" tag="span" scope="global">
|
|
241
241
|
<template #link>
|
|
@@ -343,7 +343,7 @@ function manageKeys() {
|
|
|
343
343
|
|
|
344
344
|
<p v-if="store.refreshError" class="text-xs text-rose-400">{{ store.refreshError }}</p>
|
|
345
345
|
|
|
346
|
-
<div v-if="visible.length" class="max-h-96 space-y-1 overflow-y-auto
|
|
346
|
+
<div v-if="visible.length" class="max-h-96 space-y-1 overflow-y-auto pe-1">
|
|
347
347
|
<label
|
|
348
348
|
v-for="m in visible"
|
|
349
349
|
:key="m.id"
|
|
@@ -357,7 +357,7 @@ function manageKeys() {
|
|
|
357
357
|
<span class="block truncate text-slate-200">{{ m.name }}</span>
|
|
358
358
|
<span class="block truncate font-mono text-[11px] text-slate-500">{{ m.id }}</span>
|
|
359
359
|
</span>
|
|
360
|
-
<span class="shrink-0 text-
|
|
360
|
+
<span class="shrink-0 text-end text-[11px] text-slate-500">
|
|
361
361
|
<span v-if="m.contextLength" class="block">{{
|
|
362
362
|
contextLabel(m.contextLength)
|
|
363
363
|
}}</span>
|
|
@@ -97,7 +97,7 @@ function remove(id: string) {
|
|
|
97
97
|
:title="f.summary"
|
|
98
98
|
@click="remove(f.id)"
|
|
99
99
|
>
|
|
100
|
-
{{ f.title }}<UIcon name="i-lucide-x" class="
|
|
100
|
+
{{ f.title }}<UIcon name="i-lucide-x" class="ms-0.5 h-3 w-3" />
|
|
101
101
|
</UBadge>
|
|
102
102
|
</div>
|
|
103
103
|
<p v-else class="text-[11px] text-slate-500">
|
|
@@ -137,7 +137,7 @@ function kindLabel(item: RequirementItem): string {
|
|
|
137
137
|
{{ spec?.service || block.title }}
|
|
138
138
|
</p>
|
|
139
139
|
</div>
|
|
140
|
-
<div class="
|
|
140
|
+
<div class="ms-auto flex items-center gap-1.5">
|
|
141
141
|
<!-- view toggle: Gherkin only when the spec (and its feature files) are on main -->
|
|
142
142
|
<div v-if="present" class="flex items-center rounded-lg border border-slate-700 p-0.5">
|
|
143
143
|
<UButton
|
|
@@ -200,7 +200,7 @@ function kindLabel(item: RequirementItem): string {
|
|
|
200
200
|
<!-- spec body: navigable tree + detail -->
|
|
201
201
|
<div v-else class="flex min-h-0 flex-1">
|
|
202
202
|
<!-- nav: modules → feature groups -->
|
|
203
|
-
<nav class="w-64 shrink-0 overflow-y-auto border-
|
|
203
|
+
<nav class="w-64 shrink-0 overflow-y-auto border-e border-slate-800 px-3 py-4">
|
|
204
204
|
<UButton
|
|
205
205
|
block
|
|
206
206
|
class="mb-2 justify-start"
|
|
@@ -222,7 +222,7 @@ function kindLabel(item: RequirementItem): string {
|
|
|
222
222
|
<li v-for="(group, gi) in mod.groups ?? []" :key="gi">
|
|
223
223
|
<button
|
|
224
224
|
type="button"
|
|
225
|
-
class="flex w-full items-center justify-between gap-2 rounded-md px-2 py-1.5 text-
|
|
225
|
+
class="flex w-full items-center justify-between gap-2 rounded-md px-2 py-1.5 text-start text-[13px] transition"
|
|
226
226
|
:class="
|
|
227
227
|
selected?.m === mi && selected?.g === gi
|
|
228
228
|
? 'bg-indigo-500/15 text-indigo-200'
|
|
@@ -203,12 +203,12 @@ onMounted(() => {
|
|
|
203
203
|
v-for="row in importedRows"
|
|
204
204
|
:key="`imp:${row.externalId}`"
|
|
205
205
|
type="button"
|
|
206
|
-
class="flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-
|
|
206
|
+
class="flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-start text-xs text-slate-300 hover:bg-slate-800/70"
|
|
207
207
|
@click="pickImported(row)"
|
|
208
208
|
>
|
|
209
209
|
<UIcon :name="icon" class="h-3.5 w-3.5 shrink-0 text-indigo-400" />
|
|
210
210
|
<span class="truncate">{{ row.externalId }} · {{ row.title }}</span>
|
|
211
|
-
<UBadge color="neutral" variant="soft" size="xs" class="
|
|
211
|
+
<UBadge color="neutral" variant="soft" size="xs" class="ms-auto shrink-0">{{
|
|
212
212
|
t('tasks.picker.imported')
|
|
213
213
|
}}</UBadge>
|
|
214
214
|
</button>
|
|
@@ -218,12 +218,12 @@ onMounted(() => {
|
|
|
218
218
|
v-for="r in searchRows"
|
|
219
219
|
:key="`hit:${r.externalId}`"
|
|
220
220
|
type="button"
|
|
221
|
-
class="flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-
|
|
221
|
+
class="flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-start text-xs text-slate-300 hover:bg-slate-800/70"
|
|
222
222
|
@click="pickSearch(r)"
|
|
223
223
|
>
|
|
224
224
|
<UIcon :name="icon" class="h-3.5 w-3.5 shrink-0 text-slate-400" />
|
|
225
225
|
<span class="truncate">{{ r.externalId }} · {{ r.title }}</span>
|
|
226
|
-
<UBadge v-if="r.status" color="neutral" variant="soft" size="xs" class="
|
|
226
|
+
<UBadge v-if="r.status" color="neutral" variant="soft" size="xs" class="ms-auto shrink-0">
|
|
227
227
|
{{ r.status }}
|
|
228
228
|
</UBadge>
|
|
229
229
|
</button>
|
|
@@ -232,7 +232,7 @@ onMounted(() => {
|
|
|
232
232
|
<button
|
|
233
233
|
v-if="refRow"
|
|
234
234
|
type="button"
|
|
235
|
-
class="flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-
|
|
235
|
+
class="flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-start text-xs text-slate-300 hover:bg-slate-800/70"
|
|
236
236
|
@click="pickRef(refRow)"
|
|
237
237
|
>
|
|
238
238
|
<UIcon name="i-lucide-link" class="h-3.5 w-3.5 shrink-0 text-slate-400" />
|
|
@@ -79,7 +79,7 @@ const attachMenu = computed<DropdownMenuItem[][]>(() => {
|
|
|
79
79
|
class="h-3.5 w-3.5 shrink-0 text-indigo-400"
|
|
80
80
|
/>
|
|
81
81
|
<span class="truncate">{{ task.externalId }} · {{ task.title }}</span>
|
|
82
|
-
<UBadge color="neutral" variant="soft" size="xs" class="
|
|
82
|
+
<UBadge color="neutral" variant="soft" size="xs" class="ms-auto shrink-0">
|
|
83
83
|
{{ task.status }}
|
|
84
84
|
</UBadge>
|
|
85
85
|
</a>
|