@cat-factory/app 0.162.1 → 0.163.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,148 @@
1
+ import { defineStore } from 'pinia'
2
+ import { computed, ref } from 'vue'
3
+ import type { BugHuntResult, RunBugHuntInput, TaskSourceKind, TrackerBoard } from '~/types/domain'
4
+ import { apiErrorEnvelope } from '~/composables/api/errors'
5
+ import { useWorkspaceStore } from '~/stores/workspace'
6
+ import { usePersonalSubscriptionsStore } from '~/stores/personalSubscriptions'
7
+
8
+ /** The backend's `error.details.reason` code, when it sent one (see `useApi`'s error envelope). */
9
+ function errorReasonOf(error: unknown): string | null {
10
+ const details = apiErrorEnvelope(error)?.details
11
+ if (!details || typeof details !== 'object') return null
12
+ const reason = (details as Record<string, unknown>).reason
13
+ return typeof reason === 'string' ? reason : null
14
+ }
15
+
16
+ /**
17
+ * Bug-hunt state: the boards of the tracker being browsed, the last hunt's ranked candidates,
18
+ * and the actions behind the three steps (list boards → run the hunt → adopt one candidate).
19
+ *
20
+ * Nothing here is persisted server-side — a hunt is a live read plus a ranking, so the store
21
+ * holds the whole feature's state and a page reload starts a fresh hunt. That is deliberate:
22
+ * a stale ranking of a board that has since moved on is worse than no ranking.
23
+ */
24
+ export const useBugHuntStore = defineStore('bugHunt', () => {
25
+ const api = useApi()
26
+ const workspace = useWorkspaceStore()
27
+
28
+ /** Boards of the last source `loadBoards` was called for, keyed so a source switch re-fetches. */
29
+ const boards = ref<TrackerBoard[]>([])
30
+ const boardsSource = ref<TaskSourceKind | null>(null)
31
+ const boardsLoading = ref(false)
32
+ /**
33
+ * Why board listing failed, if it did. Kept rather than swallowed: a source whose provider
34
+ * can't enumerate boards is a normal, actionable state (type the board in yourself), and an
35
+ * empty picker alone doesn't say that.
36
+ */
37
+ const boardsError = ref<string | null>(null)
38
+ /**
39
+ * The backend's machine-readable reason for that failure. Only `boards_unsupported` means
40
+ * "this tracker cannot enumerate boards, so type one in"; every other failure (an unreachable
41
+ * site, an expired token) is a real error and must be shown as one — offering a free-text
42
+ * field there would just move the same failure to the next click.
43
+ */
44
+ const boardsErrorReason = ref<string | null>(null)
45
+
46
+ const result = ref<BugHuntResult | null>(null)
47
+ const hunting = ref(false)
48
+ const huntError = ref<string | null>(null)
49
+ /** The candidate currently being adopted, so only its own row shows a spinner. */
50
+ const adopting = ref<string | null>(null)
51
+
52
+ const candidates = computed(() => result.value?.candidates ?? [])
53
+ const hasResult = computed(() => result.value !== null)
54
+
55
+ /** Load the boards a hunt can run against for one source. */
56
+ async function loadBoards(source: TaskSourceKind): Promise<void> {
57
+ boardsLoading.value = true
58
+ boardsError.value = null
59
+ boardsErrorReason.value = null
60
+ boardsSource.value = source
61
+ try {
62
+ const view = await api.listTrackerBoards(workspace.requireId(), source)
63
+ // A source switch mid-flight would otherwise land the slower response over the newer
64
+ // one, leaving the picker showing another tracker's boards.
65
+ if (boardsSource.value !== source) return
66
+ boards.value = view.boards
67
+ } catch (e) {
68
+ if (boardsSource.value !== source) return
69
+ boards.value = []
70
+ boardsError.value = e instanceof Error ? e.message : String(e)
71
+ boardsErrorReason.value = errorReasonOf(e)
72
+ } finally {
73
+ boardsLoading.value = false
74
+ }
75
+ }
76
+
77
+ /** Run a hunt and keep its ranked result. Returns false when the scan itself failed. */
78
+ async function hunt(source: TaskSourceKind, input: RunBugHuntInput): Promise<boolean> {
79
+ hunting.value = true
80
+ huntError.value = null
81
+ try {
82
+ result.value = await api.runBugHunt(workspace.requireId(), source, input)
83
+ return true
84
+ } catch (e) {
85
+ result.value = null
86
+ huntError.value = e instanceof Error ? e.message : String(e)
87
+ return false
88
+ } finally {
89
+ hunting.value = false
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Adopt a candidate as a bug task and start its run. Rides the personal password like every
95
+ * other run start, so an individual-usage model prompts here rather than failing the start.
96
+ * Returns the new block's id on success, null when the user cancelled the credential prompt.
97
+ */
98
+ async function adopt(
99
+ source: TaskSourceKind,
100
+ externalId: string,
101
+ containerId: string,
102
+ pipelineId?: string,
103
+ ): Promise<string | null> {
104
+ const personal = usePersonalSubscriptionsStore()
105
+ adopting.value = externalId
106
+ try {
107
+ let blockId: string | null = null
108
+ const ok = await personal.withCredential(async (password) => {
109
+ const adopted = await api.adoptBugHuntCandidate(
110
+ workspace.requireId(),
111
+ source,
112
+ { externalId, containerId, ...(pipelineId ? { pipelineId } : {}) },
113
+ password,
114
+ )
115
+ blockId = adopted.block.id
116
+ await workspace.refresh()
117
+ })
118
+ return ok ? blockId : null
119
+ } finally {
120
+ adopting.value = null
121
+ }
122
+ }
123
+
124
+ /** Drop the last hunt (on close, or when the source/board changes under it). */
125
+ function reset(): void {
126
+ result.value = null
127
+ huntError.value = null
128
+ adopting.value = null
129
+ }
130
+
131
+ return {
132
+ boards,
133
+ boardsSource,
134
+ boardsLoading,
135
+ boardsError,
136
+ boardsErrorReason,
137
+ result,
138
+ candidates,
139
+ hasResult,
140
+ hunting,
141
+ huntError,
142
+ adopting,
143
+ loadBoards,
144
+ hunt,
145
+ adopt,
146
+ reset,
147
+ }
148
+ })
@@ -180,6 +180,10 @@ function createDocumentTaskModals(resetHubReturn: ResetHubReturn) {
180
180
  // the create-in target AND scopes the issue search to the frame's linked repo.
181
181
  // Null → the unscoped "import an issue" surface (workspace-wide search).
182
182
  const taskImport = ref<{ source: TaskSourceKind | null; containerId: string | null } | null>(null)
183
+ // Bug hunt: pick a tracker + one of its boards, rank its open unassigned bugs, adopt one.
184
+ // `containerId` (a service frame or module) preselects where an adopted bug lands; null →
185
+ // opened standalone, and the modal offers every container on the board.
186
+ const bugHunt = ref<{ source: TaskSourceKind | null; containerId: string | null } | null>(null)
183
187
 
184
188
  // Add-task modal: the container (service frame or module) a new task is being
185
189
  // added to, or null when closed. The user types the title + description; nothing
@@ -255,6 +259,13 @@ function createDocumentTaskModals(resetHubReturn: ResetHubReturn) {
255
259
  function closeTaskImport() {
256
260
  taskImport.value = null
257
261
  }
262
+ function openBugHunt(source: TaskSourceKind | null = null, containerId: string | null = null) {
263
+ resetHubReturn()
264
+ bugHunt.value = { source, containerId }
265
+ }
266
+ function closeBugHunt() {
267
+ bugHunt.value = null
268
+ }
258
269
  function openAddTask(containerId: string, prefill: AddTaskPrefill | null = null) {
259
270
  addTaskPrefill.value = prefill
260
271
  addTaskContainerId.value = containerId
@@ -289,6 +300,7 @@ function createDocumentTaskModals(resetHubReturn: ResetHubReturn) {
289
300
  spawnPreview,
290
301
  taskConnect,
291
302
  taskImport,
303
+ bugHunt,
292
304
  addTaskContainerId,
293
305
  addTaskPrefill,
294
306
  reviewFrictionContext,
@@ -306,6 +318,8 @@ function createDocumentTaskModals(resetHubReturn: ResetHubReturn) {
306
318
  closeTaskConnect,
307
319
  openTaskImport,
308
320
  closeTaskImport,
321
+ openBugHunt,
322
+ closeBugHunt,
309
323
  openAddTask,
310
324
  closeAddTask,
311
325
  openReviewFriction,
@@ -0,0 +1,21 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Bug hunt: pick a connected tracker + one of its boards, get its open and
3
+ // unassigned bugs ranked by impact against implementation complexity, then adopt
4
+ // one onto the board and run the bug-fix pipeline on it.
5
+ //
6
+ // The interactive dual of the recurring `bug-intake` step. All wire shapes are
7
+ // sourced from @cat-factory/contracts (single source of truth).
8
+ // ---------------------------------------------------------------------------
9
+
10
+ export type {
11
+ TrackerBoard,
12
+ TrackerBoardsView,
13
+ BugCandidate,
14
+ BugHuntAnalysis,
15
+ BugHuntAnalysisStatus,
16
+ BugHuntCandidate,
17
+ BugHuntConfidence,
18
+ BugHuntResult,
19
+ RunBugHuntInput,
20
+ AdoptBugHuntCandidateInput,
21
+ } from '@cat-factory/contracts'
@@ -170,6 +170,7 @@ export type * from './fragments'
170
170
  export type * from './skills'
171
171
  export type * from './documents'
172
172
  export type * from './tasks'
173
+ export type * from './bugHunt'
173
174
  export type * from './bootstrap'
174
175
  export type * from './envConfigRepair'
175
176
  export type * from './github'
@@ -1650,7 +1650,8 @@
1650
1650
  "title": "Diesen Dienst archivieren?",
1651
1651
  "body": "„{name}“ und seine Aufgaben werden vom Board ausgeblendet. Du kannst den Dienst jederzeit wiederherstellen."
1652
1652
  },
1653
- "runBlocked": "Blockiert durch eine unerledigte Abhängigkeit: {names} | Blockiert durch {count} unerledigte Abhängigkeiten: {names}"
1653
+ "runBlocked": "Blockiert durch eine unerledigte Abhängigkeit: {names} | Blockiert durch {count} unerledigte Abhängigkeiten: {names}",
1654
+ "huntBugs": "Fehler jagen"
1654
1655
  }
1655
1656
  },
1656
1657
  "layout": {
@@ -1989,7 +1990,8 @@
1989
1990
  "accountSettings": "Konto-Einstellungen",
1990
1991
  "localModels": "Meine lokalen Runner",
1991
1992
  "sandbox": "Sandbox öffnen",
1992
- "shortcuts": "Tastenkürzel"
1993
+ "shortcuts": "Tastenkürzel",
1994
+ "bugHunt": "Fehlerjagd"
1993
1995
  },
1994
1996
  "keywords": {
1995
1997
  "newPipeline": "pipeline agents chain",
@@ -2009,7 +2011,8 @@
2009
2011
  "accountSettings": "account team members roles invitations email api keys fragment best practice library context organization personal",
2010
2012
  "localModels": "local model runner ollama lm studio llamacpp vllm endpoint",
2011
2013
  "sandbox": "sandbox prompt model test experiment judge fixture benchmark evaluate",
2012
- "shortcuts": "keyboard shortcuts keys hotkeys cheatsheet help"
2014
+ "shortcuts": "keyboard shortcuts keys hotkeys cheatsheet help",
2015
+ "bugHunt": "fehler bug jagd triage backlog tracker nicht zugewiesen"
2013
2016
  }
2014
2017
  },
2015
2018
  "shortcuts": {
@@ -2102,6 +2105,10 @@
2102
2105
  },
2103
2106
  "documentTemplates": {
2104
2107
  "label": "Vorlagen & Beispiele"
2108
+ },
2109
+ "bugHunt": {
2110
+ "label": "Fehlerjagd",
2111
+ "description": "Offene, nicht zugewiesene Fehler eines Boards bewerten und einen zum Beheben auswählen"
2105
2112
  }
2106
2113
  }
2107
2114
  },
@@ -3300,6 +3307,49 @@
3300
3307
  "oauthOr": "oder mit einem API-Schlüssel verbinden"
3301
3308
  }
