diff --git a/src/agents/bash-tools.exec-runtime.ts b/src/agents/bash-tools.exec-runtime.ts index b3183da9fb82..cbf1169a237d 100644 --- a/src/agents/bash-tools.exec-runtime.ts +++ b/src/agents/bash-tools.exec-runtime.ts @@ -403,9 +403,7 @@ export function buildApprovalPendingMessage(params: { ); lines.push(`Reply with: /approve ${params.approvalSlug} ${decisionText}`); if (!allowedDecisions.includes("allow-always")) { - lines.push( - "The effective approval policy requires approval every time, so Allow Always is unavailable.", - ); + lines.push("Allow Always is unavailable for this command."); } lines.push("If the short code is ambiguous, use the full id in /approve."); return lines.join("\n"); diff --git a/src/gateway/server-methods/exec-approval.ts b/src/gateway/server-methods/exec-approval.ts index 60fda32e4b0d..494b8ab7e8dd 100644 --- a/src/gateway/server-methods/exec-approval.ts +++ b/src/gateway/server-methods/exec-approval.ts @@ -480,8 +480,7 @@ export function createExecApprovalHandlers( return allowedDecisions.includes(decision) ? null : { - message: - "allow-always is unavailable because the effective policy requires approval every time", + message: "allow-always is unavailable for this command", details: APPROVAL_ALLOW_ALWAYS_UNAVAILABLE_DETAILS, }; }, diff --git a/src/gateway/server-methods/server-methods.test.ts b/src/gateway/server-methods/server-methods.test.ts index 310d9cc6d7f3..964e55c4dbcc 100644 --- a/src/gateway/server-methods/server-methods.test.ts +++ b/src/gateway/server-methods/server-methods.test.ts @@ -3716,8 +3716,7 @@ describe("exec approval handlers", () => { expect(mockCallArg(resolveRespond)).toBe(false); expect(mockCallArg(resolveRespond, 0, 1)).toBeUndefined(); expectRecordFields(mockCallArg(resolveRespond, 0, 2), { - message: - "allow-always is unavailable because the effective policy requires approval every time", + message: "allow-always is unavailable for this command", }); const denyRespond = vi.fn(); @@ -3759,8 +3758,7 @@ describe("exec approval handlers", () => { expect(mockCallArg(resolveRespond)).toBe(false); expect(mockCallArg(resolveRespond, 0, 1)).toBeUndefined(); expectRecordFields(mockCallArg(resolveRespond, 0, 2), { - message: - "allow-always is unavailable because the effective policy requires approval every time", + message: "allow-always is unavailable for this command", }); const allowOnceRespond = vi.fn(); diff --git a/src/infra/exec-approval-forwarder.ts b/src/infra/exec-approval-forwarder.ts index bc4fa4888a79..705d010fd975 100644 --- a/src/infra/exec-approval-forwarder.ts +++ b/src/infra/exec-approval-forwarder.ts @@ -283,9 +283,7 @@ export function buildExecApprovalRequestMessage(request: ExecApprovalRequest, no ); lines.push(`Reply with: /approve ${request.id} ${decisionText}`); if (!allowedDecisions.includes("allow-always")) { - lines.push( - "Allow Always is unavailable because the effective policy requires approval every time.", - ); + lines.push("Allow Always is unavailable for this command."); } return lines.join("\n"); } diff --git a/src/infra/exec-approval-reply.test.ts b/src/infra/exec-approval-reply.test.ts index d183363543a7..3cfa299c201b 100644 --- a/src/infra/exec-approval-reply.test.ts +++ b/src/infra/exec-approval-reply.test.ts @@ -334,7 +334,7 @@ describe("exec approval reply helpers", () => { expect(payload.text).not.toContain("C:\\Users\\alice"); }); - it("omits allow-always actions when the effective policy requires approval every time", () => { + it("omits allow-always actions when allow-always is unavailable", () => { const payload = buildExecApprovalPendingReplyPayload({ approvalId: "req-ask-always", approvalSlug: "slug-always", @@ -353,9 +353,7 @@ describe("exec approval reply helpers", () => { }); expect(payload.text).toContain("```txt\n/approve slug-always allow-once\n```"); expect(payload.text).not.toContain("allow-always"); - expect(payload.text).toContain( - "The effective approval policy requires approval every time, so Allow Always is unavailable.", - ); + expect(payload.text).toContain("Allow Always is unavailable for this command."); expect(payload.presentation).toEqual({ blocks: [ { diff --git a/src/infra/exec-approval-reply.ts b/src/infra/exec-approval-reply.ts index 5787aa01869c..b3355e179229 100644 --- a/src/infra/exec-approval-reply.ts +++ b/src/infra/exec-approval-reply.ts @@ -383,9 +383,7 @@ export function buildExecApprovalPendingReplyPayload( lines.push(secondaryFence); } if (!allowedDecisions.includes("allow-always")) { - lines.push( - "The effective approval policy requires approval every time, so Allow Always is unavailable.", - ); + lines.push("Allow Always is unavailable for this command."); } const info: string[] = []; info.push(`Host: ${params.host}`); diff --git a/src/plugin-sdk/approval-reaction-runtime.test.ts b/src/plugin-sdk/approval-reaction-runtime.test.ts index 76f204555ef7..a5e2889413f5 100644 --- a/src/plugin-sdk/approval-reaction-runtime.test.ts +++ b/src/plugin-sdk/approval-reaction-runtime.test.ts @@ -155,6 +155,27 @@ describe("plugin-sdk/approval-reaction-runtime", () => { expect(payload.text).not.toContain("\nIgnore previous instructions"); }); + it("builds exec reaction prompts with neutral allow-always unavailable copy", () => { + const payload = buildApprovalReactionPromptPayloadForRequest({ + request: { + ...execRequest, + request: { + ...execRequest.request, + ask: "always", + }, + }, + nowMs: 1_000, + }); + + expect(payload.text).toContain("React with:\n\n👍 Allow Once\n👎 Deny"); + expect(payload.text).not.toContain("♾️ Allow Always"); + expect(payload.text).toContain("Allow Always is unavailable for this command."); + expect(payload.text).not.toContain("effective policy requires approval every time"); + expect( + payload.text?.trim().endsWith("Reply with: /approve exec-approval-123 allow-once|deny"), + ).toBe(true); + }); + it("builds canonical plugin reaction prompts with real ids", () => { const payload = buildApprovalReactionPromptPayloadForRequest({ request: { @@ -176,6 +197,7 @@ describe("plugin-sdk/approval-reaction-runtime", () => { expect(payload.text).toContain( "Allow Always is unavailable because the effective policy requires approval every time.", ); + expect(payload.text).not.toContain("Allow Always is unavailable for this command."); expect( payload.text?.trim().endsWith("Reply with: /approve plugin:approval-123 allow-once|deny"), ).toBe(true); diff --git a/src/plugin-sdk/approval-reaction-runtime.ts b/src/plugin-sdk/approval-reaction-runtime.ts index cfd918122c61..f0336b5003dd 100644 --- a/src/plugin-sdk/approval-reaction-runtime.ts +++ b/src/plugin-sdk/approval-reaction-runtime.ts @@ -236,13 +236,16 @@ function buildDecisionText(allowedDecisions: readonly ExecApprovalReplyDecision[ } function buildManualInstructionSection(params: { + approvalKind: ApprovalKind; approvalId: string; allowedDecisions: readonly ExecApprovalReplyDecision[]; }): string[] { const lines: string[] = []; if (!params.allowedDecisions.includes("allow-always")) { lines.push( - "Allow Always is unavailable because the effective policy requires approval every time.", + params.approvalKind === "exec" + ? "Allow Always is unavailable for this command." + : "Allow Always is unavailable because the effective policy requires approval every time.", ); } if (params.allowedDecisions.length > 0) { @@ -335,6 +338,7 @@ function buildApprovalReactionPromptText(params: { sections.push(commandInstructions.join("\n")); } const manualInstructions = buildManualInstructionSection({ + approvalKind: view.approvalKind, approvalId: view.approvalId, allowedDecisions, }); diff --git a/ui/src/components/exec-approval.test.ts b/ui/src/components/exec-approval.test.ts new file mode 100644 index 000000000000..c0f09b955dc0 --- /dev/null +++ b/ui/src/components/exec-approval.test.ts @@ -0,0 +1,107 @@ +/* @vitest-environment jsdom */ + +import { html, nothing, render, type LitElement } from "lit"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import type { ExecApprovalRequest } from "../app/exec-approval.ts"; +import { i18n } from "../i18n/index.ts"; +import { getRenderedModalDialog, installDialogPolyfill } from "../test-helpers/modal-dialog.ts"; +import "./exec-approval.ts"; + +let container: HTMLDivElement; +let restoreDialogPolyfill: () => void; + +function createExecRequest(overrides: Partial = {}): ExecApprovalRequest { + return { + id: "approval-1", + kind: "exec", + request: { + command: "echo hello", + ask: "on-request", + }, + createdAtMs: Date.now() - 1_000, + expiresAtMs: Date.now() + 60_000, + ...overrides, + }; +} + +async function renderApproval(request: ExecApprovalRequest) { + render( + html``, + container, + ); + const approval = container.querySelector("openclaw-exec-approval"); + if (!approval) { + throw new Error("Expected exec approval"); + } + await approval.updateComplete; +} + +describe("openclaw-exec-approval", () => { + beforeEach(async () => { + restoreDialogPolyfill = installDialogPolyfill(); + await i18n.setLocale("en"); + container = document.createElement("div"); + document.body.append(container); + }); + + afterEach(async () => { + render(nothing, container); + container.remove(); + await i18n.setLocale("en"); + restoreDialogPolyfill(); + vi.restoreAllMocks(); + }); + + it("uses neutral unavailable copy for exec allow-always decisions", async () => { + await renderApproval( + createExecRequest({ + request: { + command: "echo hello", + ask: "always", + allowedDecisions: ["allow-once", "deny"], + }, + }), + ); + + await getRenderedModalDialog(container); + + expect( + Array.from(container.querySelectorAll(".exec-approval-actions button")).map((button) => + button.textContent?.trim(), + ), + ).toEqual(["Allow once", "Deny"]); + expect(container.querySelector(".exec-approval-warning")?.textContent?.trim()).toBe( + "Allow Always is unavailable for this command.", + ); + }); + + it("does not show exec unavailable copy for restricted plugin approvals", async () => { + await renderApproval( + createExecRequest({ + id: "plugin-approval-1", + kind: "plugin", + request: { + command: "Plugin approval", + allowedDecisions: ["allow-once", "deny"], + }, + pluginTitle: "Plugin approval", + }), + ); + + await getRenderedModalDialog(container); + + expect( + Array.from(container.querySelectorAll(".exec-approval-actions button")).map((button) => + button.textContent?.trim(), + ), + ).toEqual(["Allow once", "Deny"]); + expect(container.querySelector(".exec-approval-warning")).toBeNull(); + }); +}); diff --git a/ui/src/i18n/.i18n/ar.meta.json b/ui/src/i18n/.i18n/ar.meta.json index 83c17f32fc47..e6588acfae24 100644 --- a/ui/src/i18n/.i18n/ar.meta.json +++ b/ui/src/i18n/.i18n/ar.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:33.404Z", + "generatedAt": "2026-07-11T09:56:49.437Z", "locale": "ar", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/de.meta.json b/ui/src/i18n/.i18n/de.meta.json index 990233662a3e..1998ec5c0ae1 100644 --- a/ui/src/i18n/.i18n/de.meta.json +++ b/ui/src/i18n/.i18n/de.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:32.165Z", + "generatedAt": "2026-07-11T09:56:48.554Z", "locale": "de", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/es.meta.json b/ui/src/i18n/.i18n/es.meta.json index de3d078f1568..03058aa0c561 100644 --- a/ui/src/i18n/.i18n/es.meta.json +++ b/ui/src/i18n/.i18n/es.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:32.362Z", + "generatedAt": "2026-07-11T09:56:48.697Z", "locale": "es", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/fa.meta.json b/ui/src/i18n/.i18n/fa.meta.json index 94b22f25eede..79d904aee426 100644 --- a/ui/src/i18n/.i18n/fa.meta.json +++ b/ui/src/i18n/.i18n/fa.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:35.201Z", + "generatedAt": "2026-07-11T09:56:51.134Z", "locale": "fa", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/fr.meta.json b/ui/src/i18n/.i18n/fr.meta.json index 2bd50458dab4..40cf83872367 100644 --- a/ui/src/i18n/.i18n/fr.meta.json +++ b/ui/src/i18n/.i18n/fr.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:32.981Z", + "generatedAt": "2026-07-11T09:56:49.141Z", "locale": "fr", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/hi.meta.json b/ui/src/i18n/.i18n/hi.meta.json index b07d00a24096..3b7e386ff169 100644 --- a/ui/src/i18n/.i18n/hi.meta.json +++ b/ui/src/i18n/.i18n/hi.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:33.193Z", + "generatedAt": "2026-07-11T09:56:49.292Z", "locale": "hi", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/id.meta.json b/ui/src/i18n/.i18n/id.meta.json index 40188082994c..0d3f0cd58990 100644 --- a/ui/src/i18n/.i18n/id.meta.json +++ b/ui/src/i18n/.i18n/id.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:34.204Z", + "generatedAt": "2026-07-11T09:56:50.018Z", "locale": "id", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/it.meta.json b/ui/src/i18n/.i18n/it.meta.json index 2c2288d0566d..acbfb57a5a45 100644 --- a/ui/src/i18n/.i18n/it.meta.json +++ b/ui/src/i18n/.i18n/it.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:33.611Z", + "generatedAt": "2026-07-11T09:56:49.584Z", "locale": "it", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/ja-JP.meta.json b/ui/src/i18n/.i18n/ja-JP.meta.json index a90dbc4168c1..649ac1361028 100644 --- a/ui/src/i18n/.i18n/ja-JP.meta.json +++ b/ui/src/i18n/.i18n/ja-JP.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:32.564Z", + "generatedAt": "2026-07-11T09:56:48.848Z", "locale": "ja-JP", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/ko.meta.json b/ui/src/i18n/.i18n/ko.meta.json index 3b7d9973b81d..f6c7ec46b954 100644 --- a/ui/src/i18n/.i18n/ko.meta.json +++ b/ui/src/i18n/.i18n/ko.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:32.774Z", + "generatedAt": "2026-07-11T09:56:48.993Z", "locale": "ko", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/nl.meta.json b/ui/src/i18n/.i18n/nl.meta.json index 3834b785b012..29d5a752c20d 100644 --- a/ui/src/i18n/.i18n/nl.meta.json +++ b/ui/src/i18n/.i18n/nl.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:34.993Z", + "generatedAt": "2026-07-11T09:56:50.985Z", "locale": "nl", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/pl.meta.json b/ui/src/i18n/.i18n/pl.meta.json index 4d15fe047487..6050e4517ef7 100644 --- a/ui/src/i18n/.i18n/pl.meta.json +++ b/ui/src/i18n/.i18n/pl.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:34.419Z", + "generatedAt": "2026-07-11T09:56:50.155Z", "locale": "pl", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/pt-BR.meta.json b/ui/src/i18n/.i18n/pt-BR.meta.json index b4c432fb84c2..72839d72adb2 100644 --- a/ui/src/i18n/.i18n/pt-BR.meta.json +++ b/ui/src/i18n/.i18n/pt-BR.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:31.982Z", + "generatedAt": "2026-07-11T09:56:48.414Z", "locale": "pt-BR", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/ru.meta.json b/ui/src/i18n/.i18n/ru.meta.json index 0fcb758af22a..34f0206864bb 100644 --- a/ui/src/i18n/.i18n/ru.meta.json +++ b/ui/src/i18n/.i18n/ru.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:35.401Z", + "generatedAt": "2026-07-11T09:56:51.279Z", "locale": "ru", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/th.meta.json b/ui/src/i18n/.i18n/th.meta.json index 30581877a3a6..863fb0cc74cf 100644 --- a/ui/src/i18n/.i18n/th.meta.json +++ b/ui/src/i18n/.i18n/th.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:34.610Z", + "generatedAt": "2026-07-11T09:56:50.298Z", "locale": "th", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/tr.meta.json b/ui/src/i18n/.i18n/tr.meta.json index 71e2ec8ffa98..57e30fd350e8 100644 --- a/ui/src/i18n/.i18n/tr.meta.json +++ b/ui/src/i18n/.i18n/tr.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:33.815Z", + "generatedAt": "2026-07-11T09:56:49.733Z", "locale": "tr", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/uk.meta.json b/ui/src/i18n/.i18n/uk.meta.json index 149b7ccdbae0..5acadcfbcfc3 100644 --- a/ui/src/i18n/.i18n/uk.meta.json +++ b/ui/src/i18n/.i18n/uk.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:34.005Z", + "generatedAt": "2026-07-11T09:56:49.871Z", "locale": "uk", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/vi.meta.json b/ui/src/i18n/.i18n/vi.meta.json index af8e38ddc6ba..2d98d5f79d20 100644 --- a/ui/src/i18n/.i18n/vi.meta.json +++ b/ui/src/i18n/.i18n/vi.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:34.811Z", + "generatedAt": "2026-07-11T09:56:50.827Z", "locale": "vi", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/zh-CN.meta.json b/ui/src/i18n/.i18n/zh-CN.meta.json index 7ddf30e9d3a2..f61832b3268f 100644 --- a/ui/src/i18n/.i18n/zh-CN.meta.json +++ b/ui/src/i18n/.i18n/zh-CN.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:31.467Z", + "generatedAt": "2026-07-11T09:56:47.987Z", "locale": "zh-CN", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/.i18n/zh-TW.meta.json b/ui/src/i18n/.i18n/zh-TW.meta.json index 52e57f1d555e..bda15a77c157 100644 --- a/ui/src/i18n/.i18n/zh-TW.meta.json +++ b/ui/src/i18n/.i18n/zh-TW.meta.json @@ -1,10 +1,10 @@ { "fallbackKeys": [], - "generatedAt": "2026-07-11T09:23:31.818Z", + "generatedAt": "2026-07-11T09:56:48.269Z", "locale": "zh-TW", "model": "gpt-5.5", "provider": "openai", - "sourceHash": "9146812dfe02813bf7fc8eb1e6aa5d92db8285d2979abbdb2aa3ad7df99cbfa6", + "sourceHash": "fba37d0370a89c15e35e7cb0cc8fa13860cd265f7fd54d798a9e625cdb2e932b", "totalKeys": 2107, "translatedKeys": 2107, "workflow": 1 diff --git a/ui/src/i18n/locales/ar.ts b/ui/src/i18n/locales/ar.ts index 56054fff2d2e..d4692b4cc0e4 100644 --- a/ui/src/i18n/locales/ar.ts +++ b/ui/src/i18n/locales/ar.ts @@ -501,8 +501,7 @@ export const ar: TranslationMap = { pending: "{count} قيد الانتظار", allowOnce: "السماح مرة واحدة", alwaysAllow: "السماح دائمًا", - allowAlwaysUnavailable: - "تتطلب سياسة الموافقة السارية الحصول على الموافقة في كل مرة، لذا فإن خيار السماح دائمًا غير متاح.", + allowAlwaysUnavailable: "خيار السماح دائمًا غير متاح لهذا الأمر.", deny: "رفض", labels: { host: "المضيف", diff --git a/ui/src/i18n/locales/de.ts b/ui/src/i18n/locales/de.ts index 00f54a282a3f..7ebcf98fcfaf 100644 --- a/ui/src/i18n/locales/de.ts +++ b/ui/src/i18n/locales/de.ts @@ -506,8 +506,7 @@ export const de: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "Die wirksame Genehmigungsrichtlinie erfordert jedes Mal eine Genehmigung, daher ist Immer erlauben nicht verfügbar.", + allowAlwaysUnavailable: "Allow Always ist für diesen Befehl nicht verfügbar.", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/en.ts b/ui/src/i18n/locales/en.ts index 506be2fb1a7d..770a07ca52a6 100644 --- a/ui/src/i18n/locales/en.ts +++ b/ui/src/i18n/locales/en.ts @@ -500,8 +500,7 @@ export const en: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "The effective approval policy requires approval every time, so Allow Always is unavailable.", + allowAlwaysUnavailable: "Allow Always is unavailable for this command.", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/es.ts b/ui/src/i18n/locales/es.ts index 6f4d74f6d137..6d1d5ce45fe5 100644 --- a/ui/src/i18n/locales/es.ts +++ b/ui/src/i18n/locales/es.ts @@ -503,8 +503,7 @@ export const es: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "La política de aprobación efectiva requiere aprobación cada vez, por lo que Permitir siempre no está disponible.", + allowAlwaysUnavailable: "Permitir siempre no está disponible para este comando.", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/fa.ts b/ui/src/i18n/locales/fa.ts index fb600c45f9d5..f6545381d52b 100644 --- a/ui/src/i18n/locales/fa.ts +++ b/ui/src/i18n/locales/fa.ts @@ -503,8 +503,7 @@ export const fa: TranslationMap = { pending: "{count} در انتظار", allowOnce: "یک‌بار مجاز کن", alwaysAllow: "همیشه مجاز کن", - allowAlwaysUnavailable: - "سیاست تأیید مؤثر هر بار به تأیید نیاز دارد، بنابراین «همیشه مجاز باشد» در دسترس نیست.", + allowAlwaysUnavailable: "«همیشه مجاز باشد» برای این فرمان در دسترس نیست.", deny: "رد کردن", labels: { host: "میزبان", diff --git a/ui/src/i18n/locales/fr.ts b/ui/src/i18n/locales/fr.ts index 96747357abf4..98a07c0954e4 100644 --- a/ui/src/i18n/locales/fr.ts +++ b/ui/src/i18n/locales/fr.ts @@ -509,8 +509,7 @@ export const fr: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "La politique d’approbation effective exige une approbation à chaque fois, donc Autoriser toujours n’est pas disponible.", + allowAlwaysUnavailable: "Autoriser toujours n’est pas disponible pour cette commande.", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/hi.ts b/ui/src/i18n/locales/hi.ts index 329e069e5efb..dc26a402db45 100644 --- a/ui/src/i18n/locales/hi.ts +++ b/ui/src/i18n/locales/hi.ts @@ -502,8 +502,7 @@ export const hi: TranslationMap = { pending: "{count} लंबित", allowOnce: "एक बार अनुमति दें", alwaysAllow: "हमेशा अनुमति दें", - allowAlwaysUnavailable: - "प्रभावी अनुमोदन नीति हर बार अनुमोदन की आवश्यकता रखती है, इसलिए हमेशा अनुमति दें उपलब्ध नहीं है।", + allowAlwaysUnavailable: "इस कमांड के लिए हमेशा अनुमति दें उपलब्ध नहीं है।", deny: "अस्वीकार करें", labels: { host: "होस्ट", diff --git a/ui/src/i18n/locales/id.ts b/ui/src/i18n/locales/id.ts index a74f335efad2..977df84ba569 100644 --- a/ui/src/i18n/locales/id.ts +++ b/ui/src/i18n/locales/id.ts @@ -503,8 +503,7 @@ export const id: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "Kebijakan persetujuan yang berlaku mengharuskan persetujuan setiap kali, sehingga Izinkan Selalu tidak tersedia.", + allowAlwaysUnavailable: "Izinkan Selalu tidak tersedia untuk perintah ini.", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/it.ts b/ui/src/i18n/locales/it.ts index 7308e4cdb7dd..b8620fa526d4 100644 --- a/ui/src/i18n/locales/it.ts +++ b/ui/src/i18n/locales/it.ts @@ -508,8 +508,7 @@ export const it: TranslationMap = { pending: "{count} in sospeso", allowOnce: "Consenti una volta", alwaysAllow: "Consenti sempre", - allowAlwaysUnavailable: - "Il criterio di approvazione effettivo richiede l’approvazione ogni volta, quindi Consenti sempre non è disponibile.", + allowAlwaysUnavailable: "Consenti sempre non è disponibile per questo comando.", deny: "Nega", labels: { host: "Host", diff --git a/ui/src/i18n/locales/ja-JP.ts b/ui/src/i18n/locales/ja-JP.ts index 5cc40d77a97a..75c199fadd02 100644 --- a/ui/src/i18n/locales/ja-JP.ts +++ b/ui/src/i18n/locales/ja-JP.ts @@ -508,8 +508,7 @@ export const ja_JP: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "有効な承認ポリシーでは毎回承認が必要なため、Allow Always は利用できません。", + allowAlwaysUnavailable: "このコマンドでは Allow Always は利用できません。", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/ko.ts b/ui/src/i18n/locales/ko.ts index 09dc595a503f..e7cfd4c7f68a 100644 --- a/ui/src/i18n/locales/ko.ts +++ b/ui/src/i18n/locales/ko.ts @@ -501,8 +501,7 @@ export const ko: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "유효한 승인 정책이 매번 승인을 요구하므로, 항상 허용을 사용할 수 없습니다.", + allowAlwaysUnavailable: "이 명령에는 항상 허용을 사용할 수 없습니다.", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/nl.ts b/ui/src/i18n/locales/nl.ts index e4a195807b3d..e702cfa6454f 100644 --- a/ui/src/i18n/locales/nl.ts +++ b/ui/src/i18n/locales/nl.ts @@ -506,8 +506,7 @@ export const nl: TranslationMap = { pending: "{count} in behandeling", allowOnce: "Eenmalig toestaan", alwaysAllow: "Altijd toestaan", - allowAlwaysUnavailable: - "Het effectieve goedkeuringsbeleid vereist elke keer goedkeuring, dus Altijd toestaan is niet beschikbaar.", + allowAlwaysUnavailable: "Altijd toestaan is niet beschikbaar voor deze opdracht.", deny: "Weigeren", labels: { host: "Host", diff --git a/ui/src/i18n/locales/pl.ts b/ui/src/i18n/locales/pl.ts index 7ea7ec16225e..1fe35fed7557 100644 --- a/ui/src/i18n/locales/pl.ts +++ b/ui/src/i18n/locales/pl.ts @@ -504,8 +504,7 @@ export const pl: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "Obowiązująca zasada zatwierdzania wymaga zatwierdzenia za każdym razem, więc opcja Zawsze zezwalaj jest niedostępna.", + allowAlwaysUnavailable: "Opcja Zawsze zezwalaj jest niedostępna dla tego polecenia.", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/pt-BR.ts b/ui/src/i18n/locales/pt-BR.ts index 83cb395965e6..cfbda9971944 100644 --- a/ui/src/i18n/locales/pt-BR.ts +++ b/ui/src/i18n/locales/pt-BR.ts @@ -502,8 +502,7 @@ export const pt_BR: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "A política de aprovação efetiva exige aprovação todas as vezes, portanto Permitir sempre não está disponível.", + allowAlwaysUnavailable: "Permitir sempre não está disponível para este comando.", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/ru.ts b/ui/src/i18n/locales/ru.ts index 9be4b61ee8c7..2d0e749185a7 100644 --- a/ui/src/i18n/locales/ru.ts +++ b/ui/src/i18n/locales/ru.ts @@ -507,8 +507,7 @@ export const ru: TranslationMap = { pending: "Ожидает: {count}", allowOnce: "Разрешить один раз", alwaysAllow: "Всегда разрешать", - allowAlwaysUnavailable: - "Действующая политика подтверждений требует подтверждения каждый раз, поэтому «Всегда разрешать» недоступно.", + allowAlwaysUnavailable: "«Всегда разрешать» недоступно для этой команды.", deny: "Запретить", labels: { host: "Хост", diff --git a/ui/src/i18n/locales/th.ts b/ui/src/i18n/locales/th.ts index 8a5685035419..61edbadcb9fc 100644 --- a/ui/src/i18n/locales/th.ts +++ b/ui/src/i18n/locales/th.ts @@ -500,8 +500,7 @@ export const th: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "นโยบายการอนุมัติที่มีผลบังคับใช้กำหนดให้ต้องอนุมัติทุกครั้ง ดังนั้น Allow Always จึงไม่พร้อมใช้งาน", + allowAlwaysUnavailable: "Allow Always ไม่พร้อมใช้งานสำหรับคำสั่งนี้", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/tr.ts b/ui/src/i18n/locales/tr.ts index 648650e2dec8..5a5aab8b274b 100644 --- a/ui/src/i18n/locales/tr.ts +++ b/ui/src/i18n/locales/tr.ts @@ -506,8 +506,7 @@ export const tr: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "Geçerli onay ilkesi her seferinde onay gerektiriyor, bu nedenle Her Zaman İzin Ver kullanılamıyor.", + allowAlwaysUnavailable: "Her Zaman İzin Ver bu komut için kullanılamıyor.", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/uk.ts b/ui/src/i18n/locales/uk.ts index 26b293b5814a..88f234ab9ef5 100644 --- a/ui/src/i18n/locales/uk.ts +++ b/ui/src/i18n/locales/uk.ts @@ -503,8 +503,7 @@ export const uk: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: - "Чинна політика схвалення вимагає схвалення щоразу, тому «Дозволяти завжди» недоступно.", + allowAlwaysUnavailable: "«Дозволяти завжди» недоступно для цієї команди.", deny: "Deny", labels: { host: "Host", diff --git a/ui/src/i18n/locales/vi.ts b/ui/src/i18n/locales/vi.ts index 550c1a100c73..1538df0b4cea 100644 --- a/ui/src/i18n/locales/vi.ts +++ b/ui/src/i18n/locales/vi.ts @@ -502,8 +502,7 @@ export const vi: TranslationMap = { pending: "{count} đang chờ", allowOnce: "Cho phép một lần", alwaysAllow: "Luôn cho phép", - allowAlwaysUnavailable: - "Chính sách phê duyệt có hiệu lực yêu cầu phê duyệt mọi lần, vì vậy Không cho phép Luôn cho phép.", + allowAlwaysUnavailable: "Luôn cho phép không khả dụng cho lệnh này.", deny: "Từ chối", labels: { host: "Máy chủ", diff --git a/ui/src/i18n/locales/zh-CN.ts b/ui/src/i18n/locales/zh-CN.ts index 25c2842d8fe3..9e82c48066fe 100644 --- a/ui/src/i18n/locales/zh-CN.ts +++ b/ui/src/i18n/locales/zh-CN.ts @@ -500,7 +500,7 @@ export const zh_CN: TranslationMap = { pending: "{count} 个待处理", allowOnce: "允许一次", alwaysAllow: "始终允许", - allowAlwaysUnavailable: "有效的批准策略要求每次都批准,因此“始终允许”不可用。", + allowAlwaysUnavailable: "“始终允许”不可用于此命令。", deny: "拒绝", labels: { host: "主机", diff --git a/ui/src/i18n/locales/zh-TW.ts b/ui/src/i18n/locales/zh-TW.ts index 12e1afe7b99b..592cf1741c98 100644 --- a/ui/src/i18n/locales/zh-TW.ts +++ b/ui/src/i18n/locales/zh-TW.ts @@ -500,7 +500,7 @@ export const zh_TW: TranslationMap = { pending: "{count} pending", allowOnce: "Allow once", alwaysAllow: "Always allow", - allowAlwaysUnavailable: "有效的核准政策要求每次都需核准,因此「一律允許」無法使用。", + allowAlwaysUnavailable: "「一律允許」無法用於此指令。", deny: "Deny", labels: { host: "Host",