@cat-factory/app 0.288.2 → 0.290.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.
Files changed (34) hide show
  1. package/app/components/environments/EnvironmentStatusPanel.logic.spec.ts +70 -0
  2. package/app/components/environments/EnvironmentStatusPanel.logic.ts +48 -0
  3. package/app/components/environments/EnvironmentStatusPanel.vue +21 -4
  4. package/app/components/foundational/FoundationalServiceCatalogList.vue +3 -0
  5. package/app/components/foundational/FoundationalServiceManager.vue +9 -1
  6. package/app/components/foundational/FoundationalServiceRegistry.vue +3 -0
  7. package/app/components/foundational/ServiceCatalogConnection.vue +392 -0
  8. package/app/components/outcome/OutcomeSummaryWindow.logic.spec.ts +1 -0
  9. package/app/components/outcome/OutcomeSummaryWindow.vue +10 -1
  10. package/app/components/panels/ObservabilityPanel.vue +19 -0
  11. package/app/components/providers/ApiKeysSection.vue +24 -14
  12. package/app/components/provisioning/ProvisioningLogsDrawer.vue +1 -0
  13. package/app/components/settings/OpenRouterCatalogPanel.vue +8 -0
  14. package/app/composables/api/foundationalServices.ts +24 -0
  15. package/app/composables/usePipelineErrorToast.ts +5 -0
  16. package/app/stores/foundationalServices.ts +22 -0
  17. package/app/stores/observability.ts +6 -0
  18. package/app/stores/serviceCatalogConnection.spec.ts +116 -0
  19. package/app/stores/serviceCatalogConnection.ts +131 -0
  20. package/app/types/foundationalServices.ts +14 -0
  21. package/app/utils/runOutcome.ts +1 -0
  22. package/app/utils/serviceCatalog.spec.ts +51 -0
  23. package/app/utils/serviceCatalog.ts +68 -0
  24. package/i18n/locales/de.json +90 -3
  25. package/i18n/locales/en.json +90 -3
  26. package/i18n/locales/es.json +90 -3
  27. package/i18n/locales/fr.json +90 -3
  28. package/i18n/locales/he.json +90 -3
  29. package/i18n/locales/it.json +90 -3
  30. package/i18n/locales/ja.json +90 -3
  31. package/i18n/locales/pl.json +90 -3
  32. package/i18n/locales/tr.json +90 -3
  33. package/i18n/locales/uk.json +90 -3
  34. package/package.json +2 -2
@@ -0,0 +1,68 @@
1
+ import type { ServiceCatalogAuthMode, ServiceCatalogSyncStatus } from '~/types/domain'
2
+
3
+ // The SERVICE CATALOG connection's two closed vocabularies → their i18n keys, in ONE place each.
4
+ //
5
+ // Here rather than inline in `ServiceCatalogConnection.vue` for the reason `utils/vcs.ts` holds the
6
+ // per-provider constants: an exhaustive `Record` over a wire union is the drift guard, and it only
7
+ // guards if there is exactly one of it. A second copy in a template would keep rendering while this
8
+ // one gained a member.
9
+ //
10
+ // Both are also the case the typed-message-key guard cannot see: the keys are reached through a
11
+ // lookup rather than written out at the call site, so nothing proves the entry still names a key
12
+ // that exists. `serviceCatalog.spec.ts` asserts every value against the base catalog, which is the
13
+ // convention `test/i18nKeys.ts` exists for.
14
+
15
+ /**
16
+ * The label for one authentication mode.
17
+ *
18
+ * The keys are camelCase where the wire values are kebab-case, because a vue-i18n path segment is
19
+ * read as a nested lookup and a hyphen in one reads fine but breaks the moment anyone writes the
20
+ * literal form.
21
+ */
22
+ export const SERVICE_CATALOG_AUTH_KEYS: Record<ServiceCatalogAuthMode, string> = {
23
+ none: 'serviceCatalog.auth.none',
24
+ 'static-token': 'serviceCatalog.auth.staticToken',
25
+ 'legacy-shared-secret': 'serviceCatalog.auth.legacySharedSecret',
26
+ 'oauth2-client-credentials': 'serviceCatalog.auth.oauth2',
27
+ basic: 'serviceCatalog.auth.basic',
28
+ headers: 'serviceCatalog.auth.headers',
29
+ }
30
+
31
+ /**
32
+ * The label for what the last import concluded.
33
+ *
34
+ * `never` is NOT a member of the wire union and has its own key beside these: "no import has run"
35
+ * is a null `lastSyncStatus` rather than a status value, and collapsing it into `failed` would tell
36
+ * an operator their portal is broken the moment they connect it.
37
+ */
38
+ export const SERVICE_CATALOG_STATUS_KEYS: Record<ServiceCatalogSyncStatus, string> = {
39
+ ok: 'serviceCatalog.status.ok',
40
+ partial: 'serviceCatalog.status.partial',
41
+ failed: 'serviceCatalog.status.failed',
42
+ }
43
+
44
+ /** The key for a connection's last verdict, including the "never imported" case. */
45
+ export function serviceCatalogStatusKey(status: ServiceCatalogSyncStatus | null): string {
46
+ return status ? SERVICE_CATALOG_STATUS_KEYS[status] : 'serviceCatalog.status.never'
47
+ }
48
+
49
+ /**
50
+ * The badge colour for one verdict. `partial` is a WARNING rather than a success, which is the
51
+ * whole point of the three-value status: a truncated import holds real services and not all of
52
+ * them, and a green badge over it is how a prefix of an estate comes to read as the estate.
53
+ */
54
+ export const SERVICE_CATALOG_STATUS_COLORS = {
55
+ ok: 'success',
56
+ partial: 'warning',
57
+ failed: 'error',
58
+ } as const satisfies Record<ServiceCatalogSyncStatus, string>
59
+
60
+ /** The modes offered in the connect form, in the order an operator is most likely to want them. */
61
+ export const SERVICE_CATALOG_AUTH_ORDER: readonly ServiceCatalogAuthMode[] = [
62
+ 'static-token',
63
+ 'legacy-shared-secret',
64
+ 'oauth2-client-credentials',
65
+ 'basic',
66
+ 'headers',
67
+ 'none',
68
+ ]
@@ -1021,6 +1021,7 @@
1021
1021
  "context": "{value} Ktx",
