Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
10 changes: 8 additions & 2 deletions tests/unit/web-ui-behavior-parity.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,9 @@ test('captured bundled app skeleton only exposes expected data key drift versus
'showEditClaudeConfigKey',
'showEditProviderKey',
'toolConfigPermissionSaving',
'toolConfigPermissions'
'toolConfigPermissions',
'promptsHint',
'promptsSubTab'
] : [
'appVersion',
'appLatestVersion',
Expand Down Expand Up @@ -413,7 +415,9 @@ test('captured bundled app skeleton only exposes expected data key drift versus
'showAddClaudeConfigKey',
'showAddProviderKey',
'showEditClaudeConfigKey',
'showEditProviderKey'
'showEditProviderKey',
'promptsHint',
'promptsSubTab'
];
const allowedMissingCurrentKeys = [
'localProxyRunning',
Expand Down Expand Up @@ -579,6 +583,8 @@ test('captured bundled app skeleton only exposes expected data key drift versus
'resetTaskOrchestrationDraft',
'appendTaskWorkflowId',
'openClaudeMdEditor',
'switchPromptsSubTab',
'loadPromptsContent',
'saveNavState',
'isLocalBridgeExcluded',
'loadLocalBridgeExcluded',
Expand Down
17 changes: 16 additions & 1 deletion web-ui/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ document.addEventListener('DOMContentLoaded', () => {
showOpenclawConfigModal: false,
showConfigTemplateModal: false,
showAgentsModal: false,
promptsSubTab: 'codex',
promptsHint: '',
showSkillsModal: false,
showHealthCheckModal: false,
showCodexBridgePoolModal: false,
Expand Down Expand Up @@ -486,7 +488,7 @@ document.addEventListener('DOMContentLoaded', () => {
}
{
const NAV_STATE_STORAGE_KEY = 'codexmateNavState.v1';
const mainTabSet = new Set(['dashboard', 'config', 'sessions', 'usage', 'orchestration', 'market', 'plugins', 'docs', 'settings', 'trash']);
const mainTabSet = new Set(['dashboard', 'config', 'sessions', 'usage', 'orchestration', 'market', 'plugins', 'docs', 'settings', 'trash', 'prompts']);
let restored = null;
try {
const raw = localStorage.getItem(NAV_STATE_STORAGE_KEY) || '';
Expand Down Expand Up @@ -710,6 +712,19 @@ document.addEventListener('DOMContentLoaded', () => {
this.clearSessionTimelineRefs();
},

watch: {
mainTab(newTab) {
if (newTab === 'prompts' && typeof this.loadPromptsContent === 'function') {
this.loadPromptsContent();
}
},
promptsSubTab() {
if (this.mainTab === 'prompts' && typeof this.loadPromptsContent === 'function') {
this.loadPromptsContent();
}
}
},

computed: createAppComputed(),
methods: createAppMethods()
};
Expand Down
1 change: 1 addition & 0 deletions web-ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<!-- @include ./partials/index/panel-trash.html -->
<!-- @include ./partials/index/panel-market.html -->
<!-- @include ./partials/index/panel-plugins.html -->
<!-- @include ./partials/index/panel-prompts.html -->
<!-- @include ./partials/index/layout-footer.html -->
<!-- @include ./partials/index/modals-basic.html -->
<!-- @include ./partials/index/modal-webhook.html -->
Expand Down
3 changes: 3 additions & 0 deletions web-ui/modules/app.computed.main-tabs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export function createMainTabsComputed() {
if (this.mainTab === 'plugins') return this.t('kicker.plugins');
if (this.mainTab === 'docs') return this.t('kicker.docs');
if (this.mainTab === 'trash') return this.t('kicker.trash');
if (this.mainTab === 'prompts') return this.t('kicker.prompts');
return this.t('kicker.settings');
},
mainTabTitle() {
Expand All @@ -163,6 +164,7 @@ export function createMainTabsComputed() {
if (this.mainTab === 'plugins') return this.t('title.plugins');
if (this.mainTab === 'docs') return this.t('title.docs');
if (this.mainTab === 'trash') return this.t('settings.trash.title');
if (this.mainTab === 'prompts') return this.t('title.prompts');
return this.t('title.settings');
},
mainTabSubtitle() {
Expand All @@ -175,6 +177,7 @@ export function createMainTabsComputed() {
if (this.mainTab === 'plugins') return this.t('subtitle.plugins');
if (this.mainTab === 'docs') return this.t('subtitle.docs');
if (this.mainTab === 'trash') return this.t('settings.trash.meta');
if (this.mainTab === 'prompts') return this.t('subtitle.prompts');
return this.t('subtitle.settings');
},
taskOrchestrationSelectedRun() {
Expand Down
55 changes: 54 additions & 1 deletion web-ui/modules/app.methods.agents.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -640,12 +640,65 @@ export function createAgentsMethods(options = {}) {
? 'CLAUDE.md 已保存'
: (this.agentsContext === 'openclaw' ? 'OpenClaw AGENTS.md 已保存' : 'AGENTS.md 已保存'));
this.showMessage(successLabel, 'success');
this.closeAgentsModal({ force: true });
if (this.mainTab === 'prompts') {
this.loadPromptsContent();
} else {
this.closeAgentsModal({ force: true });
}
} catch (e) {
this.showMessage(this.t('toast.save.fail'), 'error');
} finally {
this.agentsSaving = false;
}
},

switchPromptsSubTab(subTab) {
const normalized = subTab === 'claude-md' ? 'claude-md' : 'codex';
if (this.promptsSubTab === normalized) {
this.loadPromptsContent();
return;
}
this.promptsSubTab = normalized;
},

async loadPromptsContent() {
const requestToken = issueLatestRequestToken(this, '_agentsOpenRequestToken');
this.agentsLoading = true;
this.resetAgentsDiffState();
try {
const isClaude = this.promptsSubTab === 'claude-md';
const action = isClaude ? 'get-claude-md-file' : 'get-agents-file';
const res = await api(action);
if (!isLatestRequestToken(this, '_agentsOpenRequestToken', requestToken)) {
return;
}
if (res.error) {
this.showMessage(res.error, 'error');
return;
}
this.agentsContent = res.content || '';
this.agentsOriginalContent = this.agentsContent;
this.agentsPath = res.path || '';
this.agentsExists = !!res.exists;
this.agentsLineEnding = res.lineEnding === '\r\n' ? '\r\n' : '\n';
this.agentsContext = isClaude ? 'claude-md' : 'codex';
const t = typeof this.t === 'function' ? this.t : null;
const tr = (key, fallback) => (t ? t(key) : fallback);
if (isClaude) {
this.promptsHint = tr('modal.agents.hint.claudeMd', '保存后会写入 ~/.claude/CLAUDE.md。');
} else {
this.promptsHint = tr('modal.agents.hint.default', '保存后会写入目标 AGENTS.md(与 config.toml 同级)。');
}
} catch (e) {
if (!isLatestRequestToken(this, '_agentsOpenRequestToken', requestToken)) {
return;
}
this.showMessage(this.t('toast.load.fail'), 'error');
} finally {
if (isLatestRequestToken(this, '_agentsOpenRequestToken', requestToken)) {
this.agentsLoading = false;
}
}
}
};
}
3 changes: 2 additions & 1 deletion web-ui/modules/app.methods.navigation.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
'plugins',
'docs',
'settings',
'trash'
'trash',
'prompts'
]);
const loadDoctorOverview = async (vm, options = {}) => {
if (!vm || typeof vm !== 'object') return false;
Expand Down
11 changes: 11 additions & 0 deletions web-ui/modules/i18n/locales/en.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,14 @@ const en = Object.freeze({
'tab.market': 'Skills',
'tab.plugins': 'Plugins',
'tab.settings': 'Settings',
'tab.prompts': 'Prompts',

// Side rail section titles
'side.overview': 'Overview',
'side.docs': 'Docs',
'side.config': 'Config',
'side.sessions': 'Sessions',
'side.prompts': 'Prompts',
'side.plugins': 'Plugins',
'side.system': 'System',
'side.orchestration': 'Tasks',
Expand Down Expand Up @@ -164,6 +166,10 @@ const en = Object.freeze({
'side.config.openclaw.meta': 'JSON5 / AGENTS',
'side.sessions.browser': 'Session Browser',
'side.sessions.browser.meta': 'Browse / Export / Cleanup',
'side.prompts.agents': 'AGENTS.md',
'side.prompts.agents.meta': 'Codex prompt file',
'side.prompts.claude': 'CLAUDE.md',
'side.prompts.claude.meta': 'Claude prompt file',
'side.plugins.tools': 'Prompt Tools',
'side.plugins.tools.meta': 'Templates / Variables',
'side.plugins.templatesCount': '{count} templates',
Expand All @@ -182,6 +188,7 @@ const en = Object.freeze({
'kicker.docs': 'Docs',
'kicker.trash': 'Trash',
'kicker.settings': 'Settings',
'kicker.prompts': 'Prompts',

'title.dashboard': 'Dashboard / Doctor',
'title.config': 'Local Configuration Console',
Expand All @@ -192,6 +199,7 @@ const en = Object.freeze({
'title.plugins': 'Plugins & Templates',
'title.docs': 'CLI Install & Docs',
'title.settings': 'System & Data Settings',
'title.prompts': 'Prompt Files Editor',

'subtitle.dashboard': 'Aggregate status and diagnostics.',
'subtitle.config': 'Manage local configs and models.',
Expand All @@ -202,6 +210,9 @@ const en = Object.freeze({
'subtitle.plugins': 'Manage reusable prompt templates and plugins.',
'subtitle.docs': 'CLI install commands and troubleshooting.',
'subtitle.settings': 'Manage downloads, directories, and trash.',
'subtitle.prompts': 'Edit AGENTS.md and CLAUDE.md.',
'prompts.subTab.codex': 'AGENTS.md (Codex)',
'prompts.subTab.claude': 'CLAUDE.md (Claude)',
'dashboard.doctor.title': 'Doctor',
'dashboard.doctor.runChecks': 'Run checks',
'dashboard.doctor.checking': 'Checking...',
Expand Down
11 changes: 11 additions & 0 deletions web-ui/modules/i18n/locales/ja.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,14 @@ const ja = Object.freeze({
'tab.market': 'Skills',
'tab.plugins': 'プラグイン',
'tab.settings': '設定',
'tab.prompts': 'Prompts',

// Side rail section titles
'side.overview': '概要',
'side.docs': 'ドキュメント',
'side.config': '設定',
'side.sessions': 'セッション',
'side.prompts': 'Prompts',
'side.plugins': 'プラグイン',
'side.system': 'システム',
'side.orchestration': 'タスク',
Expand Down Expand Up @@ -165,6 +167,10 @@ const ja = Object.freeze({
'side.config.openclaw.meta': 'JSON5 / AGENTS',
'side.sessions.browser': 'セッション閲覧',
'side.sessions.browser.meta': '閲覧 / エクスポート / クリーンアップ',
'side.prompts.agents': 'AGENTS.md',
'side.prompts.agents.meta': 'Codex プロンプトファイル',
'side.prompts.claude': 'CLAUDE.md',
'side.prompts.claude.meta': 'Claude プロンプトファイル',
'side.plugins.tools': 'プロンプトツール',
'side.plugins.tools.meta': 'テンプレート / 変数',
'side.plugins.templatesCount': '{count} 件のテンプレート',
Expand All @@ -183,6 +189,7 @@ const ja = Object.freeze({
'kicker.docs': 'Docs',
'kicker.trash': 'ゴミ箱',
'kicker.settings': 'Settings',
'kicker.prompts': 'Prompts',

'title.dashboard': 'Dashboard / Doctor',
'title.config': 'ローカル設定コンソール',
Expand All @@ -193,6 +200,7 @@ const ja = Object.freeze({
'title.plugins': 'プラグインとテンプレート',
'title.docs': 'CLI インストールとドキュメント',
'title.settings': 'システムとデータ設定',
'title.prompts': 'プロンプトファイルエディタ',

'subtitle.dashboard': '集約状態と診断エントリ。',
'subtitle.config': 'ローカル設定とモデルの管理。',
Expand All @@ -203,6 +211,9 @@ const ja = Object.freeze({
'subtitle.plugins': 'テンプレート化されたプロンプトと再利用可能なプラグインの管理。',
'subtitle.docs': 'CLI インストールコマンドとトラブルシューティング。',
'subtitle.settings': 'ダウンロード・ディレクトリ・ゴミ箱の管理。',
'subtitle.prompts': 'AGENTS.md と CLAUDE.md を編集。',
'prompts.subTab.codex': 'AGENTS.md (Codex)',
'prompts.subTab.claude': 'CLAUDE.md (Claude)',

'dashboard.doctor.title': 'Doctor',
'dashboard.doctor.runChecks': 'チェックを実行',
Expand Down
11 changes: 11 additions & 0 deletions web-ui/modules/i18n/locales/vi.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@ const vi = Object.freeze({
'tab.market': 'Skills',
'tab.plugins': 'Plugin',
'tab.settings': 'Cài đặt',
'tab.prompts': 'Prompts',

// Side rail section titles
'side.overview': 'Tổng quan',
'side.docs': 'Tài liệu',
'side.config': 'Cấu hình',
'side.sessions': 'Phiên',
'side.prompts': 'Prompts',
'side.plugins': 'Plugin',
'side.system': 'Hệ thống',
'side.orchestration': 'Tác vụ',
Expand Down Expand Up @@ -125,6 +127,10 @@ const vi = Object.freeze({
'side.config.openclaw.meta': 'JSON5 / AGENTS',
'side.sessions.browser': 'Trình duyệt phiên',
'side.sessions.browser.meta': 'Duyệt / Xuất / Dọn dẹp',
'side.prompts.agents': 'AGENTS.md',
'side.prompts.agents.meta': 'Tệp lệnh Codex',
'side.prompts.claude': 'CLAUDE.md',
'side.prompts.claude.meta': 'Tệp lệnh Claude',
'side.plugins.tools': 'Công cụ prompt',
'side.plugins.tools.meta': 'Mẫu / Biến',
'side.system.settings': 'Cài đặt runtime',
Expand Down Expand Up @@ -162,6 +168,7 @@ const vi = Object.freeze({
'kicker.plugins': 'Plugin',
'kicker.docs': 'Tài liệu',
'kicker.settings': 'Cài đặt',
'kicker.prompts': 'Prompts',
'kicker.trash': 'Thùng rác',

'title.dashboard': 'Dashboard / Doctor',
Expand All @@ -173,6 +180,7 @@ const vi = Object.freeze({
'title.plugins': 'Plugin & Mẫu',
'title.docs': 'Cài CLI & Tài liệu',
'title.settings': 'Hệ thống & Dữ liệu',
'title.prompts': 'Trình chỉnh sửa tệp lệnh',

'subtitle.dashboard': 'Tổng hợp trạng thái và chẩn đoán.',
'subtitle.config': 'Quản lý cấu hình và mô hình cục bộ.',
Expand All @@ -183,6 +191,9 @@ const vi = Object.freeze({
'subtitle.plugins': 'Quản lý plugin và mẫu tái sử dụng.',
'subtitle.docs': 'Lệnh cài CLI và hướng dẫn.',
'subtitle.settings': 'Quản lý tải xuống, thư mục và dữ liệu.',
'subtitle.prompts': 'Chỉnh sửa AGENTS.md và CLAUDE.md.',
'prompts.subTab.codex': 'AGENTS.md (Codex)',
'prompts.subTab.claude': 'CLAUDE.md (Claude)',


// Task orchestration readiness
Expand Down
11 changes: 11 additions & 0 deletions web-ui/modules/i18n/locales/zh.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,14 @@ const zh = Object.freeze({
'tab.market': 'Skills',
'tab.plugins': '插件',
'tab.settings': '设置',
'tab.prompts': 'Prompts',

// Side rail section titles
'side.overview': '概览',
'side.docs': '文档',
'side.config': '配置',
'side.sessions': '会话',
'side.prompts': 'Prompts',
'side.plugins': '插件',
'side.system': '系统',
'side.orchestration': '任务',
Expand Down Expand Up @@ -164,6 +166,10 @@ const zh = Object.freeze({
'side.config.openclaw.meta': 'JSON5 / AGENTS',
'side.sessions.browser': '会话浏览',
'side.sessions.browser.meta': '浏览 / 导出 / 清理',
'side.prompts.agents': 'AGENTS.md',
'side.prompts.agents.meta': 'Codex 指令文件',
'side.prompts.claude': 'CLAUDE.md',
'side.prompts.claude.meta': 'Claude 指令文件',
'side.plugins.tools': '提示词工具',
'side.plugins.tools.meta': '模板 / 变量',
'side.plugins.templatesCount': '{count} 个模板',
Expand All @@ -182,6 +188,7 @@ const zh = Object.freeze({
'kicker.docs': 'Docs',
'kicker.trash': '回收站',
'kicker.settings': 'Settings',
'kicker.prompts': 'Prompts',

'title.dashboard': 'Dashboard / Doctor',
'title.config': '本地配置控制台',
Expand All @@ -192,6 +199,7 @@ const zh = Object.freeze({
'title.plugins': '插件与模板',
'title.docs': 'CLI 安装与文档',
'title.settings': '系统与数据设置',
'title.prompts': '指令文件编辑器',

'subtitle.dashboard': '聚合状态与诊断入口。',
'subtitle.config': '管理本地配置与模型。',
Expand All @@ -202,6 +210,9 @@ const zh = Object.freeze({
'subtitle.plugins': '管理模板化 prompt 与可复用插件。',
'subtitle.docs': '查看 CLI 安装命令与排障。',
'subtitle.settings': '管理下载、目录与回收站。',
'subtitle.prompts': '编辑 AGENTS.md 与 CLAUDE.md。',
'prompts.subTab.codex': 'AGENTS.md (Codex)',
'prompts.subTab.claude': 'CLAUDE.md (Claude)',
'dashboard.doctor.title': 'Doctor',
'dashboard.doctor.runChecks': '运行检查',
'dashboard.doctor.checking': '检查中...',
Expand Down
Loading
Loading