@cat-factory/app 0.308.0 → 0.310.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/README.md +32 -2
- package/app/assets/css/main.css +22 -0
- package/app/assets/css/prose.css +4 -4
- package/app/assets/css/type.css +24 -0
- package/app/components/assistant/AssistantModal.vue +8 -6
- 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 +5 -4
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +48 -37
- package/app/components/binaryOutput/BinaryOutputReport.vue +10 -14
- package/app/components/binaryOutput/StoredAssetView.vue +13 -11
- package/app/components/board/AddTaskModal.vue +30 -27
- package/app/components/board/AgentFailureCard.vue +21 -18
- package/app/components/board/AgentFailureHistory.vue +18 -9
- package/app/components/board/CreateInitiativeModal.vue +7 -6
- package/app/components/board/FailureDetail.vue +22 -12
- package/app/components/board/FailureHistoryList.vue +5 -5
- package/app/components/board/RecurringPipelineModal.vue +12 -11
- package/app/components/board/ReviewFrictionDialog.vue +8 -6
- package/app/components/board/StepExecutionHistory.vue +8 -8
- package/app/components/board/nodes/AgentChip.vue +1 -1
- package/app/components/board/nodes/BlockNode.vue +25 -24
- package/app/components/board/nodes/DecisionBadge.vue +4 -3
- package/app/components/board/nodes/EpicNode.vue +4 -4
- package/app/components/board/nodes/FrameSwimlanes.vue +8 -10
- package/app/components/board/nodes/InitiativeCard.vue +4 -4
- package/app/components/board/nodes/LaneGroup.vue +3 -5
- package/app/components/board/nodes/TaskCard.vue +20 -15
- package/app/components/board/nodes/TaskLane.vue +3 -3
- package/app/components/board/nodes/TaskPipelineMini.vue +21 -18
- package/app/components/bootstrap/AdoptionReviewModal.vue +36 -26
- package/app/components/bootstrap/BootstrapModal.vue +14 -13
- package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
- package/app/components/brainstorm/BrainstormWindow.vue +13 -10
- package/app/components/bugFishing/BugFishingWindow.vue +81 -58
- package/app/components/clarity/ClarityReviewWindow.vue +13 -10
- package/app/components/common/AsyncViewError.vue +1 -1
- package/app/components/common/ClarificationItem.vue +6 -6
- package/app/components/common/CopyButton.vue +12 -11
- package/app/components/common/DescriptorFields.vue +1 -1
- package/app/components/common/EmptyState.vue +1 -1
- package/app/components/common/IconButton.vue +34 -9
- package/app/components/common/InterviewGateNotice.vue +4 -4
- package/app/components/common/MarkdownProse.vue +8 -2
- package/app/components/common/SectionLabel.vue +38 -0
- package/app/components/consensus/ConsensusSessionWindow.vue +10 -9
- package/app/components/context/ContextAttachmentFields.vue +32 -20
- package/app/components/docs/DocInterviewWindow.vue +10 -9
- package/app/components/documents/ContextDocumentPicker.vue +22 -21
- package/app/components/documents/DocumentImportModal.vue +7 -5
- package/app/components/documents/DocumentOriginLink.vue +12 -9
- package/app/components/documents/DocumentSourceConnectModal.vue +2 -2
- package/app/components/documents/DocumentSyncState.vue +4 -4
- package/app/components/documents/DocumentTemplatesModal.vue +5 -4
- package/app/components/documents/RepoContextDocPicker.vue +7 -9
- package/app/components/documents/StartFromDesignModal.vue +4 -4
- package/app/components/documents/TaskContextDocs.vue +1 -1
- package/app/components/environments/EnvSetupStepper.vue +3 -3
- package/app/components/environments/EnvironmentStatusPanel.vue +15 -13
- package/app/components/environments/steps/EnvPreflightStep.vue +8 -8
- package/app/components/environments/steps/EnvReviewStep.vue +23 -22
- package/app/components/environments/steps/EnvSaveStep.vue +5 -5
- package/app/components/focus/BlockFocusView.vue +11 -10
- package/app/components/followUp/FollowUpWindow.vue +18 -15
- package/app/components/forkDecision/ForkDecisionWindow.vue +85 -97
- package/app/components/foundational/FoundationalContractSummary.vue +2 -2
- package/app/components/foundational/FoundationalServiceCatalogList.vue +6 -5
- package/app/components/foundational/FoundationalServiceRegistry.vue +10 -9
- package/app/components/foundational/FoundationalServiceSources.vue +7 -6
- package/app/components/foundational/FoundationalSuppressions.vue +2 -2
- package/app/components/fragments/FragmentLibraryManager.vue +8 -7
- package/app/components/fragments/FragmentSelector.vue +22 -20
- package/app/components/gates/GateFailingCheckList.vue +7 -6
- package/app/components/gates/GateResultView.vue +55 -49
- package/app/components/github/AddServiceFromRepoModal.vue +16 -11
- package/app/components/github/BranchProtectionPreflight.vue +5 -5
- package/app/components/github/GitHubConnect.vue +5 -3
- package/app/components/github/GitHubOnboarding.vue +7 -2
- package/app/components/github/GitHubPanel.vue +23 -19
- package/app/components/github/RepoTreeBrowser.vue +16 -13
- package/app/components/humanTest/HumanTestWindow.vue +29 -24
- package/app/components/initiative/InitiativePlanNotice.vue +3 -3
- package/app/components/initiative/InitiativePlanReview.vue +46 -38
- package/app/components/initiative/InitiativePlanningWindow.vue +5 -5
- package/app/components/initiative/InitiativeTrackerWindow.vue +213 -165
- package/app/components/judge/JudgeResultView.vue +28 -27
- package/app/components/kaizen/KaizenPanel.vue +70 -56
- package/app/components/kaizen/KaizenStepStatus.vue +7 -6
- package/app/components/layout/AccountAuditLog.vue +1 -1
- package/app/components/layout/AccountDeploymentSettings.vue +10 -10
- package/app/components/layout/AccountFailureKindRules.vue +13 -13
- package/app/components/layout/AccountFoundationalSettings.vue +1 -1
- package/app/components/layout/AccountFragmentSettings.vue +1 -1
- package/app/components/layout/AccountModelPolicySettings.vue +7 -7
- package/app/components/layout/AccountPlatformAlertSettings.vue +8 -8
- package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
- package/app/components/layout/AccountRunCredentialSettings.vue +3 -3
- package/app/components/layout/AccountSkillSettings.vue +1 -1
- package/app/components/layout/AccountTeamSettings.vue +13 -9
- package/app/components/layout/AiProvidersBanner.vue +1 -1
- package/app/components/layout/AppearanceSwitcher.vue +5 -4
- package/app/components/layout/BoardSwitcher.vue +13 -10
- package/app/components/layout/BoardToolbar.vue +10 -5
- package/app/components/layout/CommandBar.vue +8 -5
- package/app/components/layout/DefaultTestEnvBanner.vue +6 -5
- package/app/components/layout/IntegrationsHub.vue +12 -9
- package/app/components/layout/LanguageSwitcher.vue +5 -4
- package/app/components/layout/ModelProvidersHub.vue +10 -7
- package/app/components/layout/NotificationsInbox.vue +47 -36
- package/app/components/layout/PersonalSetupModal.vue +9 -6
- package/app/components/layout/RolePrompt.vue +5 -4
- package/app/components/layout/SideBar.vue +7 -8
- package/app/components/layout/SpendWarningBanner.vue +3 -3
- package/app/components/layout/TranslationWarningBanner.vue +5 -4
- package/app/components/layout/UiModeSwitcher.vue +15 -12
- package/app/components/layout/UiRoleSwitcher.vue +10 -8
- package/app/components/layout/WorkspaceMembersSettings.vue +2 -2
- package/app/components/media/ArtifactLightbox.vue +74 -44
- package/app/components/media/ImageCompare.vue +80 -85
- package/app/components/merge/MergeEffortChips.vue +4 -6
- package/app/components/notifications/NotificationSettingsPanel.vue +6 -5
- package/app/components/observability/OutcomeFilterChips.vue +6 -5
- package/app/components/observability/RunFailureSummary.vue +22 -23
- package/app/components/observability/StepMetricsBar.vue +9 -8
- package/app/components/observability/StepModelActivity.vue +8 -5
- package/app/components/observability/ToolCallList.vue +19 -20
- package/app/components/outcome/OutcomeSummaryWindow.vue +48 -46
- package/app/components/palettes/AgentPalette.vue +21 -15
- package/app/components/palettes/AgentTierSelect.vue +1 -1
- package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
- package/app/components/panels/AgentStepDetail.vue +57 -49
- package/app/components/panels/AttemptEntryHeader.vue +2 -2
- package/app/components/panels/DecisionModal.vue +1 -1
- package/app/components/panels/GenericStructuredResultView.vue +6 -5
- package/app/components/panels/InspectorPanel.vue +15 -13
- package/app/components/panels/MergerResultView.vue +10 -9
- package/app/components/panels/ObservabilityPanel.vue +211 -186
- package/app/components/panels/OperatorDashboardPanel.vue +124 -115
- package/app/components/panels/ReportsPanel.vue +87 -83
- package/app/components/panels/ReportsSpendBreakdown.vue +2 -2
- package/app/components/panels/ResultWindowShell.vue +152 -137
- package/app/components/panels/RunDetailLoadState.vue +1 -1
- package/app/components/panels/StepContainerStatus.vue +17 -16
- package/app/components/panels/StepDelegatedStatus.vue +24 -21
- package/app/components/panels/StepEffortReport.vue +12 -17
- package/app/components/panels/StepFragmentAdherence.vue +9 -10
- package/app/components/panels/StepMetadataCard.vue +41 -43
- package/app/components/panels/StepReproductionReport.vue +18 -20
- package/app/components/panels/StepRestartControl.vue +3 -2
- package/app/components/panels/StepRunMeta.vue +27 -26
- package/app/components/panels/StepTestReport.vue +16 -15
- package/app/components/panels/StepToolServers.vue +7 -8
- package/app/components/panels/StepValidationReport.vue +5 -5
- package/app/components/panels/inspector/ContainerSummary.vue +4 -4
- package/app/components/panels/inspector/DocReferenceRepos.vue +5 -4
- package/app/components/panels/inspector/EnvProbeReport.vue +16 -13
- package/app/components/panels/inspector/EpicChildren.vue +12 -10
- package/app/components/panels/inspector/FrontendBindingsResolved.vue +5 -4
- package/app/components/panels/inspector/FrontendConfig.vue +29 -36
- package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
- package/app/components/panels/inspector/InspectorSection.vue +25 -17
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +9 -8
- package/app/components/panels/inspector/ServiceConnections.vue +5 -4
- package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
- package/app/components/panels/inspector/ServiceSelfTests.vue +9 -13
- package/app/components/panels/inspector/ServiceTestConfig.vue +46 -49
- package/app/components/panels/inspector/ServiceTestSecrets.vue +3 -3
- package/app/components/panels/inspector/ServiceTestingContext.vue +2 -2
- package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAgentConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAprioriBranches.vue +6 -5
- package/app/components/panels/inspector/TaskDependencies.vue +1 -1
- package/app/components/panels/inspector/TaskEstimateBadge.vue +3 -7
- package/app/components/panels/inspector/TaskExecution.vue +18 -16
- package/app/components/panels/inspector/TaskRunSettings.vue +45 -44
- package/app/components/panels/inspector/TaskStructure.vue +5 -4
- package/app/components/pipeline/AgentPromptEditor.vue +15 -14
- package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -52
- package/app/components/pipeline/EstimateThresholdFields.vue +14 -11
- package/app/components/pipeline/GateConfigFields.vue +19 -23
- package/app/components/pipeline/IterationCapPrompt.vue +1 -1
- package/app/components/pipeline/PipelineBuilder.vue +113 -99
- package/app/components/pipeline/PipelineHealthModal.vue +7 -7
- package/app/components/pipeline/PipelinePicker.vue +11 -9
- package/app/components/pipeline/PipelinePreview.vue +6 -7
- package/app/components/pipeline/PipelineProgress.vue +49 -45
- package/app/components/prReview/PrReviewWindow.vue +87 -65
- package/app/components/providers/AiPresetMismatchDialog.vue +4 -3
- package/app/components/providers/AiProviderOnboardingModal.vue +2 -2
- package/app/components/providers/ApiKeysSection.vue +11 -9
- package/app/components/providers/PersonalSubscriptionSection.vue +4 -3
- package/app/components/providers/VendorCredentialsModal.vue +5 -4
- package/app/components/provisioning/ProvisioningLogsDrawer.vue +10 -9
- package/app/components/ralph/RalphLoopResultView.vue +29 -29
- package/app/components/requirements/RequirementsReviewWindow.vue +22 -17
- package/app/components/riskPolicy/RiskPolicyPicker.vue +13 -11
- package/app/components/riskPolicy/RiskPolicyPreview.vue +16 -15
- package/app/components/sandbox/SandboxPanel.vue +93 -73
- package/app/components/settings/ApiTokensPanel.vue +1 -1
- package/app/components/settings/BudgetSettings.vue +18 -17
- package/app/components/settings/CapabilityCredentialsPanel.vue +5 -5
- package/app/components/settings/CloudflareHandlerSection.vue +44 -41
- package/app/components/settings/ComposeEnvironmentSetupSection.vue +14 -12
- package/app/components/settings/ConnectionTestVerdict.vue +1 -1
- package/app/components/settings/ConsensusGroupsSection.vue +58 -47
- package/app/components/settings/CustomManifestTypeEditor.vue +8 -7
- package/app/components/settings/DefaultProvisionTypeSection.vue +5 -5
- package/app/components/settings/InfraHandlersConfigurator.vue +26 -24
- package/app/components/settings/InfrastructureBackendPicker.vue +18 -18
- package/app/components/settings/IssueTrackerPanel.vue +30 -21
- package/app/components/settings/KubernetesEngineForm.vue +9 -8
- package/app/components/settings/KubernetesEnvironmentForm.vue +4 -3
- package/app/components/settings/LocalContainerPoolSettings.vue +2 -2
- package/app/components/settings/LocalModelEndpointsPanel.vue +13 -11
- package/app/components/settings/MergeClassRulesEditor.vue +6 -5
- package/app/components/settings/MergeRolePolicyEditor.vue +13 -12
- package/app/components/settings/ModelConfigurationPanel.vue +17 -19
- package/app/components/settings/ModelPresetHealthModal.vue +3 -3
- package/app/components/settings/ObservabilityConnectionPanel.vue +1 -1
- package/app/components/settings/OpenRouterCatalogPanel.vue +10 -8
- package/app/components/settings/PackageRegistriesPanel.vue +4 -4
- package/app/components/settings/ProviderConnectionTab.vue +5 -4
- package/app/components/settings/ProviderManifestEditor.vue +9 -8
- package/app/components/settings/ProviderPreferenceEditor.vue +13 -13
- package/app/components/settings/RiskPolicyCreateForm.vue +40 -26
- package/app/components/settings/RiskPolicyEditorRow.vue +21 -19
- package/app/components/settings/RiskPolicyHealthModal.vue +3 -3
- package/app/components/settings/RiskPolicyPanel.vue +11 -13
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +15 -12
- package/app/components/settings/SharedStacksPanel.vue +5 -5
- package/app/components/settings/TaskSourceCard.vue +2 -2
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +4 -4
- package/app/components/settings/ToolServerChecklist.vue +22 -22
- package/app/components/settings/UsageSettings.vue +13 -13
- package/app/components/settings/UserSecretsSection.vue +4 -3
- package/app/components/settings/WorkspaceMetadataSettings.vue +6 -5
- package/app/components/settings/WorkspaceSettingsPanel.vue +72 -58
- package/app/components/skills/ReviewSkillQueue.vue +12 -10
- package/app/components/skills/SkillLibraryManager.vue +9 -8
- package/app/components/slack/SlackPanel.vue +17 -12
- package/app/components/spec/ServiceSpecWindow.vue +19 -19
- package/app/components/tasks/BugHuntModal.vue +1 -1
- package/app/components/tasks/ContextIssuePicker.vue +16 -15
- package/app/components/tasks/TaskContextIssues.vue +5 -4
- package/app/components/tasks/TaskImportModal.vue +3 -2
- package/app/components/tasks/TaskSourceConnectModal.vue +5 -5
- package/app/components/testing/TestReportWindow.vue +67 -60
- package/app/components/theme/ThemeImportModal.vue +2 -2
- package/app/components/tutorial/TutorialNudge.vue +3 -2
- package/app/components/tutorial/TutorialOverlay.vue +3 -2
- package/app/components/vcs/GitLabConnect.vue +1 -1
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +79 -54
- package/app/utils/theme/builtins.ts +7 -1
- 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 +1 -1
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
// FrontendConfig opening its Build group after a detect run) can bind `v-model:open`;
|
|
11
11
|
// without a binding the model acts as local state and `defaultOpen` picks the initial
|
|
12
12
|
// value (controlled callers should drive their own ref instead of passing it).
|
|
13
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
14
|
+
|
|
13
15
|
const props = defineProps<{
|
|
14
16
|
title: string
|
|
15
17
|
icon?: string
|
|
@@ -26,26 +28,32 @@ if (props.defaultOpen) open.value = true
|
|
|
26
28
|
<template>
|
|
27
29
|
<section class="border-t border-default pt-2" data-testid="inspector-section">
|
|
28
30
|
<div class="flex items-center gap-1.5">
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
<UButton
|
|
32
|
+
color="neutral"
|
|
33
|
+
variant="link"
|
|
34
|
+
class="group min-w-0 flex-1 p-0"
|
|
32
35
|
:aria-expanded="open"
|
|
33
36
|
data-testid="inspector-section-toggle"
|
|
34
37
|
@click="open = !open"
|
|
35
38
|
>
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
class="
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
v-if="
|
|
45
|
-
|
|
46
|
-
class="
|
|
47
|
-
|
|
48
|
-
|
|
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>
|
|
49
57
|
<!-- An action ("+", attach, menu) mutates the body list, so expand (never collapse)
|
|
50
58
|
on interaction — otherwise the new row lands inside the collapsed body. -->
|
|
51
59
|
<div v-if="$slots.actions" class="contents" @click="open = true">
|
|
@@ -53,7 +61,7 @@ if (props.defaultOpen) open.value = true
|
|
|
53
61
|
</div>
|
|
54
62
|
</div>
|
|
55
63
|
<div v-if="open" class="mt-2 space-y-3">
|
|
56
|
-
<p v-if="hint" class="text-
|
|
64
|
+
<p v-if="hint" class="text-2xs leading-snug text-dimmed">{{ hint }}</p>
|
|
57
65
|
<slot />
|
|
58
66
|
</div>
|
|
59
67
|
</section>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// (lazily loaded; retained ~1 week on the backend).
|
|
5
5
|
import type { Block } from '~/types/domain'
|
|
6
6
|
import type { Recurrence } from '~/types/recurring'
|
|
7
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
7
8
|
|
|
8
9
|
const props = defineProps<{ block: Block }>()
|
|
9
10
|
const recurring = useRecurringPipelinesStore()
|
|
@@ -126,7 +127,7 @@ function fmtTime(ms: number) {
|
|
|
126
127
|
<div v-if="schedule" class="space-y-2 rounded-lg border border-primary/50 bg-primary/10 p-3">
|
|
127
128
|
<div class="flex items-center justify-between">
|
|
128
129
|
<span
|
|
129
|
-
class="flex items-center gap-1.5 text-
|
|
130
|
+
class="flex items-center gap-1.5 text-2xs font-semibold uppercase tracking-wide text-primary"
|
|
130
131
|
>
|
|
131
132
|
<UIcon name="i-lucide-repeat" class="h-3.5 w-3.5" />
|
|
132
133
|
{{ t('inspector.recurring.title') }}
|
|
@@ -146,13 +147,13 @@ function fmtTime(ms: number) {
|
|
|
146
147
|
</UBadge>
|
|
147
148
|
</div>
|
|
148
149
|
|
|
149
|
-
<p class="text-
|
|
150
|
+
<p class="text-2xs text-muted">
|
|
150
151
|
<span class="text-toned">{{ pipelineName }}</span>
|
|
151
152
|
</p>
|
|
152
153
|
|
|
153
154
|
<!-- On-demand: no cadence, no pause/resume — it fires only when a person triggers it. -->
|
|
154
155
|
<template v-if="schedule.onDemand">
|
|
155
|
-
<p class="text-
|
|
156
|
+
<p class="text-2xs text-dimmed">{{ t('inspector.recurring.onDemandHint') }}</p>
|
|
156
157
|
<div class="flex flex-wrap gap-1.5 pt-1">
|
|
157
158
|
<UButton size="xs" variant="soft" icon="i-lucide-play" :loading="busy" @click="runNow">
|
|
158
159
|
{{ t('inspector.recurring.runNow') }}
|
|
@@ -161,8 +162,8 @@ function fmtTime(ms: number) {
|
|
|
161
162
|
</template>
|
|
162
163
|
|
|
163
164
|
<template v-else-if="!editing">
|
|
164
|
-
<p class="text-
|
|
165
|
-
<p class="text-
|
|
165
|
+
<p class="text-2xs text-muted">{{ describeCadence(schedule.recurrence) }}</p>
|
|
166
|
+
<p class="text-2xs text-dimmed">
|
|
166
167
|
{{ t('inspector.recurring.nextRun', { time: fmtTime(schedule.nextRunAt) }) }}
|
|
167
168
|
</p>
|
|
168
169
|
<div class="flex flex-wrap gap-1.5 pt-1">
|
|
@@ -213,10 +214,10 @@ function fmtTime(ms: number) {
|
|
|
213
214
|
|
|
214
215
|
<!-- run history -->
|
|
215
216
|
<div v-if="runs.length" class="space-y-1 border-t border-default pt-2">
|
|
216
|
-
<
|
|
217
|
+
<SectionLabel as="span">
|
|
217
218
|
{{ t('inspector.recurring.recentRuns') }}
|
|
218
|
-
</
|
|
219
|
-
<div v-for="run in runs" :key="run.id" class="flex items-center gap-2 text-
|
|
219
|
+
</SectionLabel>
|
|
220
|
+
<div v-for="run in runs" :key="run.id" class="flex items-center gap-2 text-2xs">
|
|
220
221
|
<span :class="RUN_COLOR[run.status] ?? 'text-muted'" class="w-14 shrink-0">
|
|
221
222
|
{{ runStatusLabel(run.status) }}
|
|
222
223
|
</span>
|
|
@@ -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,23 +125,23 @@ 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
|
/>
|
|
136
137
|
</div>
|
|
137
138
|
</div>
|
|
138
|
-
<div v-else class="text-
|
|
139
|
+
<div v-else class="text-2xs text-dimmed">
|
|
139
140
|
{{ t('inspector.serviceConnections.empty') }}
|
|
140
141
|
</div>
|
|
141
142
|
|
|
142
143
|
<div v-if="usedBy.length" class="space-y-1" data-testid="service-connections-used-by">
|
|
143
|
-
<span class="text-
|
|
144
|
+
<span class="text-2xs text-muted">{{ t('inspector.serviceConnections.usedBy') }}</span>
|
|
144
145
|
<div class="flex flex-wrap gap-1">
|
|
145
146
|
<UBadge v-for="f in usedBy" :key="f.id" size="sm" variant="soft" color="neutral">
|
|
146
147
|
{{ f.title || f.id }}
|
|
@@ -114,7 +114,7 @@ async function clear() {
|
|
|
114
114
|
<!-- Disabled affordance until an observability integration is connected. -->
|
|
115
115
|
<div
|
|
116
116
|
v-if="!connected"
|
|
117
|
-
class="flex items-center justify-between gap-2 rounded-md border border-default bg-default/60 px-2 py-1.5 text-
|
|
117
|
+
class="flex items-center justify-between gap-2 rounded-md border border-default bg-default/60 px-2 py-1.5 text-2xs text-muted"
|
|
118
118
|
>
|
|
119
119
|
<span>{{ t('inspector.releaseHealth.connectPrompt') }}</span>
|
|
120
120
|
<UButton
|
|
@@ -130,7 +130,7 @@ async function clear() {
|
|
|
130
130
|
</div>
|
|
131
131
|
|
|
132
132
|
<div v-else class="space-y-2">
|
|
133
|
-
<p class="text-
|
|
133
|
+
<p class="text-2xs text-dimmed">
|
|
134
134
|
{{ t('inspector.releaseHealth.hint') }}
|
|
135
135
|
</p>
|
|
136
136
|
<div class="grid grid-cols-2 gap-2">
|
|
@@ -188,17 +188,17 @@ async function stop(mode: EnvironmentTestMode) {
|
|
|
188
188
|
<div class="mt-3 space-y-3 border-t border-default pt-3" data-testid="env-test-section">
|
|
189
189
|
<!-- The precondition both self-tests share, stated once at the top: with no provision type
|
|
190
190
|
there is no environment to stand up and therefore nothing for an agent to drive either. -->
|
|
191
|
-
<p v-if="!canTest" class="text-
|
|
191
|
+
<p v-if="!canTest" class="text-2xs text-dimmed">
|
|
192
192
|
{{ t('inspector.testConfig.envTest.infraless') }}
|
|
193
193
|
</p>
|
|
194
194
|
|
|
195
195
|
<!-- 1. The provisioning self-test: the whole lifecycle against a throwaway branch. -->
|
|
196
196
|
<div class="flex items-center justify-between gap-2">
|
|
197
197
|
<div class="min-w-0">
|
|
198
|
-
<p class="text-
|
|
198
|
+
<p class="text-2xs font-medium text-toned">
|
|
199
199
|
{{ t('inspector.testConfig.envTest.title') }}
|
|
200
200
|
</p>
|
|
201
|
-
<p class="text-
|
|
201
|
+
<p class="text-2xs text-muted">{{ t('inspector.testConfig.envTest.hint') }}</p>
|
|
202
202
|
</div>
|
|
203
203
|
<UButton
|
|
204
204
|
v-if="!isRunning('provision')"
|
|
@@ -228,7 +228,7 @@ async function stop(mode: EnvironmentTestMode) {
|
|
|
228
228
|
|
|
229
229
|
<p
|
|
230
230
|
v-if="provisionRun"
|
|
231
|
-
class="text-
|
|
231
|
+
class="text-2xs"
|
|
232
232
|
:class="{
|
|
233
233
|
'text-app-info-300/80': provisionRun.status === 'running',
|
|
234
234
|
'text-app-success-300/80': provisionRun.status === 'succeeded',
|
|
@@ -253,11 +253,7 @@ async function stop(mode: EnvironmentTestMode) {
|
|
|
253
253
|
</template>
|
|
254
254
|
</p>
|
|
255
255
|
|
|
256
|
-
<div
|
|
257
|
-
v-if="errors.provision"
|
|
258
|
-
class="text-[11px] text-app-error-400"
|
|
259
|
-
data-testid="env-test-error"
|
|
260
|
-
>
|
|
256
|
+
<div v-if="errors.provision" class="text-2xs text-app-error-400" data-testid="env-test-error">
|
|
261
257
|
<p>{{ errors.provision.text }}</p>
|
|
262
258
|
<!-- Only the not-provisionable handler case is one-click fixable: jump to Infrastructure →
|
|
263
259
|
Test environments, where the workspace's per-type environment handler is registered. -->
|
|
@@ -279,10 +275,10 @@ async function stop(mode: EnvironmentTestMode) {
|
|
|
279
275
|
and could not do with the environment it was handed. -->
|
|
280
276
|
<div class="flex items-center justify-between gap-2 border-t border-default pt-3">
|
|
281
277
|
<div class="min-w-0">
|
|
282
|
-
<p class="text-
|
|
278
|
+
<p class="text-2xs font-medium text-toned">
|
|
283
279
|
{{ t('inspector.testConfig.envProbe.title') }}
|
|
284
280
|
</p>
|
|
285
|
-
<p class="text-
|
|
281
|
+
<p class="text-2xs text-muted">
|
|
286
282
|
{{ t('inspector.testConfig.envProbe.hint') }}
|
|
287
283
|
{{
|
|
288
284
|
probeSurface === 'ui'
|
|
@@ -319,7 +315,7 @@ async function stop(mode: EnvironmentTestMode) {
|
|
|
319
315
|
|
|
320
316
|
<p
|
|
321
317
|
v-if="probeRun"
|
|
322
|
-
class="text-
|
|
318
|
+
class="text-2xs"
|
|
323
319
|
:class="{
|
|
324
320
|
'text-app-info-300/80': probeRun.status === 'running',
|
|
325
321
|
'text-app-success-300/80': probeRun.status === 'succeeded',
|
|
@@ -355,7 +351,7 @@ async function stop(mode: EnvironmentTestMode) {
|
|
|
355
351
|
|
|
356
352
|
<div
|
|
357
353
|
v-if="errors['agent-probe']"
|
|
358
|
-
class="text-
|
|
354
|
+
class="text-2xs text-app-error-400"
|
|
359
355
|
data-testid="env-probe-error"
|
|
360
356
|
>
|
|
361
357
|
<p>{{ errors['agent-probe']!.text }}</p>
|
|
@@ -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
|
|
@@ -429,7 +430,7 @@ function setSize(value: InstanceSize) {
|
|
|
429
430
|
:default-open="props.defaultOpen"
|
|
430
431
|
>
|
|
431
432
|
<div class="space-y-1">
|
|
432
|
-
<span class="text-
|
|
433
|
+
<span class="text-2xs text-muted">{{ t('inspector.testConfig.provisionType') }}</span>
|
|
433
434
|
<div class="flex flex-wrap gap-1">
|
|
434
435
|
<UButton
|
|
435
436
|
v-for="p in PROVISION_TYPES"
|
|
@@ -442,7 +443,7 @@ function setSize(value: InstanceSize) {
|
|
|
442
443
|
{{ p.label }}
|
|
443
444
|
</UButton>
|
|
444
445
|
</div>
|
|
445
|
-
<p class="text-
|
|
446
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
446
447
|
{{ t('inspector.testConfig.provisionTypeHint') }}
|
|
447
448
|
</p>
|
|
448
449
|
</div>
|
|
@@ -452,14 +453,14 @@ function setSize(value: InstanceSize) {
|
|
|
452
453
|
provisions the compose stack, rather than editing the raw path inline. -->
|
|
453
454
|
<div
|
|
454
455
|
v-if="provisionType === 'docker-compose'"
|
|
455
|
-
class="flex items-center justify-between gap-2 rounded border border-primary/40 bg-primary/10 p-2"
|
|
456
|
+
class="flex items-center justify-between gap-2 rounded-sm border border-primary/40 bg-primary/10 p-2"
|
|
456
457
|
data-testid="env-setup-nudge"
|
|
457
458
|
>
|
|
458
459
|
<div class="min-w-0">
|
|
459
|
-
<p class="text-
|
|
460
|
+
<p class="text-2xs font-medium text-primary/90">
|
|
460
461
|
{{ t('inspector.testConfig.envWizard.title') }}
|
|
461
462
|
</p>
|
|
462
|
-
<p class="text-
|
|
463
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
463
464
|
{{ t('inspector.testConfig.envWizard.hint') }}
|
|
464
465
|
</p>
|
|
465
466
|
</div>
|
|
@@ -477,9 +478,9 @@ function setSize(value: InstanceSize) {
|
|
|
477
478
|
|
|
478
479
|
<!-- Auto-detect a recommended provisioning config from the repo (slice 11). Non-binding:
|
|
479
480
|
it prefills the form below + the kube edit refs; the user confirms/edits everything. -->
|
|
480
|
-
<div v-if="repoContext" class="space-y-2 rounded border border-default bg-default/40 p-2">
|
|
481
|
+
<div v-if="repoContext" class="space-y-2 rounded-sm border border-default bg-default/40 p-2">
|
|
481
482
|
<div class="flex items-center justify-between gap-2">
|
|
482
|
-
<span class="text-
|
|
483
|
+
<span class="text-2xs text-muted">{{ t('inspector.testConfig.detect.title') }}</span>
|
|
483
484
|
<UButton
|
|
484
485
|
size="xs"
|
|
485
486
|
variant="soft"
|
|
@@ -491,23 +492,23 @@ function setSize(value: InstanceSize) {
|
|
|
491
492
|
{{ t('inspector.testConfig.detect.button') }}
|
|
492
493
|
</UButton>
|
|
493
494
|
</div>
|
|
494
|
-
<p class="text-
|
|
495
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
495
496
|
{{ t('inspector.testConfig.detect.hint') }}
|
|
496
497
|
</p>
|
|
497
498
|
|
|
498
|
-
<p v-if="detectError" class="text-
|
|
499
|
+
<p v-if="detectError" class="text-2xs text-app-error-300/80">
|
|
499
500
|
{{ detectError }}
|
|
500
501
|
</p>
|
|
501
502
|
|
|
502
503
|
<template v-if="detectResult && !detecting">
|
|
503
504
|
<p
|
|
504
505
|
v-if="!detectResult.detected && detectResult.provisioning.type !== 'custom'"
|
|
505
|
-
class="text-
|
|
506
|
+
class="text-2xs text-app-warning-300/80"
|
|
506
507
|
>
|
|
507
508
|
{{ t('inspector.testConfig.detect.none') }}
|
|
508
509
|
</p>
|
|
509
510
|
<template v-else>
|
|
510
|
-
<p class="text-
|
|
511
|
+
<p class="text-2xs text-app-success-300/80">
|
|
511
512
|
{{
|
|
512
513
|
t('inspector.testConfig.detect.applied', {
|
|
513
514
|
type: provisionTypeLabel(detectResult.provisioning.type),
|
|
@@ -516,7 +517,7 @@ function setSize(value: InstanceSize) {
|
|
|
516
517
|
</p>
|
|
517
518
|
|
|
518
519
|
<div v-if="detectResult.serviceDirCandidates?.length" class="space-y-1">
|
|
519
|
-
<span class="text-
|
|
520
|
+
<span class="text-2xs text-muted">{{
|
|
520
521
|
t('inspector.testConfig.detect.serviceDirTitle')
|
|
521
522
|
}}</span>
|
|
522
523
|
<div class="flex flex-wrap gap-1">
|
|
@@ -534,7 +535,7 @@ function setSize(value: InstanceSize) {
|
|
|
534
535
|
</div>
|
|
535
536
|
|
|
536
537
|
<div v-if="detectResult.manifestRootCandidates?.length" class="space-y-1">
|
|
537
|
-
<span class="text-
|
|
538
|
+
<span class="text-2xs text-muted">{{
|
|
538
539
|
t('inspector.testConfig.detect.manifestRootTitle')
|
|
539
540
|
}}</span>
|
|
540
541
|
<div class="flex flex-wrap gap-1">
|
|
@@ -552,7 +553,7 @@ function setSize(value: InstanceSize) {
|
|
|
552
553
|
</div>
|
|
553
554
|
|
|
554
555
|
<div v-if="detectResult.overlayCandidates?.length" class="space-y-1">
|
|
555
|
-
<span class="text-
|
|
556
|
+
<span class="text-2xs text-muted">{{
|
|
556
557
|
t('inspector.testConfig.detect.overlayTitle')
|
|
557
558
|
}}</span>
|
|
558
559
|
<div class="flex flex-wrap gap-1">
|
|
@@ -570,7 +571,7 @@ function setSize(value: InstanceSize) {
|
|
|
570
571
|
</div>
|
|
571
572
|
|
|
572
573
|
<div v-if="detectResult.composeServiceCandidates?.length" class="space-y-1">
|
|
573
|
-
<span class="text-
|
|
574
|
+
<span class="text-2xs text-muted">{{
|
|
574
575
|
t('inspector.testConfig.detect.composeServiceTitle')
|
|
575
576
|
}}</span>
|
|
576
577
|
<div class="flex flex-wrap gap-1">
|
|
@@ -587,12 +588,12 @@ function setSize(value: InstanceSize) {
|
|
|
587
588
|
</div>
|
|
588
589
|
</div>
|
|
589
590
|
|
|
590
|
-
<p v-if="detectResult.urlSource" class="text-
|
|
591
|
+
<p v-if="detectResult.urlSource" class="text-2xs text-dimmed">
|
|
591
592
|
{{
|
|
592
593
|
t('inspector.testConfig.detect.urlSource', { source: detectResult.urlSource.source })
|
|
593
594
|
}}
|
|
594
595
|
</p>
|
|
595
|
-
<p v-if="detectResult.namespace" class="text-
|
|
596
|
+
<p v-if="detectResult.namespace" class="text-2xs text-dimmed">
|
|
596
597
|
{{ t('inspector.testConfig.detect.namespace', { namespace: detectResult.namespace }) }}
|
|
597
598
|
</p>
|
|
598
599
|
|
|
@@ -600,7 +601,7 @@ function setSize(value: InstanceSize) {
|
|
|
600
601
|
<li
|
|
601
602
|
v-for="(n, i) in detectResult.notes"
|
|
602
603
|
:key="i"
|
|
603
|
-
class="flex items-start gap-1.5 text-
|
|
604
|
+
class="flex items-start gap-1.5 text-2xs leading-snug text-dimmed"
|
|
604
605
|
>
|
|
605
606
|
<span
|
|
606
607
|
:class="
|
|
@@ -622,7 +623,7 @@ function setSize(value: InstanceSize) {
|
|
|
622
623
|
|
|
623
624
|
<div v-if="provisionType === 'docker-compose'" class="space-y-2">
|
|
624
625
|
<div class="space-y-1">
|
|
625
|
-
<label class="text-
|
|
626
|
+
<label class="text-2xs text-muted">{{ t('inspector.testConfig.composePath') }}</label>
|
|
626
627
|
<div class="flex items-center gap-1">
|
|
627
628
|
<UInput
|
|
628
629
|
:model-value="composePath"
|
|
@@ -634,17 +635,17 @@ 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>
|
|
647
|
-
<p class="text-
|
|
648
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
648
649
|
{{ t('inspector.testConfig.composeHint') }}
|
|
649
650
|
</p>
|
|
650
651
|
</div>
|
|
@@ -660,9 +661,7 @@ function setSize(value: InstanceSize) {
|
|
|
660
661
|
connection (the "how") is configured per-type in the Infrastructure window. -->
|
|
661
662
|
<div v-if="provisionType === 'kubernetes'" class="space-y-2">
|
|
662
663
|
<div class="space-y-1">
|
|
663
|
-
<span class="text-
|
|
664
|
-
t('inspector.testConfig.manifestSourceLabel')
|
|
665
|
-
}}</span>
|
|
664
|
+
<span class="text-2xs text-muted">{{ t('inspector.testConfig.manifestSourceLabel') }}</span>
|
|
666
665
|
<div class="flex flex-wrap gap-1">
|
|
667
666
|
<UButton
|
|
668
667
|
:color="kubeSourceType === 'colocated' ? 'primary' : 'neutral'"
|
|
@@ -684,7 +683,7 @@ function setSize(value: InstanceSize) {
|
|
|
684
683
|
</div>
|
|
685
684
|
|
|
686
685
|
<div v-if="kubeSourceType === 'separate'" class="space-y-1">
|
|
687
|
-
<label class="text-
|
|
686
|
+
<label class="text-2xs text-muted">{{ t('inspector.testConfig.manifestRepo') }}</label>
|
|
688
687
|
<UInput
|
|
689
688
|
:model-value="kubeRepo"
|
|
690
689
|
size="xs"
|
|
@@ -695,7 +694,7 @@ function setSize(value: InstanceSize) {
|
|
|
695
694
|
/>
|
|
696
695
|
</div>
|
|
697
696
|
<div v-if="kubeSourceType === 'separate'" class="space-y-1">
|
|
698
|
-
<label class="text-
|
|
697
|
+
<label class="text-2xs text-muted">{{ t('inspector.testConfig.manifestRef') }}</label>
|
|
699
698
|
<UInput
|
|
700
699
|
:model-value="kubeRef"
|
|
701
700
|
size="xs"
|
|
@@ -707,7 +706,7 @@ function setSize(value: InstanceSize) {
|
|
|
707
706
|
</div>
|
|
708
707
|
|
|
709
708
|
<div class="space-y-1">
|
|
710
|
-
<label class="text-
|
|
709
|
+
<label class="text-2xs text-muted">{{ t('inspector.testConfig.manifestPath') }}</label>
|
|
711
710
|
<div class="flex items-center gap-1">
|
|
712
711
|
<UInput
|
|
713
712
|
:model-value="kubePath"
|
|
@@ -717,23 +716,23 @@ function setSize(value: InstanceSize) {
|
|
|
717
716
|
@blur="(e: FocusEvent) => setKubePath((e.target as HTMLInputElement).value)"
|
|
718
717
|
@keydown.enter="(e: KeyboardEvent) => setKubePath((e.target as HTMLInputElement).value)"
|
|
719
718
|
/>
|
|
720
|
-
<
|
|
719
|
+
<IconButton
|
|
721
720
|
v-if="repoContext && kubeSourceType === 'colocated'"
|
|
722
721
|
size="xs"
|
|
723
722
|
variant="soft"
|
|
724
723
|
color="neutral"
|
|
725
724
|
icon="i-lucide-folder-search"
|
|
726
|
-
:
|
|
725
|
+
:label="t('inspector.testConfig.browseRepo')"
|
|
727
726
|
@click="openBrowse('k8s')"
|
|
728
727
|
/>
|
|
729
728
|
</div>
|
|
730
|
-
<p class="text-
|
|
729
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
731
730
|
{{ t('inspector.testConfig.manifestPathHint') }}
|
|
732
731
|
</p>
|
|
733
732
|
</div>
|
|
734
733
|
|
|
735
734
|
<div class="space-y-1">
|
|
736
|
-
<span class="text-
|
|
735
|
+
<span class="text-2xs text-muted">{{ t('inspector.testConfig.rendererLabel') }}</span>
|
|
737
736
|
<div class="flex flex-wrap gap-1">
|
|
738
737
|
<UButton
|
|
739
738
|
v-for="r in RENDERERS"
|
|
@@ -746,7 +745,7 @@ function setSize(value: InstanceSize) {
|
|
|
746
745
|
{{ r.label }}
|
|
747
746
|
</UButton>
|
|
748
747
|
</div>
|
|
749
|
-
<p class="text-
|
|
748
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
750
749
|
{{ t('inspector.testConfig.rendererHint') }}
|
|
751
750
|
</p>
|
|
752
751
|
</div>
|
|
@@ -756,7 +755,7 @@ function setSize(value: InstanceSize) {
|
|
|
756
755
|
source), the per-PR recipe lives in the target repository's own preview workflow, so
|
|
757
756
|
declaring the type IS the whole service-side configuration. Say so explicitly rather
|
|
758
757
|
than rendering an empty panel that reads like something failed to load. -->
|
|
759
|
-
<p v-if="provisionType === 'cloudflare'" class="text-
|
|
758
|
+
<p v-if="provisionType === 'cloudflare'" class="text-2xs text-dimmed">
|
|
760
759
|
{{ t('inspector.testConfig.cloudflareHint') }}
|
|
761
760
|
</p>
|
|
762
761
|
|
|
@@ -764,9 +763,7 @@ function setSize(value: InstanceSize) {
|
|
|
764
763
|
handler the workspace configures). -->
|
|
765
764
|
<div v-if="provisionType === 'custom'" class="space-y-2">
|
|
766
765
|
<div class="space-y-1">
|
|
767
|
-
<label class="text-
|
|
768
|
-
t('inspector.testConfig.customManifestId')
|
|
769
|
-
}}</label>
|
|
766
|
+
<label class="text-2xs text-muted">{{ t('inspector.testConfig.customManifestId') }}</label>
|
|
770
767
|
<USelect
|
|
771
768
|
v-if="customTypeItems.length"
|
|
772
769
|
:model-value="customManifestId"
|
|
@@ -776,15 +773,15 @@ function setSize(value: InstanceSize) {
|
|
|
776
773
|
:placeholder="t('inspector.testConfig.customManifestIdPlaceholder')"
|
|
777
774
|
@update:model-value="(v: string) => setCustomManifestId(v)"
|
|
778
775
|
/>
|
|
779
|
-
<p v-else class="text-
|
|
776
|
+
<p v-else class="text-2xs leading-snug text-app-warning-300/80">
|
|
780
777
|
{{ t('inspector.testConfig.customNoTypes') }}
|
|
781
778
|
</p>
|
|
782
|
-
<p class="text-
|
|
779
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
783
780
|
{{ t('inspector.testConfig.customManifestIdHint') }}
|
|
784
781
|
</p>
|
|
785
782
|
</div>
|
|
786
783
|
<div class="space-y-1">
|
|
787
|
-
<label class="text-
|
|
784
|
+
<label class="text-2xs text-muted">{{
|
|
788
785
|
t('inspector.testConfig.customManifestPath')
|
|
789
786
|
}}</label>
|
|
790
787
|
<UInput
|
|
@@ -796,7 +793,7 @@ function setSize(value: InstanceSize) {
|
|
|
796
793
|
(e: KeyboardEvent) => setCustomManifestPath((e.target as HTMLInputElement).value)
|
|
797
794
|
"
|
|
798
795
|
/>
|
|
799
|
-
<p class="text-
|
|
796
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
800
797
|
{{ t('inspector.testConfig.customManifestPathHint') }}
|
|
801
798
|
</p>
|
|
802
799
|
</div>
|
|
@@ -805,10 +802,10 @@ function setSize(value: InstanceSize) {
|
|
|
805
802
|
shown when the selected type declares a fixer prompt. -->
|
|
806
803
|
<div
|
|
807
804
|
v-if="manifestFixerAvailable && repoContext"
|
|
808
|
-
class="space-y-1.5 rounded border border-default bg-default/40 p-2"
|
|
805
|
+
class="space-y-1.5 rounded-sm border border-default bg-default/40 p-2"
|
|
809
806
|
>
|
|
810
807
|
<div class="flex items-center justify-between gap-2">
|
|
811
|
-
<span class="text-
|
|
808
|
+
<span class="text-2xs text-muted">{{
|
|
812
809
|
t('inspector.testConfig.generateManifest.title')
|
|
813
810
|
}}</span>
|
|
814
811
|
<UButton
|
|
@@ -823,15 +820,15 @@ function setSize(value: InstanceSize) {
|
|
|
823
820
|
{{ t('inspector.testConfig.generateManifest.button') }}
|
|
824
821
|
</UButton>
|
|
825
822
|
</div>
|
|
826
|
-
<p class="text-
|
|
823
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
827
824
|
{{ t('inspector.testConfig.generateManifest.hint') }}
|
|
828
825
|
</p>
|
|
829
|
-
<p v-if="manifestRepairError" class="text-
|
|
826
|
+
<p v-if="manifestRepairError" class="text-2xs text-app-error-300/80">
|
|
830
827
|
{{ t('inspector.testConfig.generateManifest.error') }}
|
|
831
828
|
</p>
|
|
832
829
|
<p
|
|
833
830
|
v-else-if="manifestRepairJob"
|
|
834
|
-
class="text-
|
|
831
|
+
class="text-2xs"
|
|
835
832
|
:class="{
|
|
836
833
|
'text-app-info-300/80': manifestRepairJob.status === 'running',
|
|
837
834
|
'text-app-success-300/80': manifestRepairJob.status === 'succeeded',
|
|
@@ -840,7 +837,7 @@ function setSize(value: InstanceSize) {
|
|
|
840
837
|
>
|
|
841
838
|
{{ t(`inspector.testConfig.generateManifest.status.${manifestRepairJob.status}`) }}
|
|
842
839
|
</p>
|
|
843
|
-
<p v-else-if="manifestRepairJobId" class="text-
|
|
840
|
+
<p v-else-if="manifestRepairJobId" class="text-2xs text-app-info-300/80">
|
|
844
841
|
{{ t('inspector.testConfig.generateManifest.dispatched') }}
|
|
845
842
|
</p>
|
|
846
843
|
</div>
|
|
@@ -896,7 +893,7 @@ function setSize(value: InstanceSize) {
|
|
|
896
893
|
:hint="t('inspector.testConfig.provisioningHint')"
|
|
897
894
|
>
|
|
898
895
|
<div class="space-y-1">
|
|
899
|
-
<span class="text-
|
|
896
|
+
<span class="text-2xs text-muted">{{ t('inspector.testConfig.cloudProvider') }}</span>
|
|
900
897
|
<div class="flex flex-wrap gap-1">
|
|
901
898
|
<UButton
|
|
902
899
|
v-for="p in PROVIDERS"
|
|
@@ -912,7 +909,7 @@ function setSize(value: InstanceSize) {
|
|
|
912
909
|
</div>
|
|
913
910
|
|
|
914
911
|
<div class="space-y-1">
|
|
915
|
-
<span class="text-
|
|
912
|
+
<span class="text-2xs text-muted">{{ t('inspector.testConfig.instanceSize') }}</span>
|
|
916
913
|
<div class="flex flex-wrap gap-1">
|
|
917
914
|
<UButton
|
|
918
915
|
v-for="s in SIZES"
|
|
@@ -165,13 +165,13 @@ async function clearAll() {
|
|
|
165
165
|
|
|
166
166
|
<!-- These are REAL secrets: an unmistakable sensitivity + replace-all warning. -->
|
|
167
167
|
<div
|
|
168
|
-
class="flex items-start gap-2 rounded-md border border-app-warning-500/40 bg-app-warning-500/10 px-2.5 py-2 text-
|
|
168
|
+
class="flex items-start gap-2 rounded-md border border-app-warning-500/40 bg-app-warning-500/10 px-2.5 py-2 text-2xs leading-snug text-app-warning-200"
|
|
169
169
|
>
|
|
170
170
|
<UIcon name="i-lucide-shield-alert" class="mt-0.5 h-4 w-4 shrink-0 text-app-warning-400" />
|
|
171
171
|
<span>{{ t('inspector.testSecrets.warning') }}</span>
|
|
172
172
|
</div>
|
|
173
173
|
|
|
174
|
-
<p class="text-
|
|
174
|
+
<p class="text-2xs leading-snug text-dimmed">
|
|
175
175
|
{{ t('inspector.testSecrets.replaceNote') }}
|
|
176
176
|
</p>
|
|
177
177
|
|
|
@@ -234,7 +234,7 @@ async function clearAll() {
|
|
|
234
234
|
</UFormField>
|
|
235
235
|
</div>
|
|
236
236
|
|
|
237
|
-
<p v-if="duplicateKeys.size" class="text-
|
|
237
|
+
<p v-if="duplicateKeys.size" class="text-2xs text-app-error-400">
|
|
238
238
|
{{ t('inspector.testSecrets.duplicateKey') }}
|
|
239
239
|
</p>
|
|
240
240
|
|
|
@@ -89,7 +89,7 @@ function revert() {
|
|
|
89
89
|
>
|
|
90
90
|
<!-- This text reaches the model in the prompt, so it must never hold a real secret. -->
|
|
91
91
|
<div
|
|
92
|
-
class="flex items-start gap-2 rounded-md border border-muted bg-elevated/40 px-2.5 py-2 text-
|
|
92
|
+
class="flex items-start gap-2 rounded-md border border-muted bg-elevated/40 px-2.5 py-2 text-2xs leading-snug text-toned"
|
|
93
93
|
>
|
|
94
94
|
<UIcon name="i-lucide-info" class="mt-0.5 h-4 w-4 shrink-0 text-muted" />
|
|
95
95
|
<span>{{ t('inspector.testingContext.notSecret') }}</span>
|
|
@@ -104,7 +104,7 @@ function revert() {
|
|
|
104
104
|
/>
|
|
105
105
|
|
|
106
106
|
<div class="flex items-center justify-between gap-2">
|
|
107
|
-
<p class="text-
|
|
107
|
+
<p class="text-2xs text-dimmed" :class="{ 'text-app-error-400': tooLong }">
|
|
108
108
|
{{
|
|
109
109
|
t('inspector.testingContext.length', {
|
|
110
110
|
count: outgoing.length,
|