1022
1022
  "contextThousands": "{value}K Ktx",
1023
1023
  "price": "{input}/{output} pro Mtok",
1024
+ "retiresOn": "Auslauf am {date}",
1024
1025
  "toast": {
1025
1026
  "connected": "OpenRouter-Schlüssel verbunden",
1026
1027
  "connectFailed": "Schlüssel konnte nicht verbunden werden",
@@ -3843,6 +3844,8 @@
3843
3844
  "cacheRead": "{tokens} aus dem Cache gelesen",
3844
3845
  "cacheWrite": "{tokens} in den Cache geschrieben",
3845
3846
  "total": "gesamt {duration}",
3847
+ "viaUpstream": "über {upstream}",
3848
+ "reportedCost": "abgerechnet {cost}",
3846
3849
  "prompt": "Prompt",
3847
3850
  "promptPrefixOmitted": "(nur neue Nachrichten: {count} frühere ausgelassen)",
3848
3851
  "response": "Antwort",
@@ -5231,7 +5234,8 @@
5231
5234
  },
5232
5235
  "tab": {
5233
5236
  "catalog": "Katalog",
5234
- "sources": "Repo-Quellen"
5237
+ "sources": "Repo-Quellen",
5238
+ "portal": "Entwicklerportal"
5235
5239
  },