3302
3309
  },
3310
+ "bugHunt": {
3311
+ "title": "Fehlerjagd",
3312
+ "intro": "Durchsuche ein Tracker-Board nach offenen, nicht zugewiesenen Fehlern und bewerte sie nach Auswirkung im Verhältnis zum geschätzten Aufwand. Wähle einen aus, und er wird zu einer Aufgabe, die die Fehlerbehebungs-Pipeline durchläuft.",
3313
+ "connectFirst": "Verbinde oder aktiviere zuerst eine Aufgabenquelle.",
3314
+ "connectSource": "{label} verbinden",
3315
+ "needFrameFirst": "Füge zuerst einen Service-Rahmen zum Board hinzu, damit ein übernommener Fehler irgendwo landen kann.",
3316
+ "tracker": "Tracker",
3317
+ "board": "Board",
3318
+ "pickBoard": "Board auswählen",
3319
+ "boardPlaceholder": "Projektschlüssel, Team-ID oder owner/repo",
3320
+ "boardsFailed": "Boards konnten nicht geladen werden: {reason}",
3321
+ "issueType": "Vorgangstyp",
3322
+ "issueTypeHelp": "Standard ist bug. Wird von Trackern ohne Vorgangstypen ignoriert.",
3323
+ "labels": "Labels",
3324
+ "labelsHelp": "Durch Komma getrennt. Alle müssen vorhanden sein.",
3325
+ "adoptInto": "Ausgewählten Fehler hinzufügen zu",
3326
+ "run": "Jagen",
3327
+ "running": "Board wird gelesen und die Funde werden bewertet…",
3328
+ "huntFailed": "Die Jagd ist fehlgeschlagen",
3329
+ "notAssessed": "Nicht bewertet",
3330
+ "recommended": "Empfohlen",
3331
+ "adopt": "Diesen wählen",
3332
+ "adopted": "{id} übernommen",
3333
+ "adoptedRunning": "Die Fehlerbehebungs-Pipeline läuft dafür.",
3334
+ "adoptFailed": "Dieser Fehler konnte nicht übernommen werden",
3335
+ "noCandidates": "Auf diesem Board gab es keine offenen, nicht zugewiesenen Fehler.",
3336
+ "ratings": "Auswirkung {impact}/5, Aufwand {complexity}/5, Konfidenz {confidence}",
3337
+ "viaModel": "Bewertet von {model}.",
3338
+ "truncated": "Es wurden nur die ersten {count} passenden Fehler geprüft; dieses Board enthält mehr.",
3339
+ "comments": "{count} Kommentar | {count} Kommentare",
3340
+ "confidence": {
3341
+ "high": "hoch",
3342
+ "medium": "mittel",
3343
+ "low": "niedrig"
3344
+ },
3345
+ "status": {
3346
+ "ranked": "Sortiert nach Auswirkung im Verhältnis zum geschätzten Aufwand.",
3347
+ "unavailable": "Es ist kein Bewertungsmodell konfiguriert, daher sind diese unbewertet.",
3348
+ "failed": "Die Bewertung konnte nicht abgeschlossen werden, daher sind diese unbewertet.",
3349
+ "over_budget": "Dieser Arbeitsbereich hat sein Ausgabenbudget überschritten, daher wurden diese nicht bewertet.",
3350
+ "empty": "Nichts zu bewerten."
3351
+ }
3352
+ },
3303
3353
  "pipeline": {
3304
3354
  "iterationCap": {
3305
3355
  "extraRound": "Noch eine Runde",
@@ -5236,11 +5286,12 @@
5236
5286
  },
5237
5287
  "reviewingChunks": {
5238
5288
  "title": "Abschnitte werden geprüft…",
5239
- "hint": "Die Zerlegung ist abgeschlossen. Jeder Abschnitt wird nacheinander geprüft und die Ergebnisse werden gesammelt."
5289
+ "hint": "Die Zerlegung ist abgeschlossen. Der Prüfer arbeitet die Abschnitte in kleinen Gruppen ab und sammelt die Ergebnisse, sobald ein Abschnitt zurückkommt."
5240
5290
  },
5241
5291
  "chunks": "{completed} von {total} Abschnitten geprüft",
5242
5292
  "inProgress": "{count} in Bearbeitung",
5243
5293
  "activeHeading": "Wird jetzt geprüft",
5294
+ "activeIdle": "Derzeit wird kein Abschnitt geprüft. Der Prüfer startet gerade die nächste Gruppe.",
5244
5295
  "chunksHeading": "Abschnitte",
5245
5296
  "chunkStatus": {
5246
5297
  "completed": "Geprüft",
@@ -1398,7 +1398,8 @@
1398
1398
  "runBlocked": "Blocked by an unfinished dependency: {names} | Blocked by {count} unfinished dependencies: {names}",
1399
1399
  "@runBlocked": {
1400
1400
  "description": "Count-driven plural: {count} unfinished dependencies, {names} their comma-joined titles. Languages with more than two plural forms (e.g. Polish, Ukrainian: one/few/many) need the extra pipe-separated forms."
1401
- }
1401
+ },
1402
+ "huntBugs": "Hunt bugs"
1402
1403
  }
