@cat-factory/app 0.162.0 → 0.162.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/panels/AgentStepDetail.vue +58 -6
- package/app/components/panels/inspector/TaskExecution.vue +25 -1
- package/app/components/pipeline/PipelineProgress.vue +13 -3
- package/app/composables/useStepApproval.ts +10 -9
- package/app/stores/execution/commands.ts +47 -16
- package/app/stores/ui/resultViews.ts +5 -1
- package/app/utils/pipelineRender.spec.ts +72 -0
- package/app/utils/pipelineRender.ts +26 -0
- package/i18n/locales/de.json +9 -1
- package/i18n/locales/en.json +9 -1
- package/i18n/locales/es.json +9 -1
- package/i18n/locales/fr.json +9 -1
- package/i18n/locales/he.json +9 -1
- package/i18n/locales/it.json +9 -1
- package/i18n/locales/ja.json +9 -1
- package/i18n/locales/pl.json +9 -1
- package/i18n/locales/tr.json +9 -1
- package/i18n/locales/uk.json +9 -1
- package/package.json +2 -2
|
@@ -15,6 +15,7 @@ import StepExecutionHistory from '~/components/board/StepExecutionHistory.vue'
|
|
|
15
15
|
import { useStepTimer } from '~/composables/useStepTimer'
|
|
16
16
|
import { useStepProse } from '~/composables/useStepProse'
|
|
17
17
|
import { useStepApproval } from '~/composables/useStepApproval'
|
|
18
|
+
import { dedicatedParkView } from '~/utils/pipelineRender'
|
|
18
19
|
|
|
19
20
|
// Detail overlay for a single pipeline step. Opened by clicking an agent in the
|
|
20
21
|
// inspector list (TaskExecution) or the focus-view pipeline (PipelineProgress) via
|
|
@@ -151,6 +152,25 @@ const approvalId = computed(() => step.value?.approval?.id ?? null)
|
|
|
151
152
|
// approve/request-changes/reject rail, it shows the shared iteration-cap prompt
|
|
152
153
|
// (one more round / proceed / stop & reset), resolved through its own endpoint.
|
|
153
154
|
const companionExceeded = computed(() => approvalPending.value && !!step.value?.companion?.exceeded)
|
|
155
|
+
// A park a DEDICATED window owns (fork choice / follow-up triage): the generic approve
|
|
156
|
+
// resolver refuses these server-side, so the rail is replaced by a redirect to that window.
|
|
157
|
+
// Computed live, since a coder step can park on one WHILE this overlay is already open
|
|
158
|
+
// (the routing in `dispatchStepView` only covers the open click).
|
|
159
|
+
const dedicatedPark = computed(() => (step.value ? dedicatedParkView(step.value) : null))
|
|
160
|
+
/** The generic approve/request-changes/reject rail applies (no dedicated surface owns the park). */
|
|
161
|
+
const genericApprovalPending = computed(
|
|
162
|
+
() => approvalPending.value && !companionExceeded.value && !dedicatedPark.value,
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
/** Jump from this overlay to the window that can actually resolve the dedicated park. */
|
|
166
|
+
function openDedicatedWindow() {
|
|
167
|
+
const c = ctx.value
|
|
168
|
+
const park = dedicatedPark.value
|
|
169
|
+
if (!c || !park) return
|
|
170
|
+
close()
|
|
171
|
+
if (park === 'follow-ups') ui.openFollowUps(c.instanceId, c.stepIndex)
|
|
172
|
+
else ui.openForkDecision(c.instanceId, c.stepIndex)
|
|
173
|
+
}
|
|
154
174
|
|
|
155
175
|
function close() {
|
|
156
176
|
// Reset the approval-mode sub-states so reopening the same step is clean
|
|
@@ -159,13 +179,14 @@ function close() {
|
|
|
159
179
|
ui.closeStepDetail()
|
|
160
180
|
}
|
|
161
181
|
|
|
162
|
-
// The GitHub-style approval/review state machine for a pending gate step.
|
|
182
|
+
// The GitHub-style approval/review state machine for a pending gate step. A park a
|
|
183
|
+
// dedicated window owns is NOT reviewable here, so it doesn't count as pending.
|
|
163
184
|
const approval = useStepApproval({
|
|
164
185
|
step: () => step.value,
|
|
165
186
|
scrollEl: () => scrollEl.value,
|
|
166
187
|
instanceId: () => ctx.value?.instanceId,
|
|
167
188
|
approvalId: () => approvalId.value,
|
|
168
|
-
approvalPending: () => approvalPending.value,
|
|
189
|
+
approvalPending: () => approvalPending.value && !dedicatedPark.value,
|
|
169
190
|
companionExceeded: () => companionExceeded.value,
|
|
170
191
|
close,
|
|
171
192
|
})
|
|
@@ -292,7 +313,7 @@ async function copyOutput() {
|
|
|
292
313
|
</div>
|
|
293
314
|
<div class="ms-auto flex items-center gap-1.5">
|
|
294
315
|
<UBadge
|
|
295
|
-
v-if="
|
|
316
|
+
v-if="genericApprovalPending"
|
|
296
317
|
color="warning"
|
|
297
318
|
variant="subtle"
|
|
298
319
|
size="sm"
|
|
@@ -302,7 +323,7 @@ async function copyOutput() {
|
|
|
302
323
|
{{ t('panels.stepDetail.approvalRequired') }}
|
|
303
324
|
</UBadge>
|
|
304
325
|
<UBadge
|
|
305
|
-
v-else-if="companionExceeded"
|
|
326
|
+
v-else-if="companionExceeded || dedicatedPark"
|
|
306
327
|
color="warning"
|
|
307
328
|
variant="subtle"
|
|
308
329
|
size="sm"
|
|
@@ -396,6 +417,37 @@ async function copyOutput() {
|
|
|
396
417
|
@resolve="resolveCompanionCap"
|
|
397
418
|
/>
|
|
398
419
|
|
|
420
|
+
<!-- a park a dedicated window owns (fork choice / follow-up triage): the
|
|
421
|
+
generic approval rail can't resolve it (the server refuses), so point
|
|
422
|
+
the human at the window that can -->
|
|
423
|
+
<div
|
|
424
|
+
v-if="dedicatedPark"
|
|
425
|
+
class="rounded-xl border border-amber-500/30 bg-amber-500/5 p-4"
|
|
426
|
+
data-testid="dedicated-park-redirect"
|
|
427
|
+
>
|
|
428
|
+
<p class="text-[13px] leading-relaxed text-amber-200/90">
|
|
429
|
+
{{
|
|
430
|
+
dedicatedPark === 'follow-ups'
|
|
431
|
+
? t('panels.stepDetail.followUpsParked')
|
|
432
|
+
: t('panels.stepDetail.forkParked')
|
|
433
|
+
}}
|
|
434
|
+
</p>
|
|
435
|
+
<UButton
|
|
436
|
+
class="mt-3"
|
|
437
|
+
color="primary"
|
|
438
|
+
size="sm"
|
|
439
|
+
:icon="dedicatedPark === 'follow-ups' ? 'i-lucide-compass' : 'i-lucide-git-fork'"
|
|
440
|
+
data-testid="dedicated-park-open"
|
|
441
|
+
@click="openDedicatedWindow"
|
|
442
|
+
>
|
|
443
|
+
{{
|
|
444
|
+
dedicatedPark === 'follow-ups'
|
|
445
|
+
? t('panels.stepDetail.openFollowUps')
|
|
446
|
+
: t('panels.stepDetail.chooseApproach')
|
|
447
|
+
}}
|
|
448
|
+
</UButton>
|
|
449
|
+
</div>
|
|
450
|
+
|
|
399
451
|
<!-- ephemeral environment lifecycle (spinning up / running / shut down /
|
|
400
452
|
errored + the exact error), when this step runs against one -->
|
|
401
453
|
<EnvironmentStatusPanel v-if="stepEnvironment" :environment="stepEnvironment" />
|
|
@@ -545,7 +597,7 @@ async function copyOutput() {
|
|
|
545
597
|
class="reader-prose mt-1 text-[13px] leading-relaxed text-slate-300"
|
|
546
598
|
:class="[
|
|
547
599
|
s.depth > 0 ? 'ps-6' : '',
|
|
548
|
-
|
|
600
|
+
genericApprovalPending && !editing ? 'review-mode' : '',
|
|
549
601
|
]"
|
|
550
602
|
@click="onProseClick"
|
|
551
603
|
v-html="s.bodyHtml"
|
|
@@ -567,7 +619,7 @@ async function copyOutput() {
|
|
|
567
619
|
Approve / Request changes / Reject. A end-side rail on wide screens; a
|
|
568
620
|
bottom sheet (still reachable) below lg, so the gate is always actionable. -->
|
|
569
621
|
<aside
|
|
570
|
-
v-if="
|
|
622
|
+
v-if="genericApprovalPending"
|
|
571
623
|
class="absolute inset-x-0 bottom-0 z-10 flex max-h-[70dvh] flex-col rounded-t-2xl border-t border-slate-700 bg-slate-900/95 shadow-2xl backdrop-blur lg:static lg:inset-auto lg:z-auto lg:max-h-none lg:w-96 lg:shrink-0 lg:rounded-none lg:border-s lg:border-t-0 lg:border-slate-800 lg:bg-slate-900/60 lg:shadow-none lg:backdrop-blur-none"
|
|
572
624
|
>
|
|
573
625
|
<div class="border-b border-slate-800 px-4 py-3">
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
COMPANION_STATE_META,
|
|
7
7
|
isCompanionKind,
|
|
8
8
|
containerPhaseLabel,
|
|
9
|
+
dedicatedParkView,
|
|
9
10
|
} from '~/utils/pipelineRender'
|
|
10
11
|
import AgentFailureCard from '~/components/board/AgentFailureCard.vue'
|
|
11
12
|
import AgentFailureHistory from '~/components/board/AgentFailureHistory.vue'
|
|
@@ -154,6 +155,12 @@ function openForkFor(i: number) {
|
|
|
154
155
|
if (instance.value) ui.openForkDecision(instance.value.id, i)
|
|
155
156
|
}
|
|
156
157
|
|
|
158
|
+
// Open the follow-up triage window for a coder step parked on undecided follow-up items
|
|
159
|
+
// (its dedicated chip — the generic approve resolver refuses this park server-side).
|
|
160
|
+
function openFollowUpsFor(i: number) {
|
|
161
|
+
if (instance.value) ui.openFollowUps(instance.value.id, i)
|
|
162
|
+
}
|
|
163
|
+
|
|
157
164
|
// Open the PR deep-review findings-selection window for a pr-reviewer step parked awaiting
|
|
158
165
|
// a selection (its dedicated chip, mirroring the fork-decision one above).
|
|
159
166
|
function openPrReviewFor(i: number) {
|
|
@@ -425,7 +432,7 @@ async function mergePr() {
|
|
|
425
432
|
v-else-if="
|
|
426
433
|
s.approval &&
|
|
427
434
|
s.approval.status === 'pending' &&
|
|
428
|
-
s
|
|
435
|
+
dedicatedParkView(s) === 'fork-decision'
|
|
429
436
|
"
|
|
430
437
|
color="primary"
|
|
431
438
|
variant="soft"
|
|
@@ -435,6 +442,23 @@ async function mergePr() {
|
|
|
435
442
|
>
|
|
436
443
|
{{ t('inspector.execution.chooseApproach') }}
|
|
437
444
|
</UButton>
|
|
445
|
+
<!-- A coder step parked on undecided follow-up items: triage them (file /
|
|
446
|
+
send back / answer / dismiss) in the dedicated window, not a plain
|
|
447
|
+
approval — the generic approve resolver refuses this park. -->
|
|
448
|
+
<UButton
|
|
449
|
+
v-else-if="
|
|
450
|
+
s.approval &&
|
|
451
|
+
s.approval.status === 'pending' &&
|
|
452
|
+
dedicatedParkView(s) === 'follow-ups'
|
|
453
|
+
"
|
|
454
|
+
color="primary"
|
|
455
|
+
variant="soft"
|
|
456
|
+
size="xs"
|
|
457
|
+
icon="i-lucide-compass"
|
|
458
|
+
@click="openFollowUpsFor(i)"
|
|
459
|
+
>
|
|
460
|
+
{{ t('inspector.execution.triageFollowUps') }}
|
|
461
|
+
</UButton>
|
|
438
462
|
<!-- A pr-reviewer step parked awaiting a finding selection: open the dedicated
|
|
439
463
|
findings-selection window, not the generic approval gate. -->
|
|
440
464
|
<UButton
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
isFailedStep,
|
|
11
11
|
FAILED_STEP_META,
|
|
12
12
|
containerPhaseLabel,
|
|
13
|
+
dedicatedParkView,
|
|
13
14
|
} from '~/utils/pipelineRender'
|
|
14
15
|
import { prReviewPhase } from '~/utils/prReviewProgress'
|
|
15
16
|
import StepMetricsBar from '~/components/observability/StepMetricsBar.vue'
|
|
@@ -74,7 +75,9 @@ function followUpLabel(step: PipelineStep): string {
|
|
|
74
75
|
/** The active fork-decision phase status on a coder step (proposing / awaiting a choice). */
|
|
75
76
|
function forkPhase(step: PipelineStep): 'proposing' | 'awaiting_choice' | null {
|
|
76
77
|
const status = step.forkDecision?.status
|
|
77
|
-
|
|
78
|
+
if (status === 'proposing') return 'proposing'
|
|
79
|
+
// `answering` (a chat reply in flight) still belongs to the fork window's choice phase.
|
|
80
|
+
return status === 'awaiting_choice' || status === 'answering' ? 'awaiting_choice' : null
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
/**
|
|
@@ -670,9 +673,16 @@ const ITEM_ICON: Record<string, string> = {
|
|
|
670
673
|
{{ reviewStageLabel(s.agentKind) }}
|
|
671
674
|
</div>
|
|
672
675
|
|
|
673
|
-
<!-- approval gate: review (and edit) the proposal before continuing
|
|
676
|
+
<!-- approval gate: review (and edit) the proposal before continuing. A park a
|
|
677
|
+
dedicated window owns (fork choice / follow-up triage) renders its own chip
|
|
678
|
+
above instead — the generic approve resolver refuses those server-side. -->
|
|
674
679
|
<div
|
|
675
|
-
v-else-if="
|
|
680
|
+
v-else-if="
|
|
681
|
+
s.approval &&
|
|
682
|
+
s.approval.status === 'pending' &&
|
|
683
|
+
!prReviewAwaiting(s) &&
|
|
684
|
+
!dedicatedParkView(s)
|
|
685
|
+
"
|
|
676
686
|
class="mt-3"
|
|
677
687
|
>
|
|
678
688
|
<UButton
|
|
@@ -100,14 +100,15 @@ export function useStepApproval(opts: {
|
|
|
100
100
|
() => !!feedback.value.trim() || reviewComments.value.length > 0,
|
|
101
101
|
)
|
|
102
102
|
|
|
103
|
-
// Plain approve: accept the agent's proposal verbatim and advance.
|
|
103
|
+
// Plain approve: accept the agent's proposal verbatim and advance. Every action below
|
|
104
|
+
// closes the overlay ONLY when the command actually ran — a server refusal (surfaced as
|
|
105
|
+
// a toast by the store) or a cancelled credential prompt keeps the review open.
|
|
104
106
|
async function approve() {
|
|
105
107
|
const id = opts.approvalId()
|
|
106
108
|
if (!opts.instanceId() || !id || submitting.value) return
|
|
107
109
|
submitting.value = true
|
|
108
110
|
try {
|
|
109
|
-
await execution.approveStep(opts.instanceId()!, id)
|
|
110
|
-
opts.close()
|
|
111
|
+
if (await execution.approveStep(opts.instanceId()!, id)) opts.close()
|
|
111
112
|
} finally {
|
|
112
113
|
submitting.value = false
|
|
113
114
|
}
|
|
@@ -130,8 +131,7 @@ export function useStepApproval(opts: {
|
|
|
130
131
|
if (!opts.instanceId() || !id || submitting.value) return
|
|
131
132
|
submitting.value = true
|
|
132
133
|
try {
|
|
133
|
-
await execution.approveStep(opts.instanceId()!, id, draftProposal.value)
|
|
134
|
-
opts.close()
|
|
134
|
+
if (await execution.approveStep(opts.instanceId()!, id, draftProposal.value)) opts.close()
|
|
135
135
|
} finally {
|
|
136
136
|
submitting.value = false
|
|
137
137
|
}
|
|
@@ -141,7 +141,7 @@ export function useStepApproval(opts: {
|
|
|
141
141
|
if (!opts.instanceId() || !id || submitting.value || !canRequestChanges.value) return
|
|
142
142
|
submitting.value = true
|
|
143
143
|
try {
|
|
144
|
-
await execution.requestStepChanges(opts.instanceId()!, id, {
|
|
144
|
+
const ok = await execution.requestStepChanges(opts.instanceId()!, id, {
|
|
145
145
|
feedback: feedback.value.trim() || undefined,
|
|
146
146
|
comments: reviewComments.value.length
|
|
147
147
|
? reviewComments.value.map((c) => ({
|
|
@@ -152,7 +152,7 @@ export function useStepApproval(opts: {
|
|
|
152
152
|
}))
|
|
153
153
|
: undefined,
|
|
154
154
|
})
|
|
155
|
-
opts.close()
|
|
155
|
+
if (ok) opts.close()
|
|
156
156
|
} finally {
|
|
157
157
|
submitting.value = false
|
|
158
158
|
}
|
|
@@ -168,8 +168,9 @@ export function useStepApproval(opts: {
|
|
|
168
168
|
if (!opts.instanceId() || !id || submitting.value) return
|
|
169
169
|
submitting.value = true
|
|
170
170
|
try {
|
|
171
|
-
await execution.rejectStep(opts.instanceId()!, id, feedback.value.trim() || undefined)
|
|
172
|
-
|
|
171
|
+
if (await execution.rejectStep(opts.instanceId()!, id, feedback.value.trim() || undefined)) {
|
|
172
|
+
opts.close()
|
|
173
|
+
}
|
|
173
174
|
} finally {
|
|
174
175
|
submitting.value = false
|
|
175
176
|
rejectArmed.value = false
|
|
@@ -69,35 +69,66 @@ export function createExecutionCommands(ctx: ExecutionCommandContext) {
|
|
|
69
69
|
})
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
/**
|
|
73
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Approve a step's gated proposal (optionally edited); the run advances. Returns false —
|
|
74
|
+
* with the failure surfaced as an actionable toast — when the server refused (e.g. a 409
|
|
75
|
+
* for a park a dedicated window owns) or the user cancelled the credential prompt, so the
|
|
76
|
+
* approval rail can stay open instead of closing over a silently-failed approve.
|
|
77
|
+
*/
|
|
78
|
+
async function approveStep(
|
|
79
|
+
instanceId: string,
|
|
80
|
+
approvalId: string,
|
|
81
|
+
proposal?: string,
|
|
82
|
+
): Promise<boolean> {
|
|
74
83
|
const ws = useWorkspaceStore()
|
|
75
84
|
const personal = usePersonalSubscriptionsStore()
|
|
76
|
-
|
|
77
|
-
await
|
|
78
|
-
|
|
79
|
-
|
|
85
|
+
try {
|
|
86
|
+
return await personal.withCredential(async (password) => {
|
|
87
|
+
await api.approveStep(ws.requireId(), instanceId, approvalId, { proposal }, password)
|
|
88
|
+
await ws.refresh()
|
|
89
|
+
})
|
|
90
|
+
} catch (e) {
|
|
91
|
+
runErrors.present(e, 'errors.action.approveFailed')
|
|
92
|
+
return false
|
|
93
|
+
}
|
|
80
94
|
}
|
|
81
95
|
|
|
82
|
-
/** Request changes on a gated proposal; the step re-runs with the review.
|
|
96
|
+
/** Request changes on a gated proposal; the step re-runs with the review. Returns false
|
|
97
|
+
* (with a toast) on refusal / a cancelled credential prompt, like {@link approveStep}. */
|
|
83
98
|
async function requestStepChanges(
|
|
84
99
|
instanceId: string,
|
|
85
100
|
approvalId: string,
|
|
86
101
|
review: RequestStepChangesInput,
|
|
87
|
-
) {
|
|
102
|
+
): Promise<boolean> {
|
|
88
103
|
const ws = useWorkspaceStore()
|
|
89
104
|
const personal = usePersonalSubscriptionsStore()
|
|
90
|
-
|
|
91
|
-
await
|
|
92
|
-
|
|
93
|
-
|
|
105
|
+
try {
|
|
106
|
+
return await personal.withCredential(async (password) => {
|
|
107
|
+
await api.requestStepChanges(ws.requireId(), instanceId, approvalId, review, password)
|
|
108
|
+
await ws.refresh()
|
|
109
|
+
})
|
|
110
|
+
} catch (e) {
|
|
111
|
+
runErrors.present(e, 'errors.action.requestChangesFailed')
|
|
112
|
+
return false
|
|
113
|
+
}
|
|
94
114
|
}
|
|
95
115
|
|
|
96
|
-
/** Reject a gated proposal; the run stops entirely (a retryable failure).
|
|
97
|
-
|
|
116
|
+
/** Reject a gated proposal; the run stops entirely (a retryable failure). Returns false
|
|
117
|
+
* (with a toast) when the server refused. */
|
|
118
|
+
async function rejectStep(
|
|
119
|
+
instanceId: string,
|
|
120
|
+
approvalId: string,
|
|
121
|
+
reason?: string,
|
|
122
|
+
): Promise<boolean> {
|
|
98
123
|
const ws = useWorkspaceStore()
|
|
99
|
-
|
|
100
|
-
|
|
124
|
+
try {
|
|
125
|
+
await api.rejectStep(ws.requireId(), instanceId, approvalId, { reason })
|
|
126
|
+
await ws.refresh()
|
|
127
|
+
return true
|
|
128
|
+
} catch (e) {
|
|
129
|
+
runErrors.present(e, 'errors.action.rejectFailed')
|
|
130
|
+
return false
|
|
131
|
+
}
|
|
101
132
|
}
|
|
102
133
|
|
|
103
134
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ref } from 'vue'
|
|
2
2
|
import { useExecutionStore } from '~/stores/execution'
|
|
3
3
|
import { agentKindMeta } from '~/utils/catalog'
|
|
4
|
+
import { dedicatedParkView } from '~/utils/pipelineRender'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* The step-inspection / result-view slice of the UI store: the dedicated result-view overlay
|
|
@@ -73,12 +74,15 @@ export function createUiResultViews() {
|
|
|
73
74
|
// A step carrying a PR deep-review parks with BOTH a pending approval and
|
|
74
75
|
// `prReview.status`, so the generic approval button funnels here; route it to the
|
|
75
76
|
// findings-selection window regardless of catalog/manifest state (mirrors consensus).
|
|
77
|
+
// Likewise a coder parked on the implementation-fork choice or on undecided follow-up
|
|
78
|
+
// items: those parks ride `step.approval` too, but the generic approve resolver refuses
|
|
79
|
+
// them server-side, so the step must open the window that CAN resolve it.
|
|
76
80
|
const view = step?.consensus?.enabled
|
|
77
81
|
? 'consensus-session'
|
|
78
82
|
: step?.prReview
|
|
79
83
|
? 'pr-review'
|
|
80
84
|
: step
|
|
81
|
-
? agentKindMeta(step.agentKind).resultView
|
|
85
|
+
? (dedicatedParkView(step) ?? agentKindMeta(step.agentKind).resultView)
|
|
82
86
|
: undefined
|
|
83
87
|
if (view && instance) {
|
|
84
88
|
// The brainstorm window is shared by both stages; carry which one from the step's kind.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import type { PipelineStep } from '~/types/execution'
|
|
3
|
+
import { dedicatedParkView } from './pipelineRender'
|
|
4
|
+
|
|
5
|
+
/** A minimal coder step; the predicate only reads approval/followUps/forkDecision. */
|
|
6
|
+
const step = (over: Partial<PipelineStep>): PipelineStep =>
|
|
7
|
+
({
|
|
8
|
+
agentKind: 'coder',
|
|
9
|
+
state: 'waiting_decision',
|
|
10
|
+
approval: { id: 'ap_1', status: 'pending', proposal: '' },
|
|
11
|
+
...over,
|
|
12
|
+
}) as PipelineStep
|
|
13
|
+
|
|
14
|
+
const followUps = (statuses: string[]) => ({
|
|
15
|
+
enabled: true,
|
|
16
|
+
items: statuses.map((status, i) => ({
|
|
17
|
+
id: `fu_${i}`,
|
|
18
|
+
kind: 'follow_up',
|
|
19
|
+
title: 't',
|
|
20
|
+
detail: '',
|
|
21
|
+
status,
|
|
22
|
+
createdAt: 0,
|
|
23
|
+
updatedAt: 0,
|
|
24
|
+
})),
|
|
25
|
+
loops: 0,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe('dedicatedParkView', () => {
|
|
29
|
+
// The regression this pins: a coder parked on the follow-up gate (or the fork choice)
|
|
30
|
+
// carries a pending `step.approval`, but the generic approve resolver 409s on it — the
|
|
31
|
+
// surfaces must route these parks to their dedicated window, never the "Approve &
|
|
32
|
+
// proceed" rail.
|
|
33
|
+
it('owns a follow-up park (pending approval + undecided items)', () => {
|
|
34
|
+
expect(
|
|
35
|
+
dedicatedParkView(step({ followUps: followUps(['pending', 'answered']) as never })),
|
|
36
|
+
).toBe('follow-ups')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('does not claim a step whose follow-up items are all decided', () => {
|
|
40
|
+
expect(
|
|
41
|
+
dedicatedParkView(step({ followUps: followUps(['answered', 'dismissed']) as never })),
|
|
42
|
+
).toBeNull()
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('does not claim a WORKING coder that is still streaming items (no approval raised)', () => {
|
|
46
|
+
// Clicking a live step must keep opening the ordinary detail (progress + output).
|
|
47
|
+
expect(
|
|
48
|
+
dedicatedParkView(
|
|
49
|
+
step({ state: 'working', approval: null, followUps: followUps(['pending']) as never }),
|
|
50
|
+
),
|
|
51
|
+
).toBeNull()
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('owns the fork park while awaiting a choice, and while a chat reply is in flight', () => {
|
|
55
|
+
expect(dedicatedParkView(step({ forkDecision: { status: 'awaiting_choice' } as never }))).toBe(
|
|
56
|
+
'fork-decision',
|
|
57
|
+
)
|
|
58
|
+
expect(dedicatedParkView(step({ forkDecision: { status: 'answering' } as never }))).toBe(
|
|
59
|
+
'fork-decision',
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('releases the step once the fork is resolved (chosen / single_path / skipped)', () => {
|
|
64
|
+
for (const status of ['chosen', 'single_path', 'skipped', 'proposing']) {
|
|
65
|
+
expect(dedicatedParkView(step({ forkDecision: { status } as never }))).toBeNull()
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('leaves a plain approval park to the generic rail', () => {
|
|
70
|
+
expect(dedicatedParkView(step({}))).toBeNull()
|
|
71
|
+
})
|
|
72
|
+
})
|
|
@@ -133,6 +133,32 @@ export function isCompanionKind(kind: string): boolean {
|
|
|
133
133
|
)
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
/**
|
|
137
|
+
* The dedicated window that owns a step's approval park, when the park is NOT a generic
|
|
138
|
+
* prose approval: the implementation-fork window while a coder waits on (or chats about)
|
|
139
|
+
* an approach choice, or the follow-up triage window while surfaced items are undecided.
|
|
140
|
+
* The generic approve/request-changes/reject resolvers deliberately refuse these parks
|
|
141
|
+
* server-side (`assertNotIterativeGate`), so every surface that offers a step's pending
|
|
142
|
+
* approval must route these to their window instead of the generic "Approve & proceed"
|
|
143
|
+
* rail — which would blink a 409 and resolve nothing.
|
|
144
|
+
*/
|
|
145
|
+
export function dedicatedParkView(step: PipelineStep): 'follow-ups' | 'fork-decision' | null {
|
|
146
|
+
// The fork park sits BEFORE the coder's build dispatch; `answering` (a chat turn in
|
|
147
|
+
// flight) still belongs to the fork window, which renders the pending reply.
|
|
148
|
+
const fork = step.forkDecision?.status
|
|
149
|
+
if (fork === 'awaiting_choice' || fork === 'answering') return 'fork-decision'
|
|
150
|
+
// Follow-ups only own the park itself: while the coder is still WORKING (streaming
|
|
151
|
+
// items, no approval raised) a step click should keep opening the ordinary detail.
|
|
152
|
+
if (
|
|
153
|
+
step.approval?.status === 'pending' &&
|
|
154
|
+
step.followUps?.enabled &&
|
|
155
|
+
step.followUps.items.some((i) => i.status === 'pending')
|
|
156
|
+
) {
|
|
157
|
+
return 'follow-ups'
|
|
158
|
+
}
|
|
159
|
+
return null
|
|
160
|
+
}
|
|
161
|
+
|
|
136
162
|
/**
|
|
137
163
|
* The friendly label for a container's live phase (clone → "Preparing workspace",
|
|
138
164
|
* agent → "Agent running", …), falling back to the raw phase string for an unknown/new
|
package/i18n/locales/de.json
CHANGED
|
@@ -1298,6 +1298,7 @@
|
|
|
1298
1298
|
"open": "Öffnen",
|
|
1299
1299
|
"mergePr": "PR mergen",
|
|
1300
1300
|
"chooseApproach": "Ansatz wählen",
|
|
1301
|
+
"triageFollowUps": "Folgeaufgaben entscheiden",
|
|
1301
1302
|
"elapsedTooltip": "Verstrichene Zeit für diesen Schritt",
|
|
1302
1303
|
"reviewFindings": "Befunde prüfen"
|
|
1303
1304
|
},
|
|
@@ -1531,6 +1532,10 @@
|
|
|
1531
1532
|
"details": "Details",
|
|
1532
1533
|
"approvalRequired": "Freigabe erforderlich",
|
|
1533
1534
|
"decisionRequired": "Entscheidung erforderlich",
|
|
1535
|
+
"followUpsParked": "Der Coder hat Folgeaufgaben aufgeworfen, die entschieden werden müssen, bevor der Lauf fortgesetzt werden kann. Bearbeite jeden Punkt (anlegen, zurückgeben, beantworten oder verwerfen) im Folgeaufgaben-Fenster.",
|
|
1536
|
+
"forkParked": "Dieser Coder-Schritt wartet darauf, dass ein Implementierungsansatz gewählt wird, bevor Code geschrieben wird. Wähle einen vorgeschlagenen Ansatz (oder gib einen eigenen ein) im Entscheidungsfenster.",
|
|
1537
|
+
"openFollowUps": "Folgeaufgaben öffnen",
|
|
1538
|
+
"chooseApproach": "Ansatz wählen",
|
|
1534
1539
|
"expandAll": "Alle Abschnitte ausklappen",
|
|
1535
1540
|
"collapseAll": "Alle Abschnitte einklappen",
|
|
1536
1541
|
"copyRawOutput": "Rohausgabe kopieren",
|
|
@@ -4231,7 +4236,10 @@
|
|
|
4231
4236
|
"retryFailed": "Wiederholung fehlgeschlagen",
|
|
4232
4237
|
"startFailed": "Start fehlgeschlagen",
|
|
4233
4238
|
"mergeFailed": "Zusammenführen fehlgeschlagen",
|
|
4234
|
-
"restartFailed": "Neustart fehlgeschlagen"
|
|
4239
|
+
"restartFailed": "Neustart fehlgeschlagen",
|
|
4240
|
+
"approveFailed": "Freigeben fehlgeschlagen",
|
|
4241
|
+
"requestChangesFailed": "Anfordern von Änderungen fehlgeschlagen",
|
|
4242
|
+
"rejectFailed": "Ablehnen fehlgeschlagen"
|
|
4235
4243
|
},
|
|
4236
4244
|
"reviewFriction": {
|
|
4237
4245
|
"warnTitle": "Aufgaben warten auf Prüfung",
|
package/i18n/locales/en.json
CHANGED
|
@@ -492,7 +492,10 @@
|
|
|
492
492
|
"retryFailed": "Retry failed",
|
|
493
493
|
"startFailed": "Failed to start",
|
|
494
494
|
"mergeFailed": "Failed to merge",
|
|
495
|
-
"restartFailed": "Failed to restart"
|
|
495
|
+
"restartFailed": "Failed to restart",
|
|
496
|
+
"approveFailed": "Failed to approve",
|
|
497
|
+
"requestChangesFailed": "Failed to request changes",
|
|
498
|
+
"rejectFailed": "Failed to reject"
|
|
496
499
|
},
|
|
497
500
|
"reviewFriction": {
|
|
498
501
|
"warnTitle": "Tasks waiting on review",
|
|
@@ -1040,6 +1043,7 @@
|
|
|
1040
1043
|
"open": "Open",
|
|
1041
1044
|
"mergePr": "Merge PR",
|
|
1042
1045
|
"chooseApproach": "Choose approach",
|
|
1046
|
+
"triageFollowUps": "Decide follow-ups",
|
|
1043
1047
|
"elapsedTooltip": "Elapsed time on this step",
|
|
1044
1048
|
"reviewFindings": "Review findings"
|
|
1045
1049
|
},
|
|
@@ -1273,6 +1277,10 @@
|
|
|
1273
1277
|
"details": "Details",
|
|
1274
1278
|
"approvalRequired": "Approval required",
|
|
1275
1279
|
"decisionRequired": "Decision required",
|
|
1280
|
+
"followUpsParked": "The Coder surfaced follow-up items that need a decision before the run can continue. Triage each item (file, send back, answer, or dismiss) in the follow-ups window.",
|
|
1281
|
+
"forkParked": "This Coder step is waiting for an implementation approach to be chosen before any code is written. Pick a proposed approach (or enter your own) in the fork-decision window.",
|
|
1282
|
+
"openFollowUps": "Open follow-ups",
|
|
1283
|
+
"chooseApproach": "Choose approach",
|
|
1276
1284
|
"expandAll": "Expand all sections",
|
|
1277
1285
|
"collapseAll": "Collapse all sections",
|
|
1278
1286
|
"copyRawOutput": "Copy raw output",
|
package/i18n/locales/es.json
CHANGED
|
@@ -456,7 +456,10 @@
|
|
|
456
456
|
"retryFailed": "El reintento falló",
|
|
457
457
|
"startFailed": "No se pudo iniciar",
|
|
458
458
|
"mergeFailed": "No se pudo fusionar",
|
|
459
|
-
"restartFailed": "No se pudo reiniciar"
|
|
459
|
+
"restartFailed": "No se pudo reiniciar",
|
|
460
|
+
"approveFailed": "No se pudo aprobar",
|
|
461
|
+
"requestChangesFailed": "No se pudieron solicitar cambios",
|
|
462
|
+
"rejectFailed": "No se pudo rechazar"
|
|
460
463
|
},
|
|
461
464
|
"reviewFriction": {
|
|
462
465
|
"warnTitle": "Tareas esperando revisión",
|
|
@@ -980,6 +983,7 @@
|
|
|
980
983
|
"body": "Inicia un pipeline para ver el historial de ejecución aquí."
|
|
981
984
|
},
|
|
982
985
|
"chooseApproach": "Elegir enfoque",
|
|
986
|
+
"triageFollowUps": "Decidir seguimientos",
|
|
983
987
|
"elapsedTooltip": "Tiempo transcurrido en este paso",
|
|
984
988
|
"reviewFindings": "Revisar hallazgos"
|
|
985
989
|
},
|
|
@@ -1213,6 +1217,10 @@
|
|
|
1213
1217
|
"details": "Detalles",
|
|
1214
1218
|
"approvalRequired": "Se requiere aprobación",
|
|
1215
1219
|
"decisionRequired": "Se requiere una decisión",
|
|
1220
|
+
"followUpsParked": "El Coder planteó seguimientos que necesitan una decisión antes de que la ejecución pueda continuar. Resuelve cada elemento (crear, devolver, responder o descartar) en la ventana de seguimientos.",
|
|
1221
|
+
"forkParked": "Este paso del Coder espera a que se elija un enfoque de implementación antes de escribir código. Elige un enfoque propuesto (o introduce el tuyo) en la ventana de decisión.",
|
|
1222
|
+
"openFollowUps": "Abrir seguimientos",
|
|
1223
|
+
"chooseApproach": "Elegir enfoque",
|
|
1216
1224
|
"expandAll": "Expandir todas las secciones",
|
|
1217
1225
|
"collapseAll": "Contraer todas las secciones",
|
|
1218
1226
|
"copyRawOutput": "Copiar salida sin procesar",
|
package/i18n/locales/fr.json
CHANGED
|
@@ -456,7 +456,10 @@
|
|
|
456
456
|
"retryFailed": "Échec de la nouvelle tentative",
|
|
457
457
|
"startFailed": "Échec du démarrage",
|
|
458
458
|
"mergeFailed": "Échec de la fusion",
|
|
459
|
-
"restartFailed": "Échec du redémarrage"
|
|
459
|
+
"restartFailed": "Échec du redémarrage",
|
|
460
|
+
"approveFailed": "Échec de l'approbation",
|
|
461
|
+
"requestChangesFailed": "Échec de la demande de modifications",
|
|
462
|
+
"rejectFailed": "Échec du rejet"
|
|
460
463
|
},
|
|
461
464
|
"reviewFriction": {
|
|
462
465
|
"warnTitle": "Tâches en attente de revue",
|
|
@@ -980,6 +983,7 @@
|
|
|
980
983
|
"body": "Lancez un pipeline pour voir l'historique d'exécution ici."
|
|
981
984
|
},
|
|
982
985
|
"chooseApproach": "Choisir l'approche",
|
|
986
|
+
"triageFollowUps": "Trancher les suivis",
|
|
983
987
|
"elapsedTooltip": "Temps écoulé sur cette étape",
|
|
984
988
|
"reviewFindings": "Examiner les remarques"
|
|
985
989
|
},
|
|
@@ -1213,6 +1217,10 @@
|
|
|
1213
1217
|
"details": "Détails",
|
|
1214
1218
|
"approvalRequired": "Approbation requise",
|
|
1215
1219
|
"decisionRequired": "Décision requise",
|
|
1220
|
+
"followUpsParked": "Le Coder a soulevé des suivis qui doivent être tranchés avant que l'exécution puisse continuer. Traitez chaque élément (créer, renvoyer, répondre ou écarter) dans la fenêtre des suivis.",
|
|
1221
|
+
"forkParked": "Cette étape du Coder attend le choix d'une approche d'implémentation avant d'écrire du code. Choisissez une approche proposée (ou saisissez la vôtre) dans la fenêtre de décision.",
|
|
1222
|
+
"openFollowUps": "Ouvrir les suivis",
|
|
1223
|
+
"chooseApproach": "Choisir l'approche",
|
|
1216
1224
|
"expandAll": "Développer toutes les sections",
|
|
1217
1225
|
"collapseAll": "Réduire toutes les sections",
|
|
1218
1226
|
"copyRawOutput": "Copier la sortie brute",
|
package/i18n/locales/he.json
CHANGED
|
@@ -456,7 +456,10 @@
|
|
|
456
456
|
"retryFailed": "הניסיון החוזר נכשל",
|
|
457
457
|
"startFailed": "ההפעלה נכשלה",
|
|
458
458
|
"mergeFailed": "המיזוג נכשל",
|
|
459
|
-
"restartFailed": "ההפעלה מחדש נכשלה"
|
|
459
|
+
"restartFailed": "ההפעלה מחדש נכשלה",
|
|
460
|
+
"approveFailed": "האישור נכשל",
|
|
461
|
+
"requestChangesFailed": "בקשת השינויים נכשלה",
|
|
462
|
+
"rejectFailed": "הדחייה נכשלה"
|
|
460
463
|
},
|
|
461
464
|
"reviewFriction": {
|
|
462
465
|
"warnTitle": "משימות ממתינות לסקירה",
|
|
@@ -980,6 +983,7 @@
|
|
|
980
983
|
"body": "התחל pipeline כדי לראות כאן את היסטוריית ההרצות."
|
|
981
984
|
},
|
|
982
985
|
"chooseApproach": "בחר גישה",
|
|
986
|
+
"triageFollowUps": "הכרע בהמשכים",
|
|
983
987
|
"elapsedTooltip": "הזמן שחלף בשלב זה",
|
|
984
988
|
"reviewFindings": "עיין בממצאים"
|
|
985
989
|
},
|
|
@@ -1213,6 +1217,10 @@
|
|
|
1213
1217
|
"details": "פרטים",
|
|
1214
1218
|
"approvalRequired": "נדרש אישור",
|
|
1215
1219
|
"decisionRequired": "נדרשת החלטה",
|
|
1220
|
+
"followUpsParked": "ה-Coder העלה המשכים שדורשים הכרעה לפני שהריצה תוכל להמשיך. טפל בכל פריט (תייק, החזר, ענה או דחה) בחלון ההמשכים.",
|
|
1221
|
+
"forkParked": "שלב ה-Coder הזה ממתין לבחירת גישת מימוש לפני כתיבת קוד. בחר גישה מוצעת (או הזן גישה משלך) בחלון ההחלטה.",
|
|
1222
|
+
"openFollowUps": "פתח את ההמשכים",
|
|
1223
|
+
"chooseApproach": "בחר גישה",
|
|
1216
1224
|
"expandAll": "הרחב את כל המקטעים",
|
|
1217
1225
|
"collapseAll": "כווץ את כל המקטעים",
|
|
1218
1226
|
"copyRawOutput": "העתק פלט גולמי",
|
package/i18n/locales/it.json
CHANGED
|
@@ -1298,6 +1298,7 @@
|
|
|
1298
1298
|
"open": "Aperta",
|
|
1299
1299
|
"mergePr": "Unisci PR",
|
|
1300
1300
|
"chooseApproach": "Scegli approccio",
|
|
1301
|
+
"triageFollowUps": "Decidi i follow-up",
|
|
1301
1302
|
"elapsedTooltip": "Tempo trascorso su questo passaggio",
|
|
1302
1303
|
"reviewFindings": "Esamina i rilievi"
|
|
1303
1304
|
},
|
|
@@ -1531,6 +1532,10 @@
|
|
|
1531
1532
|
"details": "Dettagli",
|
|
1532
1533
|
"approvalRequired": "Approvazione richiesta",
|
|
1533
1534
|
"decisionRequired": "Decisione richiesta",
|
|
1535
|
+
"followUpsParked": "Il Coder ha sollevato follow-up che richiedono una decisione prima che la run possa continuare. Gestisci ogni elemento (crea, rimanda indietro, rispondi o scarta) nella finestra dei follow-up.",
|
|
1536
|
+
"forkParked": "Questo passo del Coder attende la scelta di un approccio di implementazione prima di scrivere codice. Scegli un approccio proposto (o inserisci il tuo) nella finestra di decisione.",
|
|
1537
|
+
"openFollowUps": "Apri i follow-up",
|
|
1538
|
+
"chooseApproach": "Scegli approccio",
|
|
1534
1539
|
"expandAll": "Espandi tutte le sezioni",
|
|
1535
1540
|
"collapseAll": "Comprimi tutte le sezioni",
|
|
1536
1541
|
"copyRawOutput": "Copia l'output grezzo",
|
|
@@ -4231,7 +4236,10 @@
|
|
|
4231
4236
|
"retryFailed": "Nuovo tentativo non riuscito",
|
|
4232
4237
|
"startFailed": "Avvio non riuscito",
|
|
4233
4238
|
"mergeFailed": "Merge non riuscito",
|
|
4234
|
-
"restartFailed": "Riavvio non riuscito"
|
|
4239
|
+
"restartFailed": "Riavvio non riuscito",
|
|
4240
|
+
"approveFailed": "Approvazione non riuscita",
|
|
4241
|
+
"requestChangesFailed": "Richiesta di modifiche non riuscita",
|
|
4242
|
+
"rejectFailed": "Rifiuto non riuscito"
|
|
4235
4243
|
},
|
|
4236
4244
|
"reviewFriction": {
|
|
4237
4245
|
"warnTitle": "Attività in attesa di revisione",
|
package/i18n/locales/ja.json
CHANGED
|
@@ -456,7 +456,10 @@
|
|
|
456
456
|
"retryFailed": "再試行に失敗しました",
|
|
457
457
|
"startFailed": "開始に失敗しました",
|
|
458
458
|
"mergeFailed": "マージに失敗しました",
|
|
459
|
-
"restartFailed": "再起動に失敗しました"
|
|
459
|
+
"restartFailed": "再起動に失敗しました",
|
|
460
|
+
"approveFailed": "承認に失敗しました",
|
|
461
|
+
"requestChangesFailed": "変更リクエストに失敗しました",
|
|
462
|
+
"rejectFailed": "却下に失敗しました"
|
|
460
463
|
},
|
|
461
464
|
"reviewFriction": {
|
|
462
465
|
"warnTitle": "レビュー待ちのタスク",
|
|
@@ -980,6 +983,7 @@
|
|
|
980
983
|
"body": "パイプラインを開始すると、ここに実行履歴が表示されます。"
|
|
981
984
|
},
|
|
982
985
|
"chooseApproach": "アプローチを選択",
|
|
986
|
+
"triageFollowUps": "フォローアップを決定",
|
|
983
987
|
"elapsedTooltip": "このステップの経過時間",
|
|
984
988
|
"reviewFindings": "指摘を確認"
|
|
985
989
|
},
|
|
@@ -1213,6 +1217,10 @@
|
|
|
1213
1217
|
"details": "詳細",
|
|
1214
1218
|
"approvalRequired": "承認が必要",
|
|
1215
1219
|
"decisionRequired": "判断が必要",
|
|
1220
|
+
"followUpsParked": "Coderが決定待ちのフォローアップ項目を提起しています。実行を続行するには、フォローアップウィンドウで各項目を処理してください(起票、差し戻し、回答、または却下)。",
|
|
1221
|
+
"forkParked": "このCoderステップは、コードを書く前に実装アプローチの選択を待っています。決定ウィンドウで提案されたアプローチを選ぶか、独自のアプローチを入力してください。",
|
|
1222
|
+
"openFollowUps": "フォローアップを開く",
|
|
1223
|
+
"chooseApproach": "アプローチを選択",
|
|
1216
1224
|
"expandAll": "すべてのセクションを展開",
|
|
1217
1225
|
"collapseAll": "すべてのセクションを折りたたむ",
|
|
1218
1226
|
"copyRawOutput": "生の出力をコピー",
|
package/i18n/locales/pl.json
CHANGED
|
@@ -456,7 +456,10 @@
|
|
|
456
456
|
"retryFailed": "Ponowienie nie powiodło się",
|
|
457
457
|
"startFailed": "Nie udało się uruchomić",
|
|
458
458
|
"mergeFailed": "Nie udało się scalić",
|
|
459
|
-
"restartFailed": "Nie udało się ponownie uruchomić"
|
|
459
|
+
"restartFailed": "Nie udało się ponownie uruchomić",
|
|
460
|
+
"approveFailed": "Nie udało się zatwierdzić",
|
|
461
|
+
"requestChangesFailed": "Nie udało się poprosić o zmiany",
|
|
462
|
+
"rejectFailed": "Nie udało się odrzucić"
|
|
460
463
|
},
|
|
461
464
|
"reviewFriction": {
|
|
462
465
|
"warnTitle": "Zadania czekające na przegląd",
|
|
@@ -980,6 +983,7 @@
|
|
|
980
983
|
"body": "Uruchom pipeline, aby zobaczyć tutaj historię uruchomień."
|
|
981
984
|
},
|
|
982
985
|
"chooseApproach": "Wybierz podejście",
|
|
986
|
+
"triageFollowUps": "Rozstrzygnij działania następcze",
|
|
983
987
|
"elapsedTooltip": "Czas, który upłynął na tym kroku",
|
|
984
988
|
"reviewFindings": "Przejrzyj ustalenia"
|
|
985
989
|
},
|
|
@@ -1213,6 +1217,10 @@
|
|
|
1213
1217
|
"details": "Szczegóły",
|
|
1214
1218
|
"approvalRequired": "Wymagane zatwierdzenie",
|
|
1215
1219
|
"decisionRequired": "Wymagana decyzja",
|
|
1220
|
+
"followUpsParked": "Coder zgłosił działania następcze, które wymagają rozstrzygnięcia, zanim uruchomienie będzie mogło kontynuować. Rozstrzygnij każdy element (utwórz, odeślij, odpowiedz lub odrzuć) w oknie działań następczych.",
|
|
1221
|
+
"forkParked": "Ten krok Codera czeka na wybór podejścia do implementacji, zanim powstanie kod. Wybierz zaproponowane podejście (lub wpisz własne) w oknie decyzji.",
|
|
1222
|
+
"openFollowUps": "Otwórz działania następcze",
|
|
1223
|
+
"chooseApproach": "Wybierz podejście",
|
|
1216
1224
|
"expandAll": "Rozwiń wszystkie sekcje",
|
|
1217
1225
|
"collapseAll": "Zwiń wszystkie sekcje",
|
|
1218
1226
|
"copyRawOutput": "Kopiuj surowy wynik",
|
package/i18n/locales/tr.json
CHANGED
|
@@ -456,7 +456,10 @@
|
|
|
456
456
|
"retryFailed": "Yeniden deneme başarısız oldu",
|
|
457
457
|
"startFailed": "Başlatılamadı",
|
|
458
458
|
"mergeFailed": "Birleştirilemedi",
|
|
459
|
-
"restartFailed": "Yeniden başlatılamadı"
|
|
459
|
+
"restartFailed": "Yeniden başlatılamadı",
|
|
460
|
+
"approveFailed": "Onaylanamadı",
|
|
461
|
+
"requestChangesFailed": "Değişiklik istenemedi",
|
|
462
|
+
"rejectFailed": "Reddedilemedi"
|
|
460
463
|
},
|
|
461
464
|
"reviewFriction": {
|
|
462
465
|
"warnTitle": "Görevler incelemeyi bekliyor",
|
|
@@ -980,6 +983,7 @@
|
|
|
980
983
|
"body": "Çalıştırma geçmişini burada görmek için bir pipeline başlatın."
|
|
981
984
|
},
|
|
982
985
|
"chooseApproach": "Yaklaşım seç",
|
|
986
|
+
"triageFollowUps": "Takipleri karara bağla",
|
|
983
987
|
"elapsedTooltip": "Bu adımda geçen süre",
|
|
984
988
|
"reviewFindings": "Bulguları incele"
|
|
985
989
|
},
|
|
@@ -1213,6 +1217,10 @@
|
|
|
1213
1217
|
"details": "Ayrıntılar",
|
|
1214
1218
|
"approvalRequired": "Onay gerekli",
|
|
1215
1219
|
"decisionRequired": "Karar gerekli",
|
|
1220
|
+
"followUpsParked": "Coder, çalıştırmanın devam edebilmesi için karara bağlanması gereken takipler ortaya çıkardı. Her maddeyi takipler penceresinde ele alın (kaydet, geri gönder, yanıtla veya yok say).",
|
|
1221
|
+
"forkParked": "Bu Coder adımı, kod yazılmadan önce bir uygulama yaklaşımının seçilmesini bekliyor. Karar penceresinde önerilen bir yaklaşımı seçin (veya kendi yaklaşımınızı girin).",
|
|
1222
|
+
"openFollowUps": "Takipleri aç",
|
|
1223
|
+
"chooseApproach": "Yaklaşım seç",
|
|
1216
1224
|
"expandAll": "Tüm bölümleri genişlet",
|
|
1217
1225
|
"collapseAll": "Tüm bölümleri daralt",
|
|
1218
1226
|
"copyRawOutput": "Ham çıktıyı kopyala",
|
package/i18n/locales/uk.json
CHANGED
|
@@ -456,7 +456,10 @@
|
|
|
456
456
|
"retryFailed": "Не вдалося повторити",
|
|
457
457
|
"startFailed": "Не вдалося запустити",
|
|
458
458
|
"mergeFailed": "Не вдалося злити",
|
|
459
|
-
"restartFailed": "Не вдалося перезапустити"
|
|
459
|
+
"restartFailed": "Не вдалося перезапустити",
|
|
460
|
+
"approveFailed": "Не вдалося затвердити",
|
|
461
|
+
"requestChangesFailed": "Не вдалося запросити зміни",
|
|
462
|
+
"rejectFailed": "Не вдалося відхилити"
|
|
460
463
|
},
|
|
461
464
|
"reviewFriction": {
|
|
462
465
|
"warnTitle": "Завдання чекають на рев’ю",
|
|
@@ -980,6 +983,7 @@
|
|
|
980
983
|
"body": "Запустіть pipeline, щоб побачити тут історію запусків."
|
|
981
984
|
},
|
|
982
985
|
"chooseApproach": "Обрати підхід",
|
|
986
|
+
"triageFollowUps": "Вирішити подальші дії",
|
|
983
987
|
"elapsedTooltip": "Час, що минув на цьому кроці",
|
|
984
988
|
"reviewFindings": "Переглянути зауваження"
|
|
985
989
|
},
|
|
@@ -1213,6 +1217,10 @@
|
|
|
1213
1217
|
"details": "Деталі",
|
|
1214
1218
|
"approvalRequired": "Потрібне затвердження",
|
|
1215
1219
|
"decisionRequired": "Потрібне рішення",
|
|
1220
|
+
"followUpsParked": "Coder підняв подальші дії, які потребують рішення, перш ніж запуск зможе продовжитися. Опрацюйте кожен елемент (створіть, поверніть, дайте відповідь або відхиліть) у вікні подальших дій.",
|
|
1221
|
+
"forkParked": "Цей крок Coder чекає на вибір підходу до реалізації, перш ніж буде написано код. Виберіть запропонований підхід (або введіть власний) у вікні рішення.",
|
|
1222
|
+
"openFollowUps": "Відкрити подальші дії",
|
|
1223
|
+
"chooseApproach": "Вибрати підхід",
|
|
1216
1224
|
"expandAll": "Розгорнути всі розділи",
|
|
1217
1225
|
"collapseAll": "Згорнути всі розділи",
|
|
1218
1226
|
"copyRawOutput": "Скопіювати сирий вивід",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.162.
|
|
3
|
+
"version": "0.162.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",
|
|
@@ -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.
|
|
43
|
+
"@cat-factory/contracts": "0.177.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@toad-contracts/testing": "0.3.2",
|