Compare commits

...

9 Commits

Author SHA1 Message Date
Matthew Zeng
e44aee78ad update 2026-03-19 12:20:13 -07:00
Matthew Zeng
1865fb0404 update 2026-03-19 11:25:30 -07:00
Matthew Zeng
b48202ea01 update 2026-03-19 10:59:14 -07:00
Matthew Zeng
a88fccb349 update 2026-03-19 10:14:50 -07:00
Matthew Zeng
7dca6cb44a update 2026-03-18 23:58:09 -07:00
Matthew Zeng
7c8b458038 update 2026-03-18 23:17:06 -07:00
Matthew Zeng
04808fa86c update 2026-03-18 22:57:16 -07:00
Matthew Zeng
352b6820dd update 2026-03-18 22:44:29 -07:00
Matthew Zeng
4d12fafef3 update 2026-03-18 14:52:15 -07:00
41 changed files with 2341 additions and 336 deletions

View File

@@ -1,6 +1,6 @@
[codespell]
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
skip = .git*,vendor,*-lock.yaml,*.lock,.codespellrc,*test.ts,*.jsonl,frame*.txt,*.snap,*.snap.new,*meriyah.umd.min.js
skip = .git*,vendor,*-lock.yaml,*.lock,.codespellrc,*test.ts,*.jsonl,frame*.txt,*.snap,*.snap.new,*meriyah.umd.min.js,*.ftl
check-hidden = true
ignore-regex = ^\s*"image/\S+": ".*|\b(afterAll)\b
ignore-words-list = ratatui,ser,iTerm,iterm2,iterm,te,TE

2
MODULE.bazel.lock generated
View File

@@ -827,8 +827,10 @@
"flate2_1.1.8": "{\"dependencies\":[{\"name\":\"cloudflare-zlib-sys\",\"optional\":true,\"req\":\"^0.3.6\"},{\"name\":\"crc32fast\",\"req\":\"^1.2.0\"},{\"name\":\"document-features\",\"optional\":true,\"req\":\"^0.2\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3\"},{\"name\":\"libz-ng-sys\",\"optional\":true,\"req\":\"^1.1.16\"},{\"default_features\":false,\"name\":\"libz-sys\",\"optional\":true,\"req\":\"^1.1.20\"},{\"default_features\":false,\"features\":[\"with-alloc\",\"simd\"],\"name\":\"miniz_oxide\",\"req\":\"^0.8.5\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", not(target_os = \\\"emscripten\\\")))\"},{\"default_features\":false,\"features\":[\"with-alloc\",\"simd\"],\"name\":\"miniz_oxide\",\"optional\":true,\"req\":\"^0.8.5\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"},{\"default_features\":false,\"features\":[\"std\",\"rust-allocator\"],\"name\":\"zlib-rs\",\"optional\":true,\"req\":\"^0.5.5\"}],\"features\":{\"any_c_zlib\":[\"any_zlib\"],\"any_impl\":[],\"any_zlib\":[\"any_impl\"],\"cloudflare_zlib\":[\"any_c_zlib\",\"cloudflare-zlib-sys\"],\"default\":[\"rust_backend\"],\"miniz-sys\":[\"rust_backend\"],\"rust_backend\":[\"miniz_oxide\",\"any_impl\"],\"zlib\":[\"any_c_zlib\",\"libz-sys\"],\"zlib-default\":[\"any_c_zlib\",\"libz-sys/default\"],\"zlib-ng\":[\"any_c_zlib\",\"libz-ng-sys\"],\"zlib-ng-compat\":[\"zlib\",\"libz-sys/zlib-ng\"],\"zlib-rs\":[\"any_zlib\",\"dep:zlib-rs\"]}}",
"float-cmp_0.10.0": "{\"dependencies\":[{\"default_features\":false,\"name\":\"num-traits\",\"optional\":true,\"req\":\"^0.2.1\"}],\"features\":{\"default\":[\"ratio\"],\"ratio\":[\"num-traits\"],\"std\":[]}}",
"fluent-bundle_0.15.3": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3\"},{\"name\":\"fluent-langneg\",\"req\":\"^0.13\"},{\"name\":\"fluent-syntax\",\"req\":\"^0.11.1\"},{\"kind\":\"dev\",\"name\":\"iai\",\"req\":\"^0.1\"},{\"name\":\"intl-memoizer\",\"req\":\"^0.5.2\"},{\"name\":\"intl_pluralrules\",\"req\":\"^7.0.1\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"},{\"name\":\"rustc-hash\",\"req\":\"^1\"},{\"name\":\"self_cell\",\"req\":\"^0.10\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_yaml\",\"req\":\"^0.8\"},{\"name\":\"smallvec\",\"req\":\"^1\"},{\"name\":\"unic-langid\",\"req\":\"^0.9\"},{\"features\":[\"macros\"],\"kind\":\"dev\",\"name\":\"unic-langid\",\"req\":\"^0.9\"}],\"features\":{\"all-benchmarks\":[],\"default\":[]}}",
"fluent-bundle_0.16.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"name\":\"fluent-langneg\",\"req\":\"^0.13\"},{\"name\":\"fluent-syntax\",\"req\":\"^0.12.0\"},{\"kind\":\"dev\",\"name\":\"iai\",\"req\":\"^0.1\"},{\"name\":\"intl-memoizer\",\"req\":\"^0.5.3\"},{\"name\":\"intl_pluralrules\",\"req\":\"^7.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"},{\"name\":\"rustc-hash\",\"req\":\"^2.1\"},{\"name\":\"self_cell\",\"req\":\"^1.2\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_yaml\",\"req\":\"^0.9\"},{\"name\":\"smallvec\",\"req\":\"^1.13\"},{\"name\":\"unic-langid\",\"req\":\"^0.9\"},{\"features\":[\"macros\"],\"kind\":\"dev\",\"name\":\"unic-langid\",\"req\":\"^0.9\"}],\"features\":{\"all-benchmarks\":[],\"default\":[]}}",
"fluent-langneg_0.13.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"unic-langid\",\"req\":\"^0.9\"},{\"features\":[\"macros\"],\"kind\":\"dev\",\"name\":\"unic-langid\",\"req\":\"^0.9\"},{\"features\":[\"macros\"],\"kind\":\"dev\",\"name\":\"unic-locale\",\"req\":\"^0.9\"}],\"features\":{\"cldr\":[\"unic-langid/likelysubtags\"],\"default\":[]}}",
"fluent-syntax_0.11.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"glob\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"iai\",\"req\":\"^0.1\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"thiserror\",\"req\":\"^1.0\"}],\"features\":{\"all-benchmarks\":[],\"default\":[],\"json\":[\"serde\",\"serde_json\"]}}",
"fluent-syntax_0.12.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"glob\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"iai\",\"req\":\"^0.1\"},{\"name\":\"memchr\",\"req\":\"^2.0\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"}],\"features\":{\"all-benchmarks\":[],\"default\":[],\"json\":[\"serde\",\"dep:serde_json\"],\"serde\":[\"dep:serde\"]}}",
"fluent_0.16.1": "{\"dependencies\":[{\"name\":\"fluent-bundle\",\"req\":\"^0.15.3\"},{\"name\":\"fluent-pseudo\",\"optional\":true,\"req\":\"^0.3.2\"},{\"name\":\"unic-langid\",\"req\":\"^0.9\"}],\"features\":{}}",
"flume_0.11.1": "{\"dependencies\":[{\"features\":[\"attributes\",\"unstable\"],\"kind\":\"dev\",\"name\":\"async-std\",\"req\":\"^1.13.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5.1\"},{\"kind\":\"dev\",\"name\":\"crossbeam-channel\",\"req\":\"^0.5.5\"},{\"kind\":\"dev\",\"name\":\"crossbeam-utils\",\"req\":\"^0.8.10\"},{\"features\":[\"std\"],\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"futures-core\",\"optional\":true,\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"futures-sink\",\"optional\":true,\"req\":\"^0.3\"},{\"features\":[\"js\"],\"kind\":\"dev\",\"name\":\"getrandom\",\"req\":\"^0.2.15\"},{\"features\":[\"getrandom\"],\"name\":\"nanorand\",\"optional\":true,\"req\":\"^0.7\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.3\"},{\"features\":[\"mutex\"],\"name\":\"spin1\",\"package\":\"spin\",\"req\":\"^0.9.8\"},{\"features\":[\"rt\",\"macros\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.16.1\"},{\"kind\":\"dev\",\"name\":\"waker-fn\",\"req\":\"^1.1.0\"}],\"features\":{\"async\":[\"futures-sink\",\"futures-core\"],\"default\":[\"async\",\"select\",\"eventual-fairness\"],\"eventual-fairness\":[\"select\",\"nanorand\"],\"select\":[],\"spin\":[]}}",
"flume_0.12.0": "{\"dependencies\":[{\"features\":[\"attributes\",\"unstable\"],\"kind\":\"dev\",\"name\":\"async-std\",\"req\":\"^1.13.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5.1\"},{\"kind\":\"dev\",\"name\":\"crossbeam-channel\",\"req\":\"^0.5.5\"},{\"kind\":\"dev\",\"name\":\"crossbeam-utils\",\"req\":\"^0.8.10\"},{\"features\":[\"std\",\"js\"],\"name\":\"fastrand\",\"optional\":true,\"req\":\"^2.3\"},{\"features\":[\"std\"],\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"futures-core\",\"optional\":true,\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"futures-sink\",\"optional\":true,\"req\":\"^0.3\"},{\"features\":[\"js\"],\"kind\":\"dev\",\"name\":\"getrandom\",\"req\":\"^0.2.15\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.3\"},{\"features\":[\"mutex\"],\"name\":\"spin1\",\"package\":\"spin\",\"req\":\"^0.9.8\"},{\"features\":[\"rt\",\"macros\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.16.1\"},{\"kind\":\"dev\",\"name\":\"waker-fn\",\"req\":\"^1.1.0\"}],\"features\":{\"async\":[\"futures-sink\",\"futures-core\"],\"default\":[\"async\",\"select\",\"eventual-fairness\"],\"eventual-fairness\":[\"select\",\"fastrand\"],\"select\":[],\"spin\":[]}}",

47
codex-rs/Cargo.lock generated
View File