1403
1404
  },
1404
1405
  "observability": {
@@ -2003,7 +2004,8 @@
2003
2004
  "accountSettings": "Account settings",
2004
2005
  "localModels": "My local runners",
2005
2006
  "sandbox": "Open Sandbox",
2006
- "shortcuts": "Keyboard shortcuts"
2007
+ "shortcuts": "Keyboard shortcuts",
2008
+ "bugHunt": "Bug hunt"
2007
2009
  },
2008
2010
  "keywords": {
2009
2011
  "newPipeline": "pipeline agents chain",
@@ -2023,7 +2025,8 @@
2023
2025
  "accountSettings": "account team members roles invitations email api keys fragment best practice library context organization personal",
2024
2026
  "localModels": "local model runner ollama lm studio llamacpp vllm endpoint",
2025
2027
  "sandbox": "sandbox prompt model test experiment judge fixture benchmark evaluate",
2026
- "shortcuts": "keyboard shortcuts keys hotkeys cheatsheet help"
2028
+ "shortcuts": "keyboard shortcuts keys hotkeys cheatsheet help",
2029
+ "bugHunt": "bug hunt triage backlog issue tracker unassigned"
2027
2030
  }
2028
2031
  },
2029
2032
  "shortcuts": {
@@ -2116,6 +2119,10 @@
2116
2119
  },
