@cat-factory/app 0.47.9 → 0.47.11
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/components/brainstorm/BrainstormWindow.vue +96 -59
- package/app/components/clarity/ClarityReviewWindow.vue +84 -59
- package/app/components/consensus/ConsensusSessionWindow.vue +72 -34
- package/app/components/focus/BlockFocusView.vue +14 -10
- package/app/components/followUp/FollowUpWindow.vue +51 -26
- package/app/components/github/AddServiceFromRepoModal.vue +76 -23
- package/app/components/humanTest/HumanTestWindow.vue +70 -35
- package/app/components/requirements/RequirementsReviewWindow.vue +130 -82
- package/app/components/spec/ServiceSpecWindow.vue +54 -28
- package/app/components/testing/TestReportWindow.vue +82 -39
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +49 -32
- package/i18n/locales/en.json +587 -3
- package/i18n/locales/es.json +551 -3
- package/i18n/locales/fr.json +551 -3
- package/i18n/locales/pl.json +551 -3
- package/i18n/locales/uk.json +551 -3
- package/package.json +1 -1
|
@@ -18,6 +18,7 @@ import StepRunMeta from '~/components/panels/StepRunMeta.vue'
|
|
|
18
18
|
const board = useBoardStore()
|
|
19
19
|
const execution = useExecutionStore()
|
|
20
20
|
const visualConfirm = useVisualConfirmStore()
|
|
21
|
+
const { t } = useI18n()
|
|
21
22
|
|
|
22
23
|
// Per-window blob cache; release the cached screenshot/reference object URLs when the window
|
|
23
24
|
// goes away, so the (potentially large) blob bytes don't linger for the rest of the session.
|
|
@@ -41,11 +42,18 @@ const busy = computed(() => (blockId.value ? visualConfirm.isBusy(blockId.value)
|
|
|
41
42
|
const awaitingHuman = computed(() => phase.value === 'awaiting_human')
|
|
42
43
|
const working = computed(() => phase.value === 'fixing')
|
|
43
44
|
|
|
44
|
-
const PHASE_LABEL
|
|
45
|
-
awaiting_human: '
|
|
46
|
-
fixing: '
|
|
47
|
-
approved: '
|
|
48
|
-
}
|
|
45
|
+
const PHASE_LABEL = computed<Record<NonNullable<VisualConfirmStepState['phase']>, string>>(() => ({
|
|
46
|
+
awaiting_human: t('visualConfirm.phase.awaiting_human'),
|
|
47
|
+
fixing: t('visualConfirm.phase.fixing'),
|
|
48
|
+
approved: t('visualConfirm.phase.approved'),
|
|
49
|
+
}))
|
|
50
|
+
|
|
51
|
+
// Exhaustive map of a round's outcome enum → label (literal keys keep the typed-key drift
|
|
52
|
+
// guard live, vs a runtime-built `visualConfirm.outcome.${outcome}`).
|
|
53
|
+
const OUTCOME_LABELS = computed<Record<'completed' | 'failed', string>>(() => ({
|
|
54
|
+
completed: t('visualConfirm.outcome.completed'),
|
|
55
|
+
failed: t('visualConfirm.outcome.failed'),
|
|
56
|
+
}))
|
|
49
57
|
|
|
50
58
|
// Resolve every pair's artifacts (the gallery + the lightbox share this one cache).
|
|
51
59
|
watch(
|
|
@@ -66,14 +74,14 @@ const lightboxItems = computed(() => {
|
|
|
66
74
|
if (p.actualArtifactId)
|
|
67
75
|
items.push({
|
|
68
76
|
artifactId: p.actualArtifactId,
|
|
69
|
-
label:
|
|
70
|
-
alt:
|
|
77
|
+
label: t('visualConfirm.lightbox.actualLabel', { view: p.view }),
|
|
78
|
+
alt: t('visualConfirm.lightbox.actualAlt', { view: p.view }),
|
|
71
79
|
})
|
|
72
80
|
if (p.referenceArtifactId)
|
|
73
81
|
items.push({
|
|
74
82
|
artifactId: p.referenceArtifactId,
|
|
75
|
-
label:
|
|
76
|
-
alt:
|
|
83
|
+
label: t('visualConfirm.lightbox.referenceLabel', { view: p.view }),
|
|
84
|
+
alt: t('visualConfirm.lightbox.referenceAlt', { view: p.view }),
|
|
77
85
|
})
|
|
78
86
|
}
|
|
79
87
|
return items
|
|
@@ -189,7 +197,7 @@ const canApprove = computed(
|
|
|
189
197
|
tabindex="-1"
|
|
190
198
|
role="dialog"
|
|
191
199
|
aria-modal="true"
|
|
192
|
-
aria-label="
|
|
200
|
+
:aria-label="t('visualConfirm.ariaLabel')"
|
|
193
201
|
class="m-4 flex w-full max-w-5xl flex-col overflow-hidden rounded-2xl border border-slate-800 bg-slate-900 shadow-2xl focus:outline-none"
|
|
194
202
|
>
|
|
195
203
|
<header class="flex items-center gap-3 border-b border-slate-800 px-5 py-3">
|
|
@@ -200,10 +208,14 @@ const canApprove = computed(
|
|
|
200
208
|
</span>
|
|
201
209
|
<div class="min-w-0 flex-1">
|
|
202
210
|
<h2 class="truncate text-sm font-semibold text-slate-100">
|
|
203
|
-
|
|
211
|
+
{{
|
|
212
|
+
block
|
|
213
|
+
? t('visualConfirm.titleWithBlock', { title: block.title })
|
|
214
|
+
: t('visualConfirm.title')
|
|
215
|
+
}}
|
|
204
216
|
</h2>
|
|
205
217
|
<p class="truncate text-[11px] text-slate-400">
|
|
206
|
-
{{ phase ? PHASE_LABEL[phase] : '
|
|
218
|
+
{{ phase ? PHASE_LABEL[phase] : t('visualConfirm.subtitle') }}
|
|
207
219
|
</p>
|
|
208
220
|
</div>
|
|
209
221
|
<button
|
|
@@ -220,7 +232,7 @@ const canApprove = computed(
|
|
|
220
232
|
class="flex flex-col items-center justify-center gap-2 py-10 text-center text-slate-400"
|
|
221
233
|
>
|
|
222
234
|
<UIcon name="i-lucide-image-play" class="h-8 w-8 opacity-40" />
|
|
223
|
-
<p class="text-sm">
|
|
235
|
+
<p class="text-sm">{{ t('visualConfirm.notStarted') }}</p>
|
|
224
236
|
</div>
|
|
225
237
|
|
|
226
238
|
<template v-else>
|
|
@@ -262,38 +274,37 @@ const canApprove = computed(
|
|
|
262
274
|
:name="noteOpen[p.view] ? 'i-lucide-chevron-down' : 'i-lucide-chevron-right'"
|
|
263
275
|
class="h-3 w-3"
|
|
264
276
|
/>
|
|
265
|
-
|
|
277
|
+
{{ t('visualConfirm.noteIssue', { view: p.view }) }}
|
|
266
278
|
<span
|
|
267
279
|
v-if="perViewNotes[p.view]?.trim()"
|
|
268
280
|
class="rounded-full bg-amber-500/15 px-1.5 text-[9px] text-amber-300"
|
|
269
|
-
>noted</span
|
|
281
|
+
>{{ t('visualConfirm.noted') }}</span
|
|
270
282
|
>
|
|
271
283
|
</button>
|
|
272
284
|
<textarea
|
|
273
285
|
v-if="noteOpen[p.view]"
|
|
274
286
|
v-model="perViewNotes[p.view]"
|
|
275
287
|
rows="2"
|
|
276
|
-
:placeholder="
|
|
288
|
+
:placeholder="t('visualConfirm.notePlaceholder', { view: p.view })"
|
|
277
289
|
class="mt-1 w-full rounded-md border border-slate-700 bg-slate-950 px-2 py-1.5 text-[12px] text-slate-200 placeholder:text-slate-600 focus:border-amber-500 focus:outline-none"
|
|
278
290
|
/>
|
|
279
291
|
</div>
|
|
280
292
|
</div>
|
|
281
293
|
</section>
|
|
282
294
|
<p v-else class="text-[12px] italic text-slate-500">
|
|
283
|
-
|
|
284
|
-
below.
|
|
295
|
+
{{ t('visualConfirm.noScreenshots') }}
|
|
285
296
|
</p>
|
|
286
297
|
|
|
287
298
|
<!-- Upload a reference for any view -->
|
|
288
299
|
<section class="rounded-lg border border-slate-800 bg-slate-900/60 p-3">
|
|
289
300
|
<h3 class="mb-2 text-[11px] font-semibold uppercase tracking-wide text-slate-500">
|
|
290
|
-
|
|
301
|
+
{{ t('visualConfirm.upload.heading') }}
|
|
291
302
|
</h3>
|
|
292
303
|
<div class="flex flex-wrap items-center gap-2">
|
|
293
304
|
<input
|
|
294
305
|
v-model="uploadView"
|
|
295
306
|
list="vc-views"
|
|
296
|
-
placeholder="
|
|
307
|
+
:placeholder="t('visualConfirm.upload.viewPlaceholder')"
|
|
297
308
|
class="rounded-md border border-slate-700 bg-slate-950 px-2 py-1 text-[12px] text-slate-200 placeholder:text-slate-600"
|
|
298
309
|
/>
|
|
299
310
|
<datalist id="vc-views">
|
|
@@ -311,8 +322,8 @@ const canApprove = computed(
|
|
|
311
322
|
<p class="mt-1.5 text-[10px] text-slate-600">
|
|
312
323
|
{{
|
|
313
324
|
uploadView.trim()
|
|
314
|
-
? '
|
|
315
|
-
: '
|
|
325
|
+
? t('visualConfirm.upload.tipReady')
|
|
326
|
+
: t('visualConfirm.upload.tipNeedView')
|
|
316
327
|
}}
|
|
317
328
|
</p>
|
|
318
329
|
</section>
|
|
@@ -323,17 +334,17 @@ const canApprove = computed(
|
|
|
323
334
|
class="rounded-lg border border-slate-800 bg-slate-900/60 p-3"
|
|
324
335
|
>
|
|
325
336
|
<h3 class="mb-2 text-[11px] font-semibold uppercase tracking-wide text-slate-500">
|
|
326
|
-
|
|
337
|
+
{{ t('visualConfirm.requestFix.heading') }}
|
|
327
338
|
</h3>
|
|
328
339
|
<textarea
|
|
329
340
|
v-model="globalFindings"
|
|
330
341
|
rows="3"
|
|
331
|
-
placeholder="
|
|
342
|
+
:placeholder="t('visualConfirm.requestFix.placeholder')"
|
|
332
343
|
class="w-full rounded-md border border-slate-700 bg-slate-950 px-3 py-2 text-[13px] text-slate-200 placeholder:text-slate-600 focus:border-amber-500 focus:outline-none"
|
|
333
344
|
/>
|
|
334
345
|
<div class="mt-2 flex items-center justify-between">
|
|
335
346
|
<span class="text-[11px] text-slate-500">
|
|
336
|
-
|
|
347
|
+
{{ t('visualConfirm.requestFix.foldedHint') }}
|
|
337
348
|
</span>
|
|
338
349
|
<UButton
|
|
339
350
|
size="sm"
|
|
@@ -343,7 +354,7 @@ const canApprove = computed(
|
|
|
343
354
|
:disabled="busy || !hasFindings"
|
|
344
355
|
@click="submitFix"
|
|
345
356
|
>
|
|
346
|
-
|
|
357
|
+
{{ t('visualConfirm.requestFix.send') }}
|
|
347
358
|
</UButton>
|
|
348
359
|
</div>
|
|
349
360
|
</section>
|
|
@@ -354,7 +365,7 @@ const canApprove = computed(
|
|
|
354
365
|
class="rounded-lg border border-slate-800 bg-slate-900/60 p-3"
|
|
355
366
|
>
|
|
356
367
|
<h3 class="mb-2 text-[11px] font-semibold uppercase tracking-wide text-slate-500">
|
|
357
|
-
|
|
368
|
+
{{ t('visualConfirm.history.heading', { count: vc.attempts }, vc.attempts) }}
|
|
358
369
|
</h3>
|
|
359
370
|
<ol class="space-y-2">
|
|
360
371
|
<li v-for="(r, i) in vc.rounds" :key="i" class="flex items-start gap-2 text-[12px]">
|
|
@@ -363,7 +374,9 @@ const canApprove = computed(
|
|
|
363
374
|
class="mt-0.5 h-3.5 w-3.5 shrink-0 text-slate-400"
|
|
364
375
|
/>
|
|
365
376
|
<div class="min-w-0 flex-1">
|
|
366
|
-
<span class="text-slate-200">
|
|
377
|
+
<span class="text-slate-200">{{
|
|
378
|
+
t('visualConfirm.history.fixRequested')
|
|
379
|
+
}}</span>
|
|
367
380
|
<span
|
|
368
381
|
class="ml-1.5 rounded px-1 text-[10px] uppercase"
|
|
369
382
|
:class="
|
|
@@ -374,7 +387,11 @@ const canApprove = computed(
|
|
|
374
387
|
: 'bg-slate-500/15 text-slate-300'
|
|
375
388
|
"
|
|
376
389
|
>
|
|
377
|
-
{{
|
|
390
|
+
{{
|
|
391
|
+
r.outcome
|
|
392
|
+
? OUTCOME_LABELS[r.outcome]
|
|
393
|
+
: t('visualConfirm.outcome.inProgress')
|
|
394
|
+
}}
|
|
378
395
|
</span>
|
|
379
396
|
<p v-if="r.findings" class="whitespace-pre-wrap leading-snug text-slate-400">
|
|
380
397
|
{{ r.findings }}
|
|
@@ -405,7 +422,7 @@ const canApprove = computed(
|
|
|
405
422
|
class="flex items-center gap-1.5 text-[11px] text-amber-300/90"
|
|
406
423
|
>
|
|
407
424
|
<input v-model="ackDegraded" type="checkbox" class="accent-amber-500" />
|
|
408
|
-
|
|
425
|
+
{{ t('visualConfirm.reviewedManually') }}
|
|
409
426
|
</label>
|
|
410
427
|
<UButton
|
|
411
428
|
size="sm"
|
|
@@ -416,7 +433,7 @@ const canApprove = computed(
|
|
|
416
433
|
:disabled="busy || !awaitingHuman"
|
|
417
434
|
@click="recapture"
|
|
418
435
|
>
|
|
419
|
-
|
|
436
|
+
{{ t('visualConfirm.recapture') }}
|
|
420
437
|
</UButton>
|
|
421
438
|
<UButton
|
|
422
439
|
color="primary"
|
|
@@ -425,7 +442,7 @@ const canApprove = computed(
|
|
|
425
442
|
:disabled="!canApprove"
|
|
426
443
|
@click="approve"
|
|
427
444
|
>
|
|
428
|
-
|
|
445
|
+
{{ t('visualConfirm.approve') }}
|
|
429
446
|
</UButton>
|
|
430
447
|
</div>
|
|
431
448
|
</footer>
|