Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
357 changes: 357 additions & 0 deletions Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -59583,6 +59583,244 @@
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Non-English locales marked as translated with untranslated text

Every locale other than en and ja for both settings.automation.claudeCode.notificationHook and its .subtitle key carries the English string but is flagged "state": "translated". Xcode's localization pipeline treats "translated" as production-ready and will surface these strings to users of those locales without any further warning. They should be "state": "needs_review" (or omitted entirely so the runtime falls back to the development language) until real translations are available. The same pattern is repeated in the search alias key settings.search.alias.setting.automation.claude-notification-hook.

}
},
"settings.automation.claudeCode.notificationHook": {
"extractionState": "manual",
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Claude Code Idle Notifications"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "Claude Codeアイドル通知"
}
},
"zh-Hans": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"zh-Hant": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"ko": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"de": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"es": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"fr": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"it": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"da": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"pl": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"ru": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"bs": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"ar": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"nb": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"pt-BR": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"th": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"tr": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
},
"uk": {
"stringUnit": {
"state": "new",
"value": "Claude Code Idle Notifications"
}
}
}
},
"settings.automation.claudeCode.notificationHook.subtitle": {
"extractionState": "manual",
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "Claude Codeが入力待ちのときに通知します。完了通知には影響しません。"
}
},
"zh-Hans": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"zh-Hant": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"ko": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"de": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"es": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"fr": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"it": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"da": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"pl": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"ru": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"bs": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"ar": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"nb": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"pt-BR": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"th": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"tr": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
},
"uk": {
"stringUnit": {
"state": "new",
"value": "Notify when Claude Code reports that it is waiting for input. Completion notifications are unaffected."
}
}
}
},
"settings.automation.claudeCode.subtitleOff": {
"extractionState": "manual",
"localizations": {
Expand Down Expand Up @@ -77615,6 +77853,125 @@
}
}
},
"settings.search.alias.setting.automation.claude-notification-hook": {
"extractionState": "manual",
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"ar": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"bs": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"da": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"de": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"es": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"fr": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"it": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"ko": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"nb": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"pl": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"pt-BR": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"ru": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"th": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"tr": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"zh-Hans": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"zh-Hant": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
},
"uk": {
"stringUnit": {
"state": "translated",
"value": "automation.claudeCodeNotificationHook claude code idle notification hook waiting input"
}
}
}
},
"settings.search.alias.setting.automation.claude-path": {
"extractionState": "manual",
"localizations": {
Expand Down
12 changes: 11 additions & 1 deletion Resources/bin/claude
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,17 @@ fi
# This is Claude Code's native blocking decision hook. It covers
# permissions, ExitPlanMode, and AskUserQuestion without using
# PreToolUse denial as a side channel.
HOOKS_JSON='{"preferredNotifChannel":"notifications_disabled","hooks":{"SessionStart":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-start","timeout":10}]}],"Stop":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude stop","timeout":10}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":10,"async":true}]}],"SessionEnd":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-end","timeout":1}]}],"Notification":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude notification","timeout":10}]}],"UserPromptSubmit":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude prompt-submit","timeout":10}]}],"PreToolUse":[{"matcher":"CronCreate","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude cron-create-guard","timeout":5}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude pre-tool-use","timeout":5,"async":true}]}],"PermissionRequest":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":125}]}]}}'
HOOKS_BASE='{"preferredNotifChannel":"notifications_disabled","hooks":{"SessionStart":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-start","timeout":10}]}],"Stop":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude stop","timeout":10}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":10,"async":true}]}],"SessionEnd":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude session-end","timeout":1}]}],'

HOOKS_NOTIFICATION='"Notification":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude notification","timeout":10}]}],'

HOOKS_TAIL='"UserPromptSubmit":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude prompt-submit","timeout":10}]}],"PreToolUse":[{"matcher":"CronCreate","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude cron-create-guard","timeout":5}]},{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks claude pre-tool-use","timeout":5,"async":true}]}],"PermissionRequest":[{"matcher":"","hooks":[{"type":"command","command":"\"${CMUX_CLAUDE_HOOK_CMUX_BIN:-cmux}\" hooks feed --source claude","timeout":125}]}]}}'

if [[ "$CMUX_CLAUDE_NOTIFICATION_HOOK_DISABLED" != "1" ]]; then
HOOKS_JSON="${HOOKS_BASE}${HOOKS_NOTIFICATION}${HOOKS_TAIL}"
else
HOOKS_JSON="${HOOKS_BASE}${HOOKS_TAIL}"
fi

if [[ "$SKIP_SESSION_ID" == true ]]; then
exec "$REAL_CLAUDE" --settings "$HOOKS_JSON" "$@"
Expand Down
1 change: 1 addition & 0 deletions Sources/CmuxSettingsJSONPathSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ extension CmuxSettingsFileStore {
"automation.socketPassword",
"automation.claudeCodeIntegration",
"automation.claudeBinaryPath",
"automation.claudeCodeNotificationHook",
"automation.cursorIntegration",
"automation.geminiIntegration",
"automation.portBase",
Expand Down
Loading