5236
5240
  "panel": {
5237
5241
  "title": "Basisdienste",
@@ -5245,7 +5249,10 @@
5245
5249
  "format": {
5246
5250
  "openapi": "OpenAPI",
5247
5251
  "toadContract": "toad-contracts",
5248
- "lokaliseApiContract": "lokalise/api-contract"
5252
+ "lokaliseApiContract": "lokalise/api-contract",
5253
+ "asyncapi": "AsyncAPI",
5254
+ "graphql": "GraphQL",
5255
+ "grpc": "gRPC"
5249
5256
  },
5250
5257
  "contracts": {
5251
5258
  "omitted": "+{count} weitere nicht aufgeführt",
@@ -5923,7 +5930,11 @@
5923
5930
  "binary_generators_unreachable": "Die generativen Integrationen dieser Installation konnten gerade nicht gelesen werden, deshalb wurde der Lauf nicht gestartet. Es ist nichts falsch konfiguriert und keine Änderung nötig: versuchen Sie es erneut, sobald die Verbindung wieder steht.",
5924
5931
  "foundational_builtins_unreachable": "Die integrierten Basisdienste dieser Installation konnten gerade nicht gelesen werden. Es ist nichts falsch konfiguriert und keine Änderung nötig: versuchen Sie es erneut, sobald die Verbindung wieder steht.",
5925
5932
  "connection_credentials_unreadable": "Die gespeicherten Zugangsdaten dieser Verbindung konnten nicht gelesen werden. Wenn diese Installation den Dienst mit dem zugehörigen Schlüssel erreicht, verbinden Sie die Quelle neu, um sie zu ersetzen; andernfalls versuchen Sie es erneut, sobald diese Verbindung wiederhergestellt ist.",
5926
- "vcs_capability_unsupported": "Der mit diesem Workspace verbundene Quellcode-Anbieter bietet diesen Vorgang nicht an. Es ist nichts falsch konfiguriert und eine Einrichtung hilft hier nicht: Für diesen Anbieter ist der Vorgang nicht verfügbar."
5933
+ "vcs_capability_unsupported": "Der mit diesem Workspace verbundene Quellcode-Anbieter bietet diesen Vorgang nicht an. Es ist nichts falsch konfiguriert und eine Einrichtung hilft hier nicht: Für diesen Anbieter ist der Vorgang nicht verfügbar.",
5934
+ "service_catalog_unreachable": "Das Entwicklerportal dieses Boards hat nicht geantwortet oder eine Antwort geliefert, die diese Plattform nicht lesen kann. Hier ist nichts falsch konfiguriert und keine Änderung hilft: versuche es erneut, sobald das Portal erreichbar ist.",
5935
+ "service_catalog_unauthorized": "Das Entwicklerportal hat die gespeicherte Zugangsdaten abgelehnt. Sie wurden wahrscheinlich rotiert oder widerrufen: öffne die Servicekatalog-Einstellungen und trage aktuelle ein.",
5936
+ "service_catalog_filter_missing": "Der Entitätsfilter dieser Verbindung konnte nicht gelesen werden, es gibt also nichts zu importieren. Speichere die Servicekatalog-Verbindung erneut, um ihn wiederherzustellen.",
5937
+ "service_catalog_response_too_large": "Das Entwicklerportal hat mit mehr Daten geantwortet, als diese Plattform in einer Antwort aufnimmt. Öffne die Servicekatalog-Einstellungen und senke das Service-Limit oder deaktiviere den Import von Schnittstellendefinitionen, und importiere dann erneut."
5927
5938
  }
5928
5939
  },
