@cat-factory/app 0.145.2 → 0.146.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/app/components/environments/EnvSetupStepper.vue +70 -0
- package/app/components/environments/EnvironmentSetupWizard.vue +9 -59
- package/app/components/prReview/PrReviewWindow.vue +65 -1
- package/app/modular/journeys/environmentSetup.logic.spec.ts +46 -15
- package/app/modular/journeys/environmentSetup.logic.ts +102 -35
- package/app/modular/journeys/environmentSetup.ts +17 -68
- package/app/types/execution.ts +2 -0
- package/i18n/locales/de.json +10 -0
- package/i18n/locales/en.json +10 -0
- package/i18n/locales/es.json +10 -0
- package/i18n/locales/fr.json +10 -0
- package/i18n/locales/he.json +10 -0
- package/i18n/locales/it.json +10 -0
- package/i18n/locales/ja.json +10 -0
- package/i18n/locales/pl.json +10 -0
- package/i18n/locales/tr.json +10 -0
- package/i18n/locales/uk.json +10 -0
- package/package.json +5 -5
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// The environment-setup wizard's stepper header, driven entirely by
|
|
3
|
+
// `useJourneyProgress` (modular-react#83, production-feedback item 4). The ordered
|
|
4
|
+
// steps, the live position, and the "Step X of N" total all come from
|
|
5
|
+
// `resolveStepSequence` walking the journey's transition graph — there is no
|
|
6
|
+
// hand-maintained step-order array to keep in sync (the old `ENV_STEP_ORDER` +
|
|
7
|
+
// `crumbState` is gone). Rendered inside `<JourneyHost>`, which hands it the live
|
|
8
|
+
// `instanceId`; each step's label is the i18n key carried in the journey's `steps`
|
|
9
|
+
// metadata.
|
|
10
|
+
import type { InstanceId } from '@modular-vue/journeys'
|
|
11
|
+
import { useJourneyProgress } from '@modular-vue/journeys'
|
|
12
|
+
import { environmentSetupJourney } from '~/modular/journeys/environmentSetup'
|
|
13
|
+
import type { EnvSetupInput } from '~/modular/journeys/environmentSetup.logic'
|
|
14
|
+
|
|
15
|
+
const props = defineProps<{
|
|
16
|
+
/** The live journey instance from `<JourneyHost>`, or null before it starts. */
|
|
17
|
+
instanceId: InstanceId | null
|
|
18
|
+
/** The launch input; frozen for the host's lifetime, so the resolved spine is
|
|
19
|
+
* stable (`useJourneyProgress` reads `sequence.input` once at setup). */
|
|
20
|
+
input: EnvSetupInput
|
|
21
|
+
}>()
|
|
22
|
+
|
|
23
|
+
const { t, te } = useI18n()
|
|
24
|
+
|
|
25
|
+
const { index, total, steps } = useJourneyProgress(
|
|
26
|
+
() => props.instanceId,
|
|
27
|
+
environmentSetupJourney,
|
|
28
|
+
{ sequence: { input: props.input } },
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
/** Resolve a step's progress-label key (from the journey's `steps` metadata)
|
|
32
|
+
* through i18n, tolerating a locale that omits it rather than leaking the key. */
|
|
33
|
+
function stepLabel(key: string | undefined): string {
|
|
34
|
+
return key && te(key) ? t(key) : ''
|
|
35
|
+
}
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<div class="space-y-2" data-testid="env-setup-stepper">
|
|
40
|
+
<p v-if="total" class="text-[11px] font-medium text-slate-400" data-testid="env-setup-progress">
|
|
41
|
+
{{ t('environmentWizard.progress', { index: index + 1, total }) }}
|
|
42
|
+
</p>
|
|
43
|
+
<ol class="flex items-center gap-2 text-[11px]">
|
|
44
|
+
<li
|
|
45
|
+
v-for="(step, i) in steps"
|
|
46
|
+
:key="step.entry"
|
|
47
|
+
class="flex items-center gap-2"
|
|
48
|
+
:data-testid="`env-setup-crumb-${step.entry}`"
|
|
49
|
+
>
|
|
50
|
+
<span
|
|
51
|
+
class="flex h-5 w-5 items-center justify-center rounded-full text-[10px] font-semibold"
|
|
52
|
+
:class="{
|
|
53
|
+
'bg-primary-500 text-white': i === index,
|
|
54
|
+
'bg-emerald-600/70 text-white': i < index,
|
|
55
|
+
'bg-slate-700 text-slate-300': i > index,
|
|
56
|
+
}"
|
|
57
|
+
>{{ i + 1 }}</span
|
|
58
|
+
>
|
|
59
|
+
<span :class="i === index ? 'text-slate-100' : 'text-slate-500'">
|
|
60
|
+
{{ stepLabel(step.progressLabel) }}
|
|
61
|
+
</span>
|
|
62
|
+
<UIcon
|
|
63
|
+
v-if="i < steps.length - 1"
|
|
64
|
+
name="i-lucide-chevron-right"
|
|
65
|
+
class="h-3 w-3 text-slate-600"
|
|
66
|
+
/>
|
|
67
|
+
</li>
|
|
68
|
+
</ol>
|
|
69
|
+
</div>
|
|
70
|
+
</template>
|
|
@@ -8,14 +8,15 @@
|
|
|
8
8
|
// journey (`~/modular/journeys/environmentSetup`), hosted here by `<JourneyHost>`:
|
|
9
9
|
// it starts the journey on open (RESUMING the in-flight instance for the same
|
|
10
10
|
// frame when one was left mid-flow, via the Pinia persistence adapter), renders
|
|
11
|
-
// the current step through `<JourneyOutlet>`, and abandons it on close.
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
11
|
+
// the current step through `<JourneyOutlet>`, and abandons it on close. The
|
|
12
|
+
// stepper header + "Step X of N" are derived from the journey's transition graph
|
|
13
|
+
// by `<EnvSetupStepper>` (via `useJourneyProgress`), not a hand-maintained step
|
|
14
|
+
// list. Each step component drives the `environmentWizard` store for its
|
|
15
|
+
// data/actions and fires the journey's exits to advance. On `complete` (the save
|
|
16
|
+
// step's Done) the journey clears its persisted blob and we close the modal.
|
|
15
17
|
import { computed } from 'vue'
|
|
16
18
|
import { JourneyHost, JourneyOutlet } from '@modular-vue/journeys'
|
|
17
19
|
import { environmentSetupHandle } from '~/modular/journeys/environmentSetup'
|
|
18
|
-
import { ENV_STEP_ORDER, type EnvStep } from '~/modular/journeys/environmentSetup.logic'
|
|
19
20
|
|
|
20
21
|
const ui = useUiStore()
|
|
21
22
|
const { t } = useI18n()
|
|
@@ -30,23 +31,6 @@ const open = computed({
|
|
|
30
31
|
// Read once at journey start; keyed for resume. Frozen for the host's lifetime,
|
|
31
32
|
// so the modal remounts the host per open (it renders under `v-if` upstream).
|
|
32
33
|
const input = computed(() => ({ frameId: ui.environmentWizardFrameId }))
|
|
33
|
-
|
|
34
|
-
const STEP_LABEL = computed<Record<EnvStep, string>>(() => ({
|
|
35
|
-
pick: t('environmentWizard.steps.pick'),
|
|
36
|
-
review: t('environmentWizard.steps.review'),
|
|
37
|
-
preflight: t('environmentWizard.steps.preflight'),
|
|
38
|
-
save: t('environmentWizard.steps.save'),
|
|
39
|
-
}))
|
|
40
|
-
|
|
41
|
-
/** The crumb index of a step, relative to the current journey step. */
|
|
42
|
-
function crumbState(
|
|
43
|
-
entry: EnvStep,
|
|
44
|
-
currentEntry: EnvStep | undefined,
|
|
45
|
-
): 'current' | 'done' | 'todo' {
|
|
46
|
-
if (!currentEntry) return 'todo'
|
|
47
|
-
if (entry === currentEntry) return 'current'
|
|
48
|
-
return ENV_STEP_ORDER.indexOf(entry) < ENV_STEP_ORDER.indexOf(currentEntry) ? 'done' : 'todo'
|
|
49
|
-
}
|
|
50
34
|
</script>
|
|
51
35
|
|
|
52
36
|
<template>
|
|
@@ -63,43 +47,9 @@ function crumbState(
|
|
|
63
47
|
:input="input"
|
|
64
48
|
@finished="ui.closeEnvironmentSetup()"
|
|
65
49
|
>
|
|
66
|
-
<template #default="{ instanceId
|
|
67
|
-
<!-- stepper header,
|
|
68
|
-
<
|
|
69
|
-
<li
|
|
70
|
-
v-for="(s, i) in ENV_STEP_ORDER"
|
|
71
|
-
:key="s"
|
|
72
|
-
class="flex items-center gap-2"
|
|
73
|
-
:data-testid="`env-setup-crumb-${s}`"
|
|
74
|
-
>
|
|
75
|
-
<span
|
|
76
|
-
class="flex h-5 w-5 items-center justify-center rounded-full text-[10px] font-semibold"
|
|
77
|
-
:class="{
|
|
78
|
-
'bg-primary-500 text-white':
|
|
79
|
-
crumbState(s, (instance?.step?.entry as EnvStep) ?? undefined) === 'current',
|
|
80
|
-
'bg-emerald-600/70 text-white':
|
|
81
|
-
crumbState(s, (instance?.step?.entry as EnvStep) ?? undefined) === 'done',
|
|
82
|
-
'bg-slate-700 text-slate-300':
|
|
83
|
-
crumbState(s, (instance?.step?.entry as EnvStep) ?? undefined) === 'todo',
|
|
84
|
-
}"
|
|
85
|
-
>{{ i + 1 }}</span
|
|
86
|
-
>
|
|
87
|
-
<span
|
|
88
|
-
:class="
|
|
89
|
-
crumbState(s, (instance?.step?.entry as EnvStep) ?? undefined) === 'current'
|
|
90
|
-
? 'text-slate-100'
|
|
91
|
-
: 'text-slate-500'
|
|
92
|
-
"
|
|
93
|
-
>
|
|
94
|
-
{{ STEP_LABEL[s] }}
|
|
95
|
-
</span>
|
|
96
|
-
<UIcon
|
|
97
|
-
v-if="i < ENV_STEP_ORDER.length - 1"
|
|
98
|
-
name="i-lucide-chevron-right"
|
|
99
|
-
class="h-3 w-3 text-slate-600"
|
|
100
|
-
/>
|
|
101
|
-
</li>
|
|
102
|
-
</ol>
|
|
50
|
+
<template #default="{ instanceId }">
|
|
51
|
+
<!-- stepper header, derived from the journey graph -->
|
|
52
|
+
<EnvSetupStepper :instance-id="instanceId" :input="input" />
|
|
103
53
|
|
|
104
54
|
<!-- the current step (pick / review / preflight / save) -->
|
|
105
55
|
<div class="mt-4">
|
|
@@ -63,6 +63,12 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
63
63
|
const working = computed(() => status.value === 'fixing' || status.value === 'posting')
|
|
64
64
|
const findings = computed<PrReviewFinding[]>(() => state.value?.findings ?? [])
|
|
65
65
|
|
|
66
|
+
// The outcome of the last `post` attempt (null until one runs). A partial/failed post re-parks
|
|
67
|
+
// the review at `awaiting_selection` carrying this, so the human sees what posted / what failed
|
|
68
|
+
// and can retry ONLY the posting rather than re-running the whole review.
|
|
69
|
+
const postReport = computed(() => state.value?.postReport ?? null)
|
|
70
|
+
const postedIds = computed(() => new Set(state.value?.postedFindingIds ?? []))
|
|
71
|
+
|
|
66
72
|
/** Severity → chip classes (styling, not copy). */
|
|
67
73
|
const SEVERITY_CLASS: Record<PrReviewSeverity, string> = {
|
|
68
74
|
blocker: 'bg-rose-500/15 text-rose-300 ring-rose-500/30',
|
|
@@ -260,6 +266,57 @@ async function onResolve(action: PrReviewResolution): Promise<void> {
|
|
|
260
266
|
{{ prReview.error }}
|
|
261
267
|
</p>
|
|
262
268
|
|
|
269
|
+
<!-- The outcome of the most recent `post` attempt: how many of how many comments landed,
|
|
270
|
+
which failed + why, and how many findings were folded into the summary because their
|
|
271
|
+
line isn't in the PR diff. Surfaced so a partial/failed post is legible + retryable. -->
|
|
272
|
+
<div
|
|
273
|
+
v-if="postReport"
|
|
274
|
+
data-testid="pr-review-post-report"
|
|
275
|
+
class="mb-3 rounded-lg border px-3 py-2 text-[12px]"
|
|
276
|
+
:class="
|
|
277
|
+
postReport.failures.length > 0 || postReport.bodyPosted === false
|
|
278
|
+
? 'border-amber-500/40 bg-amber-500/10 text-amber-200'
|
|
279
|
+
: 'border-emerald-500/40 bg-emerald-500/10 text-emerald-200'
|
|
280
|
+
"
|
|
281
|
+
>
|
|
282
|
+
<div class="mb-1 flex items-center gap-1.5 font-medium">
|
|
283
|
+
<UIcon
|
|
284
|
+
:name="
|
|
285
|
+
postReport.failures.length > 0 || postReport.bodyPosted === false
|
|
286
|
+
? 'i-lucide-alert-triangle'
|
|
287
|
+
: 'i-lucide-check-circle-2'
|
|
288
|
+
"
|
|
289
|
+
class="h-4 w-4 shrink-0"
|
|
290
|
+
/>
|
|
291
|
+
<span>{{ t('prReview.postReport.heading') }}</span>
|
|
292
|
+
</div>
|
|
293
|
+
<p data-testid="pr-review-post-count">
|
|
294
|
+
{{
|
|
295
|
+
t('prReview.postReport.posted', {
|
|
296
|
+
posted: postReport.posted,
|
|
297
|
+
attempted: postReport.attempted,
|
|
298
|
+
})
|
|
299
|
+
}}
|
|
300
|
+
</p>
|
|
301
|
+
<p v-if="postReport.folded > 0" class="mt-0.5 opacity-90">
|
|
302
|
+
{{ t('prReview.postReport.folded', { count: postReport.folded }) }}
|
|
303
|
+
</p>
|
|
304
|
+
<template v-if="postReport.failures.length > 0">
|
|
305
|
+
<p class="mt-1.5 font-medium">{{ t('prReview.postReport.failuresHeading') }}</p>
|
|
306
|
+
<ul class="mt-0.5 space-y-0.5" data-testid="pr-review-post-failures">
|
|
307
|
+
<li v-for="f in postReport.failures" :key="f.findingId" class="flex gap-1.5">
|
|
308
|
+
<code class="shrink-0 text-amber-100"
|
|
309
|
+
>{{ f.path }}<template v-if="f.line != null">:{{ f.line }}</template></code
|
|
310
|
+
>
|
|
311
|
+
<span class="opacity-90">— {{ f.reason }}</span>
|
|
312
|
+
</li>
|
|
313
|
+
</ul>
|
|
314
|
+
</template>
|
|
315
|
+
<p v-if="postReport.bodyPosted === false && postReport.bodyError" class="mt-1.5">
|
|
316
|
+
{{ t('prReview.postReport.bodyError', { error: postReport.bodyError }) }}
|
|
317
|
+
</p>
|
|
318
|
+
</div>
|
|
319
|
+
|
|
263
320
|
<!-- The reviewer's overall assessment. -->
|
|
264
321
|
<p
|
|
265
322
|
v-if="state?.summary"
|
|
@@ -330,6 +387,13 @@ async function onResolve(action: PrReviewResolution): Promise<void> {
|
|
|
330
387
|
<span class="rounded bg-slate-800 px-1.5 py-0.5 text-[10px] text-slate-300">
|
|
331
388
|
{{ t(`prReview.category.${f.category}`) }}
|
|
332
389
|
</span>
|
|
390
|
+
<span
|
|
391
|
+
v-if="postedIds.has(f.id)"
|
|
392
|
+
data-testid="pr-review-finding-posted"
|
|
393
|
+
class="rounded bg-emerald-500/15 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-emerald-300 ring-1 ring-emerald-500/30"
|
|
394
|
+
>
|
|
395
|
+
{{ t('prReview.postReport.postedBadge') }}
|
|
396
|
+
</span>
|
|
333
397
|
<h4 class="min-w-0 flex-1 text-[13px] font-medium text-slate-100">
|
|
334
398
|
{{ f.title }}
|
|
335
399
|
</h4>
|
|
@@ -381,7 +445,7 @@ async function onResolve(action: PrReviewResolution): Promise<void> {
|
|
|
381
445
|
data-testid="pr-review-post"
|
|
382
446
|
@click="onResolve('post')"
|
|
383
447
|
>
|
|
384
|
-
{{ t('prReview.post') }}
|
|
448
|
+
{{ postReport ? t('prReview.postReport.retry') : t('prReview.post') }}
|
|
385
449
|
</UButton>
|
|
386
450
|
<UButton
|
|
387
451
|
color="primary"
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { resolveStepSequence } from '@modular-vue/journeys'
|
|
2
3
|
import {
|
|
3
|
-
|
|
4
|
+
ENV_MODULE_ID,
|
|
5
|
+
environmentSetupJourney,
|
|
4
6
|
envInitialState,
|
|
5
|
-
envNextAfter,
|
|
6
7
|
envStartStep,
|
|
7
8
|
} from './environmentSetup.logic'
|
|
9
|
+
import en from '../../../i18n/locales/en.json'
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
/** Dot-path lookup into the real `en.json`, mirroring which keys actually ship. */
|
|
12
|
+
function hasKey(path: string): boolean {
|
|
13
|
+
return (
|
|
14
|
+
path.split('.').reduce<unknown>((node, seg) => {
|
|
15
|
+
return node && typeof node === 'object' ? (node as Record<string, unknown>)[seg] : undefined
|
|
16
|
+
}, en) !== undefined
|
|
17
|
+
)
|
|
18
|
+
}
|
|
17
19
|
|
|
20
|
+
// Pure navigation graph for the environment-setup journey (slice 3). The step
|
|
21
|
+
// order is derived from the annotated transition graph (production-feedback item
|
|
22
|
+
// 4), so `resolveStepSequenceResult` walking the real journey definition is the
|
|
23
|
+
// guard against a silent reorder or dropped step — no hand-maintained order array
|
|
24
|
+
// to pin separately.
|
|
25
|
+
describe('environment-setup journey logic', () => {
|
|
18
26
|
it('seeds state from the launch input', () => {
|
|
19
27
|
expect(envInitialState({ frameId: 'blk_1' })).toEqual({ frameId: 'blk_1' })
|
|
20
28
|
expect(envInitialState({ frameId: null })).toEqual({ frameId: null })
|
|
@@ -25,10 +33,33 @@ describe('environment-setup journey logic', () => {
|
|
|
25
33
|
expect(envStartStep({ frameId: null }, { frameId: null })).toBe('pick')
|
|
26
34
|
})
|
|
27
35
|
|
|
28
|
-
it('
|
|
29
|
-
|
|
30
|
-
expect(
|
|
31
|
-
expect(
|
|
32
|
-
expect(
|
|
36
|
+
it('derives the pick → review → preflight → save order from the transition graph', () => {
|
|
37
|
+
const steps = resolveStepSequence(environmentSetupJourney, { input: { frameId: null } })
|
|
38
|
+
expect(steps.map((s) => s.entry)).toEqual(['pick', 'review', 'preflight', 'save'])
|
|
39
|
+
expect(steps.every((s) => s.module === ENV_MODULE_ID)).toBe(true)
|
|
40
|
+
expect(steps.map((s) => s.progressLabel)).toEqual([
|
|
41
|
+
'environmentWizard.steps.pick',
|
|
42
|
+
'environmentWizard.steps.review',
|
|
43
|
+
'environmentWizard.steps.preflight',
|
|
44
|
+
'environmentWizard.steps.save',
|
|
45
|
+
])
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('starts the derived sequence at review when a frame is preselected', () => {
|
|
49
|
+
const steps = resolveStepSequence(environmentSetupJourney, { input: { frameId: 'blk_1' } })
|
|
50
|
+
expect(steps.map((s) => s.entry)).toEqual(['review', 'preflight', 'save'])
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
// The stepper resolves each label through a VARIABLE key (`t(step.progressLabel)`), so
|
|
54
|
+
// the tier-1 typed-message-keys check + `vue-i18n-extract` can no longer see these keys
|
|
55
|
+
// as used and can't catch a typo or a dropped key. Pin the missing-key guard here instead:
|
|
56
|
+
// every `progressLabel` the real definition emits must resolve to a shipping `en.json` key.
|
|
57
|
+
it('carries a shipping en.json label key for every derived step', () => {
|
|
58
|
+
const steps = resolveStepSequence(environmentSetupJourney, { input: { frameId: null } })
|
|
59
|
+
for (const step of steps) {
|
|
60
|
+
const key = step.progressLabel
|
|
61
|
+
expect(key, `missing i18n key for step "${step.entry}"`).toBeTruthy()
|
|
62
|
+
expect(hasKey(key ?? ''), `key "${key}" not in en.json`).toBe(true)
|
|
63
|
+
}
|
|
33
64
|
})
|
|
34
65
|
})
|
|
@@ -10,15 +10,26 @@
|
|
|
10
10
|
* trial) stay in that Pinia store, which the step components still drive; the
|
|
11
11
|
* journey just decides WHICH step shows and threads the target frame id.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
* transition graph
|
|
15
|
-
*
|
|
16
|
-
* `
|
|
13
|
+
* The step ORDER is no longer spelled out a second time as an ordered array: it
|
|
14
|
+
* is DERIVED from the annotated transition graph below (production-feedback item
|
|
15
|
+
* 4 in modular-react#83). Each transition wraps its handler with
|
|
16
|
+
* `defineTransition({ targets, handle })` so the static `targets` declare where
|
|
17
|
+
* the flow can go; `resolveStepSequence` / `useJourneyProgress` walk that graph
|
|
18
|
+
* to produce the ordered step list and the wizard's "Step X of N" progress from
|
|
19
|
+
* the one place the flow is encoded. `steps` carries each step's progress-label
|
|
20
|
+
* key beside the transitions.
|
|
21
|
+
*
|
|
22
|
+
* This definition lives in the logic file (not the SFC-importing
|
|
23
|
+
* `environmentSetup.ts`) so the graph stays free of `.vue` imports and is
|
|
24
|
+
* unit-tested directly (`environmentSetup.logic.spec.ts`). It references the step
|
|
25
|
+
* module only as a TYPE (`import type`), which is erased at runtime, so importing
|
|
26
|
+
* this file pulls no components. `environmentSetup.ts` supplies the module (with
|
|
27
|
+
* its step components) and re-exports the journey + the launch handle + the
|
|
28
|
+
* persistence adapter.
|
|
17
29
|
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export type EnvStep = (typeof ENV_STEP_ORDER)[number]
|
|
30
|
+
import type { ExitCtx } from '@modular-vue/journeys'
|
|
31
|
+
import { defineJourney, defineTransition } from '@modular-vue/journeys'
|
|
32
|
+
import type { environmentSetupModule } from '~/modular/journeys/environmentSetup'
|
|
22
33
|
|
|
23
34
|
/** The single module id every step entry lives under. */
|
|
24
35
|
export const ENV_MODULE_ID = 'cat-factory:environment-setup' as const
|
|
@@ -52,35 +63,91 @@ export function envInitialState(input: EnvSetupInput): EnvSetupState {
|
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
/** First step: skip the picker when the launcher already chose a frame. */
|
|
55
|
-
export function envStartStep(_state: EnvSetupState, input: EnvSetupInput):
|
|
66
|
+
export function envStartStep(_state: EnvSetupState, input: EnvSetupInput): 'pick' | 'review' {
|
|
56
67
|
return input.frameId ? 'review' : 'pick'
|
|
57
68
|
}
|
|
58
69
|
|
|
59
70
|
/**
|
|
60
|
-
* The
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* definition (`environmentSetup.ts`) derives its `advance` transitions' target
|
|
66
|
-
* entries from it, so pinning this function in `environmentSetup.logic.spec.ts`
|
|
67
|
-
* genuinely guards the wired graph against a silent reorder/drop. The overloads
|
|
68
|
-
* narrow the return to a concrete entry (or `'done'`) so a transition handler can
|
|
69
|
-
* feed the result straight into a `StepSpec` without a widened `EnvStep | 'done'`.
|
|
71
|
+
* The journey's module type map — one module, referenced by its `typeof` so the
|
|
72
|
+
* transition + step maps resolve its literal entry/exit vocabulary with no casts.
|
|
73
|
+
* This is the case production-feedback item 3 (modular-react#83) fixed: before it,
|
|
74
|
+
* `defineModule` widened the descriptor, so `typeof environmentSetupModule` could
|
|
75
|
+
* not stand in as a `TModules` member without re-declaring the entry names by hand.
|
|
70
76
|
*/
|
|
71
|
-
export
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
77
|
+
export type EnvModules = { [ENV_MODULE_ID]: typeof environmentSetupModule }
|
|
78
|
+
|
|
79
|
+
/** Binder threading the journey generics into each annotated transition handler. */
|
|
80
|
+
const transition = defineTransition<EnvModules, EnvSetupState>()
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The journey definition. `start` skips the picker when a frame was preselected.
|
|
84
|
+
* The forward chain is the annotated transitions' `targets`: pick →(select)→
|
|
85
|
+
* review →(advance)→ preflight →(advance)→ save →(advance)→ complete. Back
|
|
86
|
+
* navigation is handled by the entries' `allowBack` (declared on the module in
|
|
87
|
+
* `environmentSetup.ts`), not explicit transitions.
|
|
88
|
+
*/
|
|
89
|
+
export const environmentSetupJourney = defineJourney<EnvModules, EnvSetupState>()({
|
|
90
|
+
id: 'environment-setup',
|
|
91
|
+
version: '1.0.0',
|
|
92
|
+
initialState: (input: EnvSetupInput) => envInitialState(input),
|
|
93
|
+
start: (state, input: EnvSetupInput) =>
|
|
94
|
+
envStartStep(state, input) === 'review'
|
|
95
|
+
? { module: ENV_MODULE_ID, entry: 'review', input: { frameId: state.frameId } }
|
|
96
|
+
: { module: ENV_MODULE_ID, entry: 'pick', input: { frameId: state.frameId } },
|
|
97
|
+
steps: {
|
|
98
|
+
[ENV_MODULE_ID]: {
|
|
99
|
+
pick: { progressLabel: 'environmentWizard.steps.pick' },
|
|
100
|
+
review: { progressLabel: 'environmentWizard.steps.review' },
|
|
101
|
+
preflight: { progressLabel: 'environmentWizard.steps.preflight' },
|
|
102
|
+
save: { progressLabel: 'environmentWizard.steps.save' },
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
transitions: {
|
|
106
|
+
[ENV_MODULE_ID]: {
|
|
107
|
+
pick: {
|
|
108
|
+
[ENV_SELECT_EXIT]: transition({
|
|
109
|
+
targets: [{ module: ENV_MODULE_ID, entry: 'review' }],
|
|
110
|
+
handle: (ctx: ExitCtx<EnvSetupState, EnvSelectOutput, unknown>) => ({
|
|
111
|
+
next: {
|
|
112
|
+
module: ENV_MODULE_ID,
|
|
113
|
+
entry: 'review',
|
|
114
|
+
input: { frameId: ctx.output.frameId },
|
|
115
|
+
},
|
|
116
|
+
state: { frameId: ctx.output.frameId },
|
|
117
|
+
}),
|
|
118
|
+
}),
|
|
119
|
+
},
|
|
120
|
+
review: {
|
|
121
|
+
[ENV_ADVANCE_EXIT]: transition({
|
|
122
|
+
targets: [{ module: ENV_MODULE_ID, entry: 'preflight' }],
|
|
123
|
+
handle: (ctx) => ({
|
|
124
|
+
next: {
|
|
125
|
+
module: ENV_MODULE_ID,
|
|
126
|
+
entry: 'preflight',
|
|
127
|
+
input: { frameId: ctx.state.frameId },
|
|
128
|
+
},
|
|
129
|
+
}),
|
|
130
|
+
}),
|
|
131
|
+
},
|
|
132
|
+
preflight: {
|
|
133
|
+
[ENV_ADVANCE_EXIT]: transition({
|
|
134
|
+
targets: [{ module: ENV_MODULE_ID, entry: 'save' }],
|
|
135
|
+
handle: (ctx) => ({
|
|
136
|
+
next: {
|
|
137
|
+
module: ENV_MODULE_ID,
|
|
138
|
+
entry: 'save',
|
|
139
|
+
input: { frameId: ctx.state.frameId },
|
|
140
|
+
},
|
|
141
|
+
}),
|
|
142
|
+
}),
|
|
143
|
+
},
|
|
144
|
+
// `save` advances to journey completion.
|
|
145
|
+
save: {
|
|
146
|
+
[ENV_ADVANCE_EXIT]: transition({
|
|
147
|
+
targets: ['complete'],
|
|
148
|
+
handle: () => ({ complete: undefined }),
|
|
149
|
+
}),
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineModule } from '@modular-vue/core'
|
|
2
2
|
import { defineExit } from '@modular-frontend/core'
|
|
3
|
-
import {
|
|
3
|
+
import { defineJourneyHandle } from '@modular-vue/journeys'
|
|
4
4
|
import EnvPickStep from '~/components/environments/steps/EnvPickStep.vue'
|
|
5
5
|
import EnvReviewStep from '~/components/environments/steps/EnvReviewStep.vue'
|
|
6
6
|
import EnvPreflightStep from '~/components/environments/steps/EnvPreflightStep.vue'
|
|
@@ -13,9 +13,7 @@ import {
|
|
|
13
13
|
type EnvSelectOutput,
|
|
14
14
|
type EnvSetupInput,
|
|
15
15
|
type EnvSetupState,
|
|
16
|
-
|
|
17
|
-
envNextAfter,
|
|
18
|
-
envStartStep,
|
|
16
|
+
environmentSetupJourney,
|
|
19
17
|
} from '~/modular/journeys/environmentSetup.logic'
|
|
20
18
|
|
|
21
19
|
/**
|
|
@@ -25,6 +23,13 @@ import {
|
|
|
25
23
|
* with a typed, back/rewind-capable, resumable journey; the per-step data + async
|
|
26
24
|
* actions stay in that Pinia store, driven by the step components below.
|
|
27
25
|
*
|
|
26
|
+
* This file supplies the step MODULE (it imports the step `.vue` components, so —
|
|
27
|
+
* like `result-views.ts` — it's registered from the client plugin, keeping the
|
|
28
|
+
* unit-tested `registry.ts` / `*.logic.ts` import graph free of SFCs) and re-exports
|
|
29
|
+
* the JOURNEY, whose transition graph + step metadata live in the SFC-free
|
|
30
|
+
* `environmentSetup.logic.ts` (so `resolveStepSequence` / `useJourneyProgress` and
|
|
31
|
+
* the ordering test have no `.vue` dependency).
|
|
32
|
+
*
|
|
28
33
|
* Authoring notes (co-evolution): `defineModule` comes from the `@modular-vue/core`
|
|
29
34
|
* binding, but the exit helper `defineExit` is only exported from the neutral
|
|
30
35
|
* `@modular-frontend/core` engine (a direct dep) — the Vue binding doesn't re-export
|
|
@@ -36,10 +41,6 @@ import {
|
|
|
36
41
|
* pick step and never changes mid-flow, so the snapshot input a transition places is
|
|
37
42
|
* always current — even on `preserve-state` back-navigation — which keeps the module
|
|
38
43
|
* type simple (no `buildInput`-optionality quirk) and the flow fully explicit.
|
|
39
|
-
*
|
|
40
|
-
* This file imports the step `.vue` components, so — like `result-views.ts` — it's
|
|
41
|
-
* registered from the client plugin, keeping the unit-tested `registry.ts` /
|
|
42
|
-
* `*.logic.ts` import graph free of SFCs.
|
|
43
44
|
*/
|
|
44
45
|
|
|
45
46
|
/**
|
|
@@ -52,20 +53,20 @@ export const environmentSetupModule = defineModule({
|
|
|
52
53
|
id: ENV_MODULE_ID,
|
|
53
54
|
version: '1.0.0',
|
|
54
55
|
entryPoints: {
|
|
55
|
-
pick: { mountKinds: ['journey']
|
|
56
|
+
pick: { mountKinds: ['journey'], component: EnvPickStep },
|
|
56
57
|
review: {
|
|
57
|
-
mountKinds: ['journey']
|
|
58
|
-
allowBack: 'preserve-state'
|
|
58
|
+
mountKinds: ['journey'],
|
|
59
|
+
allowBack: 'preserve-state',
|
|
59
60
|
component: EnvReviewStep,
|
|
60
61
|
},
|
|
61
62
|
preflight: {
|
|
62
|
-
mountKinds: ['journey']
|
|
63
|
-
allowBack: 'preserve-state'
|
|
63
|
+
mountKinds: ['journey'],
|
|
64
|
+
allowBack: 'preserve-state',
|
|
64
65
|
component: EnvPreflightStep,
|
|
65
66
|
},
|
|
66
67
|
save: {
|
|
67
|
-
mountKinds: ['journey']
|
|
68
|
-
allowBack: 'preserve-state'
|
|
68
|
+
mountKinds: ['journey'],
|
|
69
|
+
allowBack: 'preserve-state',
|
|
69
70
|
component: EnvSaveStep,
|
|
70
71
|
},
|
|
71
72
|
},
|
|
@@ -75,59 +76,7 @@ export const environmentSetupModule = defineModule({
|
|
|
75
76
|
},
|
|
76
77
|
})
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* The journey definition. `start` skips the picker when a frame was preselected;
|
|
82
|
-
* transitions are the linear pick → review → preflight → save chain, terminating
|
|
83
|
-
* with `complete` off the save step's `advance`. Back-navigation is handled by the
|
|
84
|
-
* entries' `allowBack`, not explicit transitions.
|
|
85
|
-
*/
|
|
86
|
-
export const environmentSetupJourney = defineJourney<EnvModules, EnvSetupState>()({
|
|
87
|
-
id: 'environment-setup',
|
|
88
|
-
version: '1.0.0',
|
|
89
|
-
initialState: (input: EnvSetupInput) => envInitialState(input),
|
|
90
|
-
start: (state, input: EnvSetupInput) =>
|
|
91
|
-
envStartStep(state, input) === 'review'
|
|
92
|
-
? ({ module: ENV_MODULE_ID, entry: 'review', input: { frameId: state.frameId } } as const)
|
|
93
|
-
: ({ module: ENV_MODULE_ID, entry: 'pick', input: { frameId: state.frameId } } as const),
|
|
94
|
-
transitions: {
|
|
95
|
-
[ENV_MODULE_ID]: {
|
|
96
|
-
pick: {
|
|
97
|
-
[ENV_SELECT_EXIT]: (ctx) => ({
|
|
98
|
-
next: {
|
|
99
|
-
module: ENV_MODULE_ID,
|
|
100
|
-
entry: 'review',
|
|
101
|
-
input: { frameId: ctx.output.frameId },
|
|
102
|
-
} as const,
|
|
103
|
-
state: { frameId: ctx.output.frameId },
|
|
104
|
-
}),
|
|
105
|
-
},
|
|
106
|
-
review: {
|
|
107
|
-
[ENV_ADVANCE_EXIT]: (ctx) => ({
|
|
108
|
-
next: {
|
|
109
|
-
module: ENV_MODULE_ID,
|
|
110
|
-
entry: envNextAfter('review'),
|
|
111
|
-
input: { frameId: ctx.state.frameId },
|
|
112
|
-
} as const,
|
|
113
|
-
}),
|
|
114
|
-
},
|
|
115
|
-
preflight: {
|
|
116
|
-
[ENV_ADVANCE_EXIT]: (ctx) => ({
|
|
117
|
-
next: {
|
|
118
|
-
module: ENV_MODULE_ID,
|
|
119
|
-
entry: envNextAfter('preflight'),
|
|
120
|
-
input: { frameId: ctx.state.frameId },
|
|
121
|
-
} as const,
|
|
122
|
-
}),
|
|
123
|
-
},
|
|
124
|
-
// `save` advances to `envNextAfter('save') === 'done'`, i.e. journey completion.
|
|
125
|
-
save: {
|
|
126
|
-
[ENV_ADVANCE_EXIT]: () => ({ complete: undefined }),
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
})
|
|
79
|
+
export { environmentSetupJourney }
|
|
131
80
|
|
|
132
81
|
/** Typed launch handle — callers `runtime.start(handle, { frameId })`. */
|
|
133
82
|
export const environmentSetupHandle = defineJourneyHandle(environmentSetupJourney)
|
package/app/types/execution.ts
CHANGED
package/i18n/locales/de.json
CHANGED
|
@@ -4808,6 +4808,7 @@
|
|
|
4808
4808
|
}
|
|
4809
4809
|
},
|
|
4810
4810
|
"environmentWizard": {
|
|
4811
|
+
"progress": "Schritt {index} von {total}",
|
|
4811
4812
|
"title": "Eine Testumgebung einrichten",
|
|
4812
4813
|
"subtitle": "Erkenne, prüfe und speichere ein Docker-Compose-Rezept, damit der Deployer es bereitstellt.",
|
|
4813
4814
|
"recommended": "empfohlen",
|
|
@@ -4953,6 +4954,15 @@
|
|
|
4953
4954
|
"title": "Review-Kommentare werden gepostet…",
|
|
4954
4955
|
"hint": "Die ausgewählten Befunde werden als Inline-Kommentare im Pull Request veröffentlicht."
|
|
4955
4956
|
},
|
|
4957
|
+
"postReport": {
|
|
4958
|
+
"heading": "Ergebnis der Veröffentlichung",
|
|
4959
|
+
"posted": "{posted} von {attempted} Kommentaren veröffentlicht",
|
|
4960
|
+
"folded": "Zur Zusammenfassung hinzugefügt (keine Zeile im Diff zum Verankern): {count}",
|
|
4961
|
+
"failuresHeading": "Diese Kommentare konnten nicht veröffentlicht werden:",
|
|
4962
|
+
"bodyError": "Der Zusammenfassungskommentar konnte nicht veröffentlicht werden: {error}",
|
|
4963
|
+
"postedBadge": "Veröffentlicht",
|
|
4964
|
+
"retry": "Erneut veröffentlichen"
|
|
4965
|
+
},
|
|
4956
4966
|
"severity": {
|
|
4957
4967
|
"blocker": "Blocker",
|
|
4958
4968
|
"high": "Hoch",
|
package/i18n/locales/en.json
CHANGED
|
@@ -4941,6 +4941,7 @@
|
|
|
4941
4941
|
}
|
|
4942
4942
|
},
|
|
4943
4943
|
"environmentWizard": {
|
|
4944
|
+
"progress": "Step {index} of {total}",
|
|
4944
4945
|
"title": "Set up a test environment",
|
|
4945
4946
|
"subtitle": "Detect, review, and save a Docker Compose recipe so the Deployer provisions it.",
|
|
4946
4947
|
"recommended": "recommended",
|
|
@@ -5082,6 +5083,15 @@
|
|
|
5082
5083
|
"title": "Posting review comments…",
|
|
5083
5084
|
"hint": "Publishing the selected findings as inline comments on the pull request."
|
|
5084
5085
|
},
|
|
5086
|
+
"postReport": {
|
|
5087
|
+
"heading": "Posting result",
|
|
5088
|
+
"posted": "{posted} of {attempted} comments posted",
|
|
5089
|
+
"folded": "Added to the summary (no in-diff line to anchor to): {count}",
|
|
5090
|
+
"failuresHeading": "Could not post these comments:",
|
|
5091
|
+
"bodyError": "The summary comment failed to post: {error}",
|
|
5092
|
+
"postedBadge": "Posted",
|
|
5093
|
+
"retry": "Retry posting"
|
|
5094
|
+
},
|
|
5085
5095
|
"severity": {
|
|
5086
5096
|
"blocker": "Blocker",
|
|
5087
5097
|
"high": "High",
|
package/i18n/locales/es.json
CHANGED
|
@@ -4800,6 +4800,7 @@
|
|
|
4800
4800
|
}
|
|
4801
4801
|
},
|
|
4802
4802
|
"environmentWizard": {
|
|
4803
|
+
"progress": "Paso {index} de {total}",
|
|
4803
4804
|
"title": "Configurar un entorno de pruebas",
|
|
4804
4805
|
"subtitle": "Detecta, revisa y guarda una receta de Docker Compose para que el Deployer la aprovisione.",
|
|
4805
4806
|
"recommended": "recomendado",
|
|
@@ -4941,6 +4942,15 @@
|
|
|
4941
4942
|
"title": "Publicando comentarios de revisión…",
|
|
4942
4943
|
"hint": "Publicando los hallazgos seleccionados como comentarios en línea en el pull request."
|
|
4943
4944
|
},
|
|
4945
|
+
"postReport": {
|
|
4946
|
+
"heading": "Resultado de la publicación",
|
|
4947
|
+
"posted": "{posted} de {attempted} comentarios publicados",
|
|
4948
|
+
"folded": "Añadidos al resumen (sin línea en el diff donde anclar): {count}",
|
|
4949
|
+
"failuresHeading": "No se pudieron publicar estos comentarios:",
|
|
4950
|
+
"bodyError": "No se pudo publicar el comentario de resumen: {error}",
|
|
4951
|
+
"postedBadge": "Publicado",
|
|
4952
|
+
"retry": "Reintentar publicación"
|
|
4953
|
+
},
|
|
4944
4954
|
"severity": {
|
|
4945
4955
|
"blocker": "Bloqueante",
|
|
4946
4956
|
"high": "Alta",
|
package/i18n/locales/fr.json
CHANGED
|
@@ -4800,6 +4800,7 @@
|
|
|
4800
4800
|
}
|
|
4801
4801
|
},
|
|
4802
4802
|
"environmentWizard": {
|
|
4803
|
+
"progress": "Étape {index} sur {total}",
|
|
4803
4804
|
"title": "Configurer un environnement de test",
|
|
4804
4805
|
"subtitle": "Détectez, vérifiez et enregistrez une recette Docker Compose pour que le Deployer la provisionne.",
|
|
4805
4806
|
"recommended": "recommandé",
|
|
@@ -4941,6 +4942,15 @@
|
|
|
4941
4942
|
"title": "Publication des commentaires de revue…",
|
|
4942
4943
|
"hint": "Publication des points sélectionnés en commentaires en ligne sur la pull request."
|
|
4943
4944
|
},
|
|
4945
|
+
"postReport": {
|
|
4946
|
+
"heading": "Résultat de la publication",
|
|
4947
|
+
"posted": "{posted} commentaires sur {attempted} publiés",
|
|
4948
|
+
"folded": "Ajoutés au résumé (aucune ligne du diff où les ancrer) : {count}",
|
|
4949
|
+
"failuresHeading": "Impossible de publier ces commentaires :",
|
|
4950
|
+
"bodyError": "Le commentaire de synthèse n'a pas pu être publié : {error}",
|
|
4951
|
+
"postedBadge": "Publié",
|
|
4952
|
+
"retry": "Réessayer la publication"
|
|
4953
|
+
},
|
|
4944
4954
|
"severity": {
|
|
4945
4955
|
"blocker": "Bloquant",
|
|
4946
4956
|
"high": "Élevée",
|
package/i18n/locales/he.json
CHANGED
|
@@ -4811,6 +4811,7 @@
|
|
|
4811
4811
|
}
|
|
4812
4812
|
},
|
|
4813
4813
|
"environmentWizard": {
|
|
4814
|
+
"progress": "שלב {index} מתוך {total}",
|
|
4814
4815
|
"title": "הגדרת סביבת בדיקות",
|
|
4815
4816
|
"subtitle": "זהו, סקרו ושמרו מתכון Docker Compose כדי שה-Deployer יקצה אותו.",
|
|
4816
4817
|
"recommended": "מומלץ",
|
|
@@ -4952,6 +4953,15 @@
|
|
|
4952
4953
|
"title": "מפרסם הערות בדיקה…",
|
|
4953
4954
|
"hint": "מפרסם את הממצאים שנבחרו כהערות מוטבעות בבקשת המשיכה."
|
|
4954
4955
|
},
|
|
4956
|
+
"postReport": {
|
|
4957
|
+
"heading": "תוצאת הפרסום",
|
|
4958
|
+
"posted": "פורסמו {posted} מתוך {attempted} הערות",
|
|
4959
|
+
"folded": "נוספו לסיכום (אין שורה ב-diff לעגן אליה): {count}",
|
|
4960
|
+
"failuresHeading": "לא ניתן היה לפרסם את ההערות הבאות:",
|
|
4961
|
+
"bodyError": "לא ניתן היה לפרסם את הערת הסיכום: {error}",
|
|
4962
|
+
"postedBadge": "פורסם",
|
|
4963
|
+
"retry": "נסה לפרסם שוב"
|
|
4964
|
+
},
|
|
4955
4965
|
"severity": {
|
|
4956
4966
|
"blocker": "חוסם",
|
|
4957
4967
|
"high": "גבוה",
|
package/i18n/locales/it.json
CHANGED
|
@@ -4808,6 +4808,7 @@
|
|
|
4808
4808
|
}
|
|
4809
4809
|
},
|
|
4810
4810
|
"environmentWizard": {
|
|
4811
|
+
"progress": "Passaggio {index} di {total}",
|
|
4811
4812
|
"title": "Configura un ambiente di test",
|
|
4812
4813
|
"subtitle": "Rileva, rivedi e salva una ricetta Docker Compose in modo che il Deployer la esegua.",
|
|
4813
4814
|
"recommended": "consigliato",
|
|
@@ -4953,6 +4954,15 @@
|
|
|
4953
4954
|
"title": "Pubblicazione dei commenti di revisione…",
|
|
4954
4955
|
"hint": "Pubblicazione dei rilievi selezionati come commenti inline sulla pull request."
|
|
4955
4956
|
},
|
|
4957
|
+
"postReport": {
|
|
4958
|
+
"heading": "Esito della pubblicazione",
|
|
4959
|
+
"posted": "{posted} di {attempted} commenti pubblicati",
|
|
4960
|
+
"folded": "Aggiunti al riepilogo (nessuna riga nel diff a cui ancorarli): {count}",
|
|
4961
|
+
"failuresHeading": "Impossibile pubblicare questi commenti:",
|
|
4962
|
+
"bodyError": "Impossibile pubblicare il commento di riepilogo: {error}",
|
|
4963
|
+
"postedBadge": "Pubblicato",
|
|
4964
|
+
"retry": "Riprova la pubblicazione"
|
|
4965
|
+
},
|
|
4956
4966
|
"severity": {
|
|
4957
4967
|
"blocker": "Bloccante",
|
|
4958
4968
|
"high": "Alta",
|
package/i18n/locales/ja.json
CHANGED
|
@@ -4812,6 +4812,7 @@
|
|
|
4812
4812
|
}
|
|
4813
4813
|
},
|
|
4814
4814
|
"environmentWizard": {
|
|
4815
|
+
"progress": "ステップ {index} / {total}",
|
|
4815
4816
|
"title": "テスト環境をセットアップ",
|
|
4816
4817
|
"subtitle": "Docker Compose レシピを検出・確認・保存して、Deployer がプロビジョニングできるようにします。",
|
|
4817
4818
|
"recommended": "推奨",
|
|
@@ -4953,6 +4954,15 @@
|
|
|
4953
4954
|
"title": "レビューコメントを投稿中…",
|
|
4954
4955
|
"hint": "選択した指摘をプルリクエストのインラインコメントとして公開しています。"
|
|
4955
4956
|
},
|
|
4957
|
+
"postReport": {
|
|
4958
|
+
"heading": "投稿結果",
|
|
4959
|
+
"posted": "{attempted} 件中 {posted} 件のコメントを投稿しました",
|
|
4960
|
+
"folded": "差分に対応する行がないため要約に追加: {count}",
|
|
4961
|
+
"failuresHeading": "次のコメントを投稿できませんでした:",
|
|
4962
|
+
"bodyError": "要約コメントを投稿できませんでした: {error}",
|
|
4963
|
+
"postedBadge": "投稿済み",
|
|
4964
|
+
"retry": "投稿を再試行"
|
|
4965
|
+
},
|
|
4956
4966
|
"severity": {
|
|
4957
4967
|
"blocker": "ブロッカー",
|
|
4958
4968
|
"high": "高",
|
package/i18n/locales/pl.json
CHANGED
|
@@ -4800,6 +4800,7 @@
|
|
|
4800
4800
|
}
|
|
4801
4801
|
},
|
|
4802
4802
|
"environmentWizard": {
|
|
4803
|
+
"progress": "Krok {index} z {total}",
|
|
4803
4804
|
"title": "Skonfiguruj środowisko testowe",
|
|
4804
4805
|
"subtitle": "Wykryj, przejrzyj i zapisz przepis Docker Compose, aby Deployer go udostępnił.",
|
|
4805
4806
|
"recommended": "zalecane",
|
|
@@ -4941,6 +4942,15 @@
|
|
|
4941
4942
|
"title": "Publikowanie komentarzy przeglądu…",
|
|
4942
4943
|
"hint": "Publikowanie wybranych uwag jako komentarzy w treści pull requesta."
|
|
4943
4944
|
},
|
|
4945
|
+
"postReport": {
|
|
4946
|
+
"heading": "Wynik publikacji",
|
|
4947
|
+
"posted": "Opublikowano {posted} z {attempted} komentarzy",
|
|
4948
|
+
"folded": "Dodano do podsumowania (brak wiersza w różnicy do zakotwiczenia): {count}",
|
|
4949
|
+
"failuresHeading": "Nie udało się opublikować tych komentarzy:",
|
|
4950
|
+
"bodyError": "Nie udało się opublikować komentarza podsumowującego: {error}",
|
|
4951
|
+
"postedBadge": "Opublikowano",
|
|
4952
|
+
"retry": "Ponów publikację"
|
|
4953
|
+
},
|
|
4944
4954
|
"severity": {
|
|
4945
4955
|
"blocker": "Blokujące",
|
|
4946
4956
|
"high": "Wysokie",
|
package/i18n/locales/tr.json
CHANGED
|
@@ -4812,6 +4812,7 @@
|
|
|
4812
4812
|
}
|
|
4813
4813
|
},
|
|
4814
4814
|
"environmentWizard": {
|
|
4815
|
+
"progress": "Adım {index} / {total}",
|
|
4815
4816
|
"title": "Bir test ortamı kur",
|
|
4816
4817
|
"subtitle": "Deployer sağlasın diye bir Docker Compose tarifini algıla, gözden geçir ve kaydet.",
|
|
4817
4818
|
"recommended": "önerilen",
|
|
@@ -4953,6 +4954,15 @@
|
|
|
4953
4954
|
"title": "İnceleme yorumları gönderiliyor…",
|
|
4954
4955
|
"hint": "Seçili bulgular pull request üzerinde satır içi yorum olarak yayımlanıyor."
|
|
4955
4956
|
},
|
|
4957
|
+
"postReport": {
|
|
4958
|
+
"heading": "Gönderim sonucu",
|
|
4959
|
+
"posted": "{attempted} yorumdan {posted} tanesi gönderildi",
|
|
4960
|
+
"folded": "Özete eklendi (diff'te tutturulacak satır yok): {count}",
|
|
4961
|
+
"failuresHeading": "Bu yorumlar gönderilemedi:",
|
|
4962
|
+
"bodyError": "Özet yorumu gönderilemedi: {error}",
|
|
4963
|
+
"postedBadge": "Gönderildi",
|
|
4964
|
+
"retry": "Gönderimi yeniden dene"
|
|
4965
|
+
},
|
|
4956
4966
|
"severity": {
|
|
4957
4967
|
"blocker": "Engelleyici",
|
|
4958
4968
|
"high": "Yüksek",
|
package/i18n/locales/uk.json
CHANGED
|
@@ -4800,6 +4800,7 @@
|
|
|
4800
4800
|
}
|
|
4801
4801
|
},
|
|
4802
4802
|
"environmentWizard": {
|
|
4803
|
+
"progress": "Крок {index} з {total}",
|
|
4803
4804
|
"title": "Налаштувати тестове середовище",
|
|
4804
4805
|
"subtitle": "Виявіть, перегляньте та збережіть рецепт Docker Compose, щоб Deployer його забезпечив.",
|
|
4805
4806
|
"recommended": "рекомендовано",
|
|
@@ -4941,6 +4942,15 @@
|
|
|
4941
4942
|
"title": "Публікація коментарів огляду…",
|
|
4942
4943
|
"hint": "Публікація вибраних зауважень як вбудованих коментарів у pull request."
|
|
4943
4944
|
},
|
|
4945
|
+
"postReport": {
|
|
4946
|
+
"heading": "Результат публікації",
|
|
4947
|
+
"posted": "Опубліковано {posted} з {attempted} коментарів",
|
|
4948
|
+
"folded": "Додано до підсумку (немає рядка в різниці для прив'язки): {count}",
|
|
4949
|
+
"failuresHeading": "Не вдалося опублікувати ці коментарі:",
|
|
4950
|
+
"bodyError": "Не вдалося опублікувати підсумковий коментар: {error}",
|
|
4951
|
+
"postedBadge": "Опубліковано",
|
|
4952
|
+
"retry": "Повторити публікацію"
|
|
4953
|
+
},
|
|
4944
4954
|
"severity": {
|
|
4945
4955
|
"blocker": "Блокер",
|
|
4946
4956
|
"high": "Високий",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.146.1",
|
|
4
4
|
"description": "Reusable Nuxt layer for the Agent Architecture Board SPA (components, stores, composables, pages). Consume it from a thin deployment app via `extends: ['@cat-factory/app']` and point it at your backend with NUXT_PUBLIC_API_BASE. See deploy/frontend for an example.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"access": "public"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@modular-frontend/core": "^0.
|
|
22
|
-
"@modular-vue/core": "^1.
|
|
23
|
-
"@modular-vue/journeys": "^1.
|
|
21
|
+
"@modular-frontend/core": "^0.6.0",
|
|
22
|
+
"@modular-vue/core": "^1.5.0",
|
|
23
|
+
"@modular-vue/journeys": "^1.4.0",
|
|
24
24
|
"@modular-vue/nuxt": "^0.4.0",
|
|
25
25
|
"@modular-vue/runtime": "^1.4.1",
|
|
26
26
|
"@modular-vue/vue": "^1.4.0",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"valibot": "^1.4.2",
|
|
41
41
|
"vue": "3.5.40",
|
|
42
42
|
"wretch": "^3.0.9",
|
|
43
|
-
"@cat-factory/contracts": "0.152.
|
|
43
|
+
"@cat-factory/contracts": "0.152.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@toad-contracts/testing": "0.3.2",
|