2117
2120
  "documentTemplates": {
2118
2121
  "label": "Templates & examples"
2122
+ },
2123
+ "bugHunt": {
2124
+ "label": "Bug hunt",
2125
+ "description": "Rate a board's open, unassigned bugs and pick one to fix"
2119
2126
  }
2120
2127
  }
2121
2128
  },
@@ -3702,6 +3709,52 @@
3702
3709
  "oauthOr": "or connect with an API key"
3703
3710
  }
3704
3711
  },
3712
+ "bugHunt": {
3713
+ "title": "Bug hunt",
3714
+ "intro": "Scan a tracker board for open, unassigned bugs and rank them by impact against how hard each looks to fix. Pick one and it becomes a task running the bug-fix pipeline.",
3715
+ "connectFirst": "Connect or enable a task source first.",
3716
+ "connectSource": "Connect {label}",
3717
+ "needFrameFirst": "Add a service frame to the board first, so a picked-up bug has somewhere to land.",
3718
+ "tracker": "Tracker",
3719
+ "board": "Board",
3720
+ "pickBoard": "Pick a board",
3721
+ "boardPlaceholder": "Project key, team id or owner/repo",
3722
+ "boardsFailed": "Boards could not be loaded: {reason}",
3723
+ "issueType": "Issue type",
3724
+ "issueTypeHelp": "Defaults to bug. Ignored by trackers with no issue types.",
3725
+ "labels": "Labels",
3726
+ "labelsHelp": "Comma separated. All of them must be present.",
3727
+ "adoptInto": "Add the picked bug to",
3728
+ "run": "Hunt",
3729
+ "running": "Reading the board and rating what it finds…",
3730
+ "huntFailed": "The hunt failed",
3731
+ "notAssessed": "Not assessed",
3732
+ "recommended": "Recommended",
3733
+ "adopt": "Pick this",
3734
+ "adopted": "Picked up {id}",
3735
+ "adoptedRunning": "The bug-fix pipeline is running on it.",
3736
+ "adoptFailed": "Could not pick up this bug",
3737
+ "noCandidates": "No open, unassigned bugs matched on this board.",
3738
+ "ratings": "Impact {impact}/5, complexity {complexity}/5, {confidence} confidence",
3739
+ "viaModel": "Rated by {model}.",
3740
+ "truncated": "Only the first {count} matching bugs were scanned; this board holds more.",
3741
+ "comments": "{count} comment | {count} comments",
3742
+ "@comments": {
3743
+ "description": "Count-driven plural: how many comments a candidate bug has accumulated. Languages with more than two plural forms (e.g. Polish, Ukrainian: one/few/many) need the extra pipe-separated forms."
3744
+ },
3745
+ "confidence": {
3746
+ "high": "high",
3747
+ "medium": "medium",
3748
+ "low": "low"
3749
+ },
3750
+ "status": {
3751
+ "ranked": "Ranked by impact against how hard each looks to fix.",
3752
+ "unavailable": "No rating model is configured, so these are unrated.",
3753
+ "failed": "The rating could not be completed, so these are unrated.",
3754
+ "over_budget": "This workspace is over its spend budget, so these were not rated.",
3755
+ "empty": "Nothing to rate."
3756
+ }
3757
+ },
3705
3758
  "pipeline": {
3706
3759
  "iterationCap": {
3707
3760
  "extraRound": "One more round",
@@ -5380,11 +5433,12 @@
5380
5433
  },
5381
5434
  "reviewingChunks": {
5382
5435
  "title": "Reviewing the chunks…",
5383
- "hint": "Slicing is done. Working through each chunk one at a time and collecting findings."
5436
+ "hint": "Slicing is done. The reviewer works through the chunks a few at a time and collects findings as each one comes back."
5384
5437
  },
5385
5438
  "chunks": "{completed} of {total} chunks reviewed",
5386
5439
  "inProgress": "{count} in progress",
5387
5440
  "activeHeading": "Reviewing now",
5441
+ "activeIdle": "No chunk is in flight right now. The reviewer is starting the next batch.",
5388
5442
  "chunksHeading": "Chunks",
5389
5443
  "chunkStatus": {
5390
5444
  "completed": "Reviewed",
@@ -1335,7 +1335,8 @@
1335
1335
  "title": "¿Archivar este servicio?",
1336
1336
  "body": "«{name}» y sus tareas se ocultarán del tablero. Puedes restaurarlo en cualquier momento."
1337
1337
  },
1338
- "runBlocked": "Bloqueado por una dependencia sin terminar: {names} | Bloqueado por {count} dependencias sin terminar: {names}"
1338
+ "runBlocked": "Bloqueado por una dependencia sin terminar: {names} | Bloqueado por {count} dependencias sin terminar: {names}",
1339
+ "huntBugs": "Cazar errores"
1339
1340
  }
