@cat-factory/app 0.309.0 → 0.310.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/app/components/assistant/AssistantModal.vue +5 -4
- package/app/components/auth/BackendMisconfiguredScreen.vue +4 -3
- package/app/components/auth/LoginScreen.vue +40 -26
- package/app/components/auth/ResetPasswordScreen.vue +9 -4
- package/app/components/auth/UserMenu.vue +4 -3
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +34 -23
- package/app/components/binaryOutput/StoredAssetView.vue +8 -6
- package/app/components/board/AddTaskModal.vue +16 -15
- package/app/components/board/AgentFailureCard.vue +12 -9
- package/app/components/board/AgentFailureHistory.vue +18 -9
- package/app/components/board/CreateInitiativeModal.vue +5 -4
- package/app/components/board/FailureDetail.vue +22 -12
- package/app/components/board/ReviewFrictionDialog.vue +4 -3
- package/app/components/board/nodes/BlockNode.vue +17 -15
- package/app/components/board/nodes/DecisionBadge.vue +4 -3
- package/app/components/board/nodes/FrameSwimlanes.vue +4 -3
- package/app/components/board/nodes/TaskCard.vue +12 -7
- package/app/components/board/nodes/TaskPipelineMini.vue +9 -7
- package/app/components/bootstrap/AdoptionReviewModal.vue +30 -21
- package/app/components/bootstrap/BootstrapModal.vue +3 -3
- package/app/components/brainstorm/BrainstormWindow.vue +5 -3
- package/app/components/bugFishing/BugFishingWindow.vue +49 -27
- package/app/components/clarity/ClarityReviewWindow.vue +5 -3
- package/app/components/common/CopyButton.vue +12 -11
- package/app/components/common/IconButton.vue +34 -9
- package/app/components/context/ContextAttachmentFields.vue +23 -12
- package/app/components/documents/ContextDocumentPicker.vue +12 -9
- package/app/components/documents/DocumentImportModal.vue +4 -3
- package/app/components/documents/DocumentOriginLink.vue +12 -9
- package/app/components/documents/DocumentSyncState.vue +3 -3
- package/app/components/documents/RepoContextDocPicker.vue +4 -3
- package/app/components/environments/EnvironmentStatusPanel.vue +4 -3
- package/app/components/followUp/FollowUpWindow.vue +9 -6
- package/app/components/forkDecision/ForkDecisionWindow.vue +71 -80
- package/app/components/foundational/FoundationalServiceCatalogList.vue +3 -2
- package/app/components/foundational/FoundationalServiceRegistry.vue +7 -6
- package/app/components/foundational/FoundationalServiceSources.vue +7 -6
- package/app/components/fragments/FragmentLibraryManager.vue +5 -4
- package/app/components/fragments/FragmentSelector.vue +12 -9
- package/app/components/gates/GateFailingCheckList.vue +4 -3
- package/app/components/gates/GateResultView.vue +17 -12
- package/app/components/github/AddServiceFromRepoModal.vue +11 -7
- package/app/components/github/GitHubOnboarding.vue +7 -2
- package/app/components/github/GitHubPanel.vue +9 -6
- package/app/components/github/RepoTreeBrowser.vue +15 -12
- package/app/components/humanTest/HumanTestWindow.vue +13 -9
- package/app/components/initiative/InitiativePlanReview.vue +28 -18
- package/app/components/initiative/InitiativeTrackerWindow.vue +171 -124
- package/app/components/judge/JudgeResultView.vue +5 -3
- package/app/components/kaizen/KaizenPanel.vue +67 -53
- package/app/components/layout/AccountTeamSettings.vue +9 -9
- package/app/components/layout/AppearanceSwitcher.vue +4 -3
- package/app/components/layout/BoardSwitcher.vue +10 -8
- package/app/components/layout/BoardToolbar.vue +5 -4
- package/app/components/layout/CommandBar.vue +4 -3
- package/app/components/layout/DefaultTestEnvBanner.vue +4 -3
- package/app/components/layout/IntegrationsHub.vue +8 -6
- package/app/components/layout/LanguageSwitcher.vue +4 -3
- package/app/components/layout/ModelProvidersHub.vue +4 -3
- package/app/components/layout/NotificationsInbox.vue +40 -30
- package/app/components/layout/PersonalSetupModal.vue +4 -3
- package/app/components/layout/RolePrompt.vue +4 -3
- package/app/components/layout/SideBar.vue +4 -3
- package/app/components/layout/TranslationWarningBanner.vue +4 -3
- package/app/components/layout/UiModeSwitcher.vue +8 -6
- package/app/components/layout/UiRoleSwitcher.vue +8 -6
- package/app/components/layout/WorkspaceMembersSettings.vue +2 -2
- package/app/components/media/ArtifactLightbox.vue +69 -39
- package/app/components/media/ImageCompare.vue +69 -74
- package/app/components/observability/OutcomeFilterChips.vue +5 -4
- package/app/components/observability/RunFailureSummary.vue +8 -6
- package/app/components/observability/StepModelActivity.vue +5 -3
- package/app/components/observability/ToolCallList.vue +4 -2
- package/app/components/outcome/OutcomeSummaryWindow.vue +5 -4
- package/app/components/palettes/AgentPalette.vue +18 -14
- package/app/components/panels/AgentStepDetail.vue +30 -19
- package/app/components/panels/ObservabilityPanel.vue +149 -114
- package/app/components/panels/OperatorDashboardPanel.vue +99 -91
- package/app/components/panels/ReportsPanel.vue +64 -61
- package/app/components/panels/ResultWindowShell.vue +148 -134
- package/app/components/panels/StepContainerStatus.vue +9 -9
- package/app/components/panels/StepDelegatedStatus.vue +11 -9
- package/app/components/panels/StepRestartControl.vue +3 -2
- package/app/components/panels/inspector/EpicChildren.vue +4 -3
- package/app/components/panels/inspector/FrontendConfig.vue +3 -2
- package/app/components/panels/inspector/InspectorSection.vue +22 -17
- package/app/components/panels/inspector/ServiceConnections.vue +3 -2
- package/app/components/panels/inspector/ServiceTestConfig.vue +5 -4
- package/app/components/panels/inspector/TaskExecution.vue +5 -4
- package/app/components/panels/inspector/TaskRunSettings.vue +10 -6
- package/app/components/pipeline/EstimateThresholdFields.vue +13 -10
- package/app/components/pipeline/GateConfigFields.vue +14 -18
- package/app/components/pipeline/PipelineBuilder.vue +90 -77
- package/app/components/pipeline/PipelinePicker.vue +8 -6
- package/app/components/pipeline/PipelineProgress.vue +26 -21
- package/app/components/prReview/PrReviewWindow.vue +46 -25
- package/app/components/providers/ApiKeysSection.vue +4 -3
- package/app/components/ralph/RalphLoopResultView.vue +4 -3
- package/app/components/requirements/RequirementsReviewWindow.vue +10 -6
- package/app/components/riskPolicy/RiskPolicyPicker.vue +8 -6
- package/app/components/sandbox/SandboxPanel.vue +73 -54
- package/app/components/settings/CloudflareHandlerSection.vue +33 -30
- package/app/components/settings/ConsensusGroupsSection.vue +40 -30
- package/app/components/settings/InfraHandlersConfigurator.vue +16 -13
- package/app/components/settings/InfrastructureBackendPicker.vue +17 -17
- package/app/components/settings/IssueTrackerPanel.vue +21 -6
- package/app/components/settings/LocalModelEndpointsPanel.vue +3 -2
- package/app/components/settings/ModelConfigurationPanel.vue +9 -8
- package/app/components/settings/OpenRouterCatalogPanel.vue +4 -3
- package/app/components/settings/ProviderPreferenceEditor.vue +5 -6
- package/app/components/settings/RiskPolicyEditorRow.vue +3 -2
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +10 -8
- package/app/components/skills/ReviewSkillQueue.vue +4 -3
- package/app/components/skills/SkillLibraryManager.vue +7 -6
- package/app/components/slack/SlackPanel.vue +9 -5
- package/app/components/spec/ServiceSpecWindow.vue +4 -3
- package/app/components/tasks/ContextIssuePicker.vue +12 -9
- package/app/components/tasks/TaskContextIssues.vue +4 -3
- package/app/components/testing/TestReportWindow.vue +14 -8
- package/app/components/theme/ThemeImportModal.vue +2 -2
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +62 -35
- package/i18n/locales/de.json +7 -3
- package/i18n/locales/en.json +7 -3
- package/i18n/locales/es.json +7 -3
- package/i18n/locales/fr.json +7 -3
- package/i18n/locales/he.json +7 -3
- package/i18n/locales/it.json +7 -3
- package/i18n/locales/ja.json +7 -3
- package/i18n/locales/pl.json +7 -3
- package/i18n/locales/tr.json +7 -3
- package/i18n/locales/uk.json +7 -3
- package/package.json +2 -2
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
// self-assessment (see the footer block below), so a window never renders it itself.
|
|
23
23
|
import { computed, ref, watch } from 'vue'
|
|
24
24
|
import { useModalBehavior } from '@modular-vue/core'
|
|
25
|
+
import IconButton from '~/components/common/IconButton.vue'
|
|
25
26
|
import StepRestartControl from '~/components/panels/StepRestartControl.vue'
|
|
26
27
|
import RunDetailLoadState from '~/components/panels/RunDetailLoadState.vue'
|
|
27
28
|
import StepEffortReport from '~/components/panels/StepEffortReport.vue'
|
|
@@ -300,14 +301,15 @@ const panelClass = computed(() => [
|
|
|
300
301
|
:step-index="stepRef.stepIndex"
|
|
301
302
|
@restarted="requestClose"
|
|
302
303
|
/>
|
|
303
|
-
<
|
|
304
|
-
|
|
304
|
+
<IconButton
|
|
305
|
+
icon="i-lucide-x"
|
|
306
|
+
color="neutral"
|
|
307
|
+
variant="ghost"
|
|
308
|
+
size="sm"
|
|
305
309
|
data-testid="result-window-close"
|
|
306
|
-
:
|
|
310
|
+
:label="t('common.close')"
|
|
307
311
|
@click="requestClose"
|
|
308
|
-
|
|
309
|
-
<UIcon name="i-lucide-x" class="h-4 w-4" />
|
|
310
|
-
</button>
|
|
312
|
+
/>
|
|
311
313
|
</header>
|
|
312
314
|
<!-- Whether the whole-run fetch behind this window's prose has landed. -->
|
|
313
315
|
<RunDetailLoadState :instance-id="activeInstanceId" />
|
|
@@ -322,34 +324,37 @@ const panelClass = computed(() => [
|
|
|
322
324
|
class="shrink-0 border-t border-default bg-default/60"
|
|
323
325
|
data-testid="result-window-effort"
|
|
324
326
|
>
|
|
325
|
-
<
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
>
|
|
332
|
-
<UIcon name="i-lucide-gauge" class="h-3.5 w-3.5 shrink-0 text-muted" />
|
|
333
|
-
<SectionLabel as="span">
|
|
334
|
-
{{ t('panels.stepDetail.effort.heading') }}
|
|
335
|
-
</SectionLabel>
|
|
336
|
-
<span
|
|
337
|
-
class="shrink-0 rounded-sm px-1.5 py-0.5 text-2xs font-medium tabular-nums"
|
|
338
|
-
:class="chipClass"
|
|
327
|
+
<UCollapsible v-model:open="effortOpen">
|
|
328
|
+
<UButton
|
|
329
|
+
color="neutral"
|
|
330
|
+
variant="ghost"
|
|
331
|
+
class="flex w-full items-center gap-2 px-5 py-2 text-start hover:bg-elevated/40"
|
|
332
|
+
data-testid="result-window-effort-toggle"
|
|
339
333
|
>
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
334
|
+
<UIcon name="i-lucide-gauge" class="h-3.5 w-3.5 shrink-0 text-muted" />
|
|
335
|
+
<SectionLabel as="span">
|
|
336
|
+
{{ t('panels.stepDetail.effort.heading') }}
|
|
337
|
+
</SectionLabel>
|
|
338
|
+
<span
|
|
339
|
+
class="shrink-0 rounded-sm px-1.5 py-0.5 text-2xs font-medium tabular-nums"
|
|
340
|
+
:class="chipClass"
|
|
341
|
+
>
|
|
342
|
+
{{ t('panels.stepDetail.effort.outOfTen', { value: effortReport.difficulty }) }}
|
|
343
|
+
</span>
|
|
344
|
+
<span v-if="hint" class="min-w-0 flex-1 truncate text-xs text-muted">
|
|
345
|
+
{{ hint }}
|
|
346
|
+
</span>
|
|
347
|
+
<UIcon
|
|
348
|
+
:name="effortOpen ? 'i-lucide-chevron-down' : 'i-lucide-chevron-up'"
|
|
349
|
+
class="ms-auto h-3.5 w-3.5 shrink-0 text-dimmed"
|
|
350
|
+
/>
|
|
351
|
+
</UButton>
|
|
352
|
+
<template #content>
|
|
353
|
+
<div class="max-h-56 overflow-y-auto px-5 pb-3">
|
|
354
|
+
<StepEffortReport :report="effortReport" variant="flat" />
|
|
355
|
+
</div>
|
|
356
|
+
</template>
|
|
357
|
+
</UCollapsible>
|
|
353
358
|
</section>
|
|
354
359
|
|
|
355
360
|
<!-- Shared trailing section: the pre-PR validation report (the service's check commands
|
|
@@ -360,51 +365,54 @@ const panelClass = computed(() => [
|
|
|
360
365
|
class="shrink-0 border-t border-default bg-default/60"
|
|
361
366
|
data-testid="result-window-validation"
|
|
362
367
|
>
|
|
363
|
-
<
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
>
|
|
370
|
-
<UIcon
|
|
371
|
-
:name="validationReport.passed ? 'i-lucide-shield-check' : 'i-lucide-shield-alert'"
|
|
372
|
-
class="h-3.5 w-3.5 shrink-0"
|
|
373
|
-
:class="validationReport.passed ? 'text-app-success-400' : 'text-app-error-400'"
|
|
374
|
-
/>
|
|
375
|
-
<SectionLabel as="span">
|
|
376
|
-
{{ t('panels.stepDetail.validation.heading') }}
|
|
377
|
-
</SectionLabel>
|
|
378
|
-
<span
|
|
379
|
-
class="shrink-0 rounded-sm px-1.5 py-0.5 text-2xs font-medium tabular-nums"
|
|
380
|
-
:class="
|
|
381
|
-
validationReport.passed
|
|
382
|
-
? 'bg-app-success-500/15 text-app-success-300'
|
|
383
|
-
: 'bg-app-error-500/15 text-app-error-300'
|
|
384
|
-
"
|
|
368
|
+
<UCollapsible v-model:open="validationOpen">
|
|
369
|
+
<UButton
|
|
370
|
+
color="neutral"
|
|
371
|
+
variant="ghost"
|
|
372
|
+
class="flex w-full items-center gap-2 px-5 py-2 text-start hover:bg-elevated/40"
|
|
373
|
+
data-testid="result-window-validation-toggle"
|
|
385
374
|
>
|
|
386
|
-
|
|
387
|
-
validationReport.passed
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
375
|
+
<UIcon
|
|
376
|
+
:name="validationReport.passed ? 'i-lucide-shield-check' : 'i-lucide-shield-alert'"
|
|
377
|
+
class="h-3.5 w-3.5 shrink-0"
|
|
378
|
+
:class="validationReport.passed ? 'text-app-success-400' : 'text-app-error-400'"
|
|
379
|
+
/>
|
|
380
|
+
<SectionLabel as="span">
|
|
381
|
+
{{ t('panels.stepDetail.validation.heading') }}
|
|
382
|
+
</SectionLabel>
|
|
383
|
+
<span
|
|
384
|
+
class="shrink-0 rounded-sm px-1.5 py-0.5 text-2xs font-medium tabular-nums"
|
|
385
|
+
:class="
|
|
386
|
+
validationReport.passed
|
|
387
|
+
? 'bg-app-success-500/15 text-app-success-300'
|
|
388
|
+
: 'bg-app-error-500/15 text-app-error-300'
|
|
389
|
+
"
|
|
390
|
+
>
|
|
391
|
+
{{
|
|
392
|
+
validationReport.passed
|
|
393
|
+
? t('panels.stepDetail.validation.passed')
|
|
394
|
+
: t('panels.stepDetail.validation.failed')
|
|
395
|
+
}}
|
|
396
|
+
</span>
|
|
397
|
+
<span class="min-w-0 flex-1 truncate text-xs text-muted">
|
|
398
|
+
{{
|
|
399
|
+
t('panels.stepDetail.validation.attempts', {
|
|
400
|
+
attempts: validationReport.attempts,
|
|
401
|
+
maxAttempts: validationReport.maxAttempts,
|
|
402
|
+
})
|
|
403
|
+
}}
|
|
404
|
+
</span>
|
|
405
|
+
<UIcon
|
|
406
|
+
:name="validationOpen ? 'i-lucide-chevron-down' : 'i-lucide-chevron-up'"
|
|
407
|
+
class="ms-auto h-3.5 w-3.5 shrink-0 text-dimmed"
|
|
408
|
+
/>
|
|
409
|
+
</UButton>
|
|
410
|
+
<template #content>
|
|
411
|
+
<div class="max-h-72 overflow-y-auto px-5 pb-3">
|
|
412
|
+
<StepValidationReport :report="validationReport" />
|
|
413
|
+
</div>
|
|
414
|
+
</template>
|
|
415
|
+
</UCollapsible>
|
|
408
416
|
</section>
|
|
409
417
|
|
|
410
418
|
<!-- Shared trailing section: the bugfix reproduction proof (the declared check run against
|
|
@@ -416,42 +424,45 @@ const panelClass = computed(() => [
|
|
|
416
424
|
class="shrink-0 border-t border-default bg-default/60"
|
|
417
425
|
data-testid="result-window-reproduction"
|
|
418
426
|
>
|
|
419
|
-
<
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
>
|
|
426
|
-
<UIcon
|
|
427
|
-
:name="reproductionKeys!.icon"
|
|
428
|
-
class="h-3.5 w-3.5 shrink-0"
|
|
429
|
-
:class="reproductionKeys!.proven ? 'text-app-success-400' : 'text-app-warning-400'"
|
|
430
|
-
/>
|
|
431
|
-
<SectionLabel as="span">
|
|
432
|
-
{{ t('panels.stepDetail.reproduction.heading') }}
|
|
433
|
-
</SectionLabel>
|
|
434
|
-
<span
|
|
435
|
-
class="shrink-0 rounded-sm px-1.5 py-0.5 text-2xs font-medium"
|
|
436
|
-
:class="
|
|
437
|
-
reproductionKeys!.proven
|
|
438
|
-
? 'bg-app-success-500/15 text-app-success-300'
|
|
439
|
-
: 'bg-app-warning-500/15 text-app-warning-300'
|
|
440
|
-
"
|
|
427
|
+
<UCollapsible v-model:open="reproductionOpen">
|
|
428
|
+
<UButton
|
|
429
|
+
color="neutral"
|
|
430
|
+
variant="ghost"
|
|
431
|
+
class="flex w-full items-center gap-2 px-5 py-2 text-start hover:bg-elevated/40"
|
|
432
|
+
data-testid="result-window-reproduction-toggle"
|
|
441
433
|
>
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
434
|
+
<UIcon
|
|
435
|
+
:name="reproductionKeys!.icon"
|
|
436
|
+
class="h-3.5 w-3.5 shrink-0"
|
|
437
|
+
:class="reproductionKeys!.proven ? 'text-app-success-400' : 'text-app-warning-400'"
|
|
438
|
+
/>
|
|
439
|
+
<SectionLabel as="span">
|
|
440
|
+
{{ t('panels.stepDetail.reproduction.heading') }}
|
|
441
|
+
</SectionLabel>
|
|
442
|
+
<span
|
|
443
|
+
class="shrink-0 rounded-sm px-1.5 py-0.5 text-2xs font-medium"
|
|
444
|
+
:class="
|
|
445
|
+
reproductionKeys!.proven
|
|
446
|
+
? 'bg-app-success-500/15 text-app-success-300'
|
|
447
|
+
: 'bg-app-warning-500/15 text-app-warning-300'
|
|
448
|
+
"
|
|
449
|
+
>
|
|
450
|
+
{{ t(reproductionKeys!.chip) }}
|
|
451
|
+
</span>
|
|
452
|
+
<span class="min-w-0 flex-1 truncate text-xs text-muted">
|
|
453
|
+
{{ t(reproductionKeys!.verdict) }}
|
|
454
|
+
</span>
|
|
455
|
+
<UIcon
|
|
456
|
+
:name="reproductionOpen ? 'i-lucide-chevron-down' : 'i-lucide-chevron-up'"
|
|
457
|
+
class="ms-auto h-3.5 w-3.5 shrink-0 text-dimmed"
|
|
458
|
+
/>
|
|
459
|
+
</UButton>
|
|
460
|
+
<template #content>
|
|
461
|
+
<div class="max-h-72 overflow-y-auto px-5 pb-3">
|
|
462
|
+
<StepReproductionReport :report="reproductionReport" />
|
|
463
|
+
</div>
|
|
464
|
+
</template>
|
|
465
|
+
</UCollapsible>
|
|
455
466
|
</section>
|
|
456
467
|
|
|
457
468
|
<!-- Shared trailing section: what this step's agent declared it stored through a
|
|
@@ -464,28 +475,31 @@ const panelClass = computed(() => [
|
|
|
464
475
|
class="shrink-0 border-t border-default bg-default/60"
|
|
465
476
|
data-testid="result-window-binary-outputs"
|
|
466
477
|
>
|
|
467
|
-
<
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
478
|
+
<UCollapsible v-model:open="binaryOutputsOpen">
|
|
479
|
+
<UButton
|
|
480
|
+
color="neutral"
|
|
481
|
+
variant="ghost"
|
|
482
|
+
class="flex w-full items-center gap-2 px-5 py-2 text-start hover:bg-elevated/40"
|
|
483
|
+
data-testid="result-window-binary-outputs-toggle"
|
|
484
|
+
>
|
|
485
|
+
<UIcon name="i-lucide-image" class="h-3.5 w-3.5 shrink-0 text-muted" />
|
|
486
|
+
<SectionLabel as="span">
|
|
487
|
+
{{ t('binaryOutput.heading') }}
|
|
488
|
+
</SectionLabel>
|
|
489
|
+
<span class="min-w-0 flex-1 truncate text-xs text-muted">
|
|
490
|
+
{{ binaryOutputSummary }}
|
|
491
|
+
</span>
|
|
492
|
+
<UIcon
|
|
493
|
+
:name="binaryOutputsOpen ? 'i-lucide-chevron-down' : 'i-lucide-chevron-up'"
|
|
494
|
+
class="ms-auto h-3.5 w-3.5 shrink-0 text-dimmed"
|
|
495
|
+
/>
|
|
496
|
+
</UButton>
|
|
497
|
+
<template #content>
|
|
498
|
+
<div v-if="activeStep" class="max-h-72 overflow-y-auto px-5 pb-3">
|
|
499
|
+
<BinaryOutputReport :step="activeStep" />
|
|
500
|
+
</div>
|
|
501
|
+
</template>
|
|
502
|
+
</UCollapsible>
|
|
489
503
|
</section>
|
|
490
504
|
</div>
|
|
491
505
|
</div>
|
|
@@ -3,6 +3,7 @@ import { computed } from 'vue'
|
|
|
3
3
|
import type { PipelineStep, RunContainerStatus } from '~/types/execution'
|
|
4
4
|
import { containerPhaseLabel } from '~/utils/pipelineRender'
|
|
5
5
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
6
|
+
import IconButton from '~/components/common/IconButton.vue'
|
|
6
7
|
|
|
7
8
|
// The per-run container lifecycle for a container-backed step: its status (spinning up /
|
|
8
9
|
// running / errored / reclaimed), the live phase (preparing the checkout vs the agent
|
|
@@ -118,14 +119,13 @@ const { copy: copyText } = useCopyToClipboard()
|
|
|
118
119
|
<dd class="truncate font-mono text-2xs text-toned" :title="step.container.id">
|
|
119
120
|
{{ step.container.id }}
|
|
120
121
|
</dd>
|
|
121
|
-
<
|
|
122
|
+
<IconButton
|
|
122
123
|
icon="i-lucide-copy"
|
|
123
124
|
color="neutral"
|
|
124
125
|
variant="ghost"
|
|
125
126
|
size="xs"
|
|
126
127
|
class="ms-auto shrink-0"
|
|
127
|
-
:
|
|
128
|
-
:aria-label="t('panels.stepMeta.container.copyId')"
|
|
128
|
+
:label="t('panels.stepMeta.container.copyId')"
|
|
129
129
|
@click="copyText(step.container.id)"
|
|
130
130
|
/>
|
|
131
131
|
</div>
|
|
@@ -134,23 +134,23 @@ const { copy: copyText } = useCopyToClipboard()
|
|
|
134
134
|
{{ t('panels.stepMeta.container.url') }}
|
|
135
135
|
</SectionLabel>
|
|
136
136
|
<dd class="truncate font-mono text-2xs text-toned">
|
|
137
|
-
<
|
|
138
|
-
|
|
137
|
+
<ULink
|
|
138
|
+
raw
|
|
139
|
+
:to="step.container.url"
|
|
139
140
|
target="_blank"
|
|
140
141
|
rel="noopener noreferrer"
|
|
141
142
|
class="hover:underline"
|
|
142
143
|
>
|
|
143
144
|
{{ step.container.url }}
|
|
144
|
-
</
|
|
145
|
+
</ULink>
|
|
145
146
|
</dd>
|
|
146
|
-
<
|
|
147
|
+
<IconButton
|
|
147
148
|
icon="i-lucide-copy"
|
|
148
149
|
color="neutral"
|
|
149
150
|
variant="ghost"
|
|
150
151
|
size="xs"
|
|
151
152
|
class="ms-auto shrink-0"
|
|
152
|
-
:
|
|
153
|
-
:aria-label="t('panels.stepMeta.container.copyUrl')"
|
|
153
|
+
:label="t('panels.stepMeta.container.copyUrl')"
|
|
154
154
|
@click="copyText(step.container.url)"
|
|
155
155
|
/>
|
|
156
156
|
</div>
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from './StepDelegatedStatus.logic'
|
|
8
8
|
import type { PipelineStep } from '~/types/execution'
|
|
9
9
|
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
10
|
+
import IconButton from '~/components/common/IconButton.vue'
|
|
10
11
|
|
|
11
12
|
// The EXTERNAL work a delegated step dispatched: which registered executor is running it, what it
|
|
12
13
|
// is doing, and the link to that system's own logs, which is the affordance everything else here
|
|
@@ -106,25 +107,25 @@ const { copy: copyText } = useCopyToClipboard()
|
|
|
106
107
|
it is: refusing to follow it is right, and hiding it would report a run that named
|
|
107
108
|
no link at all. -->
|
|
108
109
|
<dd class="truncate font-mono text-2xs text-toned">
|
|
109
|
-
<
|
|
110
|
+
<ULink
|
|
111
|
+
raw
|
|
110
112
|
v-if="runHref"
|
|
111
|
-
:
|
|
113
|
+
:to="runHref"
|
|
112
114
|
target="_blank"
|
|
113
115
|
rel="noopener noreferrer"
|
|
114
116
|
class="hover:underline"
|
|
115
117
|
>
|
|
116
118
|
{{ record.url }}
|
|
117
|
-
</
|
|
119
|
+
</ULink>
|
|
118
120
|
<span v-else>{{ record.url }}</span>
|
|
119
121
|
</dd>
|
|
120
|
-
<
|
|
122
|
+
<IconButton
|
|
121
123
|
icon="i-lucide-copy"
|
|
122
124
|
color="neutral"
|
|
123
125
|
variant="ghost"
|
|
124
126
|
size="xs"
|
|
125
127
|
class="ms-auto shrink-0"
|
|
126
|
-
:
|
|
127
|
-
:aria-label="t('panels.stepMeta.delegated.copyUrl')"
|
|
128
|
+
:label="t('panels.stepMeta.delegated.copyUrl')"
|
|
128
129
|
@click="copyText(record.url)"
|
|
129
130
|
/>
|
|
130
131
|
</div>
|
|
@@ -166,15 +167,16 @@ const { copy: copyText } = useCopyToClipboard()
|
|
|
166
167
|
<span class="truncate">{{
|
|
167
168
|
attempt.outcome || t('panels.stepMeta.delegated.noOutcome')
|
|
168
169
|
}}</span>
|
|
169
|
-
<
|
|
170
|
+
<ULink
|
|
171
|
+
raw
|
|
170
172
|
v-if="externalRunHref(attempt.url)"
|
|
171
|
-
:
|
|
173
|
+
:to="externalRunHref(attempt.url)!"
|
|
172
174
|
target="_blank"
|
|
173
175
|
rel="noopener noreferrer"
|
|
174
176
|
class="ms-auto shrink-0 font-mono hover:underline"
|
|
175
177
|
>
|
|
176
178
|
{{ t('panels.stepMeta.delegated.openRun') }}
|
|
177
|
-
</
|
|
179
|
+
</ULink>
|
|
178
180
|
</li>
|
|
179
181
|
</ul>
|
|
180
182
|
</div>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref, computed } from 'vue'
|
|
3
|
+
import IconButton from '~/components/common/IconButton.vue'
|
|
3
4
|
|
|
4
5
|
// Shared "Restart pipeline from this step" control.
|
|
5
6
|
//
|
|
@@ -57,13 +58,13 @@ async function restart() {
|
|
|
57
58
|
|
|
58
59
|
<template>
|
|
59
60
|
<template v-if="canRestart">
|
|
60
|
-
<
|
|
61
|
+
<IconButton
|
|
61
62
|
v-if="!armed"
|
|
62
63
|
icon="i-lucide-rotate-ccw"
|
|
63
64
|
color="neutral"
|
|
64
65
|
variant="ghost"
|
|
65
66
|
size="sm"
|
|
66
|
-
:
|
|
67
|
+
:label="t('panels.stepRestart.restartFromStep')"
|
|
67
68
|
@click="
|
|
68
69
|
() => {
|
|
69
70
|
armed = true
|
|
@@ -72,10 +72,11 @@ const groups = computed(() => {
|
|
|
72
72
|
<SectionLabel v-if="mod.module">
|
|
73
73
|
{{ mod.module.title }}
|
|
74
74
|
</SectionLabel>
|
|
75
|
-
<
|
|
75
|
+
<UButton
|
|
76
|
+
color="neutral"
|
|
77
|
+
variant="ghost"
|
|
76
78
|
v-for="task in mod.tasks"
|
|
77
79
|
:key="task.id"
|
|
78
|
-
type="button"
|
|
79
80
|
class="flex w-full items-center gap-1.5 rounded-sm px-1 py-0.5 text-start text-xs text-default hover:bg-elevated"
|
|
80
81
|
@click="ui.select(task.id)"
|
|
81
82
|
>
|
|
@@ -87,7 +88,7 @@ const groups = computed(() => {
|
|
|
87
88
|
<span class="ms-auto shrink-0 text-3xs text-dimmed">
|
|
88
89
|
{{ STATUS_META[task.status].label }}
|
|
89
90
|
</span>
|
|
90
|
-
</
|
|
91
|
+
</UButton>
|
|
91
92
|
</div>
|
|
92
93
|
</div>
|
|
93
94
|
</div>
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
} from '~/types/domain'
|
|
13
13
|
import FrontendBindingsResolved from '~/components/panels/inspector/FrontendBindingsResolved.vue'
|
|
14
14
|
import InspectorSection from '~/components/panels/inspector/InspectorSection.vue'
|
|
15
|
+
import IconButton from '~/components/common/IconButton.vue'
|
|
15
16
|
import { apiErrorEnvelope } from '~/composables/api/errors'
|
|
16
17
|
|
|
17
18
|
// Frontend-frame (`type: 'frontend'`) configuration: how to build, serve, and mock this
|
|
@@ -556,12 +557,12 @@ onUnmounted(() => preview.stopPolling(props.block.id))
|
|
|
556
557
|
class="flex-1"
|
|
557
558
|
@update:model-value="(v: string) => setBindingSource(i, v)"
|
|
558
559
|
/>
|
|
559
|
-
<
|
|
560
|
+
<IconButton
|
|
560
561
|
size="xs"
|
|
561
562
|
variant="ghost"
|
|
562
563
|
color="neutral"
|
|
563
564
|
icon="i-lucide-x"
|
|
564
|
-
:
|
|
565
|
+
:label="t('inspector.frontendConfig.bindings.remove')"
|
|
565
566
|
@click="removeBinding(i)"
|
|
566
567
|
/>
|
|
567
568
|
</div>
|
|
@@ -28,27 +28,32 @@ if (props.defaultOpen) open.value = true
|
|
|
28
28
|
<template>
|
|
29
29
|
<section class="border-t border-default pt-2" data-testid="inspector-section">
|
|
30
30
|
<div class="flex items-center gap-1.5">
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class="
|
|
31
|
+
<UButton
|
|
32
|
+
color="neutral"
|
|
33
|
+
variant="link"
|
|
34
|
+
class="group min-w-0 flex-1 p-0"
|
|
35
35
|
:aria-expanded="open"
|
|
36
36
|
data-testid="inspector-section-toggle"
|
|
37
37
|
@click="open = !open"
|
|
38
38
|
>
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
class="
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
v-if="
|
|
48
|
-
|
|
49
|
-
class="
|
|
50
|
-
|
|
51
|
-
|
|
39
|
+
<SectionLabel
|
|
40
|
+
as="span"
|
|
41
|
+
class="flex min-w-0 flex-1 items-center gap-1.5 group-hover:text-default"
|
|
42
|
+
>
|
|
43
|
+
<UIcon
|
|
44
|
+
:name="open ? 'i-lucide-chevron-down' : 'i-lucide-chevron-right'"
|
|
45
|
+
class="h-3.5 w-3.5 shrink-0 text-dimmed"
|
|
46
|
+
/>
|
|
47
|
+
<UIcon v-if="icon" :name="icon" class="h-3.5 w-3.5 shrink-0" />
|
|
48
|
+
<span class="truncate">{{ title }}</span>
|
|
49
|
+
<span v-if="count" class="font-normal normal-case text-dimmed">({{ count }})</span>
|
|
50
|
+
<UIcon
|
|
51
|
+
v-if="warning"
|
|
52
|
+
name="i-lucide-triangle-alert"
|
|
53
|
+
class="h-3.5 w-3.5 shrink-0 text-app-warning-400"
|
|
54
|
+
/>
|
|
55
|
+
</SectionLabel>
|
|
56
|
+
</UButton>
|
|
52
57
|
<!-- An action ("+", attach, menu) mutates the body list, so expand (never collapse)
|
|
53
58
|
on interaction — otherwise the new row lands inside the collapsed body. -->
|
|
54
59
|
<div v-if="$slots.actions" class="contents" @click="open = true">
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { computed } from 'vue'
|
|
3
3
|
import type { Block, ServiceConnection } from '~/types/domain'
|
|
4
4
|
import InspectorSection from '~/components/panels/inspector/InspectorSection.vue'
|
|
5
|
+
import IconButton from '~/components/common/IconButton.vue'
|
|
5
6
|
|
|
6
7
|
// Service-frame (`type: 'service'`) connections: the other services this one USES
|
|
7
8
|
// (consumer→provider edges, stored on this frame — the consumer end). Each row picks a
|
|
@@ -124,12 +125,12 @@ const usedBy = computed(() =>
|
|
|
124
125
|
(e: KeyboardEvent) => setDescription(i, (e.target as HTMLInputElement).value)
|
|
125
126
|
"
|
|
126
127
|
/>
|
|
127
|
-
<
|
|
128
|
+
<IconButton
|
|
128
129
|
size="xs"
|
|
129
130
|
variant="ghost"
|
|
130
131
|
color="neutral"
|
|
131
132
|
icon="i-lucide-x"
|
|
132
|
-
:
|
|
133
|
+
:label="t('inspector.serviceConnections.remove')"
|
|
133
134
|
data-testid="service-connection-remove"
|
|
134
135
|
@click="removeConnection(i)"
|
|
135
136
|
/>
|
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
import RepoTreeBrowser from '~/components/github/RepoTreeBrowser.vue'
|
|
20
20
|
import InspectorSection from '~/components/panels/inspector/InspectorSection.vue'
|
|
21
21
|
import ServiceSelfTests from '~/components/panels/inspector/ServiceSelfTests.vue'
|
|
22
|
+
import IconButton from '~/components/common/IconButton.vue'
|
|
22
23
|
import { apiErrorEnvelope } from '~/composables/api/errors'
|
|
23
24
|
|
|
24
25
|
// Service-level (frame) configuration: the service-owned PROVISIONING — the provision
|
|
@@ -634,13 +635,13 @@ function setSize(value: InstanceSize) {
|
|
|
634
635
|
(e: KeyboardEvent) => setComposePath((e.target as HTMLInputElement).value)
|
|
635
636
|
"
|
|
636
637
|
/>
|
|
637
|
-
<
|
|
638
|
+
<IconButton
|
|
638
639
|
v-if="repoContext"
|
|
639
640
|
size="xs"
|
|
640
641
|
variant="soft"
|
|
641
642
|
color="neutral"
|
|
642
643
|
icon="i-lucide-folder-search"
|
|
643
|
-
:
|
|
644
|
+
:label="t('inspector.testConfig.browseRepo')"
|
|
644
645
|
@click="openBrowse('compose')"
|
|
645
646
|
/>
|
|
646
647
|
</div>
|
|
@@ -715,13 +716,13 @@ function setSize(value: InstanceSize) {
|
|
|
715
716
|
@blur="(e: FocusEvent) => setKubePath((e.target as HTMLInputElement).value)"
|
|
716
717
|
@keydown.enter="(e: KeyboardEvent) => setKubePath((e.target as HTMLInputElement).value)"
|
|
717
718
|
/>
|
|
718
|
-
<
|
|
719
|
+
<IconButton
|
|
719
720
|
v-if="repoContext && kubeSourceType === 'colocated'"
|
|
720
721
|
size="xs"
|
|
721
722
|
variant="soft"
|
|
722
723
|
color="neutral"
|
|
723
724
|
icon="i-lucide-folder-search"
|
|
724
|
-
:
|
|
725
|
+
:label="t('inspector.testConfig.browseRepo')"
|
|
725
726
|
@click="openBrowse('k8s')"
|
|
726
727
|
/>
|
|
727
728
|
</div>
|