+
{t('common.save')}
+ {!boxAvailable && (
+
+
+
+ )}
+
{
if (!detailId && !isCreateView) {
@@ -54,11 +57,16 @@ export default function SkillsPage() {
{t('common.cancel')}
-
+
{t('common.save')}
+ {!boxAvailable && (
+
+
+
+ )}
(null);
+ const [loading, setLoading] = useState(true);
+
+ const refresh = useCallback(async () => {
+ try {
+ const data = await httpClient.getBoxStatus();
+ setStatus(data);
+ } catch {
+ // Keep last-known status; the dashboard polls separately so a
+ // transient failure here should not blank the UI for sandbox
+ // consumers.
+ } finally {
+ setLoading(false);
+ }
+ }, []);
+
+ useEffect(() => {
+ void refresh();
+ const id = setInterval(() => void refresh(), refreshMs);
+ return () => clearInterval(id);
+ }, [refresh, refreshMs]);
+
+ const available = status?.available === true;
+ const disabled = status?.available === false && status?.enabled === false;
+ const hint: 'boxDisabled' | 'boxUnavailable' | null = available
+ ? null
+ : disabled
+ ? 'boxDisabled'
+ : status
+ ? 'boxUnavailable'
+ : null;
+
+ return { status, loading, available, disabled, hint, refresh };
+}
diff --git a/web/src/i18n/locales/en-US.ts b/web/src/i18n/locales/en-US.ts
index 530218db..50e0f2ae 100644
--- a/web/src/i18n/locales/en-US.ts
+++ b/web/src/i18n/locales/en-US.ts
@@ -1303,6 +1303,12 @@ const enUS = {
disabled: 'Disabled',
statusDetail: 'Status',
pluginDisabled: 'Plugin system is disabled',
+ boxDisabled:
+ 'Box sandbox is disabled in config — sandbox tools, skill add/edit, and stdio MCP are unavailable',
+ boxUnavailable:
+ 'Box sandbox is unavailable — sandbox tools, skill add/edit, and stdio MCP are unavailable',
+ boxRequiredHint:
+ 'This feature requires the Box runtime. Enable it in config (box.enabled = true) and ensure the runtime is healthy.',
boxBackend: 'Backend',
boxProfile: 'Profile',
boxSandboxes: 'Sandboxes',
diff --git a/web/src/i18n/locales/es-ES.ts b/web/src/i18n/locales/es-ES.ts
index 9034f461..318b9e7a 100644
--- a/web/src/i18n/locales/es-ES.ts
+++ b/web/src/i18n/locales/es-ES.ts
@@ -1336,6 +1336,12 @@ const esES = {
disabled: 'Desactivado',
statusDetail: 'Estado',
pluginDisabled: 'El sistema de plugins está desactivado',
+ boxDisabled:
+ 'El sandbox de Box está desactivado en la configuración — herramientas de sandbox, alta/edición de skills y MCP stdio no están disponibles',
+ boxUnavailable:
+ 'El sandbox de Box no está disponible — herramientas de sandbox, alta/edición de skills y MCP stdio no están disponibles',
+ boxRequiredHint:
+ 'Esta función requiere el runtime de Box. Actívelo en la configuración (box.enabled = true) y asegúrese de que el runtime está conectado.',
boxBackend: 'Backend',
boxProfile: 'Perfil',
boxSandboxes: 'Sandboxes',
diff --git a/web/src/i18n/locales/ja-JP.ts b/web/src/i18n/locales/ja-JP.ts
index d9e5c974..44db911a 100644
--- a/web/src/i18n/locales/ja-JP.ts
+++ b/web/src/i18n/locales/ja-JP.ts
@@ -1308,6 +1308,12 @@ const jaJP = {
disabled: '無効',
statusDetail: 'ステータス',
pluginDisabled: 'プラグインシステムが無効です',
+ boxDisabled:
+ 'Box サンドボックスは設定で無効化されています — サンドボックスツール / スキルの追加・編集 / stdio MCP は利用できません',
+ boxUnavailable:
+ 'Box サンドボックスは利用できません — サンドボックスツール / スキルの追加・編集 / stdio MCP は利用できません',
+ boxRequiredHint:
+ 'この機能には Box ランタイムが必要です。設定で有効化(box.enabled = true)し、ランタイムが正常に接続できることを確認してください。',
boxBackend: 'バックエンド',
boxProfile: 'プロファイル',
boxSandboxes: 'サンドボックス',
diff --git a/web/src/i18n/locales/ru-RU.ts b/web/src/i18n/locales/ru-RU.ts
index 69ece0d3..8ea61770 100644
--- a/web/src/i18n/locales/ru-RU.ts
+++ b/web/src/i18n/locales/ru-RU.ts
@@ -1311,6 +1311,12 @@ const ruRU = {
disabled: 'Отключено',
statusDetail: 'Статус',
pluginDisabled: 'Система плагинов отключена',
+ boxDisabled:
+ 'Песочница Box отключена в конфигурации — инструменты песочницы, добавление/редактирование навыков и stdio MCP недоступны',
+ boxUnavailable:
+ 'Песочница Box недоступна — инструменты песочницы, добавление/редактирование навыков и stdio MCP недоступны',
+ boxRequiredHint:
+ 'Для этой функции требуется среда Box. Включите её в конфигурации (box.enabled = true) и убедитесь, что соединение работает.',
boxBackend: 'Бэкенд',
boxProfile: 'Профиль',
boxSandboxes: 'Песочницы',
diff --git a/web/src/i18n/locales/th-TH.ts b/web/src/i18n/locales/th-TH.ts
index 4e760e7c..48f924f2 100644
--- a/web/src/i18n/locales/th-TH.ts
+++ b/web/src/i18n/locales/th-TH.ts
@@ -1282,6 +1282,12 @@ const thTH = {
disabled: 'ปิดใช้งาน',
statusDetail: 'สถานะ',
pluginDisabled: 'ระบบปลั๊กอินถูกปิดใช้งาน',
+ boxDisabled:
+ 'Sandbox Box ถูกปิดใช้งานในการตั้งค่า — เครื่องมือ sandbox, การเพิ่ม/แก้ไข skill และ stdio MCP ใช้งานไม่ได้',
+ boxUnavailable:
+ 'Sandbox Box ไม่พร้อมใช้งาน — เครื่องมือ sandbox, การเพิ่ม/แก้ไข skill และ stdio MCP ใช้งานไม่ได้',
+ boxRequiredHint:
+ 'ฟีเจอร์นี้ต้องใช้ Box runtime กรุณาเปิดใช้งานในการตั้งค่า (box.enabled = true) และตรวจสอบว่าการเชื่อมต่อปกติ',
boxBackend: 'แบ็กเอนด์',
boxProfile: 'โปรไฟล์',
boxSandboxes: 'แซนด์บ็อกซ์',
diff --git a/web/src/i18n/locales/vi-VN.ts b/web/src/i18n/locales/vi-VN.ts
index b01010cb..19fba640 100644
--- a/web/src/i18n/locales/vi-VN.ts
+++ b/web/src/i18n/locales/vi-VN.ts
@@ -1305,6 +1305,12 @@ const viVN = {
disabled: 'Đã tắt',
statusDetail: 'Trạng thái',
pluginDisabled: 'Hệ thống plugin đã tắt',
+ boxDisabled:
+ 'Sandbox Box đã tắt trong cấu hình — công cụ sandbox, thêm/chỉnh sửa skill và stdio MCP đều không khả dụng',
+ boxUnavailable:
+ 'Sandbox Box không khả dụng — công cụ sandbox, thêm/chỉnh sửa skill và stdio MCP đều không khả dụng',
+ boxRequiredHint:
+ 'Tính năng này cần Box runtime. Hãy bật trong cấu hình (box.enabled = true) và đảm bảo runtime đang hoạt động.',
boxBackend: 'Backend',
boxProfile: 'Hồ sơ',
boxSandboxes: 'Sandbox',
diff --git a/web/src/i18n/locales/zh-Hans.ts b/web/src/i18n/locales/zh-Hans.ts
index cb2b5ae2..203108df 100644
--- a/web/src/i18n/locales/zh-Hans.ts
+++ b/web/src/i18n/locales/zh-Hans.ts
@@ -1249,6 +1249,12 @@ const zhHans = {
disabled: '已禁用',
statusDetail: '状态',
pluginDisabled: '插件系统已禁用',
+ boxDisabled:
+ 'Box 沙箱已在配置中禁用——沙箱工具、技能添加/编辑与 stdio MCP 均不可用',
+ boxUnavailable:
+ 'Box 沙箱不可用——沙箱工具、技能添加/编辑与 stdio MCP 均不可用',
+ boxRequiredHint:
+ '此功能依赖 Box 运行时。请在配置中启用(box.enabled = true)并确认运行时连接正常。',
boxBackend: '后端',
boxProfile: '配置',
boxSandboxes: '沙箱数',
diff --git a/web/src/i18n/locales/zh-Hant.ts b/web/src/i18n/locales/zh-Hant.ts
index 45175829..6a3f2223 100644
--- a/web/src/i18n/locales/zh-Hant.ts
+++ b/web/src/i18n/locales/zh-Hant.ts
@@ -1248,6 +1248,12 @@ const zhHant = {
disabled: '已停用',
statusDetail: '狀態',
pluginDisabled: '外掛系統已停用',
+ boxDisabled:
+ 'Box 沙箱已在設定中停用——沙箱工具、技能新增/編輯與 stdio MCP 均無法使用',
+ boxUnavailable:
+ 'Box 沙箱無法使用——沙箱工具、技能新增/編輯與 stdio MCP 均無法使用',
+ boxRequiredHint:
+ '此功能需要 Box 執行時。請在設定中啟用(box.enabled = true)並確認執行時連線正常。',
boxBackend: '後端',
boxProfile: '設定檔',
boxSandboxes: '沙箱數',