1340
1341
  },
1341
1342
  "observability": {
@@ -1937,7 +1938,8 @@
1937
1938
  "accountSettings": "Ajustes de la cuenta",
1938
1939
  "localModels": "Mis ejecutores locales",
1939
1940
  "sandbox": "Abrir el entorno de pruebas",
1940
- "shortcuts": "Atajos de teclado"
1941
+ "shortcuts": "Atajos de teclado",
1942
+ "bugHunt": "Caza de errores"
1941
1943
  },
1942
1944
  "keywords": {
1943
1945
  "newPipeline": "canalización agentes cadena pipeline",
@@ -1957,7 +1959,8 @@
1957
1959
  "accountSettings": "cuenta equipo miembros roles invitaciones correo claves api fragmento buenas prácticas biblioteca contexto organización personal",
1958
1960
  "localModels": "modelo local ejecutor ollama lm studio llamacpp vllm endpoint",
1959
1961
  "sandbox": "entorno de pruebas prompt modelo prueba experimento juez fixture benchmark evaluar",
1960
- "shortcuts": "atajos teclado teclas ayuda"
1962
+ "shortcuts": "atajos teclado teclas ayuda",
1963
+ "bugHunt": "error bug caza triaje backlog incidencias sin asignar"
1961
1964
  }