5929
5940
  "action": {
@@ -6863,6 +6874,7 @@
6863
6874
  "empty": "Keine ephemere Umgebung für diesen Lauf.",
6864
6875
  "provisionTypeLabel": "Bereitstellungstyp:",
6865
6876
  "engineLabel": "Engine:",
6877
+ "statusNote": "Hinweis des Anbieters: {note}",
6866
6878
  "provisionType": {
6867
6879
  "kubernetes": "Kubernetes",
6868
6880
  "docker-compose": "Docker Compose",
@@ -6888,6 +6900,7 @@
6888
6900
  "teardown": "Abbauen",
6889
6901
  "teardown-verify": "Abbau-Prüfung",
6890
6902
  "status": "Statusprüfung",
6903
+ "remediate": "Reparatur vor Ort",
6891
6904
  "dispatch": "Hochfahren",
6892
6905
  "release": "Abbauen",
6893
6906
  "poll-failure": "Health-Check"
@@ -8098,5 +8111,79 @@
8098
8111
  "title": "Nichts zu vergleichen"
8099
8112
  },
8100
8113
  "loadFailed": "Die erzeugten Kandidaten konnten nicht geladen werden."
8114
+ },
8115
+ "serviceCatalog": {
8116
+ "unavailable": "Der Import eines Servicekatalogs ist für diese Installation nicht konfiguriert.",
8117
+ "intro": "Verweise die Plattform auf das Entwicklerportal, das deine Organisation bereits betreibt: Ihre Services werden in den Katalog oben importiert, mit Identität, Verantwortlichkeit und den API-Definitionen, die jeder Service veröffentlicht. Agenten, die Fehler einordnen oder untersuchen, lesen sie, um zu bestimmen, zu welchem Service eine Aufgabe gehört.",
8118
+ "summary": "Filter: {filter} · höchstens {max} Services",
8119
+ "form": {
8120
+ "connect": "Portal verbinden",
8121
+ "replace": "Verbindung ersetzen"
8122
+ },
8123
+ "field": {
8124
+ "baseUrl": "Portal-URL",
8125
+ "authMode": "Authentifizierung",
8126
+ "token": "Service-Token",
8127
+ "sharedSecret": "Gemeinsames Geheimnis",
8128
+ "tokenUrl": "Token-Endpunkt",
8129
+ "clientId": "Client-ID",
8130
+ "clientSecret": "Client-Secret",
8131
+ "scope": "Scope (optional)",
8132
+ "audience": "Audience (optional)",
8133
+ "username": "Benutzername",
8134
+ "password": "Passwort",
8135
+ "headerName": "Header-Name",
8136
+ "headerValue": "Header-Wert",
8137
+ "secondHeaderName": "Zweiter Header-Name (optional)",
8138
+ "secondHeaderValue": "Zweiter Header-Wert",
8139
+ "entityFilter": "Entitätsfilter",
8140
+ "maxServices": "Maximale Anzahl Services",
8141
+ "includeApis": "API-Definitionen der Services mitimportieren"
8142
+ },
8143
+ "help": {
8144
+ "baseUrl": "Die Basis-URL deiner Backstage-Instanz. Ein privater oder interner Host ist nur zulässig, wenn die Installation ihn erlaubt.",
8145
+ "token": "Ein Service-zu-Service-Token aus der External-Access-Konfiguration von Backstage.",
8146
+ "sharedSecret": "Ein base64-Geheimnis aus `backend.auth.keys`. Die Plattform signiert damit pro Anfrage ein kurzlebiges Token.",
8147
+ "headers": "Für ein Gateway, das über eigene Header authentifiziert, etwa ein Cloudflare-Access-Service-Token.",
8148
+ "entityFilter": "Ein `key=value`-Ausdruck pro Zeile; alle müssen zutreffen. Standard ist `kind=component`. Grenze ihn auf die Services ein, die als gemeinsame Fähigkeiten angeboten werden sollen.",
8149
+ "maxServices": "Ein Import, der dieses Limit erreicht, wird als Auszug des Portals gemeldet, nicht als dessen Gesamtheit."
8150
+ },
8151
+ "auth": {
8152
+ "none": "Keine",
8153
+ "staticToken": "Statisches Service-Token",
8154
+ "legacySharedSecret": "Gemeinsames Geheimnis (Legacy-Token)",
8155
+ "oauth2": "OAuth2 Client Credentials",
8156
+ "basic": "HTTP Basic",
8157
+ "headers": "Eigene Header"
8158
+ },
8159
+ "status": {
8160
+ "ok": "Importiert",
8161
+ "partial": "Teilweise importiert",
8162
+ "failed": "Import fehlgeschlagen",
8163
+ "never": "Nie importiert"
8164
+ },
8165
+ "action": {
8166
+ "connect": "Verbinden",
8167
+ "replace": "Ersetzen",
8168
+ "probe": "Verbindung testen",
8169
+ "import": "Jetzt importieren",
8170
+ "disconnect": "Trennen"
8171
+ },
8172
+ "disconnect": {
8173
+ "title": "Servicekatalog trennen?",
8174
+ "body": "Die von diesem Portal importierten Services werden aus dem Katalog zurückgezogen. Manuell registrierte oder hochgeladene Einträge bleiben unberührt.",
8175
+ "confirm": "Trennen"
8176
+ },
8177
+ "toast": {
8178
+ "connected": "Servicekatalog verbunden",
8179
+ "connectFailed": "Servicekatalog konnte nicht verbunden werden",
8180
+ "probeOk": "Das Portal hat geantwortet",
8181
+ "probeFailed": "Das Portal war nicht erreichbar",
8182
+ "imported": "Servicekatalog importiert",
8183
+ "importedDetail": "{upserted} aktualisiert, {unchanged} unverändert, {tombstoned} zurückgezogen",
8184
+ "importFailed": "Servicekatalog konnte nicht importiert werden",
8185
+ "disconnected": "Servicekatalog getrennt",
8186
+ "disconnectFailed": "Servicekatalog konnte nicht getrennt werden"
8187
+ }
8101
8188
  }
8102
8189
  }
@@ -686,7 +686,11 @@
686
686
  "binary_generators_unreachable": "This deployment's generative integrations could not be read just now, so the run was not started. Nothing is misconfigured and no change is needed: try again once the connection recovers.",
687
687
  "foundational_builtins_unreachable": "This deployment's built-in foundational services could not be read just now. Nothing is misconfigured and no change is needed: try again once the connection recovers.",
688
688
  "connection_credentials_unreadable": "The stored credentials for this connection could not be read. If this deployment can reach the service holding its key, re-connect the source to replace them; otherwise try again once that connection recovers.",