@@ -1848,6 +1848,7 @@ dependencies = [
"codex-file-search",
"codex-git",
"codex-hooks",
"codex-i18n",
"codex-keyring-store",
"codex-network-proxy",
"codex-otel",
@@ -2111,6 +2112,18 @@ dependencies = [
"tokio",
]
[[package]]
name = "codex-i18n"
version = "0.0.0"
dependencies = [
"codex-utils-cargo-bin",
"fluent-bundle 0.16.0",
"pretty_assertions",
"sys-locale",
"thiserror 2.0.18",
"unic-langid",
]
[[package]]
name = "codex-keyring-store"
version = "0.0.0"
@@ -4139,7 +4152,7 @@ version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb74634707bebd0ce645a981148e8fb8c7bccd4c33c652aeffd28bf2f96d555a"
dependencies = [
"fluent-bundle",
"fluent-bundle 0.15.3",
"unic-langid",
]
@@ -4150,7 +4163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493"
dependencies = [
"fluent-langneg",
"fluent-syntax",
"fluent-syntax 0.11.1",
"intl-memoizer",
"intl_pluralrules",
"rustc-hash 1.1.0",
@@ -4159,6 +4172,22 @@ dependencies = [
"unic-langid",
]
[[package]]
name = "fluent-bundle"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01203cb8918f5711e73891b347816d932046f95f54207710bda99beaeb423bf4"
dependencies = [
"fluent-langneg",
"fluent-syntax 0.12.0",
"intl-memoizer",
"intl_pluralrules",
"rustc-hash 2.1.1",
"self_cell 1.2.2",
"smallvec",
"unic-langid",
]
[[package]]
name = "fluent-langneg"
version = "0.13.1"
@@ -4177,6 +4206,16 @@ dependencies = [
"thiserror 1.0.69",
]
[[package]]
name = "fluent-syntax"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198"
dependencies = [
"memchr",
"thiserror 2.0.18",
]
[[package]]
name = "flume"
version = "0.11.1"
@@ -4875,7 +4914,7 @@ dependencies = [
"arc-swap",
"fluent",
"fluent-langneg",
"fluent-syntax",
"fluent-syntax 0.11.1",
"i18n-embed-impl",
"intl-memoizer",
"log",
@@ -4894,7 +4933,7 @@ checksum = "04b2969d0b3fc6143776c535184c19722032b43e6a642d710fa3f88faec53c2d"
dependencies = [
"find-crate",
"fluent",
"fluent-syntax",
"fluent-syntax 0.11.1",
"i18n-config",
"i18n-embed",
"proc-macro-error2",

View File

@@ -3,6 +3,7 @@ members = [
"backend-client",
"ansi-escape",
"async-utils",
"i18n",
"app-server",
"app-server-client",
"app-server-protocol",
@@ -112,6 +113,7 @@ codex-feedback = { path = "feedback" }
codex-file-search = { path = "file-search" }
codex-git = { path = "utils/git" }
codex-hooks = { path = "hooks" }
codex-i18n = { path = "i18n" }
codex-keyring-store = { path = "keyring-store" }
codex-linux-sandbox = { path = "linux-sandbox" }
codex-lmstudio = { path = "lmstudio" }
@@ -191,6 +193,7 @@ env-flags = "0.1.1"
env_logger = "0.11.9"
eventsource-stream = "0.2.3"
flate2 = "1.1.4"
fluent-bundle = "0.16.0"
futures = { version = "0.3", default-features = false }
gethostname = "1.1.0"
globset = "0.4"
@@ -304,6 +307,7 @@ tree-sitter-bash = "0.25"
ts-rs = "11"
tungstenite = { version = "0.27.0", features = ["deflate", "proxy"] }
uds_windows = "1.1.0"
unic-langid = "0.9.6"
unicode-segmentation = "1.12.0"
unicode-width = "0.2"
url = "2"

View File

@@ -41,6 +41,7 @@ codex-execpolicy = { workspace = true }
codex-file-search = { workspace = true }
codex-git = { workspace = true }
codex-hooks = { workspace = true }
codex-i18n = { workspace = true }
codex-keyring-store = { workspace = true }
codex-network-proxy = { workspace = true }
codex-otel = { workspace = true }

View File

@@ -2183,6 +2183,10 @@
],
"description": "Optional absolute path to the Node runtime used by `js_repl`."
},
"locale": {
"description": "Preferred locale for localized user-facing strings.",
"type": "string"
},
"log_dir": {
"allOf": [
{

View File

@@ -195,10 +195,7 @@ pub(crate) async fn monitor_action(
} else if !rationale.is_empty() {
ArcMonitorOutcome::AskUser(rationale.to_string())
} else {
ArcMonitorOutcome::AskUser(
"Additional confirmation is required before this tool call can continue."
.to_string(),
)
ArcMonitorOutcome::AskUser(String::new())
}
}
ArcMonitorResultOutcome::SteerModel => {
@@ -207,9 +204,7 @@ pub(crate) async fn monitor_action(
} else if !short_reason.is_empty() {
ArcMonitorOutcome::SteerModel(short_reason.to_string())
} else {
ArcMonitorOutcome::SteerModel(
"Tool call was cancelled because of safety risks.".to_string(),
)
ArcMonitorOutcome::SteerModel(String::new())
}
}
}

View File

@@ -329,6 +329,58 @@ async fn monitor_action_posts_expected_arc_request() {
);
}
#[tokio::test]
#[serial(arc_monitor_env)]
async fn monitor_action_returns_empty_reason_when_arc_requires_generic_confirmation() {
let server = MockServer::start().await;
let (session, mut turn_context) = make_session_and_context().await;
turn_context.auth_manager = Some(crate::test_support::auth_manager_from_auth(
crate::CodexAuth::create_dummy_chatgpt_auth_for_testing(),
));
let mut config = (*turn_context.config).clone();
config.chatgpt_base_url = server.uri();
turn_context.config = Arc::new(config);
session
.record_into_history(
&[ResponseItem::Message {
id: None,
role: "user".to_string(),
content: vec![ContentItem::InputText {
text: "please run the tool".to_string(),
}],
end_turn: None,
phase: None,
}],
&turn_context,
)
.await;
Mock::given(method("POST"))
.and(path("/codex/safety/arc"))
.respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({
"outcome": "ask-user",
"short_reason": "",
"rationale": "",
"risk_score": 42,
"risk_level": "medium",
"evidence": [],
})))
.expect(1)
.mount(&server)
.await;
let outcome = monitor_action(
&session,
&turn_context,
serde_json::json!({ "tool": "mcp_tool_call" }),
)
.await;
assert_eq!(outcome, ArcMonitorOutcome::AskUser(String::new()));
}
#[tokio::test]
#[serial(arc_monitor_env)]
async fn monitor_action_uses_env_url_and_token_overrides() {

View File

@@ -42,8 +42,6 @@ use crate::error::CodexErr;
use crate::guardian::GuardianApprovalRequest;
use crate::guardian::review_approval_request_with_cancel;
use crate::guardian::routes_approval_to_guardian;
use crate::mcp_tool_call::MCP_TOOL_APPROVAL_ACCEPT;
use crate::mcp_tool_call::MCP_TOOL_APPROVAL_ACCEPT_FOR_SESSION;
use crate::mcp_tool_call::MCP_TOOL_APPROVAL_DECLINE_SYNTHETIC;
use crate::mcp_tool_call::build_guardian_mcp_tool_review_request;
use crate::mcp_tool_call::is_mcp_tool_approval_question_id;
@@ -693,15 +691,22 @@ async fn maybe_auto_review_mcp_request_user_input(
.options
.as_ref()
.and_then(|options| {
options
.iter()
.find(|option| option.label == MCP_TOOL_APPROVAL_ACCEPT_FOR_SESSION)
if options.len() > 2 {
options.get(1)
} else {
options.first()
}
})
.map(|option| option.label.clone())
.unwrap_or_else(|| MCP_TOOL_APPROVAL_ACCEPT.to_string()),
.unwrap_or_default(),
ReviewDecision::Approved
| ReviewDecision::ApprovedExecpolicyAmendment { .. }
| ReviewDecision::NetworkPolicyAmendment { .. } => MCP_TOOL_APPROVAL_ACCEPT.to_string(),
| ReviewDecision::NetworkPolicyAmendment { .. } => question
.options
.as_ref()
.and_then(|options| options.first())
.map(|option| option.label.clone())
.unwrap_or_default(),
ReviewDecision::Denied | ReviewDecision::Abort => {
MCP_TOOL_APPROVAL_DECLINE_SYNTHETIC.to_string()
}

View File

@@ -16,6 +16,7 @@ use crate::config_loader::RequirementSource;
use crate::features::Feature;
use assert_matches::assert_matches;
use codex_config::CONFIG_TOML_FILE;
use codex_i18n::DEFAULT_LOCALE;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
@@ -4247,6 +4248,7 @@ fn test_precedence_fixture_with_o3_profile() -> std::io::Result<()> {
)?;
assert_eq!(
Config {
locale: o3_profile_config.locale.clone(),
model: Some("o3".to_string()),
review_model: None,
model_context_window: None,
@@ -4388,6 +4390,7 @@ fn test_precedence_fixture_with_gpt3_profile() -> std::io::Result<()> {
fixture.codex_home(),
)?;
let expected_gpt3_profile_config = Config {
locale: gpt3_profile_config.locale.clone(),
model: Some("gpt-3.5-turbo".to_string()),
review_model: None,
model_context_window: None,
@@ -4527,6 +4530,7 @@ fn test_precedence_fixture_with_zdr_profile() -> std::io::Result<()> {
fixture.codex_home(),
)?;
let expected_zdr_profile_config = Config {
locale: zdr_profile_config.locale.clone(),
model: Some("o3".to_string()),
review_model: None,
model_context_window: None,
@@ -4652,6 +4656,7 @@ fn test_precedence_fixture_with_gpt5_profile() -> std::io::Result<()> {
fixture.codex_home(),
)?;
let expected_gpt5_profile_config = Config {
locale: gpt5_profile_config.locale.clone(),
model: Some("gpt-5.1".to_string()),
review_model: None,
model_context_window: None,
@@ -6155,6 +6160,59 @@ speaker = "Desk Speakers"
Ok(())
}
#[test]
fn locale_loads_from_config_toml() -> std::io::Result<()> {
let cfg: ConfigToml = toml::from_str(
r#"
locale = "zh-CN"
"#,
)
.expect("TOML deserialization should succeed");
assert_eq!(cfg.locale.as_deref(), Some("zh-CN"));
let codex_home = TempDir::new()?;
let config = Config::load_from_base_config_with_overrides(
cfg,
ConfigOverrides::default(),
codex_home.path().to_path_buf(),
)?;
assert_eq!(config.locale, "zh");
Ok(())
}
#[test]
fn invalid_locale_is_rejected() {
let codex_home = TempDir::new().expect("tempdir");
let err = Config::load_from_base_config_with_overrides(
ConfigToml {
locale: Some("not a locale".to_string()),
..Default::default()
},
ConfigOverrides::default(),
codex_home.path().to_path_buf(),
)
.expect_err("invalid locale should fail");
assert_eq!(err.kind(), std::io::ErrorKind::InvalidInput);
assert!(err.to_string().contains("invalid locale `not a locale`"));
}
#[test]
fn missing_or_unsupported_locale_falls_back_to_default() -> std::io::Result<()> {
let codex_home = TempDir::new()?;
let config = Config::load_from_base_config_with_overrides(
ConfigToml::default(),
ConfigOverrides::default(),
codex_home.path().to_path_buf(),
)?;
assert!(!config.locale.trim().is_empty());
assert!(config.locale == DEFAULT_LOCALE || config.locale == "zh");
Ok(())
}
#[derive(Deserialize, Debug, PartialEq)]
struct TuiTomlTest {
#[serde(default)]

View File

@@ -65,6 +65,7 @@ use crate::windows_sandbox::resolve_windows_sandbox_mode;
use crate::windows_sandbox::resolve_windows_sandbox_private_desktop;
use codex_app_server_protocol::Tools;
use codex_app_server_protocol::UserSavedConfig;
use codex_i18n::resolve_locale;
use codex_protocol::config_types::AltScreenMode;
use codex_protocol::config_types::ForcedLoginMethod;
use codex_protocol::config_types::Personality;
@@ -237,6 +238,9 @@ pub struct Config {
/// Warnings collected during config load that should be shown on startup.
pub startup_warnings: Vec<String>,
/// Resolved UI locale used for localized user-facing strings.
pub locale: String,
/// Optional override of model selection.
pub model: Option<String>,
@@ -1247,6 +1251,9 @@ pub struct ConfigToml {
#[serde(default)]
pub notify: Option<Vec<String>>,
/// Preferred locale for localized user-facing strings.
pub locale: Option<String>,
/// System instructions.
pub instructions: Option<String>,
@@ -2400,6 +2407,9 @@ impl Config {
let allow_login_shell = cfg.allow_login_shell.unwrap_or(true);
let history = cfg.history.unwrap_or_default();
let locale = resolve_locale(cfg.locale.as_deref()).map_err(|err| {
std::io::Error::new(std::io::ErrorKind::InvalidInput, format!("{err}"))
})?;
let agent_max_threads = cfg
.agents
@@ -2650,6 +2660,7 @@ impl Config {
NetworkSandboxPolicy::from(&effective_sandbox_policy)
};
let config = Self {
locale,
model,
service_tier,
review_model,

View File

@@ -1,5 +1,5 @@
{
"schema_version": 4,
"schema_version": 5,
"templates": [
{
"source_tool_index": 0,
@@ -9,18 +9,18 @@
"template_params": [
{
"name": "pr_number",
"label": "Pull request"
"label_id": "approval-param-pull-request"
},
{
"name": "repo_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
},
{
"name": "comment",
"label": "Comment"
"label_id": "approval-param-comment"
}
],
"template": "Allow {connector_name} to add a comment to a pull request?"
"question_id": "approval-question-github-add-comment-to-issue"
},
{
"source_tool_index": 1,
@@ -30,18 +30,18 @@
"template_params": [
{
"name": "reaction",
"label": "Reaction"
"label_id": "approval-param-reaction"
},
{
"name": "comment_id",
"label": "Comment"
"label_id": "approval-param-comment"
},
{
"name": "repo_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
}
],
"template": "Allow {connector_name} to add a reaction to an issue comment?"
"question_id": "approval-question-github-add-reaction-to-issue-comment"
},
{
"source_tool_index": 2,
@@ -51,18 +51,18 @@
"template_params": [
{
"name": "reaction",
"label": "Reaction"
"label_id": "approval-param-reaction"
},
{
"name": "pr_number",
"label": "Pull request"
"label_id": "approval-param-pull-request"
},
{
"name": "repo_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
}
],
"template": "Allow {connector_name} to add a reaction to a pull request?"
"question_id": "approval-question-github-add-reaction-to-pr"
},
{
"source_tool_index": 3,
@@ -72,18 +72,18 @@
"template_params": [
{
"name": "reaction",
"label": "Reaction"
"label_id": "approval-param-reaction"
},
{
"name": "comment_id",
"label": "Comment"
"label_id": "approval-param-comment"
},
{
"name": "repo_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
}
],
"template": "Allow {connector_name} to add a reaction to a pull request review comment?"
"question_id": "approval-question-github-add-reaction-to-pr-review-comment"
},
{
"source_tool_index": 4,
@@ -93,18 +93,18 @@
"template_params": [
{
"name": "action",
"label": "Action"
"label_id": "approval-param-action"
},
{
"name": "pr_number",
"label": "Pull request"
"label_id": "approval-param-pull-request"
},
{
"name": "review",
"label": "Review"
"label_id": "approval-param-review"
}
],
"template": "Allow {connector_name} to submit a pull request review?"
"question_id": "approval-question-github-add-review-to-pr"
},
{
"source_tool_index": 5,
@@ -114,14 +114,14 @@
"template_params": [
{
"name": "repository_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
},
{
"name": "content",
"label": "Content"
"label_id": "approval-param-content"
}
],
"template": "Allow {connector_name} to create a Git blob?"
"question_id": "approval-question-github-create-blob"
},
{
"source_tool_index": 6,
@@ -131,14 +131,14 @@
"template_params": [
{
"name": "branch_name",
"label": "Branch"
"label_id": "approval-param-branch"
},
{
"name": "repository_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
}
],
"template": "Allow {connector_name} to create a branch?"
"question_id": "approval-question-github-create-branch"
},
{
"source_tool_index": 7,
@@ -148,14 +148,14 @@
"template_params": [
{
"name": "repository_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
},
{
"name": "message",
"label": "Message"
"label_id": "approval-param-message"
}
],
"template": "Allow {connector_name} to create a commit?"
"question_id": "approval-question-github-create-commit"
},
{
"source_tool_index": 8,
@@ -165,18 +165,18 @@
"template_params": [
{
"name": "title",
"label": "Title"
"label_id": "approval-param-title"
},
{
"name": "head_branch",
"label": "Head branch"
"label_id": "approval-param-head-branch"
},
{
"name": "base_branch",
"label": "Base branch"
"label_id": "approval-param-base-branch"
}
],
"template": "Allow {connector_name} to create a pull request?"
"question_id": "approval-question-github-create-pull-request"
},
{
"source_tool_index": 9,
@@ -186,14 +186,14 @@
"template_params": [
{
"name": "repository_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
},
{
"name": "tree_elements",
"label": "Changes"
"label_id": "approval-param-changes"
}
],
"template": "Allow {connector_name} to create a Git tree?"
"question_id": "approval-question-github-create-tree"
},
{
"source_tool_index": 10,
@@ -203,14 +203,14 @@
"template_params": [
{
"name": "pr_number",
"label": "Pull request"
"label_id": "approval-param-pull-request"
},
{
"name": "repository_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
}
],
"template": "Allow {connector_name} to enable pull request auto-merge?"
"question_id": "approval-question-github-enable-auto-merge"
},
{
"source_tool_index": 11,
@@ -220,18 +220,18 @@
"template_params": [
{
"name": "label",
"label": "Label"
"label_id": "approval-param-label"
},
{
"name": "pr_number",
"label": "Pull request"
"label_id": "approval-param-pull-request"
},
{
"name": "repository_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
}
],
"template": "Allow {connector_name} to add a label to a pull request?"
"question_id": "approval-question-github-label-pr"
},
{
"source_tool_index": 12,
@@ -241,18 +241,18 @@
"template_params": [
{
"name": "reaction_id",
"label": "Reaction"
"label_id": "approval-param-reaction"
},
{
"name": "comment_id",
"label": "Comment"
"label_id": "approval-param-comment"
},
{
"name": "repo_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
}
],
"template": "Allow {connector_name} to remove a reaction from an issue comment?"
"question_id": "approval-question-github-remove-reaction-from-issue-comment"
},
{
"source_tool_index": 13,
@@ -262,18 +262,18 @@
"template_params": [
{
"name": "reaction_id",
"label": "Reaction"
"label_id": "approval-param-reaction"
},
{
"name": "pr_number",
"label": "Pull request"
"label_id": "approval-param-pull-request"
},
{
"name": "repo_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
}
],
"template": "Allow {connector_name} to remove a reaction from a pull request?"
"question_id": "approval-question-github-remove-reaction-from-pr"
},
{
"source_tool_index": 14,
@@ -283,18 +283,18 @@
"template_params": [
{
"name": "reaction_id",
"label": "Reaction"
"label_id": "approval-param-reaction"
},
{
"name": "comment_id",
"label": "Comment"
"label_id": "approval-param-comment"
},
{
"name": "repo_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
}
],
"template": "Allow {connector_name} to remove a reaction from a pull request review comment?"
"question_id": "approval-question-github-remove-reaction-from-pr-review-comment"
},
{
"source_tool_index": 15,
@@ -304,18 +304,18 @@
"template_params": [
{
"name": "pr_number",
"label": "Pull request"
"label_id": "approval-param-pull-request"
},
{
"name": "repo_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
},
{
"name": "comment",
"label": "Comment"
"label_id": "approval-param-comment"
}
],
"template": "Allow {connector_name} to reply to a pull request review comment?"
"question_id": "approval-question-github-reply-to-review-comment"
},
{
"source_tool_index": 16,
@@ -325,18 +325,18 @@
"template_params": [
{
"name": "comment_id",
"label": "Comment ID"
"label_id": "approval-param-comment-id"
},
{
"name": "repo_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
},
{
"name": "comment",
"label": "Comment"
"label_id": "approval-param-comment"
}
],
"template": "Allow {connector_name} to update an issue comment?"
"question_id": "approval-question-github-update-issue-comment"
},
{
"source_tool_index": 17,
@@ -346,18 +346,18 @@
"template_params": [
{
"name": "branch_name",
"label": "Branch"
"label_id": "approval-param-branch"
},
{
"name": "repository_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
},
{
"name": "sha",
"label": "Commit"
"label_id": "approval-param-commit"
}
],
"template": "Allow {connector_name} to update a branch reference?"
"question_id": "approval-question-github-update-ref"
},
{
"source_tool_index": 18,
@@ -367,18 +367,18 @@
"template_params": [
{
"name": "comment_id",
"label": "Comment ID"
"label_id": "approval-param-comment-id"
},
{
"name": "repo_full_name",
"label": "Repository"
"label_id": "approval-param-repository"
},
{
"name": "comment",
"label": "Comment"
"label_id": "approval-param-comment"
}
],
"template": "Allow {connector_name} to update a pull request review comment?"
"question_id": "approval-question-github-update-review-comment"
},
{
"source_tool_index": 19,
@@ -388,18 +388,18 @@
"template_params": [
{
"name": "title",
"label": "Title"
"label_id": "approval-param-title"
},
{
"name": "start_time",
"label": "Start"
"label_id": "approval-param-start"
},
{
"name": "attendees",
"label": "Attendees"
"label_id": "approval-param-attendees"
}
],
"template": "Allow {connector_name} to create an event?"
"question_id": "approval-question-google-calendar-create-event"
},
{
"source_tool_index": 20,
@@ -409,10 +409,10 @@
"template_params": [
{
"name": "event_id",
"label": "Event"
"label_id": "approval-param-event"
}
],
"template": "Allow {connector_name} to delete an event?"
"question_id": "approval-question-google-calendar-delete-event"
},
{
"source_tool_index": 21,
@@ -422,14 +422,14 @@
"template_params": [
{
"name": "response_status",
"label": "Response Status"
"label_id": "approval-param-response-status"
},
{
"name": "event_id",
"label": "Event"
"label_id": "approval-param-event"
}
],
"template": "Allow {connector_name} to respond to an event?"
"question_id": "approval-question-google-calendar-respond-event"
},
{
"source_tool_index": 22,
@@ -439,10 +439,10 @@
"template_params": [
{
"name": "event_id",
"label": "Event"
"label_id": "approval-param-event"
}
],
"template": "Allow {connector_name} to update an event?"
"question_id": "approval-question-google-calendar-update-event"
},
{
"source_tool_index": 23,
@@ -452,14 +452,14 @@
"template_params": [
{
"name": "spreadsheet_url",
"label": "Spreadsheet"
"label_id": "approval-param-spreadsheet"
},
{
"name": "requests",
"label": "Changes"
"label_id": "approval-param-changes"
}
],
"template": "Allow {connector_name} to apply spreadsheet updates?"
"question_id": "approval-question-google-sheets-batch-update"
},
{
"source_tool_index": 24,
@@ -469,10 +469,10 @@
"template_params": [
{
"name": "title",
"label": "Title"
"label_id": "approval-param-title"
}
],
"template": "Allow {connector_name} to create a spreadsheet?"
"question_id": "approval-question-google-sheets-create-spreadsheet"
},
{
"source_tool_index": 25,
@@ -482,18 +482,18 @@
"template_params": [
{
"name": "source_sheet_name",
"label": "Source Sheet Name"
"label_id": "approval-param-source-sheet-name"
},
{
"name": "spreadsheet_url",
"label": "Spreadsheet"
"label_id": "approval-param-spreadsheet"
},
{
"name": "new_file_name",
"label": "New File Name"
"label_id": "approval-param-new-file-name"
}
],
"template": "Allow {connector_name} to copy a sheet into a new spreadsheet?"
"question_id": "approval-question-google-sheets-duplicate-sheet-in-new-file"
},
{
"source_tool_index": 26,
@@ -503,14 +503,14 @@
"template_params": [
{
"name": "presentation_url",
"label": "Presentation"
"label_id": "approval-param-presentation"
},
{
"name": "requests",
"label": "Changes"
"label_id": "approval-param-changes"
}
],
"template": "Allow {connector_name} to apply presentation updates?"
"question_id": "approval-question-google-slides-batch-update"
},
{
"source_tool_index": 27,
@@ -520,10 +520,10 @@
"template_params": [
{
"name": "title",
"label": "Title"
"label_id": "approval-param-title"
}
],
"template": "Allow {connector_name} to create a presentation?"
"question_id": "approval-question-google-slides-create-presentation"
},
{
"source_tool_index": 28,
@@ -533,14 +533,14 @@
"template_params": [
{
"name": "document_url",
"label": "Document"
"label_id": "approval-param-document"
},
{
"name": "requests",
"label": "Changes"
"label_id": "approval-param-changes"
}
],
"template": "Allow {connector_name} to apply document updates?"
"question_id": "approval-question-google-docs-batch-update"
},
{
"source_tool_index": 29,
@@ -550,10 +550,10 @@
"template_params": [
{
"name": "title",
"label": "Title"
"label_id": "approval-param-title"
}
],
"template": "Allow {connector_name} to create a document?"
"question_id": "approval-question-google-docs-create-document"
},
{
"source_tool_index": 30,
@@ -563,10 +563,10 @@
"template_params": [
{
"name": "url",
"label": "URL"
"label_id": "approval-param-url"
}
],
"template": "Allow {connector_name} to copy a file?"
"question_id": "approval-question-google-drive-copy-document"
},
{
"source_tool_index": 31,
@@ -576,14 +576,14 @@
"template_params": [
{
"name": "url",
"label": "URL"
"label_id": "approval-param-url"
},
{
"name": "permission",
"label": "Permission"
"label_id": "approval-param-permission"
}
],
"template": "Allow {connector_name} to change file sharing?"
"question_id": "approval-question-google-drive-share-document"
},
{
"source_tool_index": 32,
@@ -593,14 +593,14 @@
"template_params": [
{
"name": "channel_id",
"label": "Conversation"
"label_id": "approval-param-conversation"
},
{
"name": "message",
"label": "Message"
"label_id": "approval-param-message"
}
],
"template": "Allow {connector_name} to send a message?"
"question_id": "approval-question-slack-slack-send-message"
},
{
"source_tool_index": 33,
@@ -610,18 +610,18 @@
"template_params": [
{
"name": "channel_id",
"label": "Conversation"
"label_id": "approval-param-conversation"
},
{
"name": "post_at",
"label": "Send at"
"label_id": "approval-param-send-at"
},
{
"name": "message",
"label": "Message"
"label_id": "approval-param-message"
}
],
"template": "Allow {connector_name} to schedule a message?"
"question_id": "approval-question-slack-slack-schedule-message"
},
{
"source_tool_index": 34,
@@ -631,14 +631,14 @@
"template_params": [
{
"name": "title",
"label": "Title"
"label_id": "approval-param-title"
},
{
"name": "content",
"label": "Content"
"label_id": "approval-param-content"
}
],
"template": "Allow {connector_name} to create a canvas?"
"question_id": "approval-question-slack-slack-create-canvas"
},
{
"source_tool_index": 35,
@@ -648,14 +648,14 @@
"template_params": [
{
"name": "channel_id",
"label": "Conversation"
"label_id": "approval-param-conversation"
},
{
"name": "message",
"label": "Message"
"label_id": "approval-param-message"
}
],
"template": "Allow {connector_name} to create a message draft?"
"question_id": "approval-question-slack-slack-send-message-draft"
},
{
"source_tool_index": 36,
@@ -665,14 +665,14 @@
"template_params": [
{
"name": "issue_id",
"label": "Issue"
"label_id": "approval-param-issue"
},
{
"name": "body",
"label": "Body"
"label_id": "approval-param-body"
}
],
"template": "Allow {connector_name} to add a comment to an issue?"
"question_id": "approval-question-linear-add-comment-to-issue"
},
{
"source_tool_index": 37,
@@ -682,14 +682,14 @@
"template_params": [
{
"name": "label_id",
"label": "Label"
"label_id": "approval-param-label"
},
{
"name": "issue_id",
"label": "Issue"
"label_id": "approval-param-issue"
}
],
"template": "Allow {connector_name} to add a label to an issue?"
"question_id": "approval-question-linear-add-label-to-issue"
},
{
"source_tool_index": 38,
@@ -699,18 +699,18 @@
"template_params": [
{
"name": "url",
"label": "URL"
"label_id": "approval-param-url"
},
{
"name": "issue_id",
"label": "Issue"
"label_id": "approval-param-issue"
},
{
"name": "title",
"label": "Title"
"label_id": "approval-param-title"
}
],
"template": "Allow {connector_name} to attach a link to an issue?"
"question_id": "approval-question-linear-add-url-attachment-to-issue"
},
{
"source_tool_index": 39,
@@ -720,14 +720,14 @@
"template_params": [
{
"name": "issue_id",
"label": "Issue"
"label_id": "approval-param-issue"
},
{
"name": "user_id",
"label": "User"
"label_id": "approval-param-user"
}
],
"template": "Allow {connector_name} to assign an issue?"
"question_id": "approval-question-linear-assign-issue"
},
{
"source_tool_index": 40,
@@ -737,14 +737,14 @@
"template_params": [
{
"name": "title",
"label": "Title"
"label_id": "approval-param-title"
},
{
"name": "team_id",
"label": "Team"
"label_id": "approval-param-team"
}
],
"template": "Allow {connector_name} to create an issue?"
"question_id": "approval-question-linear-create-issue"
},
{
"source_tool_index": 41,
@@ -754,10 +754,10 @@
"template_params": [
{
"name": "label_name",
"label": "Label Name"
"label_id": "approval-param-label-name"
}
],
"template": "Allow {connector_name} to create a label?"
"question_id": "approval-question-linear-create-label"
},
{
"source_tool_index": 42,
@@ -767,14 +767,14 @@
"template_params": [
{
"name": "name",
"label": "Name"
"label_id": "approval-param-name"
},
{
"name": "team_id",
"label": "Team"
"label_id": "approval-param-team"
}
],
"template": "Allow {connector_name} to create a project?"
"question_id": "approval-question-linear-create-project"
},
{
"source_tool_index": 43,
@@ -784,14 +784,14 @@
"template_params": [
{
"name": "label_id",
"label": "Label"
"label_id": "approval-param-label"
},
{
"name": "issue_id",
"label": "Issue"
"label_id": "approval-param-issue"
}
],
"template": "Allow {connector_name} to remove a label from an issue?"
"question_id": "approval-question-linear-remove-label-from-issue"
},
{
"source_tool_index": 44,
@@ -801,10 +801,10 @@
"template_params": [
{
"name": "comment_id",
"label": "Comment"
"label_id": "approval-param-comment"
}
],
"template": "Allow {connector_name} to resolve a comment?"
"question_id": "approval-question-linear-resolve-comment"
},
{
"source_tool_index": 45,
@@ -814,14 +814,14 @@
"template_params": [
{
"name": "issue_id",
"label": "Issue"
"label_id": "approval-param-issue"
},
{
"name": "state_id",
"label": "State"
"label_id": "approval-param-state"
}
],
"template": "Allow {connector_name} to change issue state?"
"question_id": "approval-question-linear-set-issue-state"
},
{
"source_tool_index": 46,
@@ -831,10 +831,10 @@
"template_params": [
{
"name": "issue_id",
"label": "Issue"
"label_id": "approval-param-issue"
}
],
"template": "Allow {connector_name} to unassign an issue?"
"question_id": "approval-question-linear-unassign-issue"
},
{
"source_tool_index": 47,
@@ -844,14 +844,14 @@
"template_params": [
{
"name": "issue_id",
"label": "Issue"
"label_id": "approval-param-issue"
},
{
"name": "issue_update",
"label": "Changes"
"label_id": "approval-param-changes"
}
],
"template": "Allow {connector_name} to update an issue?"
"question_id": "approval-question-linear-update-issue"
},
{
"source_tool_index": 48,
@@ -861,14 +861,14 @@
"template_params": [
{
"name": "project_id",
"label": "Project"
"label_id": "approval-param-project"
},
{
"name": "update_fields",
"label": "Changes"
"label_id": "approval-param-changes"
}
],
"template": "Allow {connector_name} to update a project?"
"question_id": "approval-question-linear-update-project"
},
{
"source_tool_index": 49,
@@ -876,7 +876,7 @@
"server_name": "codex_apps",
"tool_title": "apply_labels_to_emails",
"template_params": [],
"template": "Allow {connector_name} to apply label changes to messages?"
"question_id": "approval-question-gmail-apply-labels-to-emails"
},
{
"source_tool_index": 50,
@@ -884,7 +884,7 @@
"server_name": "codex_apps",
"tool_title": "batch_modify_email",
"template_params": [],
"template": "Allow {connector_name} to update message labels?"
"question_id": "approval-question-gmail-batch-modify-email"
},
{
"source_tool_index": 51,
@@ -894,14 +894,14 @@
"template_params": [
{
"name": "label_name",
"label": "Label Name"
"label_id": "approval-param-label-name"
},
{
"name": "query",
"label": "Query"
"label_id": "approval-param-query"
}
],
"template": "Allow {connector_name} to label matching messages?"
"question_id": "approval-question-gmail-bulk-label-matching-emails"
},
{
"source_tool_index": 52,
@@ -911,18 +911,18 @@
"template_params": [
{
"name": "to",
"label": "To"
"label_id": "approval-param-to"
},
{
"name": "subject",
"label": "Subject"
"label_id": "approval-param-subject"
},
{
"name": "body",
"label": "Body"
"label_id": "approval-param-body"
}
],
"template": "Allow {connector_name} to create an email draft?"
"question_id": "approval-question-gmail-create-draft"
},
{
"source_tool_index": 53,
@@ -932,10 +932,10 @@
"template_params": [
{
"name": "name",
"label": "Name"
"label_id": "approval-param-name"
}
],
"template": "Allow {connector_name} to create a label?"
"question_id": "approval-question-gmail-create-label"
},
{
"source_tool_index": 54,
@@ -945,18 +945,18 @@
"template_params": [
{
"name": "to",
"label": "To"
"label_id": "approval-param-to"
},
{
"name": "subject",
"label": "Subject"
"label_id": "approval-param-subject"
},
{
"name": "body",
"label": "Body"
"label_id": "approval-param-body"
}
],
"template": "Allow {connector_name} to send an email?"
"question_id": "approval-question-gmail-send-email"
}
]
}

View File

@@ -1,14 +1,14 @@
use std::collections::HashSet;
use std::sync::LazyLock;
use codex_i18n::format_message;
use serde::Deserialize;
use serde::Serialize;
use serde_json::Map;
use serde_json::Value;
use tracing::warn;
const CONSEQUENTIAL_TOOL_MESSAGE_TEMPLATES_SCHEMA_VERSION: u8 = 4;
const CONNECTOR_NAME_TEMPLATE_VAR: &str = "{connector_name}";
const CONSEQUENTIAL_TOOL_MESSAGE_TEMPLATES_SCHEMA_VERSION: u8 = 5;
static CONSEQUENTIAL_TOOL_MESSAGE_TEMPLATES: LazyLock<
Option<Vec<ConsequentialToolMessageTemplate>>,
@@ -40,17 +40,18 @@ struct ConsequentialToolMessageTemplate {
connector_id: String,
server_name: String,
tool_title: String,
template: String,
question_id: String,
template_params: Vec<ConsequentialToolTemplateParam>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
struct ConsequentialToolTemplateParam {
name: String,
label: String,
label_id: String,
}
pub(crate) fn render_mcp_tool_approval_template(
locale: &str,
server_name: &str,
connector_id: Option<&str>,
connector_name: Option<&str>,
@@ -60,6 +61,7 @@ pub(crate) fn render_mcp_tool_approval_template(
let templates = CONSEQUENTIAL_TOOL_MESSAGE_TEMPLATES.as_ref()?;
render_mcp_tool_approval_template_from_templates(
templates,
locale,
server_name,
connector_id,
connector_name,
@@ -93,6 +95,7 @@ fn load_consequential_tool_message_templates() -> Option<Vec<ConsequentialToolMe
fn render_mcp_tool_approval_template_from_templates(
templates: &[ConsequentialToolMessageTemplate],
locale: &str,
server_name: &str,
connector_id: Option<&str>,
connector_name: Option<&str>,
@@ -106,10 +109,11 @@ fn render_mcp_tool_approval_template_from_templates(
&& template.connector_id == connector_id
&& template.tool_title == tool_title
})?;
let elicitation_message = render_question_template(&template.template, connector_name)?;
let elicitation_message =
render_question_template(locale, &template.question_id, connector_name)?;
let (tool_params, tool_params_display) = match tool_params {
Some(Value::Object(tool_params)) => {
render_tool_params(tool_params, &template.template_params)?
render_tool_params(locale, tool_params, &template.template_params)?
}
Some(_) => return None,
None => (None, Vec::new()),
@@ -123,23 +127,25 @@ fn render_mcp_tool_approval_template_from_templates(
})
}
fn render_question_template(template: &str, connector_name: Option<&str>) -> Option<String> {
let template = template.trim();
if template.is_empty() {
fn render_question_template(
locale: &str,
question_id: &str,
connector_name: Option<&str>,
) -> Option<String> {
let connector_name = connector_name
.map(str::trim)
.filter(|name| !name.is_empty())?;
let args = [("connector_name", connector_name)];
let rendered = format_message(locale, question_id, &args);
let rendered = rendered.trim();
if rendered.is_empty() {
return None;
}
if template.contains(CONNECTOR_NAME_TEMPLATE_VAR) {
let connector_name = connector_name
.map(str::trim)
.filter(|name| !name.is_empty())?;
return Some(template.replace(CONNECTOR_NAME_TEMPLATE_VAR, connector_name));
}
Some(template.to_string())
Some(rendered.to_string())
}
fn render_tool_params(
locale: &str,
tool_params: &Map<String, Value>,
template_params: &[ConsequentialToolTemplateParam],
) -> Option<(Option<Value>, Vec<RenderedMcpToolApprovalParam>)> {
@@ -148,7 +154,8 @@ fn render_tool_params(
let mut handled_names = HashSet::new();
for template_param in template_params {
let label = template_param.label.trim();
let label = format_message(locale, &template_param.label_id, &[]);
let label = label.trim();
if label.is_empty() {
return None;
}
@@ -202,21 +209,22 @@ mod tests {
connector_id: "calendar".to_string(),
server_name: "codex_apps".to_string(),
tool_title: "create_event".to_string(),
template: "Allow {connector_name} to create an event?".to_string(),
question_id: "approval-question-google-calendar-create-event".to_string(),
template_params: vec![
ConsequentialToolTemplateParam {
name: "calendar_id".to_string(),
label: "Calendar".to_string(),
label_id: "approval-param-calendar".to_string(),
},
ConsequentialToolTemplateParam {
name: "title".to_string(),
label: "Title".to_string(),
label_id: "approval-param-title".to_string(),
},
],
}];
let rendered = render_mcp_tool_approval_template_from_templates(
&templates,
"en-US",
"codex_apps",
Some("calendar"),
Some("Calendar"),
@@ -228,34 +236,31 @@ mod tests {
})),
);
let rendered = rendered.expect("template should render");
assert_eq!(rendered.question, rendered.elicitation_message);
assert_eq!(rendered.question.contains("Calendar"), true);
assert_eq!(
rendered,
Some(RenderedMcpToolApprovalTemplate {
question: "Allow Calendar to create an event?".to_string(),
elicitation_message: "Allow Calendar to create an event?".to_string(),
tool_params: Some(json!({
"title": "Roadmap review",
"calendar_id": "primary",
"timezone": "UTC",
})),
tool_params_display: vec![
RenderedMcpToolApprovalParam {
name: "calendar_id".to_string(),
value: json!("primary"),
display_name: "Calendar".to_string(),
},
RenderedMcpToolApprovalParam {
name: "title".to_string(),
value: json!("Roadmap review"),
display_name: "Title".to_string(),
},
RenderedMcpToolApprovalParam {
name: "timezone".to_string(),
value: json!("UTC"),
display_name: "timezone".to_string(),
},
],
})
rendered.tool_params,
Some(json!({
"title": "Roadmap review",
"calendar_id": "primary",
"timezone": "UTC",
}))
);
assert_eq!(
rendered
.tool_params_display
.iter()
.map(|param| param.name.as_str())
.collect::<Vec<_>>(),
vec!["calendar_id", "title", "timezone"]
);
assert_eq!(
rendered
.tool_params_display
.last()
.map(|param| param.display_name.as_str()),
Some("timezone")
);
}
@@ -265,13 +270,14 @@ mod tests {
connector_id: "calendar".to_string(),
server_name: "codex_apps".to_string(),
tool_title: "create_event".to_string(),
template: "Allow {connector_name} to create an event?".to_string(),
question_id: "approval-question-google-calendar-create-event".to_string(),
template_params: Vec::new(),
}];
assert_eq!(
render_mcp_tool_approval_template_from_templates(
&templates,
"en-US",
"codex_apps",
Some("calendar"),
Some("Calendar"),
@@ -288,16 +294,17 @@ mod tests {
connector_id: "calendar".to_string(),
server_name: "codex_apps".to_string(),
tool_title: "create_event".to_string(),
template: "Allow {connector_name} to create an event?".to_string(),
question_id: "approval-question-google-calendar-create-event".to_string(),
template_params: vec![ConsequentialToolTemplateParam {
name: "calendar_id".to_string(),
label: "timezone".to_string(),
label_id: "approval-param-timezone".to_string(),
}],
}];
assert_eq!(
render_mcp_tool_approval_template_from_templates(
&templates,
"en-US",
"codex_apps",
Some("calendar"),
Some("Calendar"),
@@ -322,15 +329,16 @@ mod tests {
connector_id: "github".to_string(),
server_name: "codex_apps".to_string(),
tool_title: "add_comment".to_string(),
template: "Allow GitHub to add a comment to a pull request?".to_string(),
question_id: "approval-question-github-add-comment-to-issue".to_string(),
template_params: Vec::new(),
}];
let rendered = render_mcp_tool_approval_template_from_templates(
&templates,
"en-US",
"codex_apps",
Some("github"),
None,
Some("GitHub"),
Some("add_comment"),
Some(&json!({})),
);
@@ -352,13 +360,14 @@ mod tests {
connector_id: "calendar".to_string(),
server_name: "codex_apps".to_string(),
tool_title: "create_event".to_string(),
template: "Allow {connector_name} to create an event?".to_string(),
question_id: "approval-question-google-calendar-create-event".to_string(),
template_params: Vec::new(),
}];
assert_eq!(
render_mcp_tool_approval_template_from_templates(
&templates,
"en-US",
"codex_apps",
Some("calendar"),
None,

View File

@@ -6,6 +6,7 @@ use codex_app_server_protocol::McpElicitationObjectType;
use codex_app_server_protocol::McpElicitationSchema;
use codex_app_server_protocol::McpServerElicitationRequest;
use codex_app_server_protocol::McpServerElicitationRequestParams;
use codex_i18n::format_message;
use tracing::error;
use crate::analytics_client::AppInvocation;
@@ -319,6 +320,117 @@ fn sanitize_mcp_tool_result_for_model(
})
}
fn arc_monitor_additional_confirmation_message(locale: &str) -> String {
localized_message(locale, "arc-monitor-additional-confirmation", &[])
}
fn arc_monitor_interrupt_message(locale: &str, reason: &str) -> String {
let reason = reason.trim();
if reason.is_empty() {
return localized_message(locale, "approval-safety-cancelled", &[]);
}
localized_message(
locale,
"approval-safety-cancelled-with-reason",
&[("reason", reason)],
)
}
fn mcp_tool_approval_copy(locale: &str) -> McpToolApprovalCopy {
McpToolApprovalCopy {
header: localized_message(locale, "approval-header", &[]),
accept: McpToolApprovalOptionCopy {
label: localized_message(locale, "approval-option-allow", &[]),
description: localized_message(locale, "approval-option-allow-description", &[]),
},
accept_for_session: McpToolApprovalOptionCopy {
label: localized_message(locale, "approval-option-allow-session", &[]),
description: localized_message(
locale,
"approval-option-allow-session-description",
&[],
),
},
accept_and_remember: McpToolApprovalOptionCopy {
label: localized_message(locale, "approval-option-allow-remember", &[]),
description: localized_message(
locale,
"approval-option-allow-remember-description",
&[],
),
},
cancel: McpToolApprovalOptionCopy {
label: localized_message(locale, "approval-option-cancel", &[]),
description: localized_message(locale, "approval-option-cancel-description", &[]),
},
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
struct McpToolApprovalOptionCopy {
label: String,
description: String,
}
#[derive(Clone, Debug, PartialEq, Eq)]
struct McpToolApprovalCopy {
header: String,
accept: McpToolApprovalOptionCopy,
accept_for_session: McpToolApprovalOptionCopy,
accept_and_remember: McpToolApprovalOptionCopy,
cancel: McpToolApprovalOptionCopy,
}
fn mcp_tool_approval_fallback_message(
locale: &str,
server: &str,
tool_name: &str,
connector_name: Option<&str>,
) -> String {
if let Some(connector_name) = connector_name
.map(str::trim)
.filter(|name| !name.is_empty())
{
return format_message(
locale,
"approval-fallback-question-connector",
&[("connector_name", connector_name), ("tool_name", tool_name)],
);
}
if server == CODEX_APPS_MCP_SERVER_NAME {
return format_message(
locale,
"approval-fallback-question-this-app",
&[("tool_name", tool_name)],
);
}
format_message(
locale,
"approval-fallback-question-server",
&[("server", server), ("tool_name", tool_name)],
)
}
fn mcp_tool_approval_question_text(
locale: &str,
question: String,
monitor_reason: Option<&str>,
) -> String {
match monitor_reason.map(str::trim) {
Some(reason) if !reason.is_empty() => {
localized_message(locale, "approval-monitor-question", &[("reason", reason)])
}
_ => question,
}
}
fn localized_message(locale: &str, message_id: &str, args: &[(&str, &str)]) -> String {
format_message(locale, message_id, args)
}
async fn notify_mcp_tool_call_event(sess: &Session, turn_context: &TurnContext, event: EventMsg) {
sess.send_event(turn_context, event).await;
}
@@ -421,15 +533,11 @@ struct McpToolApprovalElicitationRequest<'a> {
}
pub(crate) const MCP_TOOL_APPROVAL_QUESTION_ID_PREFIX: &str = "mcp_tool_call_approval";
pub(crate) const MCP_TOOL_APPROVAL_ACCEPT: &str = "Allow";
pub(crate) const MCP_TOOL_APPROVAL_ACCEPT_FOR_SESSION: &str = "Allow for this session";
// Internal-only token used when guardian auto-reviews delegated MCP approvals on the
// RequestUserInput compatibility path. That legacy MCP prompt has allow/cancel labels but no
// real "Decline" answer, so this lets guardian denials round-trip distinctly from user cancel.
// This is not a user-facing option.
pub(crate) const MCP_TOOL_APPROVAL_DECLINE_SYNTHETIC: &str = "__codex_mcp_decline__";
const MCP_TOOL_APPROVAL_ACCEPT_AND_REMEMBER: &str = "Allow and don't ask me again";
const MCP_TOOL_APPROVAL_CANCEL: &str = "Cancel";
const MCP_TOOL_APPROVAL_KIND_KEY: &str = "codex_approval_kind";
const MCP_TOOL_APPROVAL_KIND_MCP_TOOL_CALL: &str = "mcp_tool_call";
const MCP_TOOL_APPROVAL_PERSIST_KEY: &str = "persist";
@@ -492,11 +600,15 @@ async fn maybe_request_mcp_tool_approval(
{
ArcMonitorOutcome::Ok => return None,
ArcMonitorOutcome::AskUser(reason) => {
monitor_reason = Some(reason);
monitor_reason = Some(if reason.trim().is_empty() {
arc_monitor_additional_confirmation_message(&turn_context.config.locale)
} else {
reason
});
}
ArcMonitorOutcome::SteerModel(reason) => {
return Some(McpToolApprovalDecision::BlockedBySafetyMonitor(
arc_monitor_interrupt_message(&reason),
arc_monitor_interrupt_message(&turn_context.config.locale, &reason),
));
}
}
@@ -551,6 +663,7 @@ async fn maybe_request_mcp_tool_approval(
);
let question_id = format!("{MCP_TOOL_APPROVAL_QUESTION_ID_PREFIX}_{call_id}");
let rendered_template = render_mcp_tool_approval_template(
&turn_context.config.locale,
&invocation.server,
metadata.and_then(|metadata| metadata.connector_id.as_deref()),
metadata.and_then(|metadata| metadata.connector_name.as_deref()),
@@ -562,6 +675,7 @@ async fn maybe_request_mcp_tool_approval(
.map(|rendered_template| rendered_template.tool_params_display.clone())
.or_else(|| build_mcp_tool_approval_display_params(invocation.arguments.as_ref()));
let mut question = build_mcp_tool_approval_question(
&turn_context.config.locale,
question_id.clone(),
&invocation.server,
&invocation.tool,
@@ -571,8 +685,11 @@ async fn maybe_request_mcp_tool_approval(
.as_ref()
.map(|rendered_template| rendered_template.question.as_str()),
);
question.question =
mcp_tool_approval_question_text(question.question, monitor_reason.as_deref());
question.question = mcp_tool_approval_question_text(
&turn_context.config.locale,
question.question,
monitor_reason.as_deref(),
);
if tool_call_mcp_elicitation_enabled {
let request_id = rmcp::model::RequestId::String(
format!("{MCP_TOOL_APPROVAL_QUESTION_ID_PREFIX}_{call_id}").into(),
@@ -598,6 +715,7 @@ async fn maybe_request_mcp_tool_approval(
},
);
let decision = parse_mcp_tool_approval_elicitation_response(
&turn_context.config.locale,
sess.request_mcp_server_elicitation(turn_context.as_ref(), request_id, params)
.await,
&question_id,
@@ -621,7 +739,7 @@ async fn maybe_request_mcp_tool_approval(
.request_user_input(turn_context.as_ref(), call_id.to_string(), args)
.await;
let decision = normalize_approval_decision_for_mode(
parse_mcp_tool_approval_response(response, &question_id),
parse_mcp_tool_approval_response(&turn_context.config.locale, response, &question_id),
approval_mode,
);
apply_mcp_tool_approval_decision(
@@ -820,6 +938,7 @@ async fn lookup_mcp_app_usage_metadata(
}
fn build_mcp_tool_approval_question(
locale: &str,
question_id: String,
server: &str,
tool_name: &str,
@@ -827,37 +946,38 @@ fn build_mcp_tool_approval_question(
prompt_options: McpToolApprovalPromptOptions,
question_override: Option<&str>,
) -> RequestUserInputQuestion {
let approval_copy = mcp_tool_approval_copy(locale);
let question = question_override
.map(ToString::to_string)
.unwrap_or_else(|| {
build_mcp_tool_approval_fallback_message(server, tool_name, connector_name)
mcp_tool_approval_fallback_message(locale, server, tool_name, connector_name)
});
let question = format!("{}?", question.trim_end_matches('?'));
let mut options = vec![RequestUserInputQuestionOption {
label: MCP_TOOL_APPROVAL_ACCEPT.to_string(),
description: "Run the tool and continue.".to_string(),
label: approval_copy.accept.label.clone(),
description: approval_copy.accept.description,
}];
if prompt_options.allow_session_remember {
options.push(RequestUserInputQuestionOption {
label: MCP_TOOL_APPROVAL_ACCEPT_FOR_SESSION.to_string(),
description: "Run the tool and remember this choice for this session.".to_string(),
label: approval_copy.accept_for_session.label.clone(),
description: approval_copy.accept_for_session.description,
});
}
if prompt_options.allow_persistent_approval {
options.push(RequestUserInputQuestionOption {
label: MCP_TOOL_APPROVAL_ACCEPT_AND_REMEMBER.to_string(),
description: "Run the tool and remember this choice for future tool calls.".to_string(),
label: approval_copy.accept_and_remember.label.clone(),
description: approval_copy.accept_and_remember.description,
});
}
options.push(RequestUserInputQuestionOption {
label: MCP_TOOL_APPROVAL_CANCEL.to_string(),
description: "Cancel this tool call.".to_string(),
label: approval_copy.cancel.label,
description: approval_copy.cancel.description,
});
RequestUserInputQuestion {
id: question_id,
header: "Approve app tool call?".to_string(),
header: approval_copy.header,
question,
is_other: false,
is_secret: false,
@@ -865,43 +985,6 @@ fn build_mcp_tool_approval_question(
}
}
fn build_mcp_tool_approval_fallback_message(
server: &str,
tool_name: &str,
connector_name: Option<&str>,
) -> String {
let actor = connector_name
.map(str::trim)
.filter(|name| !name.is_empty())
.map(ToString::to_string)
.unwrap_or_else(|| {
if server == CODEX_APPS_MCP_SERVER_NAME {
"this app".to_string()
} else {
format!("the {server} MCP server")
}
});
format!("Allow {actor} to run tool \"{tool_name}\"?")
}
fn mcp_tool_approval_question_text(question: String, monitor_reason: Option<&str>) -> String {
match monitor_reason.map(str::trim) {
Some(reason) if !reason.is_empty() => {
format!("Tool call needs your approval. Reason: {reason}")
}
_ => question,
}
}
fn arc_monitor_interrupt_message(reason: &str) -> String {
let reason = reason.trim();
if reason.is_empty() {
"Tool call was cancelled because of safety risks.".to_string()
} else {
format!("Tool call was cancelled because of safety risks: {reason}")
}
}
fn build_mcp_tool_approval_elicitation_request(
sess: &Session,
turn_context: &TurnContext,
@@ -1052,6 +1135,7 @@ fn build_mcp_tool_approval_display_params(
}
fn parse_mcp_tool_approval_elicitation_response(
locale: &str,
response: Option<ElicitationResponse>,
question_id: &str,
) -> McpToolApprovalDecision {
@@ -1077,6 +1161,7 @@ fn parse_mcp_tool_approval_elicitation_response(
}
match parse_mcp_tool_approval_response(
locale,
request_user_input_response_from_elicitation_content(response.content),
question_id,
) {
@@ -1117,9 +1202,11 @@ fn request_user_input_response_from_elicitation_content(
}
fn parse_mcp_tool_approval_response(
locale: &str,
response: Option<RequestUserInputResponse>,
question_id: &str,
) -> McpToolApprovalDecision {
let approval_copy = mcp_tool_approval_copy(locale);
let Some(response) = response else {
return McpToolApprovalDecision::Cancel;
};
@@ -1137,17 +1224,17 @@ fn parse_mcp_tool_approval_response(
McpToolApprovalDecision::Decline
} else if answers
.iter()
.any(|answer| answer == MCP_TOOL_APPROVAL_ACCEPT_FOR_SESSION)
.any(|answer| answer == &approval_copy.accept_for_session.label)
{
McpToolApprovalDecision::AcceptForSession
} else if answers
.iter()
.any(|answer| answer == MCP_TOOL_APPROVAL_ACCEPT_AND_REMEMBER)
.any(|answer| answer == &approval_copy.accept_and_remember.label)
{
McpToolApprovalDecision::AcceptAndRemember
} else if answers
.iter()
.any(|answer| answer == MCP_TOOL_APPROVAL_ACCEPT)
.any(|answer| answer == &approval_copy.accept.label)
{
McpToolApprovalDecision::Accept
} else {

View File

@@ -7,6 +7,7 @@ use crate::config::types::AppToolConfig;
use crate::config::types::AppToolsConfig;
use crate::config::types::AppsConfigToml;
use codex_config::CONFIG_TOML_FILE;
use codex_i18n::DEFAULT_LOCALE;
use core_test_support::responses::ev_assistant_message;
use core_test_support::responses::ev_completed;
use core_test_support::responses::ev_response_created;
@@ -61,6 +62,10 @@ fn prompt_options(
}
}
fn approval_copy() -> McpToolApprovalCopy {
mcp_tool_approval_copy(DEFAULT_LOCALE)
}
#[test]
fn approval_required_when_read_only_false_and_destructive() {
let annotations = annotations(Some(false), Some(true), None);
@@ -99,19 +104,24 @@ fn prompt_mode_does_not_allow_persistent_remember() {
#[test]
fn approval_question_text_prepends_safety_reason() {
assert_eq!(
mcp_tool_approval_question_text(
"Allow this action?".to_string(),
Some("This tool may contact an external system."),
),
"Tool call needs your approval. Reason: This tool may contact an external system."
let rendered = mcp_tool_approval_question_text(
DEFAULT_LOCALE,
"Allow this action?".to_string(),
Some("This tool may contact an external system."),
);
assert_eq!(
rendered.contains("This tool may contact an external system."),
true
);
assert_ne!(rendered, "Allow this action?".to_string());
}
#[tokio::test]
async fn approval_elicitation_request_uses_message_override_and_preserves_tool_params_keys() {
let (session, turn_context) = make_session_and_context().await;
let question = build_mcp_tool_approval_question(
DEFAULT_LOCALE,
"q".to_string(),
CODEX_APPS_MCP_SERVER_NAME,
"create_event",
@@ -205,6 +215,7 @@ async fn approval_elicitation_request_uses_message_override_and_preserves_tool_p
#[test]
fn custom_mcp_tool_question_mentions_server_name() {
let question = build_mcp_tool_approval_question(
DEFAULT_LOCALE,
"q".to_string(),
"custom_server",
"run_action",
@@ -213,7 +224,7 @@ fn custom_mcp_tool_question_mentions_server_name() {
None,
);
assert_eq!(question.header, "Approve app tool call?");
assert_eq!(question.header, approval_copy().header);
assert_eq!(
question.question,
"Allow the custom_server MCP server to run tool \"run_action\"?"
@@ -224,13 +235,14 @@ fn custom_mcp_tool_question_mentions_server_name() {
.expect("options")
.into_iter()
.map(|option| option.label)
.any(|label| label == MCP_TOOL_APPROVAL_ACCEPT_AND_REMEMBER)
.any(|label| label == approval_copy().accept_and_remember.label)
);
}
#[test]
fn codex_apps_tool_question_uses_fallback_app_label() {
let question = build_mcp_tool_approval_question(
DEFAULT_LOCALE,
"q".to_string(),
CODEX_APPS_MCP_SERVER_NAME,
"run_action",
@@ -248,6 +260,7 @@ fn codex_apps_tool_question_uses_fallback_app_label() {
#[test]
fn trusted_codex_apps_tool_question_offers_always_allow() {
let question = build_mcp_tool_approval_question(
DEFAULT_LOCALE,
"q".to_string(),
CODEX_APPS_MCP_SERVER_NAME,
"run_action",
@@ -256,14 +269,15 @@ fn trusted_codex_apps_tool_question_offers_always_allow() {
None,
);
let options = question.options.expect("options");
let approval_copy = approval_copy();
assert!(options.iter().any(|option| {
option.label == MCP_TOOL_APPROVAL_ACCEPT_FOR_SESSION
&& option.description == "Run the tool and remember this choice for this session."
option.label == approval_copy.accept_for_session.label
&& option.description == approval_copy.accept_for_session.description
}));
assert!(options.iter().any(|option| {
option.label == MCP_TOOL_APPROVAL_ACCEPT_AND_REMEMBER
&& option.description == "Run the tool and remember this choice for future tool calls."
option.label == approval_copy.accept_and_remember.label
&& option.description == approval_copy.accept_and_remember.description
}));
assert_eq!(
options
@@ -271,10 +285,10 @@ fn trusted_codex_apps_tool_question_offers_always_allow() {
.map(|option| option.label)
.collect::<Vec<_>>(),
vec![
MCP_TOOL_APPROVAL_ACCEPT.to_string(),
MCP_TOOL_APPROVAL_ACCEPT_FOR_SESSION.to_string(),
MCP_TOOL_APPROVAL_ACCEPT_AND_REMEMBER.to_string(),
MCP_TOOL_APPROVAL_CANCEL.to_string(),
approval_copy.accept.label,
approval_copy.accept_for_session.label,
approval_copy.accept_and_remember.label,
approval_copy.cancel.label,
]
);
}
@@ -288,6 +302,7 @@ fn codex_apps_tool_question_without_elicitation_omits_always_allow() {
};
let persistent_key = session_key.clone();
let question = build_mcp_tool_approval_question(
DEFAULT_LOCALE,
"q".to_string(),
CODEX_APPS_MCP_SERVER_NAME,
"run_action",
@@ -304,9 +319,9 @@ fn codex_apps_tool_question_without_elicitation_omits_always_allow() {
.map(|option| option.label)
.collect::<Vec<_>>(),
vec![
MCP_TOOL_APPROVAL_ACCEPT.to_string(),
MCP_TOOL_APPROVAL_ACCEPT_FOR_SESSION.to_string(),
MCP_TOOL_APPROVAL_CANCEL.to_string(),
approval_copy().accept.label,
approval_copy().accept_for_session.label,
approval_copy().cancel.label,
]
);
}
@@ -314,6 +329,7 @@ fn codex_apps_tool_question_without_elicitation_omits_always_allow() {
#[test]
fn custom_mcp_tool_question_offers_session_remember_without_always_allow() {
let question = build_mcp_tool_approval_question(
DEFAULT_LOCALE,
"q".to_string(),
"custom_server",
"run_action",
@@ -330,9 +346,9 @@ fn custom_mcp_tool_question_offers_session_remember_without_always_allow() {
.map(|option| option.label)
.collect::<Vec<_>>(),
vec![
MCP_TOOL_APPROVAL_ACCEPT.to_string(),
MCP_TOOL_APPROVAL_ACCEPT_FOR_SESSION.to_string(),
MCP_TOOL_APPROVAL_CANCEL.to_string(),
approval_copy().accept.label,
approval_copy().accept_for_session.label,
approval_copy().cancel.label,
]
);
}
@@ -474,9 +490,10 @@ fn codex_apps_tool_call_request_meta_includes_codex_apps_meta() {
#[test]
fn accepted_elicitation_content_converts_to_request_user_input_response() {
let approval_copy = approval_copy();
let response = request_user_input_response_from_elicitation_content(Some(serde_json::json!(
{
"approval": MCP_TOOL_APPROVAL_ACCEPT_AND_REMEMBER,
"approval": approval_copy.accept_and_remember.label,
}
)));
@@ -486,7 +503,7 @@ fn accepted_elicitation_content_converts_to_request_user_input_response() {
answers: std::collections::HashMap::from([(
"approval".to_string(),
RequestUserInputAnswer {
answers: vec![MCP_TOOL_APPROVAL_ACCEPT_AND_REMEMBER.to_string()],
answers: vec![approval_copy.accept_and_remember.label],
},
)]),
})
@@ -743,10 +760,11 @@ fn approval_elicitation_meta_merges_session_and_always_persist_with_connector_so
#[test]
fn declined_elicitation_response_stays_decline() {
let response = parse_mcp_tool_approval_elicitation_response(
DEFAULT_LOCALE,
Some(ElicitationResponse {
action: ElicitationAction::Decline,
content: Some(serde_json::json!({
"approval": MCP_TOOL_APPROVAL_ACCEPT,
"approval": approval_copy().accept.label,
})),
meta: None,
}),
@@ -759,6 +777,7 @@ fn declined_elicitation_response_stays_decline() {
#[test]
fn synthetic_decline_request_user_input_response_stays_decline() {
let response = parse_mcp_tool_approval_response(
DEFAULT_LOCALE,
Some(RequestUserInputResponse {
answers: HashMap::from([(
"approval".to_string(),
@@ -776,6 +795,7 @@ fn synthetic_decline_request_user_input_response_stays_decline() {
#[test]
fn accepted_elicitation_response_uses_always_persist_meta() {
let response = parse_mcp_tool_approval_elicitation_response(
DEFAULT_LOCALE,
Some(ElicitationResponse {
action: ElicitationAction::Accept,
content: None,
@@ -792,6 +812,7 @@ fn accepted_elicitation_response_uses_always_persist_meta() {
#[test]
fn accepted_elicitation_response_uses_session_persist_meta() {
let response = parse_mcp_tool_approval_elicitation_response(
DEFAULT_LOCALE,
Some(ElicitationResponse {
action: ElicitationAction::Accept,
content: None,
@@ -808,6 +829,7 @@ fn accepted_elicitation_response_uses_session_persist_meta() {
#[test]
fn accepted_elicitation_without_content_defaults_to_accept() {
let response = parse_mcp_tool_approval_elicitation_response(
DEFAULT_LOCALE,
Some(ElicitationResponse {
action: ElicitationAction::Accept,
content: None,
@@ -991,12 +1013,13 @@ async fn approve_mode_blocks_when_arc_returns_interrupt_for_model() {
)
.await;
assert_eq!(
decision,
Some(McpToolApprovalDecision::BlockedBySafetyMonitor(
"Tool call was cancelled because of safety risks: high-risk action".to_string(),
))
);
match decision {
Some(McpToolApprovalDecision::BlockedBySafetyMonitor(message)) => {
assert_eq!(message.contains("high-risk action"), true);
assert_eq!(message.is_empty(), false);
}
other => panic!("expected BlockedBySafetyMonitor, got {other:?}"),
}
}
#[tokio::test]

View File

@@ -0,0 +1,8 @@
load("//:defs.bzl", "codex_rust_crate")
codex_rust_crate(
name = "i18n",
crate_name = "codex_i18n",
lib_data_extra = glob(["src/locales/**"]),
test_data_extra = glob(["src/locales/**"]),
)

22
codex-rs/i18n/Cargo.toml Normal file
View File

@@ -0,0 +1,22 @@
[package]
edition.workspace = true
license.workspace = true
name = "codex-i18n"
version.workspace = true
[lib]
name = "codex_i18n"
path = "src/lib.rs"
[lints]
workspace = true
[dependencies]
codex-utils-cargo-bin = { workspace = true }
fluent-bundle = { workspace = true }
sys-locale = { workspace = true }
thiserror = { workspace = true }
unic-langid = { workspace = true }
[dev-dependencies]
pretty_assertions = { workspace = true }

407
codex-rs/i18n/src/lib.rs Normal file
View File

@@ -0,0 +1,407 @@
use std::collections::HashMap;
use std::ffi::OsStr;
use std::fs;
use std::io;
use std::path::Path;
use std::path::PathBuf;
use std::sync::LazyLock;
use fluent_bundle::FluentArgs;
use fluent_bundle::FluentResource;
use fluent_bundle::concurrent::FluentBundle;
use thiserror::Error;
use unic_langid::LanguageIdentifier;
const LOCALES_DIR: &str = "src/locales";
pub const DEFAULT_LOCALE: &str = "en";
const CANONICAL_LOCALE_CODES: &[&str] = &[
DEFAULT_LOCALE,
"am",
"ar",
"bg",
"bn",
"bs",
"ca",
"cs",
"da",
"de",
"el",
"es",
"es-419",
"et",
"fa",
"fi",
"fr",
"fr-CA",
"gu",
"hi",
"hr",
"hu",
"hy",
"id",
"is",
"it",
"ja",
"ka",
"kk",
"kn",
"ko",
"lt",
"lv",
"mk",
"ml",
"mn",
"mr",
"ms",
"my",
"nb",
"nl",
"pa",
"pl",
"pt",
"pt-PT",
"ro",
"ru",
"sk",
"sl",
"so",
"sq",
"sr",
"sv",
"sw",
"ta",
"te",
"th",
"tl",
"tr",
"uk",
"ur",
"vi",
"zh",
"zh-HK",
"zh-Hant",
];
type Bundle = FluentBundle<FluentResource>;
#[derive(Debug, Error, PartialEq, Eq)]
pub enum LocaleError {
#[error("invalid locale `{0}`")]
InvalidLocale(String),
}
struct LocaleResources {
supported_locales: Vec<String>,
bundles: HashMap<String, Bundle>,
}
static LOCALE_RESOURCES: LazyLock<Option<LocaleResources>> =
LazyLock::new(|| load_locale_resources().ok());
pub fn resolve_locale(config_locale: Option<&str>) -> Result<String, LocaleError> {
resolve_locale_with_system(config_locale, sys_locale::get_locale().as_deref())
}
pub fn resolve_locale_with_system(
config_locale: Option<&str>,
system_locale: Option<&str>,
) -> Result<String, LocaleError> {
if let Some(config_locale) = config_locale {
let requested = parse_locale(config_locale)
.ok_or_else(|| LocaleError::InvalidLocale(config_locale.trim().to_string()))?;
return Ok(negotiate_locale(Some(&requested)));
}
let requested = system_locale.and_then(parse_locale);
Ok(negotiate_locale(requested.as_ref()))
}
pub fn format_message(locale: &str, message_id: &str, args: &[(&str, &str)]) -> String {
let locale = parse_locale(locale).as_ref().map_or_else(
|| DEFAULT_LOCALE.to_string(),
|requested| negotiate_locale(Some(requested)),
);
let rendered = LOCALE_RESOURCES.as_ref().and_then(|locale_resources| {
locale_resources
.bundles
.get(&locale)
.and_then(|bundle| render_message(bundle, message_id, args))
.or_else(|| {
(locale != DEFAULT_LOCALE)
.then_some(())
.and_then(|()| locale_resources.bundles.get(DEFAULT_LOCALE))
.and_then(|bundle| render_message(bundle, message_id, args))
})
});
rendered.unwrap_or_else(|| message_id.to_string())
}
fn parse_locale(value: &str) -> Option<LanguageIdentifier> {
normalize_locale_candidate(value)?.parse().ok()
}
fn normalize_locale_candidate(value: &str) -> Option<String> {
let trimmed = value.trim();
if trimmed.is_empty() {
return None;
}
let without_modifier = trimmed.split('@').next()?;
let without_encoding = without_modifier.split('.').next()?;
let normalized = without_encoding.replace('_', "-");
(!normalized.is_empty()).then_some(normalized)
}
fn negotiate_locale(requested: Option<&LanguageIdentifier>) -> String {
let Some(requested) = requested else {
return DEFAULT_LOCALE.to_string();
};
for candidate in canonical_locale_candidates(requested) {
if supported_locales()
.iter()
.any(|locale| locale == &candidate)
{
return candidate;
}
}
DEFAULT_LOCALE.to_string()
}
fn canonical_locale_candidates(requested: &LanguageIdentifier) -> Vec<String> {
let mut candidates = Vec::new();
let mut push_candidate = |candidate: String| {
if CANONICAL_LOCALE_CODES.contains(&candidate.as_str()) && !candidates.contains(&candidate)
{
candidates.push(candidate);
}
};
push_candidate(requested.to_string());
let language = requested.language.as_str();
if let Some(region) = requested.region.as_ref() {
push_candidate(format!("{language}-{region}"));
}
if let Some(script) = requested.script.as_ref() {
push_candidate(format!("{language}-{script}"));
}
push_candidate(language.to_string());
candidates
}
fn supported_locales() -> &'static [String] {
LOCALE_RESOURCES
.as_ref()
.map(|locale_resources| locale_resources.supported_locales.as_slice())
.unwrap_or(&[])
}
fn load_locale_resources() -> io::Result<LocaleResources> {
let locales_dir = resolve_locales_dir()?;
let mut supported_locales = Vec::new();
let mut bundles = HashMap::new();
for entry in sorted_dir_entries(&locales_dir)? {
if !entry.file_type()?.is_dir() {
continue;
}
let locale_name = entry.file_name().to_string_lossy().to_string();
let Some(language_identifier) = parse_locale(&locale_name) else {
continue;
};
if !CANONICAL_LOCALE_CODES.contains(&locale_name.as_str()) {
continue;
}
let bundle = load_bundle(&entry.path(), &locale_name, language_identifier)?;
supported_locales.push(locale_name.clone());
bundles.insert(locale_name, bundle);
}
supported_locales.sort();
Ok(LocaleResources {
supported_locales,
bundles,
})
}
fn resolve_locales_dir() -> io::Result<PathBuf> {
let runfile_path = codex_utils_cargo_bin::find_resource!(LOCALES_DIR);
let source_path = Path::new(env!("CARGO_MANIFEST_DIR")).join(LOCALES_DIR);
match runfile_path {
Ok(path) if path.exists() => Ok(path),
Ok(_) if source_path.exists() => Ok(source_path),
Ok(path) => Ok(path),
Err(_) if source_path.exists() => Ok(source_path),
Err(err) => Err(err),
}
}
fn load_bundle(
locale_dir: &Path,
locale_name: &str,
language_identifier: LanguageIdentifier,
) -> io::Result<Bundle> {
let mut bundle = FluentBundle::new_concurrent(vec![language_identifier]);
bundle.set_use_isolating(false);
for entry in sorted_dir_entries(locale_dir)? {
if !entry.file_type()?.is_file() || entry.path().extension() != Some(OsStr::new("ftl")) {
continue;
}
let resource_path = entry.path();
let contents = fs::read_to_string(&resource_path)?;
let resource = FluentResource::try_new(contents).map_err(|(_, errors)| {
io::Error::other(format!(
"invalid Fluent resource `{}`: {errors:?}",
resource_path.display()
))
})?;
if bundle.add_resource(resource).is_err() {
return Err(io::Error::other(format!(
"locale `{locale_name}` defines duplicate messages in `{}`",
resource_path.display()
)));
}
}
Ok(bundle)
}
fn sorted_dir_entries(dir: &Path) -> io::Result<Vec<fs::DirEntry>> {
let mut entries = fs::read_dir(dir)?.collect::<Result<Vec<_>, _>>()?;
entries.sort_by_key(fs::DirEntry::file_name);
Ok(entries)
}
fn render_message(bundle: &Bundle, message_id: &str, args: &[(&str, &str)]) -> Option<String> {
let message = bundle.get_message(message_id)?;
let pattern = message.value()?;
let mut errors = Vec::new();
let fluent_args = (!args.is_empty()).then(|| {
let mut fluent_args = FluentArgs::new();
for (name, value) in args {
fluent_args.set(*name, *value);
}
fluent_args
});
Some(
bundle
.format_pattern(pattern, fluent_args.as_ref(), &mut errors)
.into_owned(),
)
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use super::*;
#[test]
fn explicit_locale_overrides_system_locale() {
assert_eq!(
resolve_locale_with_system(Some("zh-CN"), Some("en-US")).expect("resolve locale"),
"zh"
);
}
#[test]
fn unsupported_explicit_locale_falls_back_to_default() {
assert_eq!(
resolve_locale_with_system(Some("zu-ZA"), Some("zh-CN")).expect("resolve locale"),
DEFAULT_LOCALE
);
}
#[test]
fn supported_system_locale_is_used_when_config_is_missing() {
assert_eq!(
resolve_locale_with_system(None, Some("zh")).expect("resolve locale"),
"zh"
);
}
#[test]
fn specific_locale_falls_back_to_generic_locale() {
assert_eq!(
resolve_locale_with_system(None, Some("zh-HK")).expect("resolve locale"),
"zh"
);
}
#[test]
fn unsupported_system_locale_falls_back_to_default() {
assert_eq!(
resolve_locale_with_system(None, Some("zu-ZA")).expect("resolve locale"),
DEFAULT_LOCALE
);
}
#[test]
fn invalid_explicit_locale_is_rejected() {
assert_eq!(
resolve_locale_with_system(Some("not a locale"), None),
Err(LocaleError::InvalidLocale("not a locale".to_string()))
);
}
#[test]
fn formats_message_with_interpolation() {
let rendered = format_message(
"en",
"approval-question-google-docs-create-document",
&[("connector_name", "Google Docs")],
);
assert_eq!(rendered.contains("Google Docs"), true);
assert_eq!(rendered.is_empty(), false);
}
#[test]
fn different_locales_can_render_same_message() {
let english = format_message(
"en",
"approval-question-google-docs-create-document",
&[("connector_name", "Google Docs")],
);
let chinese = format_message(
"zh-HK",
"approval-question-google-docs-create-document",
&[("connector_name", "Google Docs")],
);
assert_eq!(english.contains("Google Docs"), true);
assert_eq!(chinese.contains("Google Docs"), true);
assert_ne!(english, chinese);
}
#[test]
fn format_message_falls_back_to_english_message() {
let english = format_message("en", "approval-option-allow", &[]);
assert_eq!(
format_message("zu-ZA", "approval-option-allow", &[]),
english
);
}
#[test]
fn format_message_returns_message_id_when_message_is_missing() {
assert_eq!(
format_message("zu-ZA", "approval-option-missing", &[]),
"approval-option-missing".to_string()
);
}
}

View File

@@ -0,0 +1,114 @@
approval-header = هل تريد الموافقة على استدعاء أداة التطبيق؟
approval-option-allow = السماح
approval-option-allow-description = شغّل الأداة وتابع.
approval-option-allow-session = السماح لهذه الجلسة
approval-option-allow-session-description = شغّل الأداة وتذكّر هذا الاختيار لهذه الجلسة.
approval-option-allow-remember = السماح وعدم سؤالي مرة أخرى
approval-option-allow-remember-description = شغّل الأداة وتذكّر هذا الاختيار لاستدعاءات الأدوات المستقبلية.
approval-option-cancel = إلغاء
approval-option-cancel-description = ألغِ استدعاء الأداة هذا.
approval-fallback-question-connector = هل تسمح لـ {$connector_name} بتشغيل الأداة "{$tool_name}"؟
approval-fallback-question-this-app = هل تسمح لهذا التطبيق بتشغيل الأداة "{$tool_name}"؟
approval-fallback-question-server = هل تسمح لخادم MCP {$server} بتشغيل الأداة "{$tool_name}"؟
approval-monitor-question = يحتاج استدعاء الأداة هذا إلى موافقتك. السبب: {$reason}
approval-safety-cancelled = تم إلغاء استدعاء الأداة هذا بسبب مخاطر تتعلق بالسلامة.
approval-safety-cancelled-with-reason = تم إلغاء استدعاء الأداة هذا بسبب مخاطر تتعلق بالسلامة: {$reason}
approval-param-action = الإجراء
approval-param-attendees = الحضور
approval-param-base-branch = الفرع الأساسي
approval-param-body = المتن
approval-param-branch = الفرع
approval-param-calendar = التقويم
approval-param-changes = التغييرات
approval-param-comment = التعليق
approval-param-comment-id = معرف التعليق
approval-param-commit = الالتزام
approval-param-content = المحتوى
approval-param-conversation = المحادثة
approval-param-document = المستند
approval-param-event = الحدث
approval-param-head-branch = الفرع المصدر
approval-param-issue = المشكلة
approval-param-label = التصنيف
approval-param-label-name = اسم التصنيف
approval-param-message = الرسالة
approval-param-name = الاسم
approval-param-new-file-name = اسم الملف الجديد
approval-param-permission = الإذن
approval-param-presentation = العرض التقديمي
approval-param-project = المشروع
approval-param-pull-request = طلب السحب
approval-param-query = الاستعلام
approval-param-reaction = التفاعل
approval-param-repository = المستودع
approval-param-response-status = حالة الرد
approval-param-review = المراجعة
approval-param-send-at = وقت الإرسال
approval-param-source-sheet-name = اسم الورقة المصدر
approval-param-spreadsheet = جدول البيانات
approval-param-start = البدء
approval-param-state = الحالة
approval-param-subject = الموضوع
approval-param-team = الفريق
approval-param-title = العنوان
approval-param-to = إلى
approval-param-timezone = المنطقة الزمنية
approval-param-url = الرابط
approval-param-user = المستخدم
approval-question-github-add-comment-to-issue = هل تسمح لـ {$connector_name} بإضافة تعليق إلى طلب سحب؟
approval-question-github-add-reaction-to-issue-comment = هل تسمح لـ {$connector_name} بإضافة تفاعل إلى تعليق على مشكلة؟
approval-question-github-add-reaction-to-pr = هل تسمح لـ {$connector_name} بإضافة تفاعل إلى طلب سحب؟
approval-question-github-add-reaction-to-pr-review-comment = هل تسمح لـ {$connector_name} بإضافة تفاعل إلى تعليق مراجعة على طلب سحب؟
approval-question-github-add-review-to-pr = هل تسمح لـ {$connector_name} بإرسال مراجعة لطلب سحب؟
approval-question-github-create-blob = هل تسمح لـ {$connector_name} بإنشاء Git blob؟
approval-question-github-create-branch = هل تسمح لـ {$connector_name} بإنشاء فرع؟
approval-question-github-create-commit = هل تسمح لـ {$connector_name} بإنشاء التزام؟
approval-question-github-create-pull-request = هل تسمح لـ {$connector_name} بإنشاء طلب سحب؟
approval-question-github-create-tree = هل تسمح لـ {$connector_name} بإنشاء Git tree؟
approval-question-github-enable-auto-merge = هل تسمح لـ {$connector_name} بتمكين الدمج التلقائي لطلب السحب؟
approval-question-github-label-pr = هل تسمح لـ {$connector_name} بإضافة تصنيف إلى طلب سحب؟
approval-question-github-remove-reaction-from-issue-comment = هل تسمح لـ {$connector_name} بإزالة تفاعل من تعليق على مشكلة؟
approval-question-github-remove-reaction-from-pr = هل تسمح لـ {$connector_name} بإزالة تفاعل من طلب سحب؟
approval-question-github-remove-reaction-from-pr-review-comment = هل تسمح لـ {$connector_name} بإزالة تفاعل من تعليق مراجعة على طلب سحب؟
approval-question-github-reply-to-review-comment = هل تسمح لـ {$connector_name} بالرد على تعليق مراجعة لطلب سحب؟
approval-question-github-update-issue-comment = هل تسمح لـ {$connector_name} بتحديث تعليق على مشكلة؟
approval-question-github-update-ref = هل تسمح لـ {$connector_name} بتحديث مرجع فرع؟
approval-question-github-update-review-comment = هل تسمح لـ {$connector_name} بتحديث تعليق مراجعة على طلب سحب؟
approval-question-gmail-apply-labels-to-emails = هل تسمح لـ {$connector_name} بتطبيق تغييرات التصنيفات على الرسائل؟
approval-question-gmail-batch-modify-email = هل تسمح لـ {$connector_name} بتحديث تصنيفات الرسائل؟
approval-question-gmail-bulk-label-matching-emails = هل تسمح لـ {$connector_name} بتصنيف الرسائل المطابقة؟
approval-question-gmail-create-draft = هل تسمح لـ {$connector_name} بإنشاء مسودة بريد إلكتروني؟
approval-question-gmail-create-label = هل تسمح لـ {$connector_name} بإنشاء تصنيف؟
approval-question-gmail-send-email = هل تسمح لـ {$connector_name} بإرسال بريد إلكتروني؟
approval-question-google-calendar-create-event = هل تسمح لـ {$connector_name} بإنشاء حدث؟
approval-question-google-calendar-delete-event = هل تسمح لـ {$connector_name} بحذف حدث؟
approval-question-google-calendar-respond-event = هل تسمح لـ {$connector_name} بالرد على حدث؟
approval-question-google-calendar-update-event = هل تسمح لـ {$connector_name} بتحديث حدث؟
approval-question-google-docs-batch-update = هل تسمح لـ {$connector_name} بتطبيق تحديثات على المستند؟
approval-question-google-docs-create-document = هل تسمح لـ {$connector_name} بإنشاء مستند؟
approval-question-google-drive-copy-document = هل تسمح لـ {$connector_name} بنسخ ملف؟
approval-question-google-drive-share-document = هل تسمح لـ {$connector_name} بتغيير مشاركة الملف؟
approval-question-google-sheets-batch-update = هل تسمح لـ {$connector_name} بتطبيق تحديثات على جدول البيانات؟
approval-question-google-sheets-create-spreadsheet = هل تسمح لـ {$connector_name} بإنشاء جدول بيانات؟
approval-question-google-sheets-duplicate-sheet-in-new-file = هل تسمح لـ {$connector_name} بنسخ ورقة إلى جدول بيانات جديد؟
approval-question-google-slides-batch-update = هل تسمح لـ {$connector_name} بتطبيق تحديثات على العرض التقديمي؟
approval-question-google-slides-create-presentation = هل تسمح لـ {$connector_name} بإنشاء عرض تقديمي؟
approval-question-linear-add-comment-to-issue = هل تسمح لـ {$connector_name} بإضافة تعليق إلى مشكلة؟
approval-question-linear-add-label-to-issue = هل تسمح لـ {$connector_name} بإضافة تصنيف إلى مشكلة؟
approval-question-linear-add-url-attachment-to-issue = هل تسمح لـ {$connector_name} بإرفاق رابط بمشكلة؟
approval-question-linear-assign-issue = هل تسمح لـ {$connector_name} بتعيين مشكلة؟
approval-question-linear-create-issue = هل تسمح لـ {$connector_name} بإنشاء مشكلة؟
approval-question-linear-create-label = هل تسمح لـ {$connector_name} بإنشاء تصنيف؟
approval-question-linear-create-project = هل تسمح لـ {$connector_name} بإنشاء مشروع؟
approval-question-linear-remove-label-from-issue = هل تسمح لـ {$connector_name} بإزالة تصنيف من مشكلة؟
approval-question-linear-resolve-comment = هل تسمح لـ {$connector_name} بحل تعليق؟
approval-question-linear-set-issue-state = هل تسمح لـ {$connector_name} بتغيير حالة مشكلة؟
approval-question-linear-unassign-issue = هل تسمح لـ {$connector_name} بإلغاء تعيين مشكلة؟
approval-question-linear-update-issue = هل تسمح لـ {$connector_name} بتحديث مشكلة؟
approval-question-linear-update-project = هل تسمح لـ {$connector_name} بتحديث مشروع؟
approval-question-slack-slack-create-canvas = هل تسمح لـ {$connector_name} بإنشاء canvas؟
approval-question-slack-slack-schedule-message = هل تسمح لـ {$connector_name} بجدولة رسالة؟
approval-question-slack-slack-send-message = هل تسمح لـ {$connector_name} بإرسال رسالة؟
approval-question-slack-slack-send-message-draft = هل تسمح لـ {$connector_name} بإنشاء مسودة رسالة؟

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = يلزم تأكيد إضافي قبل متابعة استدعاء الأداة هذا.

View File

@@ -0,0 +1,114 @@
approval-header = App-Toolaufruf genehmigen?
approval-option-allow = Zulassen
approval-option-allow-description = Das Tool ausführen und fortfahren.
approval-option-allow-session = Für diese Sitzung zulassen
approval-option-allow-session-description = Das Tool ausführen und diese Auswahl für diese Sitzung merken.
approval-option-allow-remember = Zulassen und nicht erneut fragen
approval-option-allow-remember-description = Das Tool ausführen und diese Auswahl für zukünftige Toolaufrufe merken.
approval-option-cancel = Abbrechen
approval-option-cancel-description = Diesen Toolaufruf abbrechen.
approval-fallback-question-connector = {$connector_name} erlauben, das Tool "{$tool_name}" auszuführen?
approval-fallback-question-this-app = Dieser App erlauben, das Tool "{$tool_name}" auszuführen?
approval-fallback-question-server = Dem MCP-Server {$server} erlauben, das Tool "{$tool_name}" auszuführen?
approval-monitor-question = Dieser Toolaufruf benötigt deine Genehmigung. Grund: {$reason}
approval-safety-cancelled = Dieser Toolaufruf wurde wegen Sicherheitsrisiken abgebrochen.
approval-safety-cancelled-with-reason = Dieser Toolaufruf wurde wegen Sicherheitsrisiken abgebrochen: {$reason}
approval-param-action = Aktion
approval-param-attendees = Teilnehmer
approval-param-base-branch = Basis-Branch
approval-param-body = Text
approval-param-branch = Branch
approval-param-calendar = Kalender
approval-param-changes = Änderungen
approval-param-comment = Kommentar
approval-param-comment-id = Kommentar-ID
approval-param-commit = Commit
approval-param-content = Inhalt
approval-param-conversation = Unterhaltung
approval-param-document = Dokument
approval-param-event = Termin
approval-param-head-branch = Quell-Branch
approval-param-issue = Issue
approval-param-label = Label
approval-param-label-name = Labelname
approval-param-message = Nachricht
approval-param-name = Name
approval-param-new-file-name = Neuer Dateiname
approval-param-permission = Berechtigung
approval-param-presentation = Präsentation
approval-param-project = Projekt
approval-param-pull-request = Pull Request
approval-param-query = Abfrage
approval-param-reaction = Reaktion
approval-param-repository = Repository
approval-param-response-status = Antwortstatus
approval-param-review = Review
approval-param-send-at = Senden um
approval-param-source-sheet-name = Name des Quellblatts
approval-param-spreadsheet = Tabelle
approval-param-start = Start
approval-param-state = Status
approval-param-subject = Betreff
approval-param-team = Team
approval-param-title = Titel
approval-param-to = An
approval-param-timezone = Zeitzone
approval-param-url = URL
approval-param-user = Benutzer
approval-question-github-add-comment-to-issue = {$connector_name} erlauben, einen Kommentar zu einem Pull Request hinzuzufügen?
approval-question-github-add-reaction-to-issue-comment = {$connector_name} erlauben, eine Reaktion zu einem Issue-Kommentar hinzuzufügen?
approval-question-github-add-reaction-to-pr = {$connector_name} erlauben, eine Reaktion zu einem Pull Request hinzuzufügen?
approval-question-github-add-reaction-to-pr-review-comment = {$connector_name} erlauben, eine Reaktion zu einem Pull-Request-Review-Kommentar hinzuzufügen?
approval-question-github-add-review-to-pr = {$connector_name} erlauben, ein Pull-Request-Review einzureichen?
approval-question-github-create-blob = {$connector_name} erlauben, einen Git-Blob zu erstellen?
approval-question-github-create-branch = {$connector_name} erlauben, einen Branch zu erstellen?
approval-question-github-create-commit = {$connector_name} erlauben, einen Commit zu erstellen?
approval-question-github-create-pull-request = {$connector_name} erlauben, einen Pull Request zu erstellen?
approval-question-github-create-tree = {$connector_name} erlauben, einen Git-Tree zu erstellen?
approval-question-github-enable-auto-merge = {$connector_name} erlauben, Auto-Merge für einen Pull Request zu aktivieren?
approval-question-github-label-pr = {$connector_name} erlauben, einem Pull Request ein Label hinzuzufügen?
approval-question-github-remove-reaction-from-issue-comment = {$connector_name} erlauben, eine Reaktion von einem Issue-Kommentar zu entfernen?
approval-question-github-remove-reaction-from-pr = {$connector_name} erlauben, eine Reaktion von einem Pull Request zu entfernen?
approval-question-github-remove-reaction-from-pr-review-comment = {$connector_name} erlauben, eine Reaktion von einem Pull-Request-Review-Kommentar zu entfernen?
approval-question-github-reply-to-review-comment = {$connector_name} erlauben, auf einen Pull-Request-Review-Kommentar zu antworten?
approval-question-github-update-issue-comment = {$connector_name} erlauben, einen Issue-Kommentar zu aktualisieren?
approval-question-github-update-ref = {$connector_name} erlauben, eine Branch-Referenz zu aktualisieren?
approval-question-github-update-review-comment = {$connector_name} erlauben, einen Pull-Request-Review-Kommentar zu aktualisieren?
approval-question-gmail-apply-labels-to-emails = {$connector_name} erlauben, Labeländerungen auf Nachrichten anzuwenden?
approval-question-gmail-batch-modify-email = {$connector_name} erlauben, Nachrichtenlabels zu aktualisieren?
approval-question-gmail-bulk-label-matching-emails = {$connector_name} erlauben, passende Nachrichten zu labeln?
approval-question-gmail-create-draft = {$connector_name} erlauben, einen E-Mail-Entwurf zu erstellen?
approval-question-gmail-create-label = {$connector_name} erlauben, ein Label zu erstellen?
approval-question-gmail-send-email = {$connector_name} erlauben, eine E-Mail zu senden?
approval-question-google-calendar-create-event = {$connector_name} erlauben, einen Termin zu erstellen?
approval-question-google-calendar-delete-event = {$connector_name} erlauben, einen Termin zu löschen?
approval-question-google-calendar-respond-event = {$connector_name} erlauben, auf einen Termin zu antworten?
approval-question-google-calendar-update-event = {$connector_name} erlauben, einen Termin zu aktualisieren?
approval-question-google-docs-batch-update = {$connector_name} erlauben, Dokumentaktualisierungen anzuwenden?
approval-question-google-docs-create-document = {$connector_name} erlauben, ein Dokument zu erstellen?
approval-question-google-drive-copy-document = {$connector_name} erlauben, eine Datei zu kopieren?
approval-question-google-drive-share-document = {$connector_name} erlauben, die Dateifreigabe zu ändern?
approval-question-google-sheets-batch-update = {$connector_name} erlauben, Tabellenaktualisierungen anzuwenden?
approval-question-google-sheets-create-spreadsheet = {$connector_name} erlauben, eine Tabelle zu erstellen?
approval-question-google-sheets-duplicate-sheet-in-new-file = {$connector_name} erlauben, ein Blatt in eine neue Tabelle zu kopieren?
approval-question-google-slides-batch-update = {$connector_name} erlauben, Präsentationsaktualisierungen anzuwenden?
approval-question-google-slides-create-presentation = {$connector_name} erlauben, eine Präsentation zu erstellen?
approval-question-linear-add-comment-to-issue = {$connector_name} erlauben, einen Kommentar zu einem Issue hinzuzufügen?
approval-question-linear-add-label-to-issue = {$connector_name} erlauben, einem Issue ein Label hinzuzufügen?
approval-question-linear-add-url-attachment-to-issue = {$connector_name} erlauben, einen Link an ein Issue anzuhängen?
approval-question-linear-assign-issue = {$connector_name} erlauben, ein Issue zuzuweisen?
approval-question-linear-create-issue = {$connector_name} erlauben, ein Issue zu erstellen?
approval-question-linear-create-label = {$connector_name} erlauben, ein Label zu erstellen?
approval-question-linear-create-project = {$connector_name} erlauben, ein Projekt zu erstellen?
approval-question-linear-remove-label-from-issue = {$connector_name} erlauben, ein Label von einem Issue zu entfernen?
approval-question-linear-resolve-comment = {$connector_name} erlauben, einen Kommentar zu lösen?
approval-question-linear-set-issue-state = {$connector_name} erlauben, den Issue-Status zu ändern?
approval-question-linear-unassign-issue = {$connector_name} erlauben, die Zuweisung eines Issue aufzuheben?
approval-question-linear-update-issue = {$connector_name} erlauben, ein Issue zu aktualisieren?
approval-question-linear-update-project = {$connector_name} erlauben, ein Projekt zu aktualisieren?
approval-question-slack-slack-create-canvas = {$connector_name} erlauben, ein Canvas zu erstellen?
approval-question-slack-slack-schedule-message = {$connector_name} erlauben, eine Nachricht zu planen?
approval-question-slack-slack-send-message = {$connector_name} erlauben, eine Nachricht zu senden?
approval-question-slack-slack-send-message-draft = {$connector_name} erlauben, einen Nachrichtenentwurf zu erstellen?

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = Bevor dieser Toolaufruf fortgesetzt werden kann, ist eine zusätzliche Bestätigung erforderlich.

View File

@@ -0,0 +1,114 @@
approval-header = Approve app tool call?
approval-option-allow = Allow
approval-option-allow-description = Run the tool and continue.
approval-option-allow-session = Allow for this session
approval-option-allow-session-description = Run the tool and remember this choice for this session.
approval-option-allow-remember = Allow and don't ask me again
approval-option-allow-remember-description = Run the tool and remember this choice for future tool calls.
approval-option-cancel = Cancel
approval-option-cancel-description = Cancel this tool call.
approval-fallback-question-connector = Allow {$connector_name} to run tool "{$tool_name}"?
approval-fallback-question-this-app = Allow this app to run tool "{$tool_name}"?
approval-fallback-question-server = Allow the {$server} MCP server to run tool "{$tool_name}"?
approval-monitor-question = Tool call needs your approval. Reason: {$reason}
approval-safety-cancelled = Tool call was cancelled because of safety risks.
approval-safety-cancelled-with-reason = Tool call was cancelled because of safety risks: {$reason}
approval-param-action = Action
approval-param-attendees = Attendees
approval-param-base-branch = Base branch
approval-param-body = Body
approval-param-branch = Branch
approval-param-calendar = Calendar
approval-param-changes = Changes
approval-param-comment = Comment
approval-param-comment-id = Comment ID
approval-param-commit = Commit
approval-param-content = Content
approval-param-conversation = Conversation
approval-param-document = Document
approval-param-event = Event
approval-param-head-branch = Head branch
approval-param-issue = Issue
approval-param-label = Label
approval-param-label-name = Label Name
approval-param-message = Message
approval-param-name = Name
approval-param-new-file-name = New File Name
approval-param-permission = Permission
approval-param-presentation = Presentation
approval-param-project = Project
approval-param-pull-request = Pull request
approval-param-query = Query
approval-param-reaction = Reaction
approval-param-repository = Repository
approval-param-response-status = Response Status
approval-param-review = Review
approval-param-send-at = Send at
approval-param-source-sheet-name = Source Sheet Name
approval-param-spreadsheet = Spreadsheet
approval-param-start = Start
approval-param-state = State
approval-param-subject = Subject
approval-param-team = Team
approval-param-title = Title
approval-param-to = To
approval-param-timezone = timezone
approval-param-url = URL
approval-param-user = User
approval-question-github-add-comment-to-issue = Allow {$connector_name} to add a comment to a pull request?
approval-question-github-add-reaction-to-issue-comment = Allow {$connector_name} to add a reaction to an issue comment?
approval-question-github-add-reaction-to-pr = Allow {$connector_name} to add a reaction to a pull request?
approval-question-github-add-reaction-to-pr-review-comment = Allow {$connector_name} to add a reaction to a pull request review comment?
approval-question-github-add-review-to-pr = Allow {$connector_name} to submit a pull request review?
approval-question-github-create-blob = Allow {$connector_name} to create a Git blob?
approval-question-github-create-branch = Allow {$connector_name} to create a branch?
approval-question-github-create-commit = Allow {$connector_name} to create a commit?
approval-question-github-create-pull-request = Allow {$connector_name} to create a pull request?
approval-question-github-create-tree = Allow {$connector_name} to create a Git tree?
approval-question-github-enable-auto-merge = Allow {$connector_name} to enable pull request auto-merge?
approval-question-github-label-pr = Allow {$connector_name} to add a label to a pull request?
approval-question-github-remove-reaction-from-issue-comment = Allow {$connector_name} to remove a reaction from an issue comment?
approval-question-github-remove-reaction-from-pr = Allow {$connector_name} to remove a reaction from a pull request?
approval-question-github-remove-reaction-from-pr-review-comment = Allow {$connector_name} to remove a reaction from a pull request review comment?
approval-question-github-reply-to-review-comment = Allow {$connector_name} to reply to a pull request review comment?
approval-question-github-update-issue-comment = Allow {$connector_name} to update an issue comment?
approval-question-github-update-ref = Allow {$connector_name} to update a branch reference?
approval-question-github-update-review-comment = Allow {$connector_name} to update a pull request review comment?
approval-question-gmail-apply-labels-to-emails = Allow {$connector_name} to apply label changes to messages?
approval-question-gmail-batch-modify-email = Allow {$connector_name} to update message labels?
approval-question-gmail-bulk-label-matching-emails = Allow {$connector_name} to label matching messages?
approval-question-gmail-create-draft = Allow {$connector_name} to create an email draft?
approval-question-gmail-create-label = Allow {$connector_name} to create a label?
approval-question-gmail-send-email = Allow {$connector_name} to send an email?
approval-question-google-calendar-create-event = Allow {$connector_name} to create an event?
approval-question-google-calendar-delete-event = Allow {$connector_name} to delete an event?
approval-question-google-calendar-respond-event = Allow {$connector_name} to respond to an event?
approval-question-google-calendar-update-event = Allow {$connector_name} to update an event?
approval-question-google-docs-batch-update = Allow {$connector_name} to apply document updates?
approval-question-google-docs-create-document = Allow {$connector_name} to create a document?
approval-question-google-drive-copy-document = Allow {$connector_name} to copy a file?
approval-question-google-drive-share-document = Allow {$connector_name} to change file sharing?
approval-question-google-sheets-batch-update = Allow {$connector_name} to apply spreadsheet updates?
approval-question-google-sheets-create-spreadsheet = Allow {$connector_name} to create a spreadsheet?
approval-question-google-sheets-duplicate-sheet-in-new-file = Allow {$connector_name} to copy a sheet into a new spreadsheet?
approval-question-google-slides-batch-update = Allow {$connector_name} to apply presentation updates?
approval-question-google-slides-create-presentation = Allow {$connector_name} to create a presentation?
approval-question-linear-add-comment-to-issue = Allow {$connector_name} to add a comment to an issue?
approval-question-linear-add-label-to-issue = Allow {$connector_name} to add a label to an issue?
approval-question-linear-add-url-attachment-to-issue = Allow {$connector_name} to attach a link to an issue?
approval-question-linear-assign-issue = Allow {$connector_name} to assign an issue?
approval-question-linear-create-issue = Allow {$connector_name} to create an issue?
approval-question-linear-create-label = Allow {$connector_name} to create a label?
approval-question-linear-create-project = Allow {$connector_name} to create a project?
approval-question-linear-remove-label-from-issue = Allow {$connector_name} to remove a label from an issue?
approval-question-linear-resolve-comment = Allow {$connector_name} to resolve a comment?
approval-question-linear-set-issue-state = Allow {$connector_name} to change issue state?
approval-question-linear-unassign-issue = Allow {$connector_name} to unassign an issue?
approval-question-linear-update-issue = Allow {$connector_name} to update an issue?
approval-question-linear-update-project = Allow {$connector_name} to update a project?
approval-question-slack-slack-create-canvas = Allow {$connector_name} to create a canvas?
approval-question-slack-slack-schedule-message = Allow {$connector_name} to schedule a message?
approval-question-slack-slack-send-message = Allow {$connector_name} to send a message?
approval-question-slack-slack-send-message-draft = Allow {$connector_name} to create a message draft?

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = Additional confirmation is required before this tool call can continue.

View File

@@ -0,0 +1,114 @@
approval-header = ¿Aprobar la llamada a la herramienta de la app?
approval-option-allow = Permitir
approval-option-allow-description = Ejecutar la herramienta y continuar.
approval-option-allow-session = Permitir durante esta sesión
approval-option-allow-session-description = Ejecutar la herramienta y recordar esta elección durante esta sesión.
approval-option-allow-remember = Permitir y no volver a preguntar
approval-option-allow-remember-description = Ejecutar la herramienta y recordar esta elección para futuras llamadas de herramientas.
approval-option-cancel = Cancelar
approval-option-cancel-description = Cancelar esta llamada de herramienta.
approval-fallback-question-connector = ¿Permitir que {$connector_name} ejecute la herramienta "{$tool_name}"?
approval-fallback-question-this-app = ¿Permitir que esta app ejecute la herramienta "{$tool_name}"?
approval-fallback-question-server = ¿Permitir que el servidor MCP {$server} ejecute la herramienta "{$tool_name}"?
approval-monitor-question = Esta llamada de herramienta necesita tu aprobación. Motivo: {$reason}
approval-safety-cancelled = Esta llamada de herramienta se canceló por riesgos de seguridad.
approval-safety-cancelled-with-reason = Esta llamada de herramienta se canceló por riesgos de seguridad: {$reason}
approval-param-action = Acción
approval-param-attendees = Asistentes
approval-param-base-branch = Rama base
approval-param-body = Cuerpo
approval-param-branch = Rama
approval-param-calendar = Calendario
approval-param-changes = Cambios
approval-param-comment = Comentario
approval-param-comment-id = ID del comentario
approval-param-commit = Commit
approval-param-content = Contenido
approval-param-conversation = Conversación
approval-param-document = Documento
approval-param-event = Evento
approval-param-head-branch = Rama de origen
approval-param-issue = Issue
approval-param-label = Etiqueta
approval-param-label-name = Nombre de la etiqueta
approval-param-message = Mensaje
approval-param-name = Nombre
approval-param-new-file-name = Nuevo nombre de archivo
approval-param-permission = Permiso
approval-param-presentation = Presentación
approval-param-project = Proyecto
approval-param-pull-request = Pull request
approval-param-query = Consulta
approval-param-reaction = Reacción
approval-param-repository = Repositorio
approval-param-response-status = Estado de respuesta
approval-param-review = Revisión
approval-param-send-at = Enviar a las
approval-param-source-sheet-name = Nombre de la hoja de origen
approval-param-spreadsheet = Hoja de cálculo
approval-param-start = Inicio
approval-param-state = Estado
approval-param-subject = Asunto
approval-param-team = Equipo
approval-param-title = Título
approval-param-to = Para
approval-param-timezone = Zona horaria
approval-param-url = URL
approval-param-user = Usuario
approval-question-github-add-comment-to-issue = ¿Permitir que {$connector_name} agregue un comentario a un pull request?
approval-question-github-add-reaction-to-issue-comment = ¿Permitir que {$connector_name} agregue una reacción a un comentario de issue?
approval-question-github-add-reaction-to-pr = ¿Permitir que {$connector_name} agregue una reacción a un pull request?
approval-question-github-add-reaction-to-pr-review-comment = ¿Permitir que {$connector_name} agregue una reacción a un comentario de revisión de pull request?
approval-question-github-add-review-to-pr = ¿Permitir que {$connector_name} envíe una revisión de pull request?
approval-question-github-create-blob = ¿Permitir que {$connector_name} cree un blob de Git?
approval-question-github-create-branch = ¿Permitir que {$connector_name} cree una rama?
approval-question-github-create-commit = ¿Permitir que {$connector_name} cree un commit?
approval-question-github-create-pull-request = ¿Permitir que {$connector_name} cree un pull request?
approval-question-github-create-tree = ¿Permitir que {$connector_name} cree un árbol de Git?
approval-question-github-enable-auto-merge = ¿Permitir que {$connector_name} habilite la fusión automática de un pull request?
approval-question-github-label-pr = ¿Permitir que {$connector_name} agregue una etiqueta a un pull request?
approval-question-github-remove-reaction-from-issue-comment = ¿Permitir que {$connector_name} quite una reacción de un comentario de issue?
approval-question-github-remove-reaction-from-pr = ¿Permitir que {$connector_name} quite una reacción de un pull request?
approval-question-github-remove-reaction-from-pr-review-comment = ¿Permitir que {$connector_name} quite una reacción de un comentario de revisión de pull request?
approval-question-github-reply-to-review-comment = ¿Permitir que {$connector_name} responda a un comentario de revisión de pull request?
approval-question-github-update-issue-comment = ¿Permitir que {$connector_name} actualice un comentario de issue?
approval-question-github-update-ref = ¿Permitir que {$connector_name} actualice una referencia de rama?
approval-question-github-update-review-comment = ¿Permitir que {$connector_name} actualice un comentario de revisión de pull request?
approval-question-gmail-apply-labels-to-emails = ¿Permitir que {$connector_name} aplique cambios de etiquetas a mensajes?
approval-question-gmail-batch-modify-email = ¿Permitir que {$connector_name} actualice etiquetas de mensajes?
approval-question-gmail-bulk-label-matching-emails = ¿Permitir que {$connector_name} etiquete mensajes coincidentes?
approval-question-gmail-create-draft = ¿Permitir que {$connector_name} cree un borrador de correo?
approval-question-gmail-create-label = ¿Permitir que {$connector_name} cree una etiqueta?
approval-question-gmail-send-email = ¿Permitir que {$connector_name} envíe un correo?
approval-question-google-calendar-create-event = ¿Permitir que {$connector_name} cree un evento?
approval-question-google-calendar-delete-event = ¿Permitir que {$connector_name} elimine un evento?
approval-question-google-calendar-respond-event = ¿Permitir que {$connector_name} responda a un evento?
approval-question-google-calendar-update-event = ¿Permitir que {$connector_name} actualice un evento?
approval-question-google-docs-batch-update = ¿Permitir que {$connector_name} aplique actualizaciones al documento?
approval-question-google-docs-create-document = ¿Permitir que {$connector_name} cree un documento?
approval-question-google-drive-copy-document = ¿Permitir que {$connector_name} copie un archivo?
approval-question-google-drive-share-document = ¿Permitir que {$connector_name} cambie el uso compartido del archivo?
approval-question-google-sheets-batch-update = ¿Permitir que {$connector_name} aplique actualizaciones a la hoja de cálculo?
approval-question-google-sheets-create-spreadsheet = ¿Permitir que {$connector_name} cree una hoja de cálculo?
approval-question-google-sheets-duplicate-sheet-in-new-file = ¿Permitir que {$connector_name} copie una hoja en una nueva hoja de cálculo?
approval-question-google-slides-batch-update = ¿Permitir que {$connector_name} aplique actualizaciones a la presentación?
approval-question-google-slides-create-presentation = ¿Permitir que {$connector_name} cree una presentación?
approval-question-linear-add-comment-to-issue = ¿Permitir que {$connector_name} agregue un comentario a un issue?
approval-question-linear-add-label-to-issue = ¿Permitir que {$connector_name} agregue una etiqueta a un issue?
approval-question-linear-add-url-attachment-to-issue = ¿Permitir que {$connector_name} adjunte un enlace a un issue?
approval-question-linear-assign-issue = ¿Permitir que {$connector_name} asigne un issue?
approval-question-linear-create-issue = ¿Permitir que {$connector_name} cree un issue?
approval-question-linear-create-label = ¿Permitir que {$connector_name} cree una etiqueta?
approval-question-linear-create-project = ¿Permitir que {$connector_name} cree un proyecto?
approval-question-linear-remove-label-from-issue = ¿Permitir que {$connector_name} quite una etiqueta de un issue?
approval-question-linear-resolve-comment = ¿Permitir que {$connector_name} resuelva un comentario?
approval-question-linear-set-issue-state = ¿Permitir que {$connector_name} cambie el estado del issue?
approval-question-linear-unassign-issue = ¿Permitir que {$connector_name} desasigne un issue?
approval-question-linear-update-issue = ¿Permitir que {$connector_name} actualice un issue?
approval-question-linear-update-project = ¿Permitir que {$connector_name} actualice un proyecto?
approval-question-slack-slack-create-canvas = ¿Permitir que {$connector_name} cree un canvas?
approval-question-slack-slack-schedule-message = ¿Permitir que {$connector_name} programe un mensaje?
approval-question-slack-slack-send-message = ¿Permitir que {$connector_name} envíe un mensaje?
approval-question-slack-slack-send-message-draft = ¿Permitir que {$connector_name} cree un borrador de mensaje?

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = Se requiere una confirmación adicional antes de que esta llamada de herramienta pueda continuar.

View File

@@ -0,0 +1,114 @@
approval-header = Approuver l'appel d'outil de l'app ?
approval-option-allow = Autoriser
approval-option-allow-description = Exécuter l'outil et continuer.
approval-option-allow-session = Autoriser pour cette session
approval-option-allow-session-description = Exécuter l'outil et mémoriser ce choix pour cette session.
approval-option-allow-remember = Autoriser et ne plus me demander
approval-option-allow-remember-description = Exécuter l'outil et mémoriser ce choix pour les futurs appels d'outils.
approval-option-cancel = Annuler
approval-option-cancel-description = Annuler cet appel d'outil.
approval-fallback-question-connector = Autoriser {$connector_name} à exécuter l'outil "{$tool_name}" ?
approval-fallback-question-this-app = Autoriser cette app à exécuter l'outil "{$tool_name}" ?
approval-fallback-question-server = Autoriser le serveur MCP {$server} à exécuter l'outil "{$tool_name}" ?
approval-monitor-question = Cet appel d'outil nécessite votre approbation. Raison : {$reason}
approval-safety-cancelled = Cet appel d'outil a été annulé en raison de risques de sécurité.
approval-safety-cancelled-with-reason = Cet appel d'outil a été annulé en raison de risques de sécurité : {$reason}
approval-param-action = Action
approval-param-attendees = Participants
approval-param-base-branch = Branche de base
approval-param-body = Corps
approval-param-branch = Branche
approval-param-calendar = Agenda
approval-param-changes = Modifications
approval-param-comment = Commentaire
approval-param-comment-id = ID du commentaire
approval-param-commit = Commit
approval-param-content = Contenu
approval-param-conversation = Conversation
approval-param-document = Document
approval-param-event = Événement
approval-param-head-branch = Branche source
approval-param-issue = Issue
approval-param-label = Libellé
approval-param-label-name = Nom du libellé
approval-param-message = Message
approval-param-name = Nom
approval-param-new-file-name = Nouveau nom de fichier
approval-param-permission = Autorisation
approval-param-presentation = Présentation
approval-param-project = Projet
approval-param-pull-request = Pull request
approval-param-query = Requête
approval-param-reaction = Réaction
approval-param-repository = Dépôt
approval-param-response-status = Statut de réponse
approval-param-review = Revue
approval-param-send-at = Envoyer à
approval-param-source-sheet-name = Nom de la feuille source
approval-param-spreadsheet = Feuille de calcul
approval-param-start = Début
approval-param-state = État
approval-param-subject = Objet
approval-param-team = Équipe
approval-param-title = Titre
approval-param-to = À
approval-param-timezone = Fuseau horaire
approval-param-url = URL
approval-param-user = Utilisateur
approval-question-github-add-comment-to-issue = Autoriser {$connector_name} à ajouter un commentaire à une pull request ?
approval-question-github-add-reaction-to-issue-comment = Autoriser {$connector_name} à ajouter une réaction à un commentaire d'issue ?
approval-question-github-add-reaction-to-pr = Autoriser {$connector_name} à ajouter une réaction à une pull request ?
approval-question-github-add-reaction-to-pr-review-comment = Autoriser {$connector_name} à ajouter une réaction à un commentaire de revue de pull request ?
approval-question-github-add-review-to-pr = Autoriser {$connector_name} à soumettre une revue de pull request ?
approval-question-github-create-blob = Autoriser {$connector_name} à créer un blob Git ?
approval-question-github-create-branch = Autoriser {$connector_name} à créer une branche ?
approval-question-github-create-commit = Autoriser {$connector_name} à créer un commit ?
approval-question-github-create-pull-request = Autoriser {$connector_name} à créer une pull request ?
approval-question-github-create-tree = Autoriser {$connector_name} à créer un arbre Git ?
approval-question-github-enable-auto-merge = Autoriser {$connector_name} à activer la fusion automatique d'une pull request ?
approval-question-github-label-pr = Autoriser {$connector_name} à ajouter un libellé à une pull request ?
approval-question-github-remove-reaction-from-issue-comment = Autoriser {$connector_name} à retirer une réaction d'un commentaire d'issue ?
approval-question-github-remove-reaction-from-pr = Autoriser {$connector_name} à retirer une réaction d'une pull request ?
approval-question-github-remove-reaction-from-pr-review-comment = Autoriser {$connector_name} à retirer une réaction d'un commentaire de revue de pull request ?
approval-question-github-reply-to-review-comment = Autoriser {$connector_name} à répondre à un commentaire de revue de pull request ?
approval-question-github-update-issue-comment = Autoriser {$connector_name} à mettre à jour un commentaire d'issue ?
approval-question-github-update-ref = Autoriser {$connector_name} à mettre à jour une référence de branche ?
approval-question-github-update-review-comment = Autoriser {$connector_name} à mettre à jour un commentaire de revue de pull request ?
approval-question-gmail-apply-labels-to-emails = Autoriser {$connector_name} à appliquer des changements de libellés aux messages ?
approval-question-gmail-batch-modify-email = Autoriser {$connector_name} à mettre à jour les libellés des messages ?
approval-question-gmail-bulk-label-matching-emails = Autoriser {$connector_name} à libeller les messages correspondants ?
approval-question-gmail-create-draft = Autoriser {$connector_name} à créer un brouillon d'e-mail ?
approval-question-gmail-create-label = Autoriser {$connector_name} à créer un libellé ?
approval-question-gmail-send-email = Autoriser {$connector_name} à envoyer un e-mail ?
approval-question-google-calendar-create-event = Autoriser {$connector_name} à créer un événement ?
approval-question-google-calendar-delete-event = Autoriser {$connector_name} à supprimer un événement ?
approval-question-google-calendar-respond-event = Autoriser {$connector_name} à répondre à un événement ?
approval-question-google-calendar-update-event = Autoriser {$connector_name} à mettre à jour un événement ?
approval-question-google-docs-batch-update = Autoriser {$connector_name} à appliquer des mises à jour au document ?
approval-question-google-docs-create-document = Autoriser {$connector_name} à créer un document ?
approval-question-google-drive-copy-document = Autoriser {$connector_name} à copier un fichier ?
approval-question-google-drive-share-document = Autoriser {$connector_name} à modifier le partage du fichier ?
approval-question-google-sheets-batch-update = Autoriser {$connector_name} à appliquer des mises à jour à la feuille de calcul ?
approval-question-google-sheets-create-spreadsheet = Autoriser {$connector_name} à créer une feuille de calcul ?
approval-question-google-sheets-duplicate-sheet-in-new-file = Autoriser {$connector_name} à copier une feuille dans une nouvelle feuille de calcul ?
approval-question-google-slides-batch-update = Autoriser {$connector_name} à appliquer des mises à jour à la présentation ?
approval-question-google-slides-create-presentation = Autoriser {$connector_name} à créer une présentation ?
approval-question-linear-add-comment-to-issue = Autoriser {$connector_name} à ajouter un commentaire à une issue ?
approval-question-linear-add-label-to-issue = Autoriser {$connector_name} à ajouter un libellé à une issue ?
approval-question-linear-add-url-attachment-to-issue = Autoriser {$connector_name} à joindre un lien à une issue ?
approval-question-linear-assign-issue = Autoriser {$connector_name} à assigner une issue ?
approval-question-linear-create-issue = Autoriser {$connector_name} à créer une issue ?
approval-question-linear-create-label = Autoriser {$connector_name} à créer un libellé ?
approval-question-linear-create-project = Autoriser {$connector_name} à créer un projet ?
approval-question-linear-remove-label-from-issue = Autoriser {$connector_name} à retirer un libellé d'une issue ?
approval-question-linear-resolve-comment = Autoriser {$connector_name} à résoudre un commentaire ?
approval-question-linear-set-issue-state = Autoriser {$connector_name} à modifier l'état d'une issue ?
approval-question-linear-unassign-issue = Autoriser {$connector_name} à désassigner une issue ?
approval-question-linear-update-issue = Autoriser {$connector_name} à mettre à jour une issue ?
approval-question-linear-update-project = Autoriser {$connector_name} à mettre à jour un projet ?
approval-question-slack-slack-create-canvas = Autoriser {$connector_name} à créer un canvas ?
approval-question-slack-slack-schedule-message = Autoriser {$connector_name} à programmer un message ?
approval-question-slack-slack-send-message = Autoriser {$connector_name} à envoyer un message ?
approval-question-slack-slack-send-message-draft = Autoriser {$connector_name} à créer un brouillon de message ?

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = Une confirmation supplémentaire est requise avant que cet appel d'outil puisse continuer.

View File

@@ -0,0 +1,114 @@
approval-header = ऐप टूल कॉल को स्वीकृत करें?
approval-option-allow = अनुमति दें
approval-option-allow-description = टूल चलाएँ और जारी रखें।
approval-option-allow-session = इस सत्र के लिए अनुमति दें
approval-option-allow-session-description = टूल चलाएँ और इस चयन को इस सत्र के लिए याद रखें।
approval-option-allow-remember = अनुमति दें और दोबारा न पूछें
approval-option-allow-remember-description = टूल चलाएँ और इस चयन को भविष्य के टूल कॉल के लिए याद रखें।
approval-option-cancel = रद्द करें
approval-option-cancel-description = इस टूल कॉल को रद्द करें।
approval-fallback-question-connector = क्या {$connector_name} को टूल "{$tool_name}" चलाने की अनुमति दें?
approval-fallback-question-this-app = क्या इस ऐप को टूल "{$tool_name}" चलाने की अनुमति दें?
approval-fallback-question-server = क्या {$server} MCP सर्वर को टूल "{$tool_name}" चलाने की अनुमति दें?
approval-monitor-question = इस टूल कॉल के लिए आपकी स्वीकृति चाहिए। कारण: {$reason}
approval-safety-cancelled = सुरक्षा जोखिमों के कारण यह टूल कॉल रद्द कर दिया गया।
approval-safety-cancelled-with-reason = सुरक्षा जोखिमों के कारण यह टूल कॉल रद्द कर दिया गया: {$reason}
approval-param-action = कार्रवाई
approval-param-attendees = सहभागी
approval-param-base-branch = बेस ब्रांच
approval-param-body = मुख्य भाग
approval-param-branch = ब्रांच
approval-param-calendar = कैलेंडर
approval-param-changes = बदलाव
approval-param-comment = टिप्पणी
approval-param-comment-id = टिप्पणी आईडी
approval-param-commit = कमिट
approval-param-content = सामग्री
approval-param-conversation = बातचीत
approval-param-document = दस्तावेज़
approval-param-event = इवेंट
approval-param-head-branch = स्रोत ब्रांच
approval-param-issue = इश्यू
approval-param-label = लेबल
approval-param-label-name = लेबल नाम
approval-param-message = संदेश
approval-param-name = नाम
approval-param-new-file-name = नया फ़ाइल नाम
approval-param-permission = अनुमति
approval-param-presentation = प्रस्तुति
approval-param-project = प्रोजेक्ट
approval-param-pull-request = पुल रिक्वेस्ट
approval-param-query = क्वेरी
approval-param-reaction = प्रतिक्रिया
approval-param-repository = रिपॉज़िटरी
approval-param-response-status = जवाब की स्थिति
approval-param-review = समीक्षा
approval-param-send-at = भेजने का समय
approval-param-source-sheet-name = स्रोत शीट का नाम
approval-param-spreadsheet = स्प्रेडशीट
approval-param-start = शुरू
approval-param-state = स्थिति
approval-param-subject = विषय
approval-param-team = टीम
approval-param-title = शीर्षक
approval-param-to = प्रति
approval-param-timezone = समय क्षेत्र
approval-param-url = URL
approval-param-user = उपयोगकर्ता
approval-question-github-add-comment-to-issue = क्या {$connector_name} को पुल रिक्वेस्ट पर टिप्पणी जोड़ने की अनुमति दें?
approval-question-github-add-reaction-to-issue-comment = क्या {$connector_name} को इश्यू टिप्पणी पर प्रतिक्रिया जोड़ने की अनुमति दें?
approval-question-github-add-reaction-to-pr = क्या {$connector_name} को पुल रिक्वेस्ट पर प्रतिक्रिया जोड़ने की अनुमति दें?
approval-question-github-add-reaction-to-pr-review-comment = क्या {$connector_name} को पुल रिक्वेस्ट समीक्षा टिप्पणी पर प्रतिक्रिया जोड़ने की अनुमति दें?
approval-question-github-add-review-to-pr = क्या {$connector_name} को पुल रिक्वेस्ट समीक्षा सबमिट करने की अनुमति दें?
approval-question-github-create-blob = क्या {$connector_name} को Git blob बनाने की अनुमति दें?
approval-question-github-create-branch = क्या {$connector_name} को ब्रांच बनाने की अनुमति दें?
approval-question-github-create-commit = क्या {$connector_name} को कमिट बनाने की अनुमति दें?
approval-question-github-create-pull-request = क्या {$connector_name} को पुल रिक्वेस्ट बनाने की अनुमति दें?
approval-question-github-create-tree = क्या {$connector_name} को Git tree बनाने की अनुमति दें?
approval-question-github-enable-auto-merge = क्या {$connector_name} को पुल रिक्वेस्ट ऑटो-मर्ज सक्षम करने की अनुमति दें?
approval-question-github-label-pr = क्या {$connector_name} को पुल रिक्वेस्ट में लेबल जोड़ने की अनुमति दें?
approval-question-github-remove-reaction-from-issue-comment = क्या {$connector_name} को इश्यू टिप्पणी से प्रतिक्रिया हटाने की अनुमति दें?
approval-question-github-remove-reaction-from-pr = क्या {$connector_name} को पुल रिक्वेस्ट से प्रतिक्रिया हटाने की अनुमति दें?
approval-question-github-remove-reaction-from-pr-review-comment = क्या {$connector_name} को पुल रिक्वेस्ट समीक्षा टिप्पणी से प्रतिक्रिया हटाने की अनुमति दें?
approval-question-github-reply-to-review-comment = क्या {$connector_name} को पुल रिक्वेस्ट समीक्षा टिप्पणी का जवाब देने की अनुमति दें?
approval-question-github-update-issue-comment = क्या {$connector_name} को इश्यू टिप्पणी अपडेट करने की अनुमति दें?
approval-question-github-update-ref = क्या {$connector_name} को ब्रांच रेफ़रेंस अपडेट करने की अनुमति दें?
approval-question-github-update-review-comment = क्या {$connector_name} को पुल रिक्वेस्ट समीक्षा टिप्पणी अपडेट करने की अनुमति दें?
approval-question-gmail-apply-labels-to-emails = क्या {$connector_name} को संदेशों पर लेबल बदलाव लागू करने की अनुमति दें?
approval-question-gmail-batch-modify-email = क्या {$connector_name} को संदेश लेबल अपडेट करने की अनुमति दें?
approval-question-gmail-bulk-label-matching-emails = क्या {$connector_name} को मेल खाते संदेशों को लेबल करने की अनुमति दें?
approval-question-gmail-create-draft = क्या {$connector_name} को ईमेल ड्राफ़्ट बनाने की अनुमति दें?
approval-question-gmail-create-label = क्या {$connector_name} को लेबल बनाने की अनुमति दें?
approval-question-gmail-send-email = क्या {$connector_name} को ईमेल भेजने की अनुमति दें?
approval-question-google-calendar-create-event = क्या {$connector_name} को इवेंट बनाने की अनुमति दें?
approval-question-google-calendar-delete-event = क्या {$connector_name} को इवेंट हटाने की अनुमति दें?
approval-question-google-calendar-respond-event = क्या {$connector_name} को इवेंट का जवाब देने की अनुमति दें?
approval-question-google-calendar-update-event = क्या {$connector_name} को इवेंट अपडेट करने की अनुमति दें?
approval-question-google-docs-batch-update = क्या {$connector_name} को दस्तावेज़ अपडेट लागू करने की अनुमति दें?
approval-question-google-docs-create-document = क्या {$connector_name} को दस्तावेज़ बनाने की अनुमति दें?
approval-question-google-drive-copy-document = क्या {$connector_name} को फ़ाइल कॉपी करने की अनुमति दें?
approval-question-google-drive-share-document = क्या {$connector_name} को फ़ाइल शेयरिंग बदलने की अनुमति दें?
approval-question-google-sheets-batch-update = क्या {$connector_name} को स्प्रेडशीट अपडेट लागू करने की अनुमति दें?
approval-question-google-sheets-create-spreadsheet = क्या {$connector_name} को स्प्रेडशीट बनाने की अनुमति दें?
approval-question-google-sheets-duplicate-sheet-in-new-file = क्या {$connector_name} को शीट को नई स्प्रेडशीट में कॉपी करने की अनुमति दें?
approval-question-google-slides-batch-update = क्या {$connector_name} को प्रस्तुति अपडेट लागू करने की अनुमति दें?
approval-question-google-slides-create-presentation = क्या {$connector_name} को प्रस्तुति बनाने की अनुमति दें?
approval-question-linear-add-comment-to-issue = क्या {$connector_name} को इश्यू पर टिप्पणी जोड़ने की अनुमति दें?
approval-question-linear-add-label-to-issue = क्या {$connector_name} को इश्यू में लेबल जोड़ने की अनुमति दें?
approval-question-linear-add-url-attachment-to-issue = क्या {$connector_name} को इश्यू में लिंक संलग्न करने की अनुमति दें?
approval-question-linear-assign-issue = क्या {$connector_name} को इश्यू असाइन करने की अनुमति दें?
approval-question-linear-create-issue = क्या {$connector_name} को इश्यू बनाने की अनुमति दें?
approval-question-linear-create-label = क्या {$connector_name} को लेबल बनाने की अनुमति दें?
approval-question-linear-create-project = क्या {$connector_name} को प्रोजेक्ट बनाने की अनुमति दें?
approval-question-linear-remove-label-from-issue = क्या {$connector_name} को इश्यू से लेबल हटाने की अनुमति दें?
approval-question-linear-resolve-comment = क्या {$connector_name} को टिप्पणी हल करने की अनुमति दें?
approval-question-linear-set-issue-state = क्या {$connector_name} को इश्यू की स्थिति बदलने की अनुमति दें?
approval-question-linear-unassign-issue = क्या {$connector_name} को इश्यू अनअसाइन करने की अनुमति दें?
approval-question-linear-update-issue = क्या {$connector_name} को इश्यू अपडेट करने की अनुमति दें?
approval-question-linear-update-project = क्या {$connector_name} को प्रोजेक्ट अपडेट करने की अनुमति दें?
approval-question-slack-slack-create-canvas = क्या {$connector_name} को कैनवास बनाने की अनुमति दें?
approval-question-slack-slack-schedule-message = क्या {$connector_name} को संदेश शेड्यूल करने की अनुमति दें?
approval-question-slack-slack-send-message = क्या {$connector_name} को संदेश भेजने की अनुमति दें?
approval-question-slack-slack-send-message-draft = क्या {$connector_name} को संदेश ड्राफ़्ट बनाने की अनुमति दें?

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = इस टूल कॉल को जारी रखने से पहले अतिरिक्त पुष्टि आवश्यक है।

View File

@@ -0,0 +1,114 @@
approval-header = アプリのツール呼び出しを承認しますか?
approval-option-allow = 許可
approval-option-allow-description = ツールを実行して続行します。
approval-option-allow-session = このセッションで許可
approval-option-allow-session-description = ツールを実行し、このセッション中はこの選択を記憶します。
approval-option-allow-remember = 許可して今後は確認しない
approval-option-allow-remember-description = ツールを実行し、今後のツール呼び出しのためにこの選択を記憶します。
approval-option-cancel = キャンセル
approval-option-cancel-description = このツール呼び出しをキャンセルします。
approval-fallback-question-connector = {$connector_name} がツール「{$tool_name}」を実行することを許可しますか?
approval-fallback-question-this-app = このアプリがツール「{$tool_name}」を実行することを許可しますか?
approval-fallback-question-server = {$server} MCP サーバーがツール「{$tool_name}」を実行することを許可しますか?
approval-monitor-question = このツール呼び出しには承認が必要です。理由: {$reason}
approval-safety-cancelled = 安全上のリスクのため、このツール呼び出しはキャンセルされました。
approval-safety-cancelled-with-reason = 安全上のリスクのため、このツール呼び出しはキャンセルされました: {$reason}
approval-param-action = アクション
approval-param-attendees = 参加者
approval-param-base-branch = ベースブランチ
approval-param-body = 本文
approval-param-branch = ブランチ
approval-param-calendar = カレンダー
approval-param-changes = 変更
approval-param-comment = コメント
approval-param-comment-id = コメント ID
approval-param-commit = コミット
approval-param-content = 内容
approval-param-conversation = 会話
approval-param-document = ドキュメント
approval-param-event = イベント
approval-param-head-branch = ヘッドブランチ
approval-param-issue = Issue
approval-param-label = ラベル
approval-param-label-name = ラベル名
approval-param-message = メッセージ
approval-param-name = 名前
approval-param-new-file-name = 新しいファイル名
approval-param-permission = 権限
approval-param-presentation = プレゼンテーション
approval-param-project = プロジェクト
approval-param-pull-request = プルリクエスト
approval-param-query = クエリ
approval-param-reaction = リアクション
approval-param-repository = リポジトリ
approval-param-response-status = 応答ステータス
approval-param-review = レビュー
approval-param-send-at = 送信日時
approval-param-source-sheet-name = 元のシート名
approval-param-spreadsheet = スプレッドシート
approval-param-start = 開始
approval-param-state = 状態
approval-param-subject = 件名
approval-param-team = チーム
approval-param-title = タイトル
approval-param-to = 宛先
approval-param-timezone = タイムゾーン
approval-param-url = URL
approval-param-user = ユーザー
approval-question-github-add-comment-to-issue = {$connector_name} がプルリクエストにコメントを追加することを許可しますか?
approval-question-github-add-reaction-to-issue-comment = {$connector_name} が issue コメントにリアクションを追加することを許可しますか?
approval-question-github-add-reaction-to-pr = {$connector_name} がプルリクエストにリアクションを追加することを許可しますか?
approval-question-github-add-reaction-to-pr-review-comment = {$connector_name} がプルリクエストのレビューコメントにリアクションを追加することを許可しますか?
approval-question-github-add-review-to-pr = {$connector_name} がプルリクエストレビューを送信することを許可しますか?
approval-question-github-create-blob = {$connector_name} が Git blob を作成することを許可しますか?
approval-question-github-create-branch = {$connector_name} がブランチを作成することを許可しますか?
approval-question-github-create-commit = {$connector_name} がコミットを作成することを許可しますか?
approval-question-github-create-pull-request = {$connector_name} がプルリクエストを作成することを許可しますか?
approval-question-github-create-tree = {$connector_name} が Git tree を作成することを許可しますか?
approval-question-github-enable-auto-merge = {$connector_name} がプルリクエストの自動マージを有効にすることを許可しますか?
approval-question-github-label-pr = {$connector_name} がプルリクエストにラベルを追加することを許可しますか?
approval-question-github-remove-reaction-from-issue-comment = {$connector_name} が issue コメントからリアクションを削除することを許可しますか?
approval-question-github-remove-reaction-from-pr = {$connector_name} がプルリクエストからリアクションを削除することを許可しますか?
approval-question-github-remove-reaction-from-pr-review-comment = {$connector_name} がプルリクエストのレビューコメントからリアクションを削除することを許可しますか?
approval-question-github-reply-to-review-comment = {$connector_name} がプルリクエストのレビューコメントに返信することを許可しますか?
approval-question-github-update-issue-comment = {$connector_name} が issue コメントを更新することを許可しますか?
approval-question-github-update-ref = {$connector_name} がブランチ参照を更新することを許可しますか?
approval-question-github-update-review-comment = {$connector_name} がプルリクエストのレビューコメントを更新することを許可しますか?
approval-question-gmail-apply-labels-to-emails = {$connector_name} がメッセージにラベル変更を適用することを許可しますか?
approval-question-gmail-batch-modify-email = {$connector_name} がメッセージラベルを更新することを許可しますか?
approval-question-gmail-bulk-label-matching-emails = {$connector_name} が一致するメッセージにラベルを付けることを許可しますか?
approval-question-gmail-create-draft = {$connector_name} がメールの下書きを作成することを許可しますか?
approval-question-gmail-create-label = {$connector_name} がラベルを作成することを許可しますか?
approval-question-gmail-send-email = {$connector_name} がメールを送信することを許可しますか?
approval-question-google-calendar-create-event = {$connector_name} がイベントを作成することを許可しますか?
approval-question-google-calendar-delete-event = {$connector_name} がイベントを削除することを許可しますか?
approval-question-google-calendar-respond-event = {$connector_name} がイベントに返信することを許可しますか?
approval-question-google-calendar-update-event = {$connector_name} がイベントを更新することを許可しますか?
approval-question-google-docs-batch-update = {$connector_name} がドキュメントの更新を適用することを許可しますか?
approval-question-google-docs-create-document = {$connector_name} がドキュメントを作成することを許可しますか?
approval-question-google-drive-copy-document = {$connector_name} がファイルをコピーすることを許可しますか?
approval-question-google-drive-share-document = {$connector_name} がファイル共有を変更することを許可しますか?
approval-question-google-sheets-batch-update = {$connector_name} がスプレッドシートの更新を適用することを許可しますか?
approval-question-google-sheets-create-spreadsheet = {$connector_name} がスプレッドシートを作成することを許可しますか?
approval-question-google-sheets-duplicate-sheet-in-new-file = {$connector_name} がシートを新しいスプレッドシートにコピーすることを許可しますか?
approval-question-google-slides-batch-update = {$connector_name} がプレゼンテーションの更新を適用することを許可しますか?
approval-question-google-slides-create-presentation = {$connector_name} がプレゼンテーションを作成することを許可しますか?
approval-question-linear-add-comment-to-issue = {$connector_name} が issue にコメントを追加することを許可しますか?
approval-question-linear-add-label-to-issue = {$connector_name} が issue にラベルを追加することを許可しますか?
approval-question-linear-add-url-attachment-to-issue = {$connector_name} が issue にリンクを添付することを許可しますか?
approval-question-linear-assign-issue = {$connector_name} が issue をアサインすることを許可しますか?
approval-question-linear-create-issue = {$connector_name} が issue を作成することを許可しますか?
approval-question-linear-create-label = {$connector_name} がラベルを作成することを許可しますか?
approval-question-linear-create-project = {$connector_name} がプロジェクトを作成することを許可しますか?
approval-question-linear-remove-label-from-issue = {$connector_name} が issue からラベルを削除することを許可しますか?
approval-question-linear-resolve-comment = {$connector_name} がコメントを解決することを許可しますか?
approval-question-linear-set-issue-state = {$connector_name} が issue の状態を変更することを許可しますか?
approval-question-linear-unassign-issue = {$connector_name} が issue のアサインを解除することを許可しますか?
approval-question-linear-update-issue = {$connector_name} が issue を更新することを許可しますか?
approval-question-linear-update-project = {$connector_name} がプロジェクトを更新することを許可しますか?
approval-question-slack-slack-create-canvas = {$connector_name} がキャンバスを作成することを許可しますか?
approval-question-slack-slack-schedule-message = {$connector_name} がメッセージを予約送信することを許可しますか?
approval-question-slack-slack-send-message = {$connector_name} がメッセージを送信することを許可しますか?
approval-question-slack-slack-send-message-draft = {$connector_name} がメッセージの下書きを作成することを許可しますか?

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = このツール呼び出しを続行する前に、追加の確認が必要です。

View File

@@ -0,0 +1,114 @@
approval-header = 앱 도구 호출을 승인할까요?
approval-option-allow = 허용
approval-option-allow-description = 도구를 실행하고 계속합니다.
approval-option-allow-session = 이 세션 동안 허용
approval-option-allow-session-description = 도구를 실행하고 이 세션 동안 이 선택을 기억합니다.
approval-option-allow-remember = 허용하고 다시 묻지 않기
approval-option-allow-remember-description = 도구를 실행하고 이후 도구 호출을 위해 이 선택을 기억합니다.
approval-option-cancel = 취소
approval-option-cancel-description = 이 도구 호출을 취소합니다.
approval-fallback-question-connector = {$connector_name}이(가) 도구 "{$tool_name}"을(를) 실행하도록 허용할까요?
approval-fallback-question-this-app = 이 앱이 도구 "{$tool_name}"을(를) 실행하도록 허용할까요?
approval-fallback-question-server = {$server} MCP 서버가 도구 "{$tool_name}"을(를) 실행하도록 허용할까요?
approval-monitor-question = 이 도구 호출에는 승인이 필요합니다. 이유: {$reason}
approval-safety-cancelled = 안전 위험 때문에 이 도구 호출이 취소되었습니다.
approval-safety-cancelled-with-reason = 안전 위험 때문에 이 도구 호출이 취소되었습니다: {$reason}
approval-param-action = 작업
approval-param-attendees = 참석자
approval-param-base-branch = 기준 브랜치
approval-param-body = 본문
approval-param-branch = 브랜치
approval-param-calendar = 캘린더
approval-param-changes = 변경 사항
approval-param-comment = 댓글
approval-param-comment-id = 댓글 ID
approval-param-commit = 커밋
approval-param-content = 콘텐츠
approval-param-conversation = 대화
approval-param-document = 문서
approval-param-event = 일정
approval-param-head-branch = 헤드 브랜치
approval-param-issue = 이슈
approval-param-label = 라벨
approval-param-label-name = 라벨 이름
approval-param-message = 메시지
approval-param-name = 이름
approval-param-new-file-name = 새 파일 이름
approval-param-permission = 권한
approval-param-presentation = 프레젠테이션
approval-param-project = 프로젝트
approval-param-pull-request = 풀 리퀘스트
approval-param-query = 쿼리
approval-param-reaction = 반응
approval-param-repository = 저장소
approval-param-response-status = 응답 상태
approval-param-review = 리뷰
approval-param-send-at = 전송 시간
approval-param-source-sheet-name = 원본 시트 이름
approval-param-spreadsheet = 스프레드시트
approval-param-start = 시작
approval-param-state = 상태
approval-param-subject = 제목
approval-param-team = 팀
approval-param-title = 제목
approval-param-to = 받는 사람
approval-param-timezone = 시간대
approval-param-url = URL
approval-param-user = 사용자
approval-question-github-add-comment-to-issue = {$connector_name}이(가) 풀 리퀘스트에 댓글을 추가하도록 허용할까요?
approval-question-github-add-reaction-to-issue-comment = {$connector_name}이(가) 이슈 댓글에 반응을 추가하도록 허용할까요?
approval-question-github-add-reaction-to-pr = {$connector_name}이(가) 풀 리퀘스트에 반응을 추가하도록 허용할까요?
approval-question-github-add-reaction-to-pr-review-comment = {$connector_name}이(가) 풀 리퀘스트 리뷰 댓글에 반응을 추가하도록 허용할까요?
approval-question-github-add-review-to-pr = {$connector_name}이(가) 풀 리퀘스트 리뷰를 제출하도록 허용할까요?
approval-question-github-create-blob = {$connector_name}이(가) Git blob을 생성하도록 허용할까요?
approval-question-github-create-branch = {$connector_name}이(가) 브랜치를 생성하도록 허용할까요?
approval-question-github-create-commit = {$connector_name}이(가) 커밋을 생성하도록 허용할까요?
approval-question-github-create-pull-request = {$connector_name}이(가) 풀 리퀘스트를 생성하도록 허용할까요?
approval-question-github-create-tree = {$connector_name}이(가) Git tree를 생성하도록 허용할까요?
approval-question-github-enable-auto-merge = {$connector_name}이(가) 풀 리퀘스트 자동 병합을 활성화하도록 허용할까요?
approval-question-github-label-pr = {$connector_name}이(가) 풀 리퀘스트에 라벨을 추가하도록 허용할까요?
approval-question-github-remove-reaction-from-issue-comment = {$connector_name}이(가) 이슈 댓글에서 반응을 제거하도록 허용할까요?
approval-question-github-remove-reaction-from-pr = {$connector_name}이(가) 풀 리퀘스트에서 반응을 제거하도록 허용할까요?
approval-question-github-remove-reaction-from-pr-review-comment = {$connector_name}이(가) 풀 리퀘스트 리뷰 댓글에서 반응을 제거하도록 허용할까요?
approval-question-github-reply-to-review-comment = {$connector_name}이(가) 풀 리퀘스트 리뷰 댓글에 답글을 달도록 허용할까요?
approval-question-github-update-issue-comment = {$connector_name}이(가) 이슈 댓글을 업데이트하도록 허용할까요?
approval-question-github-update-ref = {$connector_name}이(가) 브랜치 참조를 업데이트하도록 허용할까요?
approval-question-github-update-review-comment = {$connector_name}이(가) 풀 리퀘스트 리뷰 댓글을 업데이트하도록 허용할까요?
approval-question-gmail-apply-labels-to-emails = {$connector_name}이(가) 메시지에 라벨 변경을 적용하도록 허용할까요?
approval-question-gmail-batch-modify-email = {$connector_name}이(가) 메시지 라벨을 업데이트하도록 허용할까요?
approval-question-gmail-bulk-label-matching-emails = {$connector_name}이(가) 일치하는 메시지에 라벨을 지정하도록 허용할까요?
approval-question-gmail-create-draft = {$connector_name}이(가) 이메일 초안을 생성하도록 허용할까요?
approval-question-gmail-create-label = {$connector_name}이(가) 라벨을 생성하도록 허용할까요?
approval-question-gmail-send-email = {$connector_name}이(가) 이메일을 보내도록 허용할까요?
approval-question-google-calendar-create-event = {$connector_name}이(가) 일정을 생성하도록 허용할까요?
approval-question-google-calendar-delete-event = {$connector_name}이(가) 일정을 삭제하도록 허용할까요?
approval-question-google-calendar-respond-event = {$connector_name}이(가) 일정에 응답하도록 허용할까요?
approval-question-google-calendar-update-event = {$connector_name}이(가) 일정을 업데이트하도록 허용할까요?
approval-question-google-docs-batch-update = {$connector_name}이(가) 문서 업데이트를 적용하도록 허용할까요?
approval-question-google-docs-create-document = {$connector_name}이(가) 문서를 생성하도록 허용할까요?
approval-question-google-drive-copy-document = {$connector_name}이(가) 파일을 복사하도록 허용할까요?
approval-question-google-drive-share-document = {$connector_name}이(가) 파일 공유를 변경하도록 허용할까요?
approval-question-google-sheets-batch-update = {$connector_name}이(가) 스프레드시트 업데이트를 적용하도록 허용할까요?
approval-question-google-sheets-create-spreadsheet = {$connector_name}이(가) 스프레드시트를 생성하도록 허용할까요?
approval-question-google-sheets-duplicate-sheet-in-new-file = {$connector_name}이(가) 시트를 새 스프레드시트로 복사하도록 허용할까요?
approval-question-google-slides-batch-update = {$connector_name}이(가) 프레젠테이션 업데이트를 적용하도록 허용할까요?
approval-question-google-slides-create-presentation = {$connector_name}이(가) 프레젠테이션을 생성하도록 허용할까요?
approval-question-linear-add-comment-to-issue = {$connector_name}이(가) 이슈에 댓글을 추가하도록 허용할까요?
approval-question-linear-add-label-to-issue = {$connector_name}이(가) 이슈에 라벨을 추가하도록 허용할까요?
approval-question-linear-add-url-attachment-to-issue = {$connector_name}이(가) 이슈에 링크를 첨부하도록 허용할까요?
approval-question-linear-assign-issue = {$connector_name}이(가) 이슈를 할당하도록 허용할까요?
approval-question-linear-create-issue = {$connector_name}이(가) 이슈를 생성하도록 허용할까요?
approval-question-linear-create-label = {$connector_name}이(가) 라벨을 생성하도록 허용할까요?
approval-question-linear-create-project = {$connector_name}이(가) 프로젝트를 생성하도록 허용할까요?
approval-question-linear-remove-label-from-issue = {$connector_name}이(가) 이슈에서 라벨을 제거하도록 허용할까요?
approval-question-linear-resolve-comment = {$connector_name}이(가) 댓글을 해결하도록 허용할까요?
approval-question-linear-set-issue-state = {$connector_name}이(가) 이슈 상태를 변경하도록 허용할까요?
approval-question-linear-unassign-issue = {$connector_name}이(가) 이슈 할당을 해제하도록 허용할까요?
approval-question-linear-update-issue = {$connector_name}이(가) 이슈를 업데이트하도록 허용할까요?
approval-question-linear-update-project = {$connector_name}이(가) 프로젝트를 업데이트하도록 허용할까요?
approval-question-slack-slack-create-canvas = {$connector_name}이(가) 캔버스를 생성하도록 허용할까요?
approval-question-slack-slack-schedule-message = {$connector_name}이(가) 메시지를 예약하도록 허용할까요?
approval-question-slack-slack-send-message = {$connector_name}이(가) 메시지를 보내도록 허용할까요?
approval-question-slack-slack-send-message-draft = {$connector_name}이(가) 메시지 초안을 생성하도록 허용할까요?

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = 이 도구 호출을 계속하기 전에 추가 확인이 필요합니다.

View File

@@ -0,0 +1,114 @@
approval-header = Aprovar a chamada de ferramenta do app?
approval-option-allow = Permitir
approval-option-allow-description = Executar a ferramenta e continuar.
approval-option-allow-session = Permitir nesta sessão
approval-option-allow-session-description = Executar a ferramenta e lembrar desta escolha nesta sessão.
approval-option-allow-remember = Permitir e não perguntar novamente
approval-option-allow-remember-description = Executar a ferramenta e lembrar desta escolha para futuras chamadas de ferramenta.
approval-option-cancel = Cancelar
approval-option-cancel-description = Cancelar esta chamada de ferramenta.
approval-fallback-question-connector = Permitir que {$connector_name} execute a ferramenta "{$tool_name}"?
approval-fallback-question-this-app = Permitir que este app execute a ferramenta "{$tool_name}"?
approval-fallback-question-server = Permitir que o servidor MCP {$server} execute a ferramenta "{$tool_name}"?
approval-monitor-question = Esta chamada de ferramenta precisa da sua aprovação. Motivo: {$reason}
approval-safety-cancelled = Esta chamada de ferramenta foi cancelada devido a riscos de segurança.
approval-safety-cancelled-with-reason = Esta chamada de ferramenta foi cancelada devido a riscos de segurança: {$reason}
approval-param-action = Ação
approval-param-attendees = Participantes
approval-param-base-branch = Branch base
approval-param-body = Corpo
approval-param-branch = Branch
approval-param-calendar = Calendário
approval-param-changes = Alterações
approval-param-comment = Comentário
approval-param-comment-id = ID do comentário
approval-param-commit = Commit
approval-param-content = Conteúdo
approval-param-conversation = Conversa
approval-param-document = Documento
approval-param-event = Evento
approval-param-head-branch = Branch de origem
approval-param-issue = Issue
approval-param-label = Rótulo
approval-param-label-name = Nome do rótulo
approval-param-message = Mensagem
approval-param-name = Nome
approval-param-new-file-name = Novo nome de arquivo
approval-param-permission = Permissão
approval-param-presentation = Apresentação
approval-param-project = Projeto
approval-param-pull-request = Pull request
approval-param-query = Consulta
approval-param-reaction = Reação
approval-param-repository = Repositório
approval-param-response-status = Status da resposta
approval-param-review = Revisão
approval-param-send-at = Enviar às
approval-param-source-sheet-name = Nome da planilha de origem
approval-param-spreadsheet = Planilha
approval-param-start = Início
approval-param-state = Estado
approval-param-subject = Assunto
approval-param-team = Equipe
approval-param-title = Título
approval-param-to = Para
approval-param-timezone = Fuso horário
approval-param-url = URL
approval-param-user = Usuário
approval-question-github-add-comment-to-issue = Permitir que {$connector_name} adicione um comentário a um pull request?
approval-question-github-add-reaction-to-issue-comment = Permitir que {$connector_name} adicione uma reação a um comentário de issue?
approval-question-github-add-reaction-to-pr = Permitir que {$connector_name} adicione uma reação a um pull request?
approval-question-github-add-reaction-to-pr-review-comment = Permitir que {$connector_name} adicione uma reação a um comentário de revisão de pull request?
approval-question-github-add-review-to-pr = Permitir que {$connector_name} envie uma revisão de pull request?
approval-question-github-create-blob = Permitir que {$connector_name} crie um Git blob?
approval-question-github-create-branch = Permitir que {$connector_name} crie uma branch?
approval-question-github-create-commit = Permitir que {$connector_name} crie um commit?
approval-question-github-create-pull-request = Permitir que {$connector_name} crie um pull request?
approval-question-github-create-tree = Permitir que {$connector_name} crie uma Git tree?
approval-question-github-enable-auto-merge = Permitir que {$connector_name} habilite o merge automático de pull request?
approval-question-github-label-pr = Permitir que {$connector_name} adicione um rótulo a um pull request?
approval-question-github-remove-reaction-from-issue-comment = Permitir que {$connector_name} remova uma reação de um comentário de issue?
approval-question-github-remove-reaction-from-pr = Permitir que {$connector_name} remova uma reação de um pull request?
approval-question-github-remove-reaction-from-pr-review-comment = Permitir que {$connector_name} remova uma reação de um comentário de revisão de pull request?
approval-question-github-reply-to-review-comment = Permitir que {$connector_name} responda a um comentário de revisão de pull request?
approval-question-github-update-issue-comment = Permitir que {$connector_name} atualize um comentário de issue?
approval-question-github-update-ref = Permitir que {$connector_name} atualize uma referência de branch?
approval-question-github-update-review-comment = Permitir que {$connector_name} atualize um comentário de revisão de pull request?
approval-question-gmail-apply-labels-to-emails = Permitir que {$connector_name} aplique alterações de rótulos às mensagens?
approval-question-gmail-batch-modify-email = Permitir que {$connector_name} atualize rótulos de mensagens?
approval-question-gmail-bulk-label-matching-emails = Permitir que {$connector_name} rotule mensagens correspondentes?
approval-question-gmail-create-draft = Permitir que {$connector_name} crie um rascunho de e-mail?
approval-question-gmail-create-label = Permitir que {$connector_name} crie um rótulo?
approval-question-gmail-send-email = Permitir que {$connector_name} envie um e-mail?
approval-question-google-calendar-create-event = Permitir que {$connector_name} crie um evento?
approval-question-google-calendar-delete-event = Permitir que {$connector_name} exclua um evento?
approval-question-google-calendar-respond-event = Permitir que {$connector_name} responda a um evento?
approval-question-google-calendar-update-event = Permitir que {$connector_name} atualize um evento?
approval-question-google-docs-batch-update = Permitir que {$connector_name} aplique atualizações ao documento?
approval-question-google-docs-create-document = Permitir que {$connector_name} crie um documento?
approval-question-google-drive-copy-document = Permitir que {$connector_name} copie um arquivo?
approval-question-google-drive-share-document = Permitir que {$connector_name} altere o compartilhamento do arquivo?
approval-question-google-sheets-batch-update = Permitir que {$connector_name} aplique atualizações à planilha?
approval-question-google-sheets-create-spreadsheet = Permitir que {$connector_name} crie uma planilha?
approval-question-google-sheets-duplicate-sheet-in-new-file = Permitir que {$connector_name} copie uma aba para uma nova planilha?
approval-question-google-slides-batch-update = Permitir que {$connector_name} aplique atualizações à apresentação?
approval-question-google-slides-create-presentation = Permitir que {$connector_name} crie uma apresentação?
approval-question-linear-add-comment-to-issue = Permitir que {$connector_name} adicione um comentário a um issue?
approval-question-linear-add-label-to-issue = Permitir que {$connector_name} adicione um rótulo a um issue?
approval-question-linear-add-url-attachment-to-issue = Permitir que {$connector_name} anexe um link a um issue?
approval-question-linear-assign-issue = Permitir que {$connector_name} atribua um issue?
approval-question-linear-create-issue = Permitir que {$connector_name} crie um issue?
approval-question-linear-create-label = Permitir que {$connector_name} crie um rótulo?
approval-question-linear-create-project = Permitir que {$connector_name} crie um projeto?
approval-question-linear-remove-label-from-issue = Permitir que {$connector_name} remova um rótulo de um issue?
approval-question-linear-resolve-comment = Permitir que {$connector_name} resolva um comentário?
approval-question-linear-set-issue-state = Permitir que {$connector_name} altere o estado do issue?
approval-question-linear-unassign-issue = Permitir que {$connector_name} desatribua um issue?
approval-question-linear-update-issue = Permitir que {$connector_name} atualize um issue?
approval-question-linear-update-project = Permitir que {$connector_name} atualize um projeto?
approval-question-slack-slack-create-canvas = Permitir que {$connector_name} crie um canvas?
approval-question-slack-slack-schedule-message = Permitir que {$connector_name} agende uma mensagem?
approval-question-slack-slack-send-message = Permitir que {$connector_name} envie uma mensagem?
approval-question-slack-slack-send-message-draft = Permitir que {$connector_name} crie um rascunho de mensagem?

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = É necessária uma confirmação adicional antes que esta chamada de ferramenta possa continuar.

View File

@@ -0,0 +1,114 @@
approval-header = Одобрить вызов инструмента приложения?
approval-option-allow = Разрешить
approval-option-allow-description = Запустить инструмент и продолжить.
approval-option-allow-session = Разрешить для этого сеанса
approval-option-allow-session-description = Запустить инструмент и запомнить этот выбор для этого сеанса.
approval-option-allow-remember = Разрешить и больше не спрашивать
approval-option-allow-remember-description = Запустить инструмент и запомнить этот выбор для будущих вызовов инструментов.
approval-option-cancel = Отмена
approval-option-cancel-description = Отменить этот вызов инструмента.
approval-fallback-question-connector = Разрешить {$connector_name} запустить инструмент "{$tool_name}"?
approval-fallback-question-this-app = Разрешить этому приложению запустить инструмент "{$tool_name}"?
approval-fallback-question-server = Разрешить MCP-серверу {$server} запустить инструмент "{$tool_name}"?
approval-monitor-question = Этот вызов инструмента требует вашего одобрения. Причина: {$reason}
approval-safety-cancelled = Этот вызов инструмента был отменен из-за рисков безопасности.
approval-safety-cancelled-with-reason = Этот вызов инструмента был отменен из-за рисков безопасности: {$reason}
approval-param-action = Действие
approval-param-attendees = Участники
approval-param-base-branch = Базовая ветка
approval-param-body = Текст
approval-param-branch = Ветка
approval-param-calendar = Календарь
approval-param-changes = Изменения
approval-param-comment = Комментарий
approval-param-comment-id = ID комментария
approval-param-commit = Коммит
approval-param-content = Содержимое
approval-param-conversation = Разговор
approval-param-document = Документ
approval-param-event = Событие
approval-param-head-branch = Исходная ветка
approval-param-issue = Issue
approval-param-label = Метка
approval-param-label-name = Название метки
approval-param-message = Сообщение
approval-param-name = Имя
approval-param-new-file-name = Новое имя файла
approval-param-permission = Разрешение
approval-param-presentation = Презентация
approval-param-project = Проект
approval-param-pull-request = Pull request
approval-param-query = Запрос
approval-param-reaction = Реакция
approval-param-repository = Репозиторий
approval-param-response-status = Статус ответа
approval-param-review = Ревью
approval-param-send-at = Отправить в
approval-param-source-sheet-name = Имя исходного листа
approval-param-spreadsheet = Таблица
approval-param-start = Начало
approval-param-state = Состояние
approval-param-subject = Тема
approval-param-team = Команда
approval-param-title = Заголовок
approval-param-to = Кому
approval-param-timezone = Часовой пояс
approval-param-url = URL
approval-param-user = Пользователь
approval-question-github-add-comment-to-issue = Разрешить {$connector_name} добавить комментарий к pull request?
approval-question-github-add-reaction-to-issue-comment = Разрешить {$connector_name} добавить реакцию к комментарию issue?
approval-question-github-add-reaction-to-pr = Разрешить {$connector_name} добавить реакцию к pull request?
approval-question-github-add-reaction-to-pr-review-comment = Разрешить {$connector_name} добавить реакцию к комментарию ревью pull request?
approval-question-github-add-review-to-pr = Разрешить {$connector_name} отправить ревью pull request?
approval-question-github-create-blob = Разрешить {$connector_name} создать Git blob?
approval-question-github-create-branch = Разрешить {$connector_name} создать ветку?
approval-question-github-create-commit = Разрешить {$connector_name} создать коммит?
approval-question-github-create-pull-request = Разрешить {$connector_name} создать pull request?
approval-question-github-create-tree = Разрешить {$connector_name} создать Git tree?
approval-question-github-enable-auto-merge = Разрешить {$connector_name} включить автослияние pull request?
approval-question-github-label-pr = Разрешить {$connector_name} добавить метку к pull request?
approval-question-github-remove-reaction-from-issue-comment = Разрешить {$connector_name} удалить реакцию из комментария issue?
approval-question-github-remove-reaction-from-pr = Разрешить {$connector_name} удалить реакцию из pull request?
approval-question-github-remove-reaction-from-pr-review-comment = Разрешить {$connector_name} удалить реакцию из комментария ревью pull request?
approval-question-github-reply-to-review-comment = Разрешить {$connector_name} ответить на комментарий ревью pull request?
approval-question-github-update-issue-comment = Разрешить {$connector_name} обновить комментарий issue?
approval-question-github-update-ref = Разрешить {$connector_name} обновить ссылку на ветку?
approval-question-github-update-review-comment = Разрешить {$connector_name} обновить комментарий ревью pull request?
approval-question-gmail-apply-labels-to-emails = Разрешить {$connector_name} применить изменения меток к сообщениям?
approval-question-gmail-batch-modify-email = Разрешить {$connector_name} обновить метки сообщений?
approval-question-gmail-bulk-label-matching-emails = Разрешить {$connector_name} пометить подходящие сообщения?
approval-question-gmail-create-draft = Разрешить {$connector_name} создать черновик письма?
approval-question-gmail-create-label = Разрешить {$connector_name} создать метку?
approval-question-gmail-send-email = Разрешить {$connector_name} отправить письмо?
approval-question-google-calendar-create-event = Разрешить {$connector_name} создать событие?
approval-question-google-calendar-delete-event = Разрешить {$connector_name} удалить событие?
approval-question-google-calendar-respond-event = Разрешить {$connector_name} ответить на событие?
approval-question-google-calendar-update-event = Разрешить {$connector_name} обновить событие?
approval-question-google-docs-batch-update = Разрешить {$connector_name} применить обновления документа?
approval-question-google-docs-create-document = Разрешить {$connector_name} создать документ?
approval-question-google-drive-copy-document = Разрешить {$connector_name} скопировать файл?
approval-question-google-drive-share-document = Разрешить {$connector_name} изменить общий доступ к файлу?
approval-question-google-sheets-batch-update = Разрешить {$connector_name} применить обновления таблицы?
approval-question-google-sheets-create-spreadsheet = Разрешить {$connector_name} создать таблицу?
approval-question-google-sheets-duplicate-sheet-in-new-file = Разрешить {$connector_name} скопировать лист в новую таблицу?
approval-question-google-slides-batch-update = Разрешить {$connector_name} применить обновления презентации?
approval-question-google-slides-create-presentation = Разрешить {$connector_name} создать презентацию?
approval-question-linear-add-comment-to-issue = Разрешить {$connector_name} добавить комментарий к issue?
approval-question-linear-add-label-to-issue = Разрешить {$connector_name} добавить метку к issue?
approval-question-linear-add-url-attachment-to-issue = Разрешить {$connector_name} прикрепить ссылку к issue?
approval-question-linear-assign-issue = Разрешить {$connector_name} назначить issue?
approval-question-linear-create-issue = Разрешить {$connector_name} создать issue?
approval-question-linear-create-label = Разрешить {$connector_name} создать метку?
approval-question-linear-create-project = Разрешить {$connector_name} создать проект?
approval-question-linear-remove-label-from-issue = Разрешить {$connector_name} удалить метку из issue?
approval-question-linear-resolve-comment = Разрешить {$connector_name} разрешить комментарий?
approval-question-linear-set-issue-state = Разрешить {$connector_name} изменить состояние issue?
approval-question-linear-unassign-issue = Разрешить {$connector_name} снять назначение с issue?
approval-question-linear-update-issue = Разрешить {$connector_name} обновить issue?
approval-question-linear-update-project = Разрешить {$connector_name} обновить проект?
approval-question-slack-slack-create-canvas = Разрешить {$connector_name} создать canvas?
approval-question-slack-slack-schedule-message = Разрешить {$connector_name} запланировать сообщение?
approval-question-slack-slack-send-message = Разрешить {$connector_name} отправить сообщение?
approval-question-slack-slack-send-message-draft = Разрешить {$connector_name} создать черновик сообщения?

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = Прежде чем продолжить этот вызов инструмента, требуется дополнительное подтверждение.

View File

@@ -0,0 +1,114 @@
approval-header = 批准应用工具调用?
approval-option-allow = 允许
approval-option-allow-description = 运行该工具并继续。
approval-option-allow-session = 在此会话中允许
approval-option-allow-session-description = 运行该工具,并在此会话中记住这个选择。
approval-option-allow-remember = 允许,不再询问
approval-option-allow-remember-description = 运行该工具,并在未来的工具调用中记住这个选择。
approval-option-cancel = 取消
approval-option-cancel-description = 取消此次工具调用。
approval-fallback-question-connector = 允许 {$connector_name} 运行工具 "{$tool_name}" 吗?
approval-fallback-question-this-app = 允许此应用运行工具 "{$tool_name}" 吗?
approval-fallback-question-server = 允许 {$server} MCP 服务器运行工具 "{$tool_name}" 吗?
approval-monitor-question = 此工具调用需要你的批准。原因:{$reason}
approval-safety-cancelled = 该工具调用因安全风险已被取消。
approval-safety-cancelled-with-reason = 该工具调用因安全风险已被取消:{$reason}
approval-param-action = 操作
approval-param-attendees = 参与者
approval-param-base-branch = 目标分支
approval-param-body = 正文
approval-param-branch = 分支
approval-param-calendar = 日历
approval-param-changes = 更改
approval-param-comment = 评论
approval-param-comment-id = 评论 ID
approval-param-commit = 提交
approval-param-content = 内容
approval-param-conversation = 对话
approval-param-document = 文档
approval-param-event = 事件
approval-param-head-branch = 源分支
approval-param-issue = Issue
approval-param-label = 标签
approval-param-label-name = 标签名称
approval-param-message = 消息
approval-param-name = 名称
approval-param-new-file-name = 新文件名
approval-param-permission = 权限
approval-param-presentation = 演示文稿
approval-param-project = 项目
approval-param-pull-request = 拉取请求
approval-param-query = 查询
approval-param-reaction = 回应表情
approval-param-repository = 仓库
approval-param-response-status = 回复状态
approval-param-review = 审查
approval-param-send-at = 发送时间
approval-param-source-sheet-name = 源工作表名称
approval-param-spreadsheet = 电子表格
approval-param-start = 开始时间
approval-param-state = 状态
approval-param-subject = 主题
approval-param-team = 团队
approval-param-title = 标题
approval-param-to = 收件人
approval-param-timezone = 时区
approval-param-url = 链接
approval-param-user = 用户
approval-question-github-add-comment-to-issue = 允许 {$connector_name} 为拉取请求添加评论吗?
approval-question-github-add-reaction-to-issue-comment = 允许 {$connector_name} 为 issue 评论添加回应表情吗?
approval-question-github-add-reaction-to-pr = 允许 {$connector_name} 为拉取请求添加回应表情吗?
approval-question-github-add-reaction-to-pr-review-comment = 允许 {$connector_name} 为拉取请求审查评论添加回应表情吗?
approval-question-github-add-review-to-pr = 允许 {$connector_name} 提交拉取请求审查吗?
approval-question-github-create-blob = 允许 {$connector_name} 创建 Git blob 吗?
approval-question-github-create-branch = 允许 {$connector_name} 创建分支吗?
approval-question-github-create-commit = 允许 {$connector_name} 创建提交吗?
approval-question-github-create-pull-request = 允许 {$connector_name} 创建拉取请求吗?
approval-question-github-create-tree = 允许 {$connector_name} 创建 Git tree 吗?
approval-question-github-enable-auto-merge = 允许 {$connector_name} 启用拉取请求自动合并吗?
approval-question-github-label-pr = 允许 {$connector_name} 为拉取请求添加标签吗?
approval-question-github-remove-reaction-from-issue-comment = 允许 {$connector_name} 从 issue 评论中移除回应表情吗?
approval-question-github-remove-reaction-from-pr = 允许 {$connector_name} 从拉取请求中移除回应表情吗?
approval-question-github-remove-reaction-from-pr-review-comment = 允许 {$connector_name} 从拉取请求审查评论中移除回应表情吗?
approval-question-github-reply-to-review-comment = 允许 {$connector_name} 回复拉取请求审查评论吗?
approval-question-github-update-issue-comment = 允许 {$connector_name} 更新 issue 评论吗?
approval-question-github-update-ref = 允许 {$connector_name} 更新分支引用吗?
approval-question-github-update-review-comment = 允许 {$connector_name} 更新拉取请求审查评论吗?
approval-question-gmail-apply-labels-to-emails = 允许 {$connector_name} 对邮件应用标签更改吗?
approval-question-gmail-batch-modify-email = 允许 {$connector_name} 更新邮件标签吗?
approval-question-gmail-bulk-label-matching-emails = 允许 {$connector_name} 为匹配邮件添加标签吗?
approval-question-gmail-create-draft = 允许 {$connector_name} 创建邮件草稿吗?
approval-question-gmail-create-label = 允许 {$connector_name} 创建标签吗?
approval-question-gmail-send-email = 允许 {$connector_name} 发送邮件吗?
approval-question-google-calendar-create-event = 允许 {$connector_name} 创建事件吗?
approval-question-google-calendar-delete-event = 允许 {$connector_name} 删除事件吗?
approval-question-google-calendar-respond-event = 允许 {$connector_name} 回复事件吗?
approval-question-google-calendar-update-event = 允许 {$connector_name} 更新事件吗?
approval-question-google-docs-batch-update = 允许 {$connector_name} 应用文档更新吗?
approval-question-google-docs-create-document = 允许 {$connector_name} 创建文档吗?
approval-question-google-drive-copy-document = 允许 {$connector_name} 复制文件吗?
approval-question-google-drive-share-document = 允许 {$connector_name} 更改文件共享设置吗?
approval-question-google-sheets-batch-update = 允许 {$connector_name} 应用电子表格更新吗?
approval-question-google-sheets-create-spreadsheet = 允许 {$connector_name} 创建电子表格吗?
approval-question-google-sheets-duplicate-sheet-in-new-file = 允许 {$connector_name} 将工作表复制到新的电子表格吗?
approval-question-google-slides-batch-update = 允许 {$connector_name} 应用演示文稿更新吗?
approval-question-google-slides-create-presentation = 允许 {$connector_name} 创建演示文稿吗?
approval-question-linear-add-comment-to-issue = 允许 {$connector_name} 为 issue 添加评论吗?
approval-question-linear-add-label-to-issue = 允许 {$connector_name} 为 issue 添加标签吗?
approval-question-linear-add-url-attachment-to-issue = 允许 {$connector_name} 为 issue 附加链接吗?
approval-question-linear-assign-issue = 允许 {$connector_name} 分配 issue 吗?
approval-question-linear-create-issue = 允许 {$connector_name} 创建 issue 吗?
approval-question-linear-create-label = 允许 {$connector_name} 创建标签吗?
approval-question-linear-create-project = 允许 {$connector_name} 创建项目吗?
approval-question-linear-remove-label-from-issue = 允许 {$connector_name} 从 issue 中移除标签吗?
approval-question-linear-resolve-comment = 允许 {$connector_name} 解决评论吗?
approval-question-linear-set-issue-state = 允许 {$connector_name} 更改 issue 状态吗?
approval-question-linear-unassign-issue = 允许 {$connector_name} 取消分配 issue 吗?
approval-question-linear-update-issue = 允许 {$connector_name} 更新 issue 吗?
approval-question-linear-update-project = 允许 {$connector_name} 更新项目吗?
approval-question-slack-slack-create-canvas = 允许 {$connector_name} 创建画布吗?
approval-question-slack-slack-schedule-message = 允许 {$connector_name} 安排发送消息吗?
approval-question-slack-slack-send-message = 允许 {$connector_name} 发送消息吗?
approval-question-slack-slack-send-message-draft = 允许 {$connector_name} 创建消息草稿吗?

View File

@@ -0,0 +1 @@
arc-monitor-additional-confirmation = 继续此工具调用前需要额外确认。

View File

@@ -26,6 +26,19 @@ Codex can run a notification hook when the agent finishes a turn. See the config
When Codex knows which client started the turn, the legacy notify JSON payload also includes a top-level `client` field. The TUI reports `codex-tui`, and the app server reports the `clientInfo.name` value from `initialize`.
## Locale
Set top-level `locale` in `config.toml` to choose the preferred locale for
localized user-facing strings. For example:
```toml
locale = "zh"
```
Codex resolves locales to canonical locale codes, preferring specific locale
codes first, then generic language codes, and finally `en-US`. For example,
`zh-HK` falls back to `zh` when there is no `zh-HK` resource bundle.
## JSON Schema
The generated JSON Schema for `config.toml` lives at `codex-rs/core/config.schema.json`.