1962
1965
  },
1963
1966
  "integrationsHub": {
@@ -2043,6 +2046,10 @@
2043
2046
  },
2044
2047
  "documentTemplates": {
2045
2048
  "label": "Plantillas y ejemplos"
2049
+ },
2050
+ "bugHunt": {
2051
+ "label": "Caza de errores",
2052
+ "description": "Valora los errores abiertos y sin asignar de un tablero y elige uno para arreglar"
2046
2053
  }
2047
2054
  }
2048
2055
  },
@@ -3594,6 +3601,49 @@
3594
3601
  "oauthOr": "o conecta con una clave API"
3595
3602
  }
3596
3603
  },
3604
+ "bugHunt": {
3605
+ "title": "Caza de errores",
3606
+ "intro": "Explora un tablero del gestor de incidencias en busca de errores abiertos y sin asignar, y clasifícalos por impacto frente a lo difícil que parece arreglar cada uno. Elige uno y se convertirá en una tarea que ejecuta la canalización de corrección de errores.",
3607
+ "connectFirst": "Conecta o activa primero una fuente de tareas.",
3608
+ "connectSource": "Conectar {label}",
3609
+ "needFrameFirst": "Añade primero un marco de servicio al tablero para que el error elegido tenga dónde aterrizar.",
3610
+ "tracker": "Gestor de incidencias",
3611
+ "board": "Tablero",
3612
+ "pickBoard": "Elige un tablero",
3613
+ "boardPlaceholder": "Clave de proyecto, id de equipo o owner/repo",
3614
+ "boardsFailed": "No se pudieron cargar los tableros: {reason}",
3615
+ "issueType": "Tipo de incidencia",
3616
+ "issueTypeHelp": "Por defecto bug. Se ignora en gestores sin tipos de incidencia.",
3617
+ "labels": "Etiquetas",
3618
+ "labelsHelp": "Separadas por comas. Todas deben estar presentes.",
3619
+ "adoptInto": "Añadir el error elegido a",
3620
+ "run": "Cazar",
3621
+ "running": "Leyendo el tablero y valorando lo que encuentra…",
3622
+ "huntFailed": "La caza ha fallado",
3623
+ "notAssessed": "Sin valorar",
3624
+ "recommended": "Recomendado",
3625
+ "adopt": "Elegir este",
3626
+ "adopted": "{id} adoptado",
3627
+ "adoptedRunning": "La canalización de corrección de errores ya se está ejecutando.",
3628
+ "adoptFailed": "No se ha podido adoptar este error",
3629
+ "noCandidates": "No hay errores abiertos y sin asignar que coincidan en este tablero.",
3630
+ "ratings": "Impacto {impact}/5, complejidad {complexity}/5, confianza {confidence}",
3631
+ "viaModel": "Valorado por {model}.",
3632
+ "truncated": "Solo se han explorado los primeros {count} errores coincidentes; este tablero contiene más.",
3633
+ "comments": "{count} comentario | {count} comentarios",
3634
+ "confidence": {
3635
+ "high": "alta",
3636
+ "medium": "media",
3637
+ "low": "baja"
3638
+ },
3639
+ "status": {
3640
+ "ranked": "Ordenados por impacto frente a lo difícil que parece arreglar cada uno.",
3641
+ "unavailable": "No hay ningún modelo de valoración configurado, así que están sin valorar.",
3642
+ "failed": "No se ha podido completar la valoración, así que están sin valorar.",
3643
+ "over_budget": "Este espacio de trabajo ha superado su presupuesto de gasto, así que no se han valorado.",
3644
+ "empty": "Nada que valorar."
3645
+ }
3646
+ },
3597
3647
  "pipeline": {
3598
3648
  "iterationCap": {
3599
3649
  "extraRound": "Una ronda más",
@@ -5224,11 +5274,12 @@
5224
5274
  },
5225
5275
  "reviewingChunks": {
5226
5276
  "title": "Revisando los fragmentos…",
5227
- "hint": "La división ha terminado. Revisando cada fragmento de uno en uno y recopilando los hallazgos."
5277
+ "hint": "La división ha terminado. El revisor examina los fragmentos en grupos pequeños y recopila los hallazgos a medida que cada uno vuelve."
5228
5278
  },
5229
5279
  "chunks": "{completed} de {total} fragmentos revisados",
5230
5280
  "inProgress": "{count} en curso",
5231
5281
  "activeHeading": "Revisando ahora",
5282
+ "activeIdle": "Ahora mismo no hay ningún fragmento en curso. El revisor está iniciando el siguiente grupo.",
5232
5283
  "chunksHeading": "Fragmentos",
5233
5284
  "chunkStatus": {
5234
5285
  "completed": "Revisado",
@@ -1335,7 +1335,8 @@
1335
1335
  "title": "Archiver ce service ?",
1336
1336
  "body": "« {name} » et ses tâches seront masqués du tableau. Vous pouvez le restaurer à tout moment."
1337
1337
  },
1338
- "runBlocked": "Bloqué par une dépendance non terminée : {names} | Bloqué par {count} dépendances non terminées : {names}"
1338
+ "runBlocked": "Bloqué par une dépendance non terminée : {names} | Bloqué par {count} dépendances non terminées : {names}",
1339
+ "huntBugs": "Chasser les bugs"
1339
1340
  }
