@cat-factory/app 0.49.2 → 0.50.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/layout/IntegrationsHub.vue +3 -66
- package/app/components/layout/SideBar.vue +39 -0
- package/app/components/panels/inspector/ServiceFragments.vue +31 -5
- package/app/components/panels/inspector/TaskStructure.vue +31 -5
- 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 +24 -23
- package/i18n/locales/es.json +27 -26
- package/i18n/locales/fr.json +27 -26
- package/i18n/locales/pl.json +27 -26
- package/i18n/locales/uk.json +27 -26
- package/package.json +2 -2
- package/app/components/settings/LocalModeSettingsPanel.vue +0 -195
|
@@ -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>
|