@cat-factory/app 0.147.1 → 0.147.2
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/board/nodes/TaskPipelineMini.vue +23 -2
- package/app/components/pipeline/PipelineProgress.vue +25 -1
- package/app/components/prReview/PrReviewPhaseBadge.vue +74 -0
- package/app/components/prReview/PrReviewWindow.vue +418 -395
- package/app/utils/prReviewProgress.spec.ts +51 -2
- package/app/utils/prReviewProgress.ts +52 -1
- package/i18n/locales/de.json +8 -0
- package/i18n/locales/en.json +8 -0
- package/i18n/locales/es.json +8 -0
- package/i18n/locales/fr.json +8 -0
- package/i18n/locales/he.json +8 -0
- package/i18n/locales/it.json +8 -0
- package/i18n/locales/ja.json +8 -0
- package/i18n/locales/pl.json +8 -0
- package/i18n/locales/tr.json +8 -0
- package/i18n/locales/uk.json +8 -0
- package/package.json +1 -1
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import type { StepSubtasks } from '~/types/execution'
|
|
3
|
-
import {
|
|
2
|
+
import type { PrReviewStepState, StepSubtasks } from '~/types/execution'
|
|
3
|
+
import {
|
|
4
|
+
activeChunkLabels,
|
|
5
|
+
chunkReviewPercent,
|
|
6
|
+
isSlicingChunks,
|
|
7
|
+
prReviewPhase,
|
|
8
|
+
} from './prReviewProgress'
|
|
4
9
|
|
|
5
10
|
const subtasks = (over: Partial<StepSubtasks>): StepSubtasks => ({
|
|
6
11
|
completed: 0,
|
|
@@ -71,3 +76,47 @@ describe('activeChunkLabels', () => {
|
|
|
71
76
|
).toEqual([])
|
|
72
77
|
})
|
|
73
78
|
})
|
|
79
|
+
|
|
80
|
+
// `prReviewPhase` reads only `status`; the other PrReviewStepState fields are irrelevant here.
|
|
81
|
+
const state = (status: PrReviewStepState['status']): PrReviewStepState =>
|
|
82
|
+
({ status }) as PrReviewStepState
|
|
83
|
+
|
|
84
|
+
describe('prReviewPhase', () => {
|
|
85
|
+
it('is null with no live review or a terminal/passed-through status', () => {
|
|
86
|
+
expect(prReviewPhase(null, null)).toBeNull()
|
|
87
|
+
expect(prReviewPhase(undefined, subtasks({ total: 3, completed: 3 }))).toBeNull()
|
|
88
|
+
expect(prReviewPhase(state('done'), subtasks({ total: 3, completed: 3 }))).toBeNull()
|
|
89
|
+
expect(prReviewPhase(state('skipped'), null)).toBeNull()
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('is slicing while reviewing with no todo list yet (counts zeroed)', () => {
|
|
93
|
+
// No plan committed → don't leak a misleading 0/0 slice count.
|
|
94
|
+
expect(prReviewPhase(state('reviewing'), null)).toEqual({
|
|
95
|
+
kind: 'slicing',
|
|
96
|
+
completed: 0,
|
|
97
|
+
total: 0,
|
|
98
|
+
})
|
|
99
|
+
expect(prReviewPhase(state('reviewing'), subtasks({ total: 0 }))).toEqual({
|
|
100
|
+
kind: 'slicing',
|
|
101
|
+
completed: 0,
|
|
102
|
+
total: 0,
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('is reviewing with the slice counts once the todo list exists', () => {
|
|
107
|
+
expect(prReviewPhase(state('reviewing'), subtasks({ total: 4, completed: 1 }))).toEqual({
|
|
108
|
+
kind: 'reviewing',
|
|
109
|
+
completed: 1,
|
|
110
|
+
total: 4,
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('maps the parked / resolving statuses to their phase', () => {
|
|
115
|
+
expect(
|
|
116
|
+
prReviewPhase(state('awaiting_selection'), subtasks({ total: 4, completed: 4 }))?.kind,
|
|
117
|
+
).toBe('awaiting')
|
|
118
|
+
expect(prReviewPhase(state('challenging'), null)?.kind).toBe('challenging')
|
|
119
|
+
expect(prReviewPhase(state('fixing'), null)?.kind).toBe('fixing')
|
|
120
|
+
expect(prReviewPhase(state('posting'), null)?.kind).toBe('posting')
|
|
121
|
+
})
|
|
122
|
+
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { StepSubtasks } from '~/types/execution'
|
|
1
|
+
import type { PrReviewStepState, StepSubtasks } from '~/types/execution'
|
|
2
2
|
|
|
3
3
|
// Pure derivation of the PR deep-reviewer's `reviewing`-phase progress, factored out of
|
|
4
4
|
// `PrReviewWindow.vue` so it is unit-testable independently of the Vue component.
|
|
@@ -26,3 +26,54 @@ export function chunkReviewPercent(subtasks: StepSubtasks | null | undefined): n
|
|
|
26
26
|
export function activeChunkLabels(subtasks: StepSubtasks | null | undefined): string[] {
|
|
27
27
|
return subtasks?.items?.filter((i) => i.status === 'in_progress').map((i) => i.label) ?? []
|
|
28
28
|
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The at-a-glance phase of a `pr-reviewer` step, collapsing its `prReview.status` (+ the
|
|
32
|
+
* slicing-vs-reviewing signal from the todo list) into a single kind the board surfaces label
|
|
33
|
+
* without re-deriving. `completed`/`total` carry the slice counts for the `reviewing` kind.
|
|
34
|
+
* Returns `null` for the terminal / passed-through states (`done`/`skipped`) and when there is
|
|
35
|
+
* no live review — those have no in-flight phase to show.
|
|
36
|
+
*/
|
|
37
|
+
export type PrReviewPhaseKind =
|
|
38
|
+
| 'slicing'
|
|
39
|
+
| 'reviewing'
|
|
40
|
+
| 'awaiting'
|
|
41
|
+
| 'challenging'
|
|
42
|
+
| 'fixing'
|
|
43
|
+
| 'posting'
|
|
44
|
+
|
|
45
|
+
export interface PrReviewPhase {
|
|
46
|
+
kind: PrReviewPhaseKind
|
|
47
|
+
/** Slices whose review is finished (0 while slicing). */
|
|
48
|
+
completed: number
|
|
49
|
+
/** Total slices the reviewer grouped the diff into (0 while slicing). */
|
|
50
|
+
total: number
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function prReviewPhase(
|
|
54
|
+
state: PrReviewStepState | null | undefined,
|
|
55
|
+
subtasks: StepSubtasks | null | undefined,
|
|
56
|
+
): PrReviewPhase | null {
|
|
57
|
+
const status = state?.status
|
|
58
|
+
if (!status) return null
|
|
59
|
+
const completed = subtasks?.completed ?? 0
|
|
60
|
+
const total = subtasks?.total ?? 0
|
|
61
|
+
switch (status) {
|
|
62
|
+
case 'reviewing':
|
|
63
|
+
// No todo list yet ⇒ still grouping the diff; otherwise working through the chunks.
|
|
64
|
+
return isSlicingChunks(subtasks)
|
|
65
|
+
? { kind: 'slicing', completed: 0, total: 0 }
|
|
66
|
+
: { kind: 'reviewing', completed, total }
|
|
67
|
+
case 'awaiting_selection':
|
|
68
|
+
return { kind: 'awaiting', completed, total }
|
|
69
|
+
case 'challenging':
|
|
70
|
+
return { kind: 'challenging', completed, total }
|
|
71
|
+
case 'fixing':
|
|
72
|
+
return { kind: 'fixing', completed, total }
|
|
73
|
+
case 'posting':
|
|
74
|
+
return { kind: 'posting', completed, total }
|
|
75
|
+
default:
|
|
76
|
+
// done / skipped — no live phase to surface.
|
|
77
|
+
return null
|
|
78
|
+
}
|
|
79
|
+
}
|
package/i18n/locales/de.json
CHANGED
|
@@ -4961,6 +4961,14 @@
|
|
|
4961
4961
|
"pending": "In Warteschlange"
|
|
4962
4962
|
}
|
|
4963
4963
|
},
|
|
4964
|
+
"phase": {
|
|
4965
|
+
"slicing": "Wird aufgeteilt…",
|
|
4966
|
+
"reviewing": "Prüfe {completed}/{total} Abschnitte",
|
|
4967
|
+
"awaiting": "Ergebnisse bereit",
|
|
4968
|
+
"challenging": "Wird untersucht…",
|
|
4969
|
+
"fixing": "Wird behoben…",
|
|
4970
|
+
"posting": "Wird veröffentlicht…"
|
|
4971
|
+
},
|
|
4964
4972
|
"challenge": {
|
|
4965
4973
|
"action": "Anfechten",
|
|
4966
4974
|
"reChallenge": "Erneut anfechten",
|
package/i18n/locales/en.json
CHANGED
|
@@ -5090,6 +5090,14 @@
|
|
|
5090
5090
|
"pending": "Queued"
|
|
5091
5091
|
}
|
|
5092
5092
|
},
|
|
5093
|
+
"phase": {
|
|
5094
|
+
"slicing": "Slicing…",
|
|
5095
|
+
"reviewing": "Reviewing {completed}/{total} slices",
|
|
5096
|
+
"awaiting": "Findings ready",
|
|
5097
|
+
"challenging": "Investigating…",
|
|
5098
|
+
"fixing": "Fixing…",
|
|
5099
|
+
"posting": "Posting…"
|
|
5100
|
+
},
|
|
5093
5101
|
"challenge": {
|
|
5094
5102
|
"action": "Challenge",
|
|
5095
5103
|
"reChallenge": "Challenge again",
|
package/i18n/locales/es.json
CHANGED
|
@@ -4949,6 +4949,14 @@
|
|
|
4949
4949
|
"pending": "En cola"
|
|
4950
4950
|
}
|
|
4951
4951
|
},
|
|
4952
|
+
"phase": {
|
|
4953
|
+
"slicing": "Dividiendo…",
|
|
4954
|
+
"reviewing": "Revisando {completed}/{total} secciones",
|
|
4955
|
+
"awaiting": "Resultados listos",
|
|
4956
|
+
"challenging": "Investigando…",
|
|
4957
|
+
"fixing": "Corrigiendo…",
|
|
4958
|
+
"posting": "Publicando…"
|
|
4959
|
+
},
|
|
4952
4960
|
"challenge": {
|
|
4953
4961
|
"action": "Cuestionar",
|
|
4954
4962
|
"reChallenge": "Cuestionar de nuevo",
|
package/i18n/locales/fr.json
CHANGED
|
@@ -4949,6 +4949,14 @@
|
|
|
4949
4949
|
"pending": "En attente"
|
|
4950
4950
|
}
|
|
4951
4951
|
},
|
|
4952
|
+
"phase": {
|
|
4953
|
+
"slicing": "Découpage…",
|
|
4954
|
+
"reviewing": "Révision {completed}/{total} sections",
|
|
4955
|
+
"awaiting": "Résultats prêts",
|
|
4956
|
+
"challenging": "Analyse en cours…",
|
|
4957
|
+
"fixing": "Correction…",
|
|
4958
|
+
"posting": "Publication…"
|
|
4959
|
+
},
|
|
4952
4960
|
"challenge": {
|
|
4953
4961
|
"action": "Contester",
|
|
4954
4962
|
"reChallenge": "Contester à nouveau",
|
package/i18n/locales/he.json
CHANGED
|
@@ -4960,6 +4960,14 @@
|
|
|
4960
4960
|
"pending": "בתור"
|
|
4961
4961
|
}
|
|
4962
4962
|
},
|
|
4963
|
+
"phase": {
|
|
4964
|
+
"slicing": "מחלק…",
|
|
4965
|
+
"reviewing": "בודק {completed}/{total} מקטעים",
|
|
4966
|
+
"awaiting": "הממצאים מוכנים",
|
|
4967
|
+
"challenging": "חוקר…",
|
|
4968
|
+
"fixing": "מתקן…",
|
|
4969
|
+
"posting": "מפרסם…"
|
|
4970
|
+
},
|
|
4963
4971
|
"challenge": {
|
|
4964
4972
|
"action": "ערער",
|
|
4965
4973
|
"reChallenge": "ערער שוב",
|
package/i18n/locales/it.json
CHANGED
|
@@ -4961,6 +4961,14 @@
|
|
|
4961
4961
|
"pending": "In coda"
|
|
4962
4962
|
}
|
|
4963
4963
|
},
|
|
4964
|
+
"phase": {
|
|
4965
|
+
"slicing": "Suddivisione…",
|
|
4966
|
+
"reviewing": "Revisione {completed}/{total} sezioni",
|
|
4967
|
+
"awaiting": "Risultati pronti",
|
|
4968
|
+
"challenging": "Analisi in corso…",
|
|
4969
|
+
"fixing": "Correzione…",
|
|
4970
|
+
"posting": "Pubblicazione…"
|
|
4971
|
+
},
|
|
4964
4972
|
"challenge": {
|
|
4965
4973
|
"action": "Contesta",
|
|
4966
4974
|
"reChallenge": "Contesta di nuovo",
|
package/i18n/locales/ja.json
CHANGED
|
@@ -4961,6 +4961,14 @@
|
|
|
4961
4961
|
"pending": "待機中"
|
|
4962
4962
|
}
|
|
4963
4963
|
},
|
|
4964
|
+
"phase": {
|
|
4965
|
+
"slicing": "分割中…",
|
|
4966
|
+
"reviewing": "レビュー中 {completed}/{total} 区分",
|
|
4967
|
+
"awaiting": "指摘の準備完了",
|
|
4968
|
+
"challenging": "調査中…",
|
|
4969
|
+
"fixing": "修正中…",
|
|
4970
|
+
"posting": "投稿中…"
|
|
4971
|
+
},
|
|
4964
4972
|
"challenge": {
|
|
4965
4973
|
"action": "異議を唱える",
|
|
4966
4974
|
"reChallenge": "再度異議を唱える",
|
package/i18n/locales/pl.json
CHANGED
|
@@ -4949,6 +4949,14 @@
|
|
|
4949
4949
|
"pending": "W kolejce"
|
|
4950
4950
|
}
|
|
4951
4951
|
},
|
|
4952
|
+
"phase": {
|
|
4953
|
+
"slicing": "Dzielenie…",
|
|
4954
|
+
"reviewing": "Przegląd {completed}/{total} fragmentów",
|
|
4955
|
+
"awaiting": "Wyniki gotowe",
|
|
4956
|
+
"challenging": "Analizowanie…",
|
|
4957
|
+
"fixing": "Naprawianie…",
|
|
4958
|
+
"posting": "Publikowanie…"
|
|
4959
|
+
},
|
|
4952
4960
|
"challenge": {
|
|
4953
4961
|
"action": "Zakwestionuj",
|
|
4954
4962
|
"reChallenge": "Zakwestionuj ponownie",
|
package/i18n/locales/tr.json
CHANGED
|
@@ -4961,6 +4961,14 @@
|
|
|
4961
4961
|
"pending": "Sırada"
|
|
4962
4962
|
}
|
|
4963
4963
|
},
|
|
4964
|
+
"phase": {
|
|
4965
|
+
"slicing": "Dilimleniyor…",
|
|
4966
|
+
"reviewing": "İnceleniyor {completed}/{total} bölüm",
|
|
4967
|
+
"awaiting": "Bulgular hazır",
|
|
4968
|
+
"challenging": "Araştırılıyor…",
|
|
4969
|
+
"fixing": "Düzeltiliyor…",
|
|
4970
|
+
"posting": "Yayınlanıyor…"
|
|
4971
|
+
},
|
|
4964
4972
|
"challenge": {
|
|
4965
4973
|
"action": "İtiraz et",
|
|
4966
4974
|
"reChallenge": "Tekrar itiraz et",
|
package/i18n/locales/uk.json
CHANGED
|
@@ -4949,6 +4949,14 @@
|
|
|
4949
4949
|
"pending": "У черзі"
|
|
4950
4950
|
}
|
|
4951
4951
|
},
|
|
4952
|
+
"phase": {
|
|
4953
|
+
"slicing": "Розбиття…",
|
|
4954
|
+
"reviewing": "Перевірка {completed}/{total} фрагментів",
|
|
4955
|
+
"awaiting": "Результати готові",
|
|
4956
|
+
"challenging": "Дослідження…",
|
|
4957
|
+
"fixing": "Виправлення…",
|
|
4958
|
+
"posting": "Публікація…"
|
|
4959
|
+
},
|
|
4952
4960
|
"challenge": {
|
|
4953
4961
|
"action": "Оскаржити",
|
|
4954
4962
|
"reChallenge": "Оскаржити знову",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.147.
|
|
3
|
+
"version": "0.147.2",
|
|
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",
|