1340
1341
  },
1341
1342
  "observability": {
@@ -1937,7 +1938,8 @@
1937
1938
  "accountSettings": "Paramètres du compte",
1938
1939
  "localModels": "Mes exécuteurs locaux",
1939
1940
  "sandbox": "Ouvrir le bac à sable",
1940
- "shortcuts": "Raccourcis clavier"
1941
+ "shortcuts": "Raccourcis clavier",
1942
+ "bugHunt": "Chasse aux bugs"
1941
1943
  },
1942
1944
  "keywords": {
1943
1945
  "newPipeline": "pipeline agents chaîne",
@@ -1957,7 +1959,8 @@
1957
1959
  "accountSettings": "compte équipe membres rôles invitations e-mail clés api fragment bonnes pratiques bibliothèque contexte organisation personnel",
1958
1960
  "localModels": "modèle local exécuteur ollama lm studio llamacpp vllm endpoint",
1959
1961
  "sandbox": "bac à sable prompt modèle test expérience juge fixture benchmark évaluer",
1960
- "shortcuts": "raccourcis clavier touches aide"
1962
+ "shortcuts": "raccourcis clavier touches aide",
1963
+ "bugHunt": "bug chasse tri backlog tickets non assignés"
1961
1964
  }
1962
1965
  },
1963
1966
  "integrationsHub": {
@@ -2043,6 +2046,10 @@
2043
2046
  },
2044
2047
  "documentTemplates": {
2045
2048
  "label": "Modèles et exemples"
2049
+ },
2050
+ "bugHunt": {
2051
+ "label": "Chasse aux bugs",
2052
+ "description": "Évaluer les bugs ouverts et non assignés d'un tableau et en choisir un à corriger"
2046
2053
  }
2047
2054
  }
2048
2055
  },
@@ -3594,6 +3601,49 @@
3594
3601
  "oauthOr": "ou connectez-vous avec une clé API"
3595
3602
  }
3596
3603
  },
3604
+ "bugHunt": {
3605
+ "title": "Chasse aux bugs",
3606
+ "intro": "Parcourez un tableau du gestionnaire de tickets à la recherche de bugs ouverts et non assignés, puis classez-les selon leur impact face à la difficulté apparente du correctif. Choisissez-en un et il devient une tâche qui exécute le pipeline de correction.",
3607
+ "connectFirst": "Connectez ou activez d'abord une source de tâches.",
3608
+ "connectSource": "Connecter {label}",
3609
+ "needFrameFirst": "Ajoutez d'abord un cadre de service au tableau, pour que le bug retenu ait un endroit où atterrir.",
3610
+ "tracker": "Gestionnaire de tickets",
3611
+ "board": "Tableau",
3612
+ "pickBoard": "Choisir un tableau",
3613
+ "boardPlaceholder": "Clé de projet, id d'équipe ou owner/repo",
3614
+ "boardsFailed": "Impossible de charger les tableaux : {reason}",
3615
+ "issueType": "Type de ticket",
3616
+ "issueTypeHelp": "Par défaut bug. Ignoré par les gestionnaires sans types de tickets.",
3617
+ "labels": "Étiquettes",
3618
+ "labelsHelp": "Séparées par des virgules. Toutes doivent être présentes.",
3619
+ "adoptInto": "Ajouter le bug retenu à",
3620
+ "run": "Chasser",
3621
+ "running": "Lecture du tableau et évaluation des résultats…",
3622
+ "huntFailed": "La chasse a échoué",
3623
+ "notAssessed": "Non évalué",
3624
+ "recommended": "Recommandé",
3625
+ "adopt": "Choisir celui-ci",
3626
+ "adopted": "{id} retenu",
3627
+ "adoptedRunning": "Le pipeline de correction est en cours dessus.",
3628
+ "adoptFailed": "Impossible de retenir ce bug",
3629
+ "noCandidates": "Aucun bug ouvert et non assigné ne correspond sur ce tableau.",
3630
+ "ratings": "Impact {impact}/5, complexité {complexity}/5, confiance {confidence}",
3631
+ "viaModel": "Évalué par {model}.",
3632
+ "truncated": "Seuls les {count} premiers bugs correspondants ont été parcourus ; ce tableau en contient davantage.",
3633
+ "comments": "{count} commentaire | {count} commentaires",
3634
+ "confidence": {
3635
+ "high": "élevée",
3636
+ "medium": "moyenne",
3637
+ "low": "faible"
3638
+ },
3639
+ "status": {
3640
+ "ranked": "Classés par impact face à la difficulté apparente du correctif.",
3641
+ "unavailable": "Aucun modèle d'évaluation n'est configuré, ils sont donc non évalués.",
3642
+ "failed": "L'évaluation n'a pas pu aboutir, ils sont donc non évalués.",
3643
+ "over_budget": "Cet espace de travail a dépassé son budget de dépenses, ces bogues n'ont donc pas été évalués.",
3644
+ "empty": "Rien à évaluer."
3645
+ }
3646
+ },
3597
3647
  "pipeline": {
3598
3648
  "iterationCap": {
3599
3649
  "extraRound": "Un tour de plus",
@@ -5224,11 +5274,12 @@
5224
5274
  },
5225
5275
  "reviewingChunks": {
5226
5276
  "title": "Revue des sections…",
5227
- "hint": "Le découpage est terminé. Chaque section est examinée l'une après l'autre et les remarques sont rassemblées."
5277
+ "hint": "Le découpage est terminé. Le relecteur traite les sections par petits groupes et rassemble les remarques au fur et à mesure des retours."
5228
5278
  },
5229
5279
  "chunks": "{completed} sur {total} sections examinées",
5230
5280
  "inProgress": "{count} en cours",
5231
5281
  "activeHeading": "Revue en cours",
5282
+ "activeIdle": "Aucune section n'est en cours pour l'instant. Le relecteur lance le groupe suivant.",
5232
5283
  "chunksHeading": "Sections",
5233
5284
  "chunkStatus": {
5234
5285
  "completed": "Examinée",