@cat-factory/app 0.184.0 → 0.185.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.
@@ -27,9 +27,15 @@ const busy = ref(false)
27
27
  const detecting = ref(false)
28
28
  const rows = ref<ValidationCheck[]>([])
29
29
  const maxAttempts = ref(VALIDATION_DEFAULT_MAX_ATTEMPTS)
30
+ // DEPENDENCY PREPOPULATION: the install run BEFORE the agent's first turn, so it reads a tree
31
+ // whose dependencies are present. Edited beside the checks because it comes from the same
32
+ // per-service row, but it is independent of them — a service may declare only this.
33
+ const dependencyInstall = ref('')
30
34
 
31
35
  const saved = computed(() => store.forBlock(props.block.id))
32
- const configured = computed(() => saved.value.checks.length > 0)
36
+ const configured = computed(
37
+ () => saved.value.checks.length > 0 || Boolean(saved.value.dependencyInstall),
38
+ )
33
39
  const canAdd = computed(() => rows.value.length < VALIDATION_MAX_CHECKS)
34
40
  /** A row is only submittable once it has a command; the label falls back to the command. */
35
41
  const submittable = computed(() =>
@@ -46,6 +52,7 @@ watch(
46
52
  (config) => {
47
53
  rows.value = config.checks.map((c) => ({ ...c }))
48
54
  maxAttempts.value = config.maxAttempts
55
+ dependencyInstall.value = config.dependencyInstall ?? ''
49
56
  },
50
57
  { immediate: true },
51
58
  )
@@ -114,7 +121,13 @@ async function detect() {
114
121
  }
115
122
  const merged = mergeDetectedChecks(rows.value, result.checks, VALIDATION_MAX_CHECKS)
116
123
  rows.value = merged.rows
117
- if (merged.added === 0) {
124
+ // Fill the install only when the operator has not written one. Detection is assistive, and
125
+ // overwriting a hand-tuned install (a workspace filter, an offline flag) with the generic
126
+ // guess is the same failure `mergeDetectedChecks` refuses to make on the check rows.
127
+ const suggestedInstall = result.dependencyInstall?.trim() ?? ''
128
+ const filledInstall = suggestedInstall !== '' && dependencyInstall.value.trim() === ''
129
+ if (filledInstall) dependencyInstall.value = suggestedInstall
130
+ if (merged.added === 0 && !filledInstall) {
118
131
  toast.add({
119
132
  title: t('inspector.validationChecks.detect.nothingNew'),
120
133
  description:
@@ -128,7 +141,13 @@ async function detect() {
128
141
  }
129
142
  const names = result.ecosystems.map(ecosystemLabel).join(', ')
130
143
  toast.add({
131
- title: t('inspector.validationChecks.detect.added', { count: merged.added }, merged.added),
144
+ // An install-only detection fills nothing but the install field, and reporting it as
145
+ // "0 checks added" would read as a failed press on the one repo shape prepopulation is
146
+ // most for (dependencies to install, nothing declared to verify).
147
+ title:
148
+ merged.added === 0
149
+ ? t('inspector.validationChecks.detect.installOnly')
150
+ : t('inspector.validationChecks.detect.added', { count: merged.added }, merged.added),
132
151
  // Name what was recognised AND what was left out: a cap that silently swallowed a
133
152
  // suggestion reads as "that is everything your repo has".
134
153
  description: [
@@ -152,7 +171,12 @@ async function detect() {
152
171
  async function save() {
153
172
  busy.value = true
154
173
  try {
155
- await store.save(props.block.id, submittable.value, maxAttempts.value)
174
+ await store.save(
175
+ props.block.id,
176
+ submittable.value,
177
+ maxAttempts.value,
178
+ dependencyInstall.value.trim() || undefined,
179
+ )
156
180
  toast.add({
157
181
  title: t('inspector.validationChecks.savedToast'),
158
182
  icon: 'i-lucide-check',
@@ -172,6 +196,7 @@ async function clear() {
172
196
  try {
173
197
  await store.remove(props.block.id)
174
198
  rows.value = []
199
+ dependencyInstall.value = ''
175
200
  toastDone('clear', noun)
176
201
  } catch (e) {
177
202
  notifyError(t('inspector.validationChecks.clearFailed'), e)
@@ -204,6 +229,19 @@ async function clear() {
204
229
  </template>
205
230
 
206
231
  <div class="space-y-2">
232
+ <UFormField
233
+ :label="t('inspector.validationChecks.dependencyInstall')"
234
+ :hint="t('inspector.validationChecks.dependencyInstallHint')"
235
+ >
236
+ <UInput
237
+ v-model="dependencyInstall"
238
+ placeholder="pnpm install --frozen-lockfile"
239
+ size="sm"
240
+ class="w-full"
241
+ data-testid="validation-dependency-install"
242
+ />
243
+ </UFormField>
244
+
207
245
  <p class="text-[11px] text-slate-500">
208
246
  {{ t('inspector.validationChecks.hint') }}
209
247
  </p>
@@ -86,21 +86,25 @@ export const useValidationChecksStore = defineStore('validationChecks', () => {
86
86
  }
87
87
 
88
88
  /**
89
- * Save a service frame's checks. An EMPTY list clears the config on the backend (the service
90
- * deletes the row), which restores the exact pre-feature behaviour so the local list drops
91
- * the entry rather than keeping an empty one that reads as "configured".
89
+ * Save a service frame's checks and its dependency-prepopulation install. The backend deletes
90
+ * the row only when BOTH are empty (restoring the exact pre-feature behaviour), so the local
91
+ * list mirrors that rule — dropping the entry on an empty save of both, and keeping it for a
92
+ * service that declares only an install. Testing `checks` alone here would evict a live
93
+ * install-only config from the store and report the service as unconfigured until a reload.
92
94
  */
93
95
  async function save(
94
96
  blockId: string,
95
97
  checks: ValidationCheck[],
96
98
  maxAttempts: number,
99
+ dependencyInstall?: string,
97
100
  ): Promise<void> {
98
101
  const ws = useWorkspaceStore()
99
102
  const saved = await api.setServiceValidationConfig(ws.requireId(), blockId, {
100
103
  checks,
101
104
  maxAttempts,
105
+ ...(dependencyInstall ? { dependencyInstall } : {}),
102
106
  })
103
- if (saved.checks.length === 0) dropLocal(blockId)
107
+ if (saved.checks.length === 0 && !saved.dependencyInstall) dropLocal(blockId)
104
108
  else upsertLocal(saved)
105
109
  }
106
110
 
@@ -1433,6 +1433,8 @@
1433
1433
  "validationChecks": {
1434
1434
  "title": "Prüfungen vor dem PR",
1435
1435
  "sectionHint": "Befehle, die nach dem Coder und vor dem Öffnen eines Pull Requests im Checkout laufen. Ein Fehlschlag geht zur Behebung an den Agenten zurück; nur ein fehlerfreier Checkout öffnet einen PR.",
1436
+ "dependencyInstall": "Abhängigkeiten installieren",
1437
+ "dependencyInstallHint": "Läuft, bevor der Agent startet",
1436
1438
  "hint": "Jeder Befehl läuft der Reihe nach mit `sh -c` im Checkout dieses Dienstes. Der Agent soll den Code reparieren, nicht die Prüfung abschwächen.",
1437
1439
  "clear": "Leeren",
1438
1440
  "configNoun": "Prüfungen",
@@ -1452,6 +1454,7 @@
1452
1454
  "action": "Erkennen",
1453
1455
  "hint": "Prüfungen aus dem Repository dieses Dienstes vorschlagen",
1454
1456
  "added": "{count} Prüfung hinzugefügt | {count} Prüfungen hinzugefügt",
1457
+ "installOnly": "Abhängigkeitsinstallation eingetragen",
1455
1458
  "found": "Erkannt: {ecosystems}.",
1456
1459
  "capped": "Einige Vorschläge wurden ausgelassen — ein Dienst nimmt höchstens {max} Prüfungen auf.",
1457
1460
  "nothingNew": "Nichts hinzuzufügen",
@@ -1155,6 +1155,9 @@
1155
1155
  "validationChecks": {
1156
1156
  "title": "Pre-PR validation",
1157
1157
  "sectionHint": "Commands run against the checkout after the coder finishes and before a pull request is opened. A failure is handed back to the agent to fix; only a passing checkout opens a PR.",
1158
+ "dependencyInstall": "Dependency install",
1159
+ "@dependencyInstall": "Field label for a shell command. \"install\" is a NOUN here (the installation step), not the imperative verb — it labels the input holding a command such as `pnpm install`, it does not ask the user to install anything.",
1160
+ "dependencyInstallHint": "Runs before the agent starts",
1158
1161
  "hint": "Each command runs with `sh -c` in this service's checkout, in order. Fix the code, not the check — the agent is told not to weaken them.",
1159
1162
  "clear": "Clear",
1160
1163
  "configNoun": "validation checks",
@@ -1174,6 +1177,7 @@
1174
1177
  "action": "Detect",
1175
1178
  "hint": "Suggest checks from this service's repository",
1176
1179
  "added": "Added {count} check | Added {count} checks",
1180
+ "installOnly": "Filled in the dependency install",
1177
1181
  "found": "Recognised {ecosystems}.",
1178
1182
  "capped": "Some suggestions were left out — a service takes at most {max} checks.",
1179
1183
  "nothingNew": "Nothing to add",
@@ -1092,6 +1092,8 @@
1092
1092
  "validationChecks": {
1093
1093
  "title": "Validación previa al PR",
1094
1094
  "sectionHint": "Comandos que se ejecutan sobre la copia de trabajo cuando el programador termina y antes de abrir una solicitud de incorporación. Un fallo vuelve al agente para que lo corrija; solo una copia sin errores abre un PR.",
1095
+ "dependencyInstall": "Instalación de dependencias",
1096
+ "dependencyInstallHint": "Se ejecuta antes de que empiece el agente",
1095
1097
  "hint": "Cada comando se ejecuta con `sh -c` en la copia de trabajo de este servicio, en orden. Hay que arreglar el código, no la comprobación: al agente se le indica que no las debilite.",
1096
1098
  "clear": "Vaciar",
1097
1099
  "configNoun": "comprobaciones de validación",
@@ -1111,6 +1113,7 @@
1111
1113
  "action": "Detectar",
1112
1114
  "hint": "Sugerir comprobaciones a partir del repositorio de este servicio",
1113
1115
  "added": "Se añadió {count} comprobación | Se añadieron {count} comprobaciones",
1116
+ "installOnly": "Se rellenó la instalación de dependencias",
1114
1117
  "found": "Se reconoció {ecosystems}.",
1115
1118
  "capped": "Se omitieron algunas sugerencias: un servicio admite como máximo {max} comprobaciones.",
1116
1119
  "nothingNew": "No hay nada que añadir",
@@ -1092,6 +1092,8 @@
1092
1092
  "validationChecks": {
1093
1093
  "title": "Validation avant la PR",
1094
1094
  "sectionHint": "Commandes exécutées sur la copie de travail une fois le développeur terminé et avant l'ouverture d'une demande de tirage. Un échec est renvoyé à l'agent pour correction ; seule une copie sans erreur ouvre une PR.",
1095
+ "dependencyInstall": "Installation des dépendances",
1096
+ "dependencyInstallHint": "S'exécute avant le démarrage de l'agent",
1095
1097
  "hint": "Chaque commande s'exécute avec `sh -c` dans la copie de travail de ce service, dans l'ordre. Il faut corriger le code, pas la vérification : il est demandé à l'agent de ne pas les affaiblir.",
1096
1098
  "clear": "Vider",
1097
1099
  "configNoun": "vérifications de validation",
@@ -1111,6 +1113,7 @@
1111
1113
  "action": "Détecter",
1112
1114
  "hint": "Proposer des vérifications à partir du dépôt de ce service",
1113
1115
  "added": "{count} vérification ajoutée | {count} vérifications ajoutées",
1116
+ "installOnly": "L'installation des dépendances a été renseignée",
1114
1117
  "found": "Reconnu : {ecosystems}.",
1115
1118
  "capped": "Certaines suggestions ont été écartées : un service accepte au plus {max} vérifications.",
1116
1119
  "nothingNew": "Rien à ajouter",
@@ -1092,6 +1092,8 @@
1092
1092
  "validationChecks": {
1093
1093
  "title": "בדיקות לפני בקשת משיכה",
1094
1094
  "sectionHint": "פקודות שרצות על העותק המקומי אחרי שהמפתח מסיים ולפני פתיחת בקשת משיכה. כישלון מוחזר לסוכן לתיקון; רק עותק תקין פותח בקשת משיכה.",
1095
+ "dependencyInstall": "התקנת תלויות",
1096
+ "dependencyInstallHint": "רץ לפני שהסוכן מתחיל",
1095
1097
  "hint": "כל פקודה רצה עם ‎`sh -c`‎ בעותק המקומי של שירות זה, לפי הסדר. יש לתקן את הקוד ולא את הבדיקה — הסוכן מונחה לא להחליש אותן.",
1096
1098
  "clear": "ניקוי",
1097
1099
  "configNoun": "בדיקות אימות",
@@ -1111,6 +1113,7 @@
1111
1113
  "action": "זהה",
1112
1114
  "hint": "הצע בדיקות מתוך המאגר של שירות זה",
1113
1115
  "added": "נוספה בדיקה {count} | נוספו {count} בדיקות",
1116
+ "installOnly": "התקנת התלויות מולאה",
1114
1117
  "found": "זוהה: {ecosystems}.",
1115
1118
  "capped": "חלק מההצעות הושמטו — שירות מקבל לכל היותר {max} בדיקות.",
1116
1119
  "nothingNew": "אין מה להוסיף",
@@ -1433,6 +1433,8 @@
1433
1433
  "validationChecks": {
1434
1434
  "title": "Validazione prima della PR",
1435
1435
  "sectionHint": "Comandi eseguiti sulla copia di lavoro quando lo sviluppatore ha finito e prima di aprire una richiesta di modifica. Un errore torna all'agente perché lo corregga; solo una copia senza errori apre una PR.",
1436
+ "dependencyInstall": "Installazione delle dipendenze",
1437
+ "dependencyInstallHint": "Viene eseguita prima dell'avvio dell'agente",
1436
1438
  "hint": "Ogni comando viene eseguito con `sh -c` nella copia di lavoro di questo servizio, in ordine. Va corretto il codice, non il controllo: all'agente viene chiesto di non indebolirli.",
1437
1439
  "clear": "Svuota",
1438
1440
  "configNoun": "controlli di validazione",
@@ -1452,6 +1454,7 @@
1452
1454
  "action": "Rileva",
1453
1455
  "hint": "Suggerisci controlli a partire dal repository di questo servizio",
1454
1456
  "added": "Aggiunto {count} controllo | Aggiunti {count} controlli",
1457
+ "installOnly": "Installazione delle dipendenze compilata",
1455
1458
  "found": "Riconosciuto: {ecosystems}.",
1456
1459
  "capped": "Alcuni suggerimenti sono stati esclusi: un servizio accetta al massimo {max} controlli.",
1457
1460
  "nothingNew": "Niente da aggiungere",
@@ -1092,6 +1092,8 @@
1092
1092
  "validationChecks": {
1093
1093
  "title": "PR 前の検証",
1094
1094
  "sectionHint": "コーダーの作業完了後、プルリクエストを開く前にチェックアウトに対して実行されるコマンドです。失敗した場合はエージェントに差し戻して修正させ、問題のないチェックアウトだけが PR を開きます。",
1095
+ "dependencyInstall": "依存関係のインストール",
1096
+ "dependencyInstallHint": "エージェントの開始前に実行されます",
1095
1097
  "hint": "各コマンドはこのサービスのチェックアウト内で `sh -c` により順番に実行されます。修正すべきはコードであり検査ではありません。エージェントには検査を弱めないよう指示しています。",
1096
1098
  "clear": "消去",
1097
1099
  "configNoun": "検証コマンド",
@@ -1111,6 +1113,7 @@
1111
1113
  "action": "自動検出",
1112
1114
  "hint": "このサービスのリポジトリからチェックを提案します",
1113
1115
  "added": "{count} 件のチェックを追加しました | {count} 件のチェックを追加しました",
1116
+ "installOnly": "依存関係のインストールを入力しました",
1114
1117
  "found": "{ecosystems} を検出しました。",
1115
1118
  "capped": "一部の候補は省略されました。1 つのサービスに設定できるチェックは最大 {max} 件です。",
1116
1119
  "nothingNew": "追加する項目はありません",
@@ -1092,6 +1092,8 @@
1092
1092
  "validationChecks": {
1093
1093
  "title": "Walidacja przed PR",
1094
1094
  "sectionHint": "Polecenia uruchamiane na kopii roboczej po zakończeniu pracy programisty, a przed otwarciem żądania scalenia. Niepowodzenie wraca do agenta do naprawy; tylko czysta kopia otwiera żądanie scalenia.",
1095
+ "dependencyInstall": "Instalacja zależności",
1096
+ "dependencyInstallHint": "Uruchamia się przed startem agenta",
1095
1097
  "hint": "Każde polecenie jest uruchamiane przez `sh -c` w kopii roboczej tej usługi, po kolei. Poprawiaj kod, a nie sprawdzenie — agent ma polecenie ich nie osłabiać.",
1096
1098
  "clear": "Wyczyść",
1097
1099
  "configNoun": "sprawdzenia walidacyjne",
@@ -1111,6 +1113,7 @@
1111
1113
  "action": "Wykryj",
1112
1114
  "hint": "Zaproponuj testy na podstawie repozytorium tej usługi",
1113
1115
  "added": "Dodano {count} test | Dodano {count} testy | Dodano {count} testów",
1116
+ "installOnly": "Uzupełniono instalację zależności",
1114
1117
  "found": "Rozpoznano: {ecosystems}.",
1115
1118
  "capped": "Część propozycji pominięto — usługa przyjmuje najwyżej {max} testów.",
1116
1119
  "nothingNew": "Nie ma czego dodać",
@@ -1092,6 +1092,8 @@
1092
1092
  "validationChecks": {
1093
1093
  "title": "PR öncesi doğrulama",
1094
1094
  "sectionHint": "Kodlayıcı işini bitirdikten sonra ve bir çekme isteği açılmadan önce çalışma kopyası üzerinde çalıştırılan komutlar. Bir hata düzeltilmesi için aracıya geri verilir; yalnızca sorunsuz bir çalışma kopyası çekme isteği açar.",
1095
+ "dependencyInstall": "Bağımlılık kurulumu",
1096
+ "dependencyInstallHint": "Aracı başlamadan önce çalışır",
1095
1097
  "hint": "Her komut bu hizmetin çalışma kopyasında sırayla `sh -c` ile çalıştırılır. Denetimi değil kodu düzeltin — aracıya denetimleri zayıflatmaması söylenir.",
1096
1098
  "clear": "Temizle",
1097
1099
  "configNoun": "doğrulama denetimleri",
@@ -1111,6 +1113,7 @@
1111
1113
  "action": "Algıla",
1112
1114
  "hint": "Bu hizmetin deposundan denetimler öner",
1113
1115
  "added": "{count} denetim eklendi | {count} denetim eklendi",
1116
+ "installOnly": "Bağımlılık kurulumu dolduruldu",
1114
1117
  "found": "{ecosystems} algılandı.",
1115
1118
  "capped": "Bazı öneriler dışarıda bırakıldı — bir hizmet en fazla {max} denetim alır.",
1116
1119
  "nothingNew": "Eklenecek bir şey yok",
@@ -1092,6 +1092,8 @@
1092
1092
  "validationChecks": {
1093
1093
  "title": "Перевірки перед PR",
1094
1094
  "sectionHint": "Команди, які виконуються на робочій копії після завершення роботи розробника та перед відкриттям запиту на злиття. Невдача повертається до агента на виправлення; лише чиста копія відкриває запит на злиття.",
1095
+ "dependencyInstall": "Встановлення залежностей",
1096
+ "dependencyInstallHint": "Виконується перед запуском агента",
1095
1097
  "hint": "Кожна команда виконується через `sh -c` у робочій копії цієї служби, по черзі. Виправляйте код, а не перевірку — агенту наказано не послаблювати їх.",
1096
1098
  "clear": "Очистити",
1097
1099
  "configNoun": "перевірки",
@@ -1111,6 +1113,7 @@
1111
1113
  "action": "Визначити",
1112
1114
  "hint": "Запропонувати перевірки з репозиторію цієї служби",
1113
1115
  "added": "Додано {count} перевірку | Додано {count} перевірки | Додано {count} перевірок",
1116
+ "installOnly": "Встановлення залежностей заповнено",
1114
1117
  "found": "Розпізнано: {ecosystems}.",
1115
1118
  "capped": "Деякі пропозиції пропущено — служба приймає щонайбільше {max} перевірок.",
1116
1119
  "nothingNew": "Немає чого додавати",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cat-factory/app",
3
- "version": "0.184.0",
3
+ "version": "0.185.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",
@@ -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.191.0"
43
+ "@cat-factory/contracts": "0.192.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@toad-contracts/testing": "0.3.2",