@cat-factory/app 0.49.2 → 0.50.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.
- package/app/components/layout/IntegrationsHub.vue +3 -66
- package/app/components/layout/SideBar.vue +39 -0
- package/app/components/settings/ExecutionBackendSelector.vue +171 -0
- package/app/components/settings/InfrastructureWindow.vue +36 -126
- package/app/components/settings/LocalContainerPoolSettings.vue +181 -0
- package/app/components/settings/ProviderConnectionTab.vue +25 -12
- package/app/pages/index.vue +0 -4
- package/app/stores/auth.ts +10 -1
- package/app/stores/ui.ts +14 -18
- package/i18n/locales/en.json +21 -22
- package/i18n/locales/es.json +24 -25
- package/i18n/locales/fr.json +24 -25
- package/i18n/locales/pl.json +24 -25
- package/i18n/locales/uk.json +24 -25
- package/package.json +2 -2
- package/app/components/settings/LocalModeSettingsPanel.vue +0 -195
package/i18n/locales/pl.json
CHANGED
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"configuration": "Konfiguracja",
|
|
35
35
|
"workspaceSettings": "Ustawienia obszaru roboczego",
|
|
36
36
|
"modelConfiguration": "Konfiguracja modelu",
|
|
37
|
-
"accountSettings": "Ustawienia konta"
|
|
37
|
+
"accountSettings": "Ustawienia konta",
|
|
38
|
+
"infrastructure": "Infrastruktura"
|
|
38
39
|
},
|
|
39
40
|
"board": {
|
|
40
41
|
"toolbar": {
|
|
@@ -1111,7 +1112,6 @@
|
|
|
1111
1112
|
"documents": "Dokumenty",
|
|
1112
1113
|
"taskTrackers": "Narzędzia do śledzenia zadań",
|
|
1113
1114
|
"observability": "Obserwowalność",
|
|
1114
|
-
"infrastructure": "Infrastruktura",
|
|
1115
1115
|
"personal": "Osobiste (tylko Ty)"
|
|
1116
1116
|
},
|
|
1117
1117
|
"items": {
|
|
@@ -1149,16 +1149,6 @@
|
|
|
1149
1149
|
"label": "Kondycja po wydaniu",
|
|
1150
1150
|
"description": "Obserwuj monitory i SLO po wdrożeniu wydania (Datadog)."
|
|
1151
1151
|
},
|
|
1152
|
-
"infrastructure": {
|
|
1153
|
-
"label": "Infrastruktura",
|
|
1154
|
-
"description": "Samodzielnie hostowana pula wykonawców dla agentów kontenerowych oraz efemeryczne środowiska testowe.",
|
|
1155
|
-
"agents": "Agenci: {state}",
|
|
1156
|
-
"envs": "Środowiska: {state}"
|
|
1157
|
-
},
|
|
1158
|
-
"localMode": {
|
|
1159
|
-
"label": "Tryb lokalny",
|
|
1160
|
-
"description": "Pula ciepłych kontenerów oraz ponowne użycie checkoutu na repozytorium dla lokalnego silnika."
|
|
1161
|
-
},
|
|
1162
1152
|
"githubPat": {
|
|
1163
1153
|
"label": "Mój token GitHub",
|
|
1164
1154
|
"description": "Osobisty token dostępu używany do uruchomień, które rozpoczynasz (pushe, PR-y, CI, scalanie)."
|
|
@@ -1225,8 +1215,8 @@
|
|
|
1225
1215
|
"windowTitle": "Infrastruktura",
|
|
1226
1216
|
"noneAvailable": "W tym wdrożeniu nie włączono żadnych dostawców infrastruktury.",
|
|
1227
1217
|
"tabs": {
|
|
1228
|
-
"
|
|
1229
|
-
"
|
|
1218
|
+
"testEnvironments": "Środowiska testowe",
|
|
1219
|
+
"agentContainers": "Agenci kontenerowi"
|
|
1230
1220
|
},
|
|
1231
1221
|
"kind": {
|
|
1232
1222
|
"environment": {
|
|
@@ -1250,17 +1240,6 @@
|
|
|
1250
1240
|
"reenterSecrets": "Wprowadź ponownie każdy sekret, aby zapisać — przechowywane sekrety są tylko do zapisu i nie są wyświetlane.",
|
|
1251
1241
|
"starterHint": "To jest przykład startowy. Zmodyfikuj go, aby pasował do API Twojego dostawcy."
|
|
1252
1242
|
},
|
|
1253
|
-
"delegation": {
|
|
1254
|
-
"title": "Delegowanie lokalne",
|
|
1255
|
-
"intro": "Domyślnie ta maszyna uruchamia wszystko lokalnie — agentów kontenerowych na Dockerze hosta, a infrastrukturę Testera przez docker-compose wewnątrz kontenera. Włącz poniższe opcje, aby przekazać dowolne z tych zadań do usługi zewnętrznej. Dotyczy wyłącznie trybu lokalnego.",
|
|
1256
|
-
"agentsToggle": "Uruchamiaj agentów kontenerowych w puli wykonawców",
|
|
1257
|
-
"agentsHint": "Wysyłaj każdego agenta kontenerowego (koder, tester, scalający, bootstrap, …) do samodzielnie hostowanej puli wykonawców tego obszaru roboczego zamiast na Dockera hosta.",
|
|
1258
|
-
"registerPoolPrompt": "Najpierw {link}, aby to włączyć.",
|
|
1259
|
-
"registerPoolLink": "Zarejestruj pulę wykonawców",
|
|
1260
|
-
"envToggle": "Udostępniaj środowiska Testera przez dostawcę",
|
|
1261
|
-
"envHint": "Uruchom środowisko podglądowe Testera przez dostawcę środowisk skonfigurowanego poniżej zamiast przez docker-compose wewnątrz kontenera. Najpierw połącz dostawcę, aby to włączyć.",
|
|
1262
|
-
"updateFailed": "Nie udało się zaktualizować delegowania"
|
|
1263
|
-
},
|
|
1264
1243
|
"viewLogs": "Pokaż dzienniki",
|
|
1265
1244
|
"hideLogs": "Ukryj dzienniki",
|
|
1266
1245
|
"connectedAt": "Połączono · {baseUrl}",
|
|
@@ -1343,6 +1322,10 @@
|
|
|
1343
1322
|
"caCertPem": "Certyfikat CA klastra (PEM)",
|
|
1344
1323
|
"caCertPemHelp": "Wklej pakiet CA klastra, aby certyfikat TLS apiservera został zweryfikowany. Pomiń tylko dla publicznie zaufanego CA.",
|
|
1345
1324
|
"harnessPort": "Port harnessa"
|
|
1325
|
+
},
|
|
1326
|
+
"advancedManifest": {
|
|
1327
|
+
"summary": "Zaawansowane: niestandardowy harmonogram oparty na API",
|
|
1328
|
+
"intro": "Potrzebne tylko do zintegrowania niestandardowego harmonogramu opartego na API. Typowe backendy (lokalny Docker, Cloudflare Containers i Kubernetes) tego nie wymagają; opisz tutaj API HTTP własnego harmonogramu tylko, jeśli go używasz."
|
|
1346
1329
|
}
|
|
1347
1330
|
},
|
|
1348
1331
|
"serviceFragmentDefaults": {
|
|
@@ -1693,6 +1676,22 @@
|
|
|
1693
1676
|
"removed": "Runner usunięty",
|
|
1694
1677
|
"removeFailed": "Nie udało się usunąć runnera"
|
|
1695
1678
|
}
|
|
1679
|
+
},
|
|
1680
|
+
"infrastructure": {
|
|
1681
|
+
"active": "Aktywne: {backend}",
|
|
1682
|
+
"registerHint": "Zarejestruj pulę runnerów poniżej, aby to włączyć.",
|
|
1683
|
+
"updateFailed": "Nie udało się zaktualizować backendu wykonawczego",
|
|
1684
|
+
"executionBackend": {
|
|
1685
|
+
"label": "Gdzie działają agenci",
|
|
1686
|
+
"local-docker": "Lokalny Docker (host)",
|
|
1687
|
+
"cloudflare-containers": "Cloudflare Containers (wbudowane)",
|
|
1688
|
+
"runner-pool": "Samodzielnie hostowana pula runnerów"
|
|
1689
|
+
},
|
|
1690
|
+
"testEnvBackend": {
|
|
1691
|
+
"label": "Gdzie działają środowiska testowe",
|
|
1692
|
+
"local-compose": "docker-compose w kontenerze",
|
|
1693
|
+
"environment-provider": "Dostawca środowisk"
|
|
1694
|
+
}
|
|
1696
1695
|
}
|
|
1697
1696
|
},
|
|
1698
1697
|
"providers": {
|
package/i18n/locales/uk.json
CHANGED
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"configuration": "Конфігурація",
|
|
35
35
|
"workspaceSettings": "Налаштування робочого простору",
|
|
36
36
|
"modelConfiguration": "Конфігурація моделі",
|
|
37
|
-
"accountSettings": "Налаштування облікового запису"
|
|
37
|
+
"accountSettings": "Налаштування облікового запису",
|
|
38
|
+
"infrastructure": "Інфраструктура"
|
|
38
39
|
},
|
|
39
40
|
"board": {
|
|
40
41
|
"toolbar": {
|
|
@@ -1111,7 +1112,6 @@
|
|
|
1111
1112
|
"documents": "Документи",
|
|
1112
1113
|
"taskTrackers": "Трекери завдань",
|
|
1113
1114
|
"observability": "Спостережуваність",
|
|
1114
|
-
"infrastructure": "Інфраструктура",
|
|
1115
1115
|
"personal": "Особисте (лише ви)"
|
|
1116
1116
|
},
|
|
1117
1117
|
"items": {
|
|
@@ -1149,16 +1149,6 @@
|
|
|
1149
1149
|
"label": "Стан після випуску",
|
|
1150
1150
|
"description": "Стежте за моніторами й SLO після випуску версії (Datadog)."
|
|
1151
1151
|
},
|
|
1152
|
-
"infrastructure": {
|
|
1153
|
-
"label": "Інфраструктура",
|
|
1154
|
-
"description": "Самостійно розміщений пул виконавців для контейнерних агентів і ефемерні тестові середовища.",
|
|
1155
|
-
"agents": "Агенти: {state}",
|
|
1156
|
-
"envs": "Середовища: {state}"
|
|
1157
|
-
},
|
|
1158
|
-
"localMode": {
|
|
1159
|
-
"label": "Локальний режим",
|
|
1160
|
-
"description": "Пул теплих контейнерів і повторне використання checkout на репозиторій для локального виконавця."
|
|
1161
|
-
},
|
|
1162
1152
|
"githubPat": {
|
|
1163
1153
|
"label": "Мій токен GitHub",
|
|
1164
1154
|
"description": "Особистий токен доступу, який використовується для запусків, що ви розпочинаєте (pushes, PR-и, CI, злиття)."
|
|
@@ -1225,8 +1215,8 @@
|
|
|
1225
1215
|
"windowTitle": "Інфраструктура",
|
|
1226
1216
|
"noneAvailable": "У цьому розгортанні не ввімкнено жодного постачальника інфраструктури.",
|
|
1227
1217
|
"tabs": {
|
|
1228
|
-
"
|
|
1229
|
-
"
|
|
1218
|
+
"testEnvironments": "Тестові середовища",
|
|
1219
|
+
"agentContainers": "Контейнерні агенти"
|
|
1230
1220
|
},
|
|
1231
1221
|
"kind": {
|
|
1232
1222
|
"environment": {
|
|
@@ -1250,17 +1240,6 @@
|
|
|
1250
1240
|
"reenterSecrets": "Введіть кожен секрет повторно, щоб зберегти — збережені секрети доступні лише для запису й не показуються.",
|
|
1251
1241
|
"starterHint": "Це початковий приклад. Відредагуйте його відповідно до API вашого постачальника."
|
|
1252
1242
|
},
|
|
1253
|
-
"delegation": {
|
|
1254
|
-
"title": "Локальне делегування",
|
|
1255
|
-
"intro": "Типово ця машина виконує все локально — контейнерні агенти на Docker хоста, а інфраструктуру Tester через docker-compose всередині контейнера. Увімкніть опції нижче, щоб делегувати будь-яке з цих завдань зовнішньому сервісу. Застосовується лише в локальному режимі.",
|
|
1256
|
-
"agentsToggle": "Запускати контейнерні агенти в пулі виконавців",
|
|
1257
|
-
"agentsHint": "Надсилайте кожного контейнерного агента (кодер, tester, об'єднувач, bootstrap, …) до самостійно розміщеного пулу виконавців цього робочого простору замість Docker хоста.",
|
|
1258
|
-
"registerPoolPrompt": "Спершу {link}, щоб увімкнути це.",
|
|
1259
|
-
"registerPoolLink": "Зареєструйте пул виконавців",
|
|
1260
|
-
"envToggle": "Надавати середовища Tester через постачальника",
|
|
1261
|
-
"envHint": "Підніміть середовище попереднього перегляду Tester через постачальника середовищ, налаштованого нижче, замість docker-compose всередині контейнера. Спершу підключіть постачальника, щоб увімкнути це.",
|
|
1262
|
-
"updateFailed": "Не вдалося оновити делегування"
|
|
1263
|
-
},
|
|
1264
1243
|
"viewLogs": "Переглянути журнали",
|
|
1265
1244
|
"hideLogs": "Сховати журнали",
|
|
1266
1245
|
"connectedAt": "Підключено · {baseUrl}",
|
|
@@ -1343,6 +1322,10 @@
|
|
|
1343
1322
|
"caCertPem": "Сертифікат CA кластера (PEM)",
|
|
1344
1323
|
"caCertPemHelp": "Вставте CA-набір кластера, щоб TLS-сертифікат apiserver проходив перевірку. Пропустіть лише для публічно довіреного CA.",
|
|
1345
1324
|
"harnessPort": "Порт harness"
|
|
1325
|
+
},
|
|
1326
|
+
"advancedManifest": {
|
|
1327
|
+
"summary": "Розширено: власний планувальник на основі API",
|
|
1328
|
+
"intro": "Потрібно лише для інтеграції власного планувальника на основі API. Звичайні бекенди (локальний Docker, Cloudflare Containers і Kubernetes) цього не потребують; опишіть тут HTTP API власного планувальника, лише якщо ви його використовуєте."
|
|
1346
1329
|
}
|
|
1347
1330
|
},
|
|
1348
1331
|
"serviceFragmentDefaults": {
|
|
@@ -1693,6 +1676,22 @@
|
|
|
1693
1676
|
"removed": "Раннер видалено",
|
|
1694
1677
|
"removeFailed": "Не вдалося видалити раннер"
|
|
1695
1678
|
}
|
|
1679
|
+
},
|
|
1680
|
+
"infrastructure": {
|
|
1681
|
+
"active": "Активно: {backend}",
|
|
1682
|
+
"registerHint": "Зареєструйте пул раннерів нижче, щоб увімкнути це.",
|
|
1683
|
+
"updateFailed": "Не вдалося оновити бекенд виконання",
|
|
1684
|
+
"executionBackend": {
|
|
1685
|
+
"label": "Де виконуються агенти",
|
|
1686
|
+
"local-docker": "Локальний Docker (хост)",
|
|
1687
|
+
"cloudflare-containers": "Cloudflare Containers (вбудовано)",
|
|
1688
|
+
"runner-pool": "Самостійно розміщений пул раннерів"
|
|
1689
|
+
},
|
|
1690
|
+
"testEnvBackend": {
|
|
1691
|
+
"label": "Де виконуються тестові середовища",
|
|
1692
|
+
"local-compose": "docker-compose у контейнері",
|
|
1693
|
+
"environment-provider": "Провайдер середовищ"
|
|
1694
|
+
}
|
|
1696
1695
|
}
|
|
1697
1696
|
},
|
|
1698
1697
|
"providers": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cat-factory/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.0",
|
|
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",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"valibot": "^1.4.2",
|
|
35
35
|
"vue": "^3.5.39",
|
|
36
36
|
"wretch": "^3.0.9",
|
|
37
|
-
"@cat-factory/contracts": "0.
|
|
37
|
+
"@cat-factory/contracts": "0.52.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@toad-contracts/testing": "0.3.2",
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
// Local-mode-only settings: the warm-container pool + per-repo checkout reuse. These are
|
|
3
|
-
// a per-DEPLOYMENT singleton stored in the DB (they replaced the LOCAL_POOL_* / HARNESS_*
|
|
4
|
-
// env vars), so a developer tunes them here instead of editing .env. The warm pool keeps
|
|
5
|
-
// idle harness containers ready and re-leases one (preferring repo affinity) to each run —
|
|
6
|
-
// far faster startup than a cold container per run. Saving applies the new sizing to the
|
|
7
|
-
// running service immediately (the pool is resized live — no restart needed); in-flight
|
|
8
|
-
// runs keep the container they already hold, and the checkout config applies to containers
|
|
9
|
-
// started after the save.
|
|
10
|
-
import { reactive, ref, watch } from 'vue'
|
|
11
|
-
|
|
12
|
-
const { t } = useI18n()
|
|
13
|
-
const ui = useUiStore()
|
|
14
|
-
const store = useLocalSettingsStore()
|
|
15
|
-
const toast = useToast()
|
|
16
|
-
|
|
17
|
-
const open = computed({
|
|
18
|
-
get: () => ui.localModeSettingsOpen,
|
|
19
|
-
set: (v: boolean) => (v ? ui.openLocalModeSettings() : ui.closeLocalModeSettings()),
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const saving = ref(false)
|
|
23
|
-
|
|
24
|
-
// Editable draft. `idleMinutes` and `cleanKeep` are friendlier renderings of the stored
|
|
25
|
-
// `pool.idleTtlMs` (ms) and `checkout.cleanKeep` (string[]).
|
|
26
|
-
const draft = reactive({
|
|
27
|
-
size: 0,
|
|
28
|
-
minWarm: 0,
|
|
29
|
-
max: null as number | null,
|
|
30
|
-
idleMinutes: 10,
|
|
31
|
-
workspaceRoot: '/workspace',
|
|
32
|
-
cleanKeep: 'node_modules,.venv,target,.gradle,.pnpm-store',
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
function syncDraft() {
|
|
36
|
-
const s = store.settings
|
|
37
|
-
if (!s) return
|
|
38
|
-
draft.size = s.pool.size
|
|
39
|
-
draft.minWarm = s.pool.minWarm
|
|
40
|
-
draft.max = s.pool.max
|
|
41
|
-
draft.idleMinutes = Math.round(s.pool.idleTtlMs / 60_000)
|
|
42
|
-
draft.workspaceRoot = s.checkout.workspaceRoot
|
|
43
|
-
draft.cleanKeep = s.checkout.cleanKeep.join(',')
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Load + hydrate the draft whenever the panel opens.
|
|
47
|
-
watch(
|
|
48
|
-
open,
|
|
49
|
-
(isOpen) => {
|
|
50
|
-
if (isOpen) void store.load().then(syncDraft)
|
|
51
|
-
},
|
|
52
|
-
{ immediate: true },
|
|
53
|
-
)
|
|
54
|
-
watch(() => store.settings, syncDraft)
|
|
55
|
-
|
|
56
|
-
async function save() {
|
|
57
|
-
const cleanKeep = draft.cleanKeep
|
|
58
|
-
.split(',')
|
|
59
|
-
.map((s) => s.trim())
|
|
60
|
-
.filter(Boolean)
|
|
61
|
-
saving.value = true
|
|
62
|
-
try {
|
|
63
|
-
await store.save({
|
|
64
|
-
pool: {
|
|
65
|
-
size: Math.max(0, Math.floor(draft.size)),
|
|
66
|
-
minWarm: Math.max(0, Math.floor(draft.minWarm)),
|
|
67
|
-
max: draft.max == null ? null : Math.max(0, Math.floor(draft.max)),
|
|
68
|
-
idleTtlMs: Math.max(0, Math.floor(draft.idleMinutes * 60_000)),
|
|
69
|
-
},
|
|
70
|
-
checkout: { workspaceRoot: draft.workspaceRoot.trim() || '/workspace', cleanKeep },
|
|
71
|
-
})
|
|
72
|
-
toast.add({
|
|
73
|
-
title: t('settings.localMode.toast.saved'),
|
|
74
|
-
icon: 'i-lucide-check',
|
|
75
|
-
color: 'success',
|
|
76
|
-
})
|
|
77
|
-
} catch (e) {
|
|
78
|
-
toast.add({
|
|
79
|
-
title: t('settings.localMode.toast.saveFailed'),
|
|
80
|
-
description: e instanceof Error ? e.message : String(e),
|
|
81
|
-
icon: 'i-lucide-triangle-alert',
|
|
82
|
-
color: 'error',
|
|
83
|
-
})
|
|
84
|
-
} finally {
|
|
85
|
-
saving.value = false
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
</script>
|
|
89
|
-
|
|
90
|
-
<template>
|
|
91
|
-
<UModal v-model:open="open" :title="t('settings.localMode.title')" :ui="{ content: 'max-w-2xl' }">
|
|
92
|
-
<template #body>
|
|
93
|
-
<div class="space-y-6">
|
|
94
|
-
<i18n-t
|
|
95
|
-
keypath="settings.localMode.intro"
|
|
96
|
-
tag="p"
|
|
97
|
-
class="text-xs text-slate-400"
|
|
98
|
-
scope="global"
|
|
99
|
-
>
|
|
100
|
-
<template #poolVars>
|
|
101
|
-
<code>LOCAL_POOL_*</code>
|
|
102
|
-
</template>
|
|
103
|
-
<template #harnessVars>
|
|
104
|
-
<code>HARNESS_*</code>
|
|
105
|
-
</template>
|
|
106
|
-
</i18n-t>
|
|
107
|
-
|
|
108
|
-
<!-- Warm container pool -->
|
|
109
|
-
<section class="space-y-3">
|
|
110
|
-
<div>
|
|
111
|
-
<h4 class="text-sm font-semibold text-slate-200">
|
|
112
|
-
{{ t('settings.localMode.pool.heading') }}
|
|
113
|
-
</h4>
|
|
114
|
-
<i18n-t
|
|
115
|
-
keypath="settings.localMode.pool.description"
|
|
116
|
-
tag="p"
|
|
117
|
-
class="text-[11px] text-slate-400"
|
|
118
|
-
scope="global"
|
|
119
|
-
>
|
|
120
|
-
<template #appleContainer>
|
|
121
|
-
<code>container</code>
|
|
122
|
-
</template>
|
|
123
|
-
</i18n-t>
|
|
124
|
-
</div>
|
|
125
|
-
<div class="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
|
126
|
-
<UFormField
|
|
127
|
-
:label="t('settings.localMode.pool.size.label')"
|
|
128
|
-
:help="t('settings.localMode.pool.size.help')"
|
|
129
|
-
>
|
|
130
|
-
<UInput v-model.number="draft.size" type="number" :min="0" size="sm" />
|
|
131
|
-
</UFormField>
|
|
132
|
-
<UFormField
|
|
133
|
-
:label="t('settings.localMode.pool.minWarm.label')"
|
|
134
|
-
:help="t('settings.localMode.pool.minWarm.help')"
|
|
135
|
-
>
|
|
136
|
-
<UInput v-model.number="draft.minWarm" type="number" :min="0" size="sm" />
|
|
137
|
-
</UFormField>
|
|
138
|
-
<UFormField
|
|
139
|
-
:label="t('settings.localMode.pool.max.label')"
|
|
140
|
-
:help="t('settings.localMode.pool.max.help')"
|
|
141
|
-
>
|
|
142
|
-
<UInput
|
|
143
|
-
v-model.number="draft.max"
|
|
144
|
-
type="number"
|
|
145
|
-
:min="0"
|
|
146
|
-
size="sm"
|
|
147
|
-
:placeholder="t('settings.localMode.pool.max.placeholder')"
|
|
148
|
-
/>
|
|
149
|
-
</UFormField>
|
|
150
|
-
<UFormField
|
|
151
|
-
:label="t('settings.localMode.pool.idleTimeout.label')"
|
|
152
|
-
:help="t('settings.localMode.pool.idleTimeout.help')"
|
|
153
|
-
>
|
|
154
|
-
<UInput v-model.number="draft.idleMinutes" type="number" :min="0" size="sm" />
|
|
155
|
-
</UFormField>
|
|
156
|
-
</div>
|
|
157
|
-
</section>
|
|
158
|
-
|
|
159
|
-
<!-- Checkout reuse -->
|
|
160
|
-
<section class="space-y-3 border-t border-slate-800 pt-6">
|
|
161
|
-
<div>
|
|
162
|
-
<h4 class="text-sm font-semibold text-slate-200">
|
|
163
|
-
{{ t('settings.localMode.checkout.heading') }}
|
|
164
|
-
</h4>
|
|
165
|
-
<p class="text-[11px] text-slate-400">
|
|
166
|
-
{{ t('settings.localMode.checkout.description') }}
|
|
167
|
-
</p>
|
|
168
|
-
</div>
|
|
169
|
-
<UFormField
|
|
170
|
-
:label="t('settings.localMode.checkout.workspaceRoot.label')"
|
|
171
|
-
:help="t('settings.localMode.checkout.workspaceRoot.help')"
|
|
172
|
-
>
|
|
173
|
-
<UInput v-model="draft.workspaceRoot" size="sm" placeholder="/workspace" />
|
|
174
|
-
</UFormField>
|
|
175
|
-
<UFormField
|
|
176
|
-
:label="t('settings.localMode.checkout.cleanKeep.label')"
|
|
177
|
-
:help="t('settings.localMode.checkout.cleanKeep.help')"
|
|
178
|
-
>
|
|
179
|
-
<UInput
|
|
180
|
-
v-model="draft.cleanKeep"
|
|
181
|
-
size="sm"
|
|
182
|
-
placeholder="node_modules,.venv,target,.gradle,.pnpm-store"
|
|
183
|
-
/>
|
|
184
|
-
</UFormField>
|
|
185
|
-
</section>
|
|
186
|
-
|
|
187
|
-
<div class="flex justify-end">
|
|
188
|
-
<UButton color="primary" icon="i-lucide-save" :loading="saving" @click="save">
|
|
189
|
-
{{ t('common.save') }}
|
|
190
|
-
</UButton>
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
</template>
|
|
194
|
-
</UModal>
|
|
195
|
-
</template>
|