689
- "vcs_capability_unsupported": "The source-control provider connected to this workspace does not offer this operation. Nothing is misconfigured and setting something up will not help: it is unavailable for this provider."
689
+ "vcs_capability_unsupported": "The source-control provider connected to this workspace does not offer this operation. Nothing is misconfigured and setting something up will not help: it is unavailable for this provider.",
690
+ "service_catalog_unreachable": "This workspace's developer portal did not answer, or answered with something this platform cannot read. Nothing here is misconfigured and no change will help: try again once the portal is reachable.",
691
+ "service_catalog_unauthorized": "The developer portal refused the stored credential. It has most likely been rotated or revoked: open the service-catalog settings and enter a current one.",
692
+ "service_catalog_filter_missing": "This connection's entity filter could not be read, so there is nothing to import. Re-save the service-catalog connection to restore it.",
693
+ "service_catalog_response_too_large": "The developer portal answered with more data than this platform will hold in one response. Open the service-catalog settings and lower the service cap, or turn off importing interface definitions, then import again."
690
694
  }
691
695
  },
692
696
  "action": {
@@ -1894,6 +1898,8 @@
1894
1898
  "cacheRead": "{tokens} cache read",
1895
1899
  "cacheWrite": "{tokens} cache write",
1896
1900
  "total": "total {duration}",
1901
+ "viaUpstream": "via {upstream}",
1902
+ "reportedCost": "billed {cost}",
1897
1903
  "prompt": "Prompt",
1898
1904
  "promptPrefixOmitted": "(new messages only: {count} earlier omitted)",
1899
1905
  "response": "Response",
@@ -3897,6 +3903,7 @@
3897
3903
  "context": "{value} ctx",
3898
3904
  "contextThousands": "{value}K ctx",
3899
3905
  "price": "{input}/{output} per Mtok",
3906
+ "retiresOn": "Retires {date}",
3900
3907
  "toast": {
3901
3908
  "connected": "OpenRouter key connected",
3902
3909
  "connectFailed": "Could not connect key",
@@ -6590,6 +6597,7 @@
6590
6597
  "empty": "No ephemeral environment for this run.",
6591
6598
  "provisionTypeLabel": "Provision type:",
6592
6599
  "engineLabel": "Engine:",
6600
+ "statusNote": "Provider note: {note}",
6593
6601
  "provisionType": {
6594
6602
  "kubernetes": "Kubernetes",
6595
6603
  "docker-compose": "Docker Compose",
@@ -6615,6 +6623,7 @@
6615
6623
  "teardown": "Tear down",
6616
6624
  "teardown-verify": "Teardown check",
6617
6625
  "status": "Status check",
6626
+ "remediate": "Repair in place",
6618
6627
  "dispatch": "Spin up",
6619
6628
  "release": "Tear down",
6620
6629
  "poll-failure": "Health check"
@@ -6852,7 +6861,8 @@
6852
6861
  },
6853
6862
  "tab": {
6854
6863
  "catalog": "Catalog",
6855
- "sources": "Repo sources"
6864
+ "sources": "Repo sources",
6865
+ "portal": "Developer portal"
6856
6866
  },
6857
6867
  "panel": {
6858
6868
  "title": "Foundational services",
@@ -6866,7 +6876,10 @@
6866
6876
  "format": {
6867
6877
  "openapi": "OpenAPI",
6868
6878
  "toadContract": "toad-contracts",
6869
- "lokaliseApiContract": "lokalise/api-contract"
6879
+ "lokaliseApiContract": "lokalise/api-contract",
6880
+ "asyncapi": "AsyncAPI",
6881
+ "graphql": "GraphQL",
6882
+ "grpc": "gRPC"
6870
6883
  },
6871
6884
  "contracts": {
6872
6885
  "omitted": "+{count} more not listed",
@@ -8387,5 +8400,79 @@
8387
8400
  "title": "Nothing to compare"
8388
8401
  },
8389
8402
  "loadFailed": "Could not load the generated candidates."
8403
+ },
8404
+ "serviceCatalog": {
8405
+ "unavailable": "Importing a service catalog is not configured for this deployment.",
8406
+ "intro": "Point the platform at the developer portal your organisation already runs, and its services are imported into the catalog above, with the identity, ownership and API definitions each one publishes. Agents that triage or investigate read them to work out which service a piece of work belongs to.",
8407
+ "summary": "Filter: {filter} · at most {max} services",
8408
+ "form": {
8409
+ "connect": "Connect a portal",
8410
+ "replace": "Replace this connection"
8411
+ },
8412
+ "field": {
8413
+ "baseUrl": "Portal URL",
8414
+ "authMode": "Authentication",
8415
+ "token": "Service token",
8416
+ "sharedSecret": "Shared secret",
8417
+ "tokenUrl": "Token endpoint",
8418
+ "clientId": "Client ID",
8419
+ "clientSecret": "Client secret",
8420
+ "scope": "Scope (optional)",
8421
+ "audience": "Audience (optional)",
8422
+ "username": "Username",
8423
+ "password": "Password",
8424
+ "headerName": "Header name",
8425
+ "headerValue": "Header value",
8426
+ "secondHeaderName": "Second header name (optional)",
8427
+ "secondHeaderValue": "Second header value",
8428
+ "entityFilter": "Entity filter",
8429
+ "maxServices": "Maximum services",
8430
+ "includeApis": "Import the API definitions each service publishes"
8431
+ },
8432
+ "help": {
8433
+ "baseUrl": "The base URL of your Backstage instance. A private or internal host is allowed only where the deployment permits it.",
8434
+ "token": "A service-to-service token from Backstage's external-access configuration.",
8435
+ "sharedSecret": "A base64 secret from `backend.auth.keys`. The platform signs a short-lived token with it per request.",
8436
+ "headers": "For a gateway that authenticates on its own header names, such as a Cloudflare Access service token.",
8437
+ "entityFilter": "One `key=value` term per line, all of which must match. Defaults to `kind=component`. Narrow it to the services you want offered as shared capabilities.",
8438
+ "maxServices": "An import that reaches this cap is reported as a prefix of the portal, not as the whole of it."
8439
+ },
8440
+ "auth": {
8441
+ "none": "None",
8442
+ "staticToken": "Static service token",
8443
+ "legacySharedSecret": "Shared secret (legacy token)",
8444
+ "oauth2": "OAuth2 client credentials",
8445
+ "basic": "HTTP Basic",
8446
+ "headers": "Custom headers"
8447
+ },
8448
+ "status": {
8449
+ "ok": "Imported",
8450
+ "partial": "Imported in part",
8451
+ "failed": "Import failed",
8452
+ "never": "Never imported"
8453
+ },
8454
+ "action": {
8455
+ "connect": "Connect",
8456
+ "replace": "Replace",
8457
+ "probe": "Test connection",
8458
+ "import": "Import now",
8459
+ "disconnect": "Disconnect"
8460
+ },
8461
+ "disconnect": {
8462
+ "title": "Disconnect the service catalog?",
8463
+ "body": "The services this portal imported are withdrawn from the catalog. Nothing you registered or uploaded by hand is touched.",
8464
+ "confirm": "Disconnect"
8465
+ },
8466
+ "toast": {
8467
+ "connected": "Service catalog connected",
8468
+ "connectFailed": "Could not connect the service catalog",
8469
+ "probeOk": "The portal answered",
8470
+ "probeFailed": "Could not reach the portal",
8471
+ "imported": "Service catalog imported",
8472
+ "importedDetail": "{upserted} updated, {unchanged} unchanged, {tombstoned} withdrawn",
8473
+ "importFailed": "Could not import the service catalog",
8474
+ "disconnected": "Service catalog disconnected",
8475
+ "disconnectFailed": "Could not disconnect the service catalog"
8476
+ }
8390
8477
  }
8391
8478
  }
@@ -617,7 +617,11 @@
617
617
  "binary_generators_unreachable": "No se han podido leer las integraciones generativas de esta instalación en este momento, así que no se ha iniciado la ejecución. No hay nada mal configurado ni hace falta ningún cambio: inténtalo de nuevo cuando se restablezca la conexión.",
618
618
  "foundational_builtins_unreachable": "No se han podido leer los servicios fundamentales integrados de esta instalación en este momento. No hay nada mal configurado ni hace falta ningún cambio: inténtalo de nuevo cuando se restablezca la conexión.",
619
619
  "connection_credentials_unreadable": "No se han podido leer las credenciales guardadas de esta conexión. Si esta instalación puede acceder al servicio que custodia su clave, vuelve a conectar la fuente para reemplazarlas; si no, inténtalo de nuevo cuando se restablezca esa conexión.",
620
- "vcs_capability_unsupported": "El proveedor de control de código conectado a este espacio de trabajo no ofrece esta operación. No hay nada mal configurado y configurar algo no servirá de nada: no está disponible para este proveedor."
620
+ "vcs_capability_unsupported": "El proveedor de control de código conectado a este espacio de trabajo no ofrece esta operación. No hay nada mal configurado y configurar algo no servirá de nada: no está disponible para este proveedor.",
621
+ "service_catalog_unreachable": "El portal de desarrollo de este espacio no respondió, o respondió con algo que esta plataforma no puede leer. Aquí no hay nada mal configurado y ningún cambio ayudará: vuelve a intentarlo cuando el portal esté accesible.",
622
+ "service_catalog_unauthorized": "El portal de desarrollo rechazó las credenciales guardadas. Lo más probable es que se hayan rotado o revocado: abre los ajustes del catálogo de servicios e introduce unas vigentes.",
623
+ "service_catalog_filter_missing": "No se pudo leer el filtro de entidades de esta conexión, así que no hay nada que importar. Vuelve a guardar la conexión del catálogo de servicios para restaurarlo.",
624
+ "service_catalog_response_too_large": "El portal de desarrollo respondió con más datos de los que esta plataforma admite en una sola respuesta. Abre la configuración del catálogo de servicios y reduce el límite de servicios, o desactiva la importación de definiciones de interfaz, y vuelve a importar."
621
625
  }
622
626
  },
623
627
  "action": {
@@ -1790,6 +1794,8 @@
1790
1794
  "cacheRead": "{tokens} leídos de caché",
1791
1795
  "cacheWrite": "{tokens} escritos en caché",
1792
1796
  "total": "total {duration}",
1797
+ "viaUpstream": "vía {upstream}",
1798
+ "reportedCost": "facturado {cost}",
1793
1799
  "prompt": "Prompt",
1794
1800
  "promptPrefixOmitted": "(solo mensajes nuevos: {count} anteriores omitidos)",
1795
1801
  "response": "Respuesta",
@@ -3612,6 +3618,7 @@
3612
3618
  "context": "{value} ctx",
3613
3619
  "contextThousands": "{value}K ctx",
3614
3620
  "price": "{input}/{output} por Mtok",
3621
+ "retiresOn": "Se retira el {date}",
3615
3622
  "toast": {
3616
3623
  "connected": "Clave de OpenRouter conectada",
3617
3624
  "connectFailed": "No se pudo conectar la clave",
@@ -6286,6 +6293,7 @@
6286
6293
  "empty": "No hay entorno efímero para esta ejecución.",
6287
6294
  "provisionTypeLabel": "Tipo de aprovisionamiento:",
6288
6295
  "engineLabel": "Motor:",
6296
+ "statusNote": "Nota del proveedor: {note}",
6289
6297
  "provisionType": {
6290
6298
  "kubernetes": "Kubernetes",
6291
6299
  "docker-compose": "Docker Compose",
@@ -6311,6 +6319,7 @@
6311
6319
  "teardown": "Desmontar",
6312
6320
  "teardown-verify": "Comprobación de desmontaje",
6313
6321
  "status": "Comprobación de estado",
6322
+ "remediate": "Reparación en sitio",
6314
6323
  "dispatch": "Arrancar",
6315
6324
  "release": "Desmontar",
6316
6325
  "poll-failure": "Comprobación de salud"
@@ -6541,7 +6550,8 @@
6541
6550
  },
6542
6551
  "tab": {
6543
6552
  "catalog": "Catálogo",
6544
- "sources": "Repos vinculados"
6553
+ "sources": "Repos vinculados",
6554
+ "portal": "Portal de desarrollo"
6545
6555
  },
6546
6556
  "panel": {
6547
6557
  "title": "Servicios fundamentales",
@@ -6555,7 +6565,10 @@
6555
6565
  "format": {
6556
6566
  "openapi": "OpenAPI",
6557
6567
  "toadContract": "toad-contracts",
6558
- "lokaliseApiContract": "lokalise/api-contract"
6568
+ "lokaliseApiContract": "lokalise/api-contract",
6569
+ "asyncapi": "AsyncAPI",
6570
+ "graphql": "GraphQL",
6571
+ "grpc": "gRPC"
6559
6572
  },
6560
6573
  "contracts": {
6561
6574
  "omitted": "+{count} más sin listar",
@@ -8098,5 +8111,79 @@
8098
8111
  "title": "Nada que comparar"
8099
8112
  },
8100
8113
  "loadFailed": "No se pudieron cargar los candidatos generados."
8114
+ },
8115
+ "serviceCatalog": {
8116
+ "unavailable": "La importación de un catálogo de servicios no está configurada en esta instalación.",
8117
+ "intro": "Apunta la plataforma al portal de desarrollo que ya usa tu organización: sus servicios se importan al catálogo de arriba, con su identidad, su responsable y las definiciones de API que publica cada uno. Los agentes que clasifican o investigan incidencias los leen para deducir a qué servicio pertenece un trabajo.",
8118
+ "summary": "Filtro: {filter} · como máximo {max} servicios",
8119
+ "form": {
8120
+ "connect": "Conectar un portal",
8121
+ "replace": "Reemplazar esta conexión"
8122
+ },
8123
+ "field": {
8124
+ "baseUrl": "URL del portal",
8125
+ "authMode": "Autenticación",
8126
+ "token": "Token de servicio",
8127
+ "sharedSecret": "Secreto compartido",
8128
+ "tokenUrl": "Endpoint de token",
8129
+ "clientId": "ID de cliente",
8130
+ "clientSecret": "Secreto de cliente",
8131
+ "scope": "Scope (opcional)",
8132
+ "audience": "Audience (opcional)",
8133
+ "username": "Usuario",
8134
+ "password": "Contraseña",
8135
+ "headerName": "Nombre de la cabecera",
8136
+ "headerValue": "Valor de la cabecera",
8137
+ "secondHeaderName": "Segunda cabecera (opcional)",
8138
+ "secondHeaderValue": "Valor de la segunda cabecera",
8139
+ "entityFilter": "Filtro de entidades",
8140
+ "maxServices": "Máximo de servicios",
8141
+ "includeApis": "Importar las definiciones de API que publica cada servicio"
8142
+ },
8143
+ "help": {
8144
+ "baseUrl": "La URL base de tu instancia de Backstage. Un host privado o interno solo se admite si la instalación lo permite.",
8145
+ "token": "Un token de servicio a servicio de la configuración de acceso externo de Backstage.",
8146
+ "sharedSecret": "Un secreto en base64 de `backend.auth.keys`. La plataforma firma con él un token de vida corta en cada petición.",
8147
+ "headers": "Para una pasarela que autentica con sus propias cabeceras, como un token de servicio de Cloudflare Access.",
8148
+ "entityFilter": "Un término `key=value` por línea; todos deben coincidir. Por defecto `kind=component`. Redúcelo a los servicios que quieras ofrecer como capacidades compartidas.",
8149
+ "maxServices": "Una importación que alcanza este límite se informa como un extracto del portal, no como su totalidad."
8150
+ },
8151
+ "auth": {
8152
+ "none": "Ninguna",
8153
+ "staticToken": "Token de servicio estático",
8154
+ "legacySharedSecret": "Secreto compartido (token heredado)",
8155
+ "oauth2": "Credenciales de cliente OAuth2",
8156
+ "basic": "HTTP Basic",
8157
+ "headers": "Cabeceras personalizadas"
8158
+ },
8159
+ "status": {
8160
+ "ok": "Importado",
8161
+ "partial": "Importado en parte",
8162
+ "failed": "Importación fallida",
8163
+ "never": "Nunca importado"
8164
+ },
8165
+ "action": {
8166
+ "connect": "Conectar",
8167
+ "replace": "Reemplazar",
8168
+ "probe": "Probar conexión",
8169
+ "import": "Importar ahora",
8170
+ "disconnect": "Desconectar"
8171
+ },
8172
+ "disconnect": {
8173
+ "title": "¿Desconectar el catálogo de servicios?",
8174
+ "body": "Los servicios importados de este portal se retiran del catálogo. Nada de lo que registraste o subiste a mano se ve afectado.",
8175
+ "confirm": "Desconectar"
8176
+ },
8177
+ "toast": {
8178
+ "connected": "Catálogo de servicios conectado",
8179
+ "connectFailed": "No se pudo conectar el catálogo de servicios",
8180
+ "probeOk": "El portal respondió",
8181
+ "probeFailed": "No se pudo acceder al portal",
8182
+ "imported": "Catálogo de servicios importado",
8183
+ "importedDetail": "{upserted} actualizados, {unchanged} sin cambios, {tombstoned} retirados",
8184
+ "importFailed": "No se pudo importar el catálogo de servicios",
8185
+ "disconnected": "Catálogo de servicios desconectado",
8186
+ "disconnectFailed": "No se pudo desconectar el catálogo de servicios"
8187
+ }
8101
8188
  }
8102
8189
  }