codexmate 0.0.56 → 0.0.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +680 -129
- package/lib/task-orchestrator.js +90 -21
- package/lib/task-workspace-chat.js +292 -0
- package/package.json +2 -2
- package/web-ui/app.js +55 -129
- package/web-ui/modules/app.computed.main-tabs.mjs +304 -7
- package/web-ui/modules/app.methods.agents.mjs +3 -0
- package/web-ui/modules/app.methods.claude-config.mjs +65 -25
- package/web-ui/modules/app.methods.navigation.mjs +67 -83
- package/web-ui/modules/app.methods.openclaw-editing.mjs +3 -6
- package/web-ui/modules/app.methods.session-actions.mjs +1 -12
- package/web-ui/modules/app.methods.session-browser.mjs +23 -54
- package/web-ui/modules/app.methods.session-trash.mjs +0 -1
- package/web-ui/modules/app.methods.startup-claude.mjs +16 -31
- package/web-ui/modules/app.methods.task-orchestration.mjs +347 -8
- package/web-ui/modules/app.methods.tool-config-permissions.mjs +0 -3
- package/web-ui/modules/app.methods.web-ui-preferences.mjs +415 -68
- package/web-ui/modules/config-template-confirm-pref.mjs +2 -3
- package/web-ui/modules/i18n/locales/en.mjs +146 -26
- package/web-ui/modules/i18n/locales/ja.mjs +143 -23
- package/web-ui/modules/i18n/locales/vi.mjs +145 -25
- package/web-ui/modules/i18n/locales/zh-tw.mjs +146 -26
- package/web-ui/modules/i18n/locales/zh.mjs +148 -28
- package/web-ui/modules/i18n.mjs +5 -12
- package/web-ui/modules/sessions-filters-url.mjs +1 -2
- package/web-ui/partials/index/layout-header.html +37 -14
- package/web-ui/partials/index/panel-orchestration.html +489 -282
- package/web-ui/res/web-ui-render.precompiled.js +1049 -610
- package/web-ui/styles/layout-shell.css +157 -1
- package/web-ui/styles/navigation-panels.css +11 -0
- package/web-ui/styles/task-orchestration.css +2161 -4
|
@@ -147,6 +147,8 @@ const zh = Object.freeze({
|
|
|
147
147
|
'side.system': '系统',
|
|
148
148
|
'side.orchestration': '任务',
|
|
149
149
|
'side.skills': 'Skills',
|
|
150
|
+
'side.collapse': '收起侧边栏',
|
|
151
|
+
'side.expand': '展开侧边栏',
|
|
150
152
|
|
|
151
153
|
// Side rail items
|
|
152
154
|
'side.overview.doctor': 'Doctor 面板',
|
|
@@ -202,7 +204,7 @@ const zh = Object.freeze({
|
|
|
202
204
|
'title.config': '本地配置控制台',
|
|
203
205
|
'title.sessions': '会话与导出',
|
|
204
206
|
'title.usage': '本地用量与趋势',
|
|
205
|
-
'title.orchestration': '
|
|
207
|
+
'title.orchestration': '任务线程',
|
|
206
208
|
'title.market': 'Skills 安装与同步',
|
|
207
209
|
'title.plugins': '插件与模板',
|
|
208
210
|
'title.docs': 'CLI 安装与文档',
|
|
@@ -213,7 +215,7 @@ const zh = Object.freeze({
|
|
|
213
215
|
'subtitle.config': '管理本地配置与模型。',
|
|
214
216
|
'subtitle.sessions': '浏览与导出会话。',
|
|
215
217
|
'subtitle.usage': '查看近 7 / 30 天用量。',
|
|
216
|
-
'subtitle.orchestration': '
|
|
218
|
+
'subtitle.orchestration': '像聊天一样整理任务,准备好后发送 /plan。',
|
|
217
219
|
'subtitle.market': '管理本地 Skills。',
|
|
218
220
|
'subtitle.plugins': '管理模板化 prompt 与可复用插件。',
|
|
219
221
|
'subtitle.docs': '查看 CLI 安装命令与排障。',
|
|
@@ -957,19 +959,105 @@ const zh = Object.freeze({
|
|
|
957
959
|
'usage.range.7d.short': '近 7 天',
|
|
958
960
|
'usage.range.30d.short': '近 30 天',
|
|
959
961
|
'orchestration.queueStats': '队列 {running} 运行中 · {queued} 等待中',
|
|
962
|
+
'orchestration.rebuilding.status': '暂停开放',
|
|
963
|
+
'orchestration.rebuilding.title': '重建中',
|
|
964
|
+
'orchestration.rebuilding.body': '任务编排入口暂时保留展示,但当前不可点击。',
|
|
960
965
|
'orchestration.hero.kicker': '任务编排',
|
|
961
|
-
'orchestration.hero.title': '
|
|
962
|
-
'orchestration.hero.subtitle': '
|
|
966
|
+
'orchestration.hero.title': '任务编排',
|
|
967
|
+
'orchestration.hero.subtitle': '规划、执行并追踪任务,保留工作区与线程上下文。',
|
|
968
|
+
'orchestration.quick.kicker': '任务输入',
|
|
969
|
+
'orchestration.quick.title': '输入任务目标',
|
|
970
|
+
'orchestration.quick.subtitle': '描述目标、约束和验收标准。执行前可用 /plan 预览计划。',
|
|
971
|
+
'orchestration.quick.caption': 'Enter 追加需求;/plan 预览计划;开始执行会生成计划并运行。',
|
|
972
|
+
'orchestration.quick.templates.reviewFix.meta': '处理 review 反馈并补回归验证。',
|
|
973
|
+
'orchestration.quick.templates.planOnly.meta': '先排查规划,不写入文件。',
|
|
974
|
+
'orchestration.quick.templates.workflowBatch.meta': '复用本地 Workflow 跑固定检查。',
|
|
975
|
+
'orchestration.chat.input.label': '任务消息',
|
|
976
|
+
'orchestration.chat.input.placeholder': '描述目标、约束和验收标准;输入 /plan 预览计划。',
|
|
977
|
+
'orchestration.chat.input.hint': '工作区、线程和运行模式可在高级设置中调整。',
|
|
978
|
+
'orchestration.chat.context.aria': '任务上下文',
|
|
979
|
+
'orchestration.chat.context.workspace.auto': '工作区自动推断',
|
|
980
|
+
'orchestration.chat.context.workspace.value': '工作区 {value}',
|
|
981
|
+
'orchestration.chat.context.thread.auto': '线程自动生成',
|
|
982
|
+
'orchestration.chat.context.thread.value': '线程 {value}',
|
|
983
|
+
'orchestration.chat.context.sequence.empty': '顺序:等待需求 1',
|
|
984
|
+
'orchestration.chat.context.sequence.value': '顺序:{count} 条需求',
|
|
985
|
+
'orchestration.privacy.workspace.selected': '已选择工作区',
|
|
986
|
+
'orchestration.privacy.thread.selected': '已选择线程',
|
|
987
|
+
'orchestration.chat.thread.aria': '任务对话',
|
|
988
|
+
'orchestration.chat.input.send': '追加需求',
|
|
989
|
+
'orchestration.chat.input.discuss': '预览计划',
|
|
990
|
+
'orchestration.chat.input.work': '开始执行',
|
|
991
|
+
'orchestration.chat.input.firstHint': '这会成为需求 1。',
|
|
992
|
+
'orchestration.chat.input.workHint': '执行前会先合并当前输入。',
|
|
993
|
+
'orchestration.chat.input.workCaption': 'Enter 追加需求;/plan 只预览;开始执行会规划并运行。',
|
|
994
|
+
'orchestration.chat.input.sequenceHint': '现在发送会成为需求 {count}。',
|
|
995
|
+
'orchestration.chat.assistant.contextLabel': '上一轮上下文',
|
|
996
|
+
'orchestration.chat.assistant.contextFallback': '已选中一个历史任务,继续时会继承它的线程和工作区。',
|
|
997
|
+
'orchestration.chat.assistant.resultLabel': '实现结果',
|
|
998
|
+
'orchestration.chat.assistant.filesSummary': '文件操作:{files}',
|
|
999
|
+
'orchestration.chat.assistant.readyLabel': 'Codexmate',
|
|
1000
|
+
'orchestration.chat.assistant.empty': '输入任务目标。多条需求会按顺序执行并保留上下文。',
|
|
1001
|
+
'orchestration.chat.assistant.planLabel': '计划预览',
|
|
1002
|
+
'orchestration.chat.assistant.planSummary': '计划已生成:{nodes} 个节点,{waves} 个批次。',
|
|
1003
|
+
'orchestration.chat.assistant.sequenceReady': '已收到多条需求;执行时会先完成需求 1,再带着上下文继续后续需求。',
|
|
1004
|
+
'orchestration.chat.assistant.singleReady': '已收到需求。可继续追加,或输入 /plan 预览计划。',
|
|
1005
|
+
'orchestration.chat.user.step': '需求 {count}',
|
|
1006
|
+
'orchestration.chat.meta.thread': '线程 {value}',
|
|
1007
|
+
'orchestration.chat.meta.workspace': '工作区 {value}',
|
|
1008
|
+
'orchestration.chat.meta.order': '顺序执行 · 保留上下文',
|
|
1009
|
+
'orchestration.chat.meta.first': '先完成这一条',
|
|
1010
|
+
'orchestration.chat.meta.afterPrevious': '等待前一条完成后继续',
|
|
1011
|
+
'orchestration.chat.meta.contextKept': '上下文会随线程保留',
|
|
1012
|
+
'orchestration.chat.meta.previewNext': '下一步:/plan 预览',
|
|
1013
|
+
'orchestration.quick.checklist.title': '执行检查',
|
|
1014
|
+
'orchestration.quick.checklist.subtitle': '只保留真正影响执行的阻塞项。',
|
|
1015
|
+
'orchestration.agent.aria': '任务编排状态',
|
|
1016
|
+
'orchestration.agent.kicker': '任务编排',
|
|
1017
|
+
'orchestration.agent.title': '任务编排控制台',
|
|
1018
|
+
'orchestration.agent.subtitle': '选择工作区与会话,执行任务,并查看运行详情。',
|
|
1019
|
+
'orchestration.agent.state.ready': 'Ready',
|
|
1020
|
+
'orchestration.agent.state.planning': 'Planning',
|
|
1021
|
+
'orchestration.agent.state.running': 'Running',
|
|
1022
|
+
'orchestration.agent.surface.workspace': 'Workspace',
|
|
1023
|
+
'orchestration.agent.surface.session': '上下文',
|
|
1024
|
+
'orchestration.agent.surface.mode': 'Mode',
|
|
1025
|
+
'orchestration.agent.surface.trace': 'Trace',
|
|
1026
|
+
'orchestration.agent.surface.runs': 'runs',
|
|
1027
|
+
'orchestration.agent.surface.queue': 'queued',
|
|
1028
|
+
'orchestration.agent.trace.title': 'Live trace',
|
|
1029
|
+
'orchestration.agent.trace.plan': 'Plan nodes',
|
|
1030
|
+
'orchestration.agent.trace.queue': 'Queue',
|
|
1031
|
+
'orchestration.agent.trace.runs': 'Runs',
|
|
1032
|
+
'orchestration.agent.trace.nodes': 'Run nodes',
|
|
1033
|
+
'orchestration.quick.status.title': '当前草稿',
|
|
1034
|
+
'orchestration.workspace.aria': '工作区与会话',
|
|
1035
|
+
'orchestration.workspace.title': '工作区',
|
|
1036
|
+
'orchestration.workspace.subtitle': '选择项目,再为该项目新建或恢复会话。',
|
|
1037
|
+
'orchestration.workspace.selector': '工作区选择',
|
|
1038
|
+
'orchestration.workspace.counts': '{runs} runs · {queue} queue',
|
|
1039
|
+
'orchestration.workspace.newSession': '+ 新建',
|
|
1040
|
+
'orchestration.workspace.sessions.title': '记录',
|
|
1041
|
+
'orchestration.workspace.sessions.empty.title': '暂无记录',
|
|
1042
|
+
'orchestration.workspace.sessions.empty.subtitle': '新建记录,或刷新后选择已有运行记录。',
|
|
1043
|
+
'orchestration.workspace.sessions.queueTitle': '排队项',
|
|
1044
|
+
'orchestration.workspace.sessions.runTitle': '运行记录',
|
|
1045
|
+
'orchestration.workspace.sessions.detailsHidden': '详情已隐藏',
|
|
1046
|
+
'orchestration.workspace.pathHidden': '路径已隐藏',
|
|
963
1047
|
'orchestration.draft.reset': '重置草稿',
|
|
964
1048
|
'orchestration.summary.aria': '任务编排概览',
|
|
965
1049
|
'orchestration.summary.running': '运行中',
|
|
966
1050
|
'orchestration.summary.queued': '排队中',
|
|
967
1051
|
'orchestration.summary.runs': '运行记录',
|
|
968
|
-
'orchestration.readiness.target.label': '
|
|
969
|
-
'orchestration.readiness.target.done': '
|
|
970
|
-
'orchestration.readiness.target.missing': '
|
|
1052
|
+
'orchestration.readiness.target.label': '任务目标',
|
|
1053
|
+
'orchestration.readiness.target.done': '已填写目标',
|
|
1054
|
+
'orchestration.readiness.target.missing': '未填写目标',
|
|
1055
|
+
'orchestration.readiness.sequence.label': '顺序',
|
|
1056
|
+
'orchestration.readiness.sequence.missing': '先发送需求 1',
|
|
1057
|
+
'orchestration.readiness.sequence.single': '当前只有需求 1;继续发送会变成需求 2。',
|
|
1058
|
+
'orchestration.readiness.sequence.multiple': '{count} 条需求会按顺序执行:先完成需求 1,再继续需求 2。',
|
|
971
1059
|
'orchestration.readiness.engine.label': '执行策略',
|
|
972
|
-
'orchestration.readiness.engine.
|
|
1060
|
+
'orchestration.readiness.engine.openaiChat': '使用 OpenAI Chat-compatible 节点',
|
|
973
1061
|
'orchestration.readiness.workflow.done': '已选 {count} 个 Workflow',
|
|
974
1062
|
'orchestration.readiness.workflow.missing': '还没选 Workflow ID',
|
|
975
1063
|
'orchestration.readiness.scope.label': '边界',
|
|
@@ -977,24 +1065,25 @@ const zh = Object.freeze({
|
|
|
977
1065
|
'orchestration.readiness.scope.writeHint': '建议补说明后再写入',
|
|
978
1066
|
'orchestration.readiness.scope.readonlyHint': '当前是只读,可直接试',
|
|
979
1067
|
'orchestration.readiness.preview.label': '预览',
|
|
980
|
-
'orchestration.readiness.preview.missing': '
|
|
1068
|
+
'orchestration.readiness.preview.missing': '还没发送 /plan',
|
|
981
1069
|
'orchestration.readiness.preview.blocked': '有 {count} 个阻塞项',
|
|
982
1070
|
'orchestration.readiness.preview.ready': '计划可用,{count} 个节点',
|
|
983
|
-
'orchestration.readiness.empty.title': '
|
|
984
|
-
'orchestration.readiness.empty.summary': '
|
|
1071
|
+
'orchestration.readiness.empty.title': '填写任务目标',
|
|
1072
|
+
'orchestration.readiness.empty.summary': '先明确目标、约束和验收标准。',
|
|
985
1073
|
'orchestration.readiness.workflow.title': '缺少 Workflow',
|
|
986
1074
|
'orchestration.readiness.workflow.summary': '你已经选了 Workflow 模式,但还没指定可复用流程。',
|
|
987
|
-
'orchestration.readiness.preview.title': '
|
|
988
|
-
'orchestration.readiness.preview.summary': '
|
|
1075
|
+
'orchestration.readiness.preview.title': '建议预览计划',
|
|
1076
|
+
'orchestration.readiness.preview.summary': '目标已填写。可用 /plan 确认节点和依赖。',
|
|
1077
|
+
'orchestration.readiness.preview.sequenceSummary': '草稿已成形,已锁定 {count} 条顺序需求:先完成需求 1,再继续需求 2。',
|
|
989
1078
|
'orchestration.readiness.blocked.title': '预览有阻塞',
|
|
990
1079
|
'orchestration.readiness.blocked.summary': '当前计划里还有 {count} 个阻塞项,先处理它们。',
|
|
991
1080
|
'orchestration.readiness.warn.title': '可以执行,但有提醒',
|
|
992
|
-
'orchestration.readiness.warn.summary': '
|
|
1081
|
+
'orchestration.readiness.warn.summary': '/plan 方案已生成,但还有 {count} 条提醒值得先看一眼。',
|
|
993
1082
|
'orchestration.readiness.dryRun.title': '适合先预演',
|
|
994
1083
|
'orchestration.readiness.dryRun.summary': '现在可以安全地跑一次仅预演,先看结果再决定是否真实执行。',
|
|
995
1084
|
'orchestration.readiness.ready.title': '可以执行',
|
|
996
|
-
'orchestration.readiness.ready.withFollowUps': '
|
|
997
|
-
'orchestration.readiness.ready.summary': '
|
|
1085
|
+
'orchestration.readiness.ready.withFollowUps': '已锁定 {count} 条顺序需求:先完成需求 1,再带上下文继续需求 2。',
|
|
1086
|
+
'orchestration.readiness.ready.summary': '目标清晰,可以执行或入队。',
|
|
998
1087
|
'orchestration.step1.title': '先把结果写清楚',
|
|
999
1088
|
'orchestration.step1.subtitle': '只写会影响执行的内容。',
|
|
1000
1089
|
'orchestration.templates.title': '快捷示例',
|
|
@@ -1009,14 +1098,15 @@ const zh = Object.freeze({
|
|
|
1009
1098
|
'orchestration.templates.workflowBatch.target': '用 Workflow 跑一组固定检查并整理结果',
|
|
1010
1099
|
'orchestration.templates.workflowBatch.workflowIds': 'diagnose-config\nsafe-provider-switch',
|
|
1011
1100
|
'orchestration.templates.workflowBatch.notes': '输出统一结论,避免重复描述',
|
|
1012
|
-
'orchestration.fields.target': '
|
|
1013
|
-
'orchestration.fields.target.placeholder': '例如:修复当前 PR review
|
|
1014
|
-
'orchestration.fields.target.hint': '
|
|
1015
|
-
'orchestration.engine.
|
|
1101
|
+
'orchestration.fields.target': '任务消息',
|
|
1102
|
+
'orchestration.fields.target.placeholder': '例如:修复当前 PR review 评论,补对应回归测试,并避免改无关模块',
|
|
1103
|
+
'orchestration.fields.target.hint': '像发消息一样写清结果、边界和验收标准就够了。',
|
|
1104
|
+
'orchestration.engine.openaiChat': 'OpenAI Chat',
|
|
1016
1105
|
'orchestration.engine.workflow': 'Workflow',
|
|
1017
1106
|
'orchestration.runMode.write': '写入',
|
|
1018
1107
|
'orchestration.runMode.readOnly': '只读',
|
|
1019
1108
|
'orchestration.runMode.dryRun': '仅预演',
|
|
1109
|
+
'orchestration.pills.sequenceCount': '顺序需求 {count}',
|
|
1020
1110
|
'orchestration.pills.hasTitle': '标题已设',
|
|
1021
1111
|
'orchestration.pills.workflowCount': 'Workflow {count}',
|
|
1022
1112
|
'orchestration.pills.planNodes': '计划 {count} 节点',
|
|
@@ -1025,11 +1115,18 @@ const zh = Object.freeze({
|
|
|
1025
1115
|
'orchestration.fields.engine': '引擎',
|
|
1026
1116
|
'orchestration.fields.runMode': '运行模式',
|
|
1027
1117
|
'orchestration.advanced.title': '高级设置',
|
|
1118
|
+
'orchestration.advanced.open': '设置',
|
|
1028
1119
|
'orchestration.fields.title': '标题',
|
|
1029
1120
|
'orchestration.fields.title.placeholder': '可选,默认从目标自动提取',
|
|
1030
1121
|
'orchestration.fields.notes': '说明',
|
|
1031
1122
|
'orchestration.fields.notes.placeholder': '例如:不要重写现有架构,只做增量实现',
|
|
1032
1123
|
'orchestration.fields.notes.hint': '补边界、禁区、风格要求或验证要求。',
|
|
1124
|
+
'orchestration.fields.workspacePath': '工作区路径',
|
|
1125
|
+
'orchestration.fields.workspacePath.placeholder': '例如:/home/me/project',
|
|
1126
|
+
'orchestration.fields.workspacePath.hint': '计划、执行和队列都会使用这个 cwd;留空则使用服务当前目录。',
|
|
1127
|
+
'orchestration.fields.threadId': '任务线程 ID',
|
|
1128
|
+
'orchestration.fields.threadId.placeholder': '可选;留空自动生成',
|
|
1129
|
+
'orchestration.fields.threadId.hint': '同一线程用于连续追加要求、重试和队列追踪。',
|
|
1033
1130
|
'orchestration.fields.followUps': '后续动作(每行一条)',
|
|
1034
1131
|
'orchestration.fields.followUps.placeholder': '例如:\n继续处理 review 评论\n最后补回归测试',
|
|
1035
1132
|
'orchestration.fields.concurrency': '并发',
|
|
@@ -1045,33 +1142,37 @@ const zh = Object.freeze({
|
|
|
1045
1142
|
'orchestration.actions.planning': '规划中...',
|
|
1046
1143
|
'orchestration.actions.previewOnly': '仅预览',
|
|
1047
1144
|
'orchestration.actions.preparing': '准备中...',
|
|
1048
|
-
'orchestration.actions.generatePlan': '
|
|
1049
|
-
'orchestration.actions.planAndRun': '
|
|
1145
|
+
'orchestration.actions.generatePlan': '发送 /plan',
|
|
1146
|
+
'orchestration.actions.planAndRun': '预览 /plan 并执行',
|
|
1050
1147
|
'orchestration.actions.processing': '处理中...',
|
|
1051
1148
|
'orchestration.actions.queueAndStart': '入队并开始',
|
|
1052
|
-
'orchestration.actions.caption': '
|
|
1053
|
-
'orchestration.stage.title': '
|
|
1054
|
-
'orchestration.stage.subtitle': '
|
|
1055
|
-
'orchestration.stage.pill.target': '
|
|
1149
|
+
'orchestration.actions.caption': '执行前会按需刷新计划;批量任务可入队运行。',
|
|
1150
|
+
'orchestration.stage.title': '任务阶段',
|
|
1151
|
+
'orchestration.stage.subtitle': '填写目标、预览计划,然后执行。',
|
|
1152
|
+
'orchestration.stage.pill.target': '写任务消息',
|
|
1056
1153
|
'orchestration.stage.pill.preview': '预览',
|
|
1057
1154
|
'orchestration.stage.pill.run': '执行或入队',
|
|
1058
1155
|
'orchestration.plan.title': '计划预览',
|
|
1059
|
-
'orchestration.plan.subtitle': '
|
|
1156
|
+
'orchestration.plan.subtitle': '确认节点、批次和依赖关系。',
|
|
1060
1157
|
'orchestration.plan.summary.nodes': '节点数',
|
|
1061
1158
|
'orchestration.plan.summary.waves': '波次',
|
|
1062
1159
|
'orchestration.plan.summary.engine': '引擎',
|
|
1160
|
+
'orchestration.plan.summary.threadId': '线程 ID',
|
|
1161
|
+
'orchestration.plan.summary.cwd': '工作区',
|
|
1063
1162
|
'orchestration.plan.node.write': 'write',
|
|
1064
1163
|
'orchestration.plan.node.readOnly': 'read-only',
|
|
1065
1164
|
'orchestration.labels.dependencies': '依赖:',
|
|
1066
1165
|
'orchestration.labels.error': '错误:',
|
|
1067
1166
|
'orchestration.workbench.title': '执行工作台',
|
|
1068
|
-
'orchestration.workbench.subtitle': '
|
|
1167
|
+
'orchestration.workbench.subtitle': '显示队列、运行记录和节点详情。',
|
|
1069
1168
|
'orchestration.queue.start': '开始队列',
|
|
1070
1169
|
'orchestration.queue.starting': '启动中...',
|
|
1071
1170
|
'orchestration.workbench.tabs.aria': '任务编排工作台视图',
|
|
1072
1171
|
'orchestration.workbench.tabs.queue': '队列 {count}',
|
|
1073
1172
|
'orchestration.workbench.tabs.runs': '运行记录 {count}',
|
|
1074
1173
|
'orchestration.workbench.tabs.detail': '运行详情',
|
|
1174
|
+
'orchestration.workbench.queueCount': '{count} 个排队中',
|
|
1175
|
+
'orchestration.workbench.ready': '就绪',
|
|
1075
1176
|
'orchestration.queue.empty.title': '当前没有排队任务',
|
|
1076
1177
|
'orchestration.queue.empty.subtitle': '批量任务可先入队,再启动队列。',
|
|
1077
1178
|
'orchestration.runs.empty.title': '还没有运行记录',
|
|
@@ -1079,13 +1180,32 @@ const zh = Object.freeze({
|
|
|
1079
1180
|
'orchestration.detail.refresh': '刷新详情',
|
|
1080
1181
|
'orchestration.detail.retry': '重试',
|
|
1081
1182
|
'orchestration.detail.retrying': '重试中...',
|
|
1183
|
+
'orchestration.detail.continueThread': '继续此线程',
|
|
1082
1184
|
'orchestration.detail.empty.title': '选择一条运行记录查看详情',
|
|
1083
1185
|
'orchestration.detail.empty.subtitle': '这里会显示节点状态、摘要和日志。',
|
|
1084
1186
|
'orchestration.detail.summary.status': '状态',
|
|
1085
1187
|
'orchestration.detail.summary.duration': '耗时',
|
|
1086
1188
|
'orchestration.detail.summary.nodes': '节点数',
|
|
1087
1189
|
'orchestration.detail.summary.summary': '摘要',
|
|
1190
|
+
'orchestration.detail.context.aria': '任务运行上下文',
|
|
1191
|
+
'orchestration.detail.context.run': 'Run ID',
|
|
1088
1192
|
'orchestration.detail.node.meta': '{id} · attempts {attempts} · auto-fix {autoFix}',
|
|
1193
|
+
'orchestration.openai.status.title': 'OpenAI Chat 运行配置',
|
|
1194
|
+
'orchestration.openai.status.subtitle': '任务节点使用当前 OpenClaw provider;执行前会检查 base URL、API key 和模型。',
|
|
1195
|
+
'orchestration.openai.status.provider': 'Provider',
|
|
1196
|
+
'orchestration.openai.status.model': '模型',
|
|
1197
|
+
'orchestration.openai.status.endpoint': 'Endpoint',
|
|
1198
|
+
'orchestration.openai.status.apiKey': 'API Key',
|
|
1199
|
+
'orchestration.openai.status.headers': '额外 headers',
|
|
1200
|
+
'orchestration.openai.status.configured': '已配置',
|
|
1201
|
+
'orchestration.openai.status.missing': '缺失',
|
|
1202
|
+
'orchestration.openai.status.notSet': '未设置',
|
|
1203
|
+
'orchestration.openai.status.notLoaded': '刷新后加载 OpenAI Chat 就绪状态。',
|
|
1204
|
+
'orchestration.openai.status.configure': '配置 OpenAI Chat',
|
|
1205
|
+
'orchestration.detail.node.output': 'AI 输出',
|
|
1206
|
+
'orchestration.detail.node.endpoint': 'Endpoint:',
|
|
1207
|
+
'orchestration.detail.node.materializedFiles': '物化文件:',
|
|
1208
|
+
'orchestration.detail.node.workspaceFiles': '工作区文件:',
|
|
1089
1209
|
'skills.localLabel': '{target} / 本地 Skills',
|
|
1090
1210
|
'skills.counts': '已装 {installed} · 可导入 {importable}',
|
|
1091
1211
|
|
package/web-ui/modules/i18n.mjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { DICT } from './i18n.dict.mjs';
|
|
2
2
|
|
|
3
|
-
const I18N_STORAGE_KEY = 'codexmateLang';
|
|
4
|
-
|
|
5
3
|
const LANGUAGE_META = Object.freeze([
|
|
6
4
|
Object.freeze({ code: 'zh', nativeName: '中文', englishName: 'Chinese', htmlLang: 'zh-CN', dir: 'ltr' }),
|
|
7
5
|
Object.freeze({ code: 'zh-tw', nativeName: '繁體中文', englishName: 'Chinese-TW', htmlLang: 'zh-TW', dir: 'ltr' }),
|
|
@@ -52,10 +50,7 @@ export function createI18nMethods() {
|
|
|
52
50
|
return {
|
|
53
51
|
normalizeLang,
|
|
54
52
|
initI18n() {
|
|
55
|
-
const
|
|
56
|
-
? localStorage.getItem(I18N_STORAGE_KEY)
|
|
57
|
-
: '';
|
|
58
|
-
const next = normalizeLang(saved);
|
|
53
|
+
const next = normalizeLang(this.lang);
|
|
59
54
|
this.lang = next;
|
|
60
55
|
applyDocumentLanguage(next);
|
|
61
56
|
},
|
|
@@ -90,15 +85,13 @@ export function createI18nMethods() {
|
|
|
90
85
|
}
|
|
91
86
|
});
|
|
92
87
|
},
|
|
93
|
-
setLang(nextLang) {
|
|
88
|
+
setLang(nextLang, options = {}) {
|
|
94
89
|
const next = normalizeLang(nextLang);
|
|
95
90
|
this.lang = next;
|
|
96
|
-
try {
|
|
97
|
-
if (typeof localStorage !== 'undefined') {
|
|
98
|
-
localStorage.setItem(I18N_STORAGE_KEY, next);
|
|
99
|
-
}
|
|
100
|
-
} catch (_) {}
|
|
101
91
|
applyDocumentLanguage(next);
|
|
92
|
+
if (!(options && options.persist === false) && typeof this.persistWebUiPreferences === 'function') {
|
|
93
|
+
this.persistWebUiPreferences({ language: next });
|
|
94
|
+
}
|
|
102
95
|
},
|
|
103
96
|
t(key, params = null) {
|
|
104
97
|
const lang = normalizeLang(this.lang);
|
|
@@ -63,16 +63,15 @@
|
|
|
63
63
|
:class="{ active: isMainTabNavActive('usage') }"
|
|
64
64
|
@pointerdown="onMainTabPointerDown('usage', $event)"
|
|
65
65
|
@click="onMainTabClick('usage', $event)">{{ t('tab.usage') }}</button>
|
|
66
|
-
<button v-if="taskOrchestrationTabEnabled" type="button" class="top-tab"
|
|
66
|
+
<button v-if="taskOrchestrationTabEnabled" type="button" class="top-tab top-tab-disabled"
|
|
67
67
|
id="tab-orchestration"
|
|
68
68
|
role="tab"
|
|
69
69
|
data-main-tab="orchestration"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
aria-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
@click="onMainTabClick('orchestration', $event)">{{ t('tab.orchestration') }}</button>
|
|
70
|
+
tabindex="-1"
|
|
71
|
+
aria-selected="false"
|
|
72
|
+
aria-disabled="true"
|
|
73
|
+
disabled
|
|
74
|
+
:title="t('orchestration.rebuilding.body')">{{ t('tab.orchestration') }}</button>
|
|
76
75
|
<button type="button" class="top-tab"
|
|
77
76
|
id="tab-market"
|
|
78
77
|
role="tab"
|
|
@@ -123,8 +122,17 @@
|
|
|
123
122
|
@click="openLanguageSettings">{{ t('settings.language.sideLabel', { language: currentLanguageLabel() }) }}</button>
|
|
124
123
|
</div>
|
|
125
124
|
|
|
126
|
-
<div :class="['app-shell', { standalone: sessionStandalone }]">
|
|
125
|
+
<div :class="['app-shell', { standalone: sessionStandalone, 'sidebar-collapsed': sidebarCollapsed }]">
|
|
127
126
|
<aside class="side-rail" v-if="!sessionStandalone">
|
|
127
|
+
<button
|
|
128
|
+
type="button"
|
|
129
|
+
class="side-rail-collapse-toggle"
|
|
130
|
+
:aria-pressed="sidebarCollapsed ? 'true' : 'false'"
|
|
131
|
+
:aria-label="sidebarCollapsed ? t('side.expand') : t('side.collapse')"
|
|
132
|
+
:title="sidebarCollapsed ? t('side.expand') : t('side.collapse')"
|
|
133
|
+
@click="toggleSidebarCollapsed">
|
|
134
|
+
<span aria-hidden="true">{{ sidebarCollapsed ? '›' : '‹' }}</span>
|
|
135
|
+
</button>
|
|
128
136
|
<div class="brand-block">
|
|
129
137
|
<div class="brand-head">
|
|
130
138
|
<img class="brand-logo" src="/res/logo-pack.webp" alt="Codex Mate logo">
|
|
@@ -156,6 +164,7 @@
|
|
|
156
164
|
:class="['side-item', { active: isMainTabNavActive('dashboard') }]"
|
|
157
165
|
@pointerdown="onMainTabPointerDown('dashboard', $event)"
|
|
158
166
|
@click="onMainTabClick('dashboard', $event)">
|
|
167
|
+
<span class="side-item-icon" aria-hidden="true">⌂</span>
|
|
159
168
|
<div class="side-item-title">{{ t('side.overview.doctor') }}</div>
|
|
160
169
|
<div class="side-item-meta">
|
|
161
170
|
<span>{{ t('side.overview.doctor.meta') }}</span>
|
|
@@ -172,6 +181,7 @@
|
|
|
172
181
|
:class="['side-item', { active: isMainTabNavActive('docs') }]"
|
|
173
182
|
@pointerdown="onMainTabPointerDown('docs', $event)"
|
|
174
183
|
@click="onMainTabClick('docs', $event)">
|
|
184
|
+
<span class="side-item-icon" aria-hidden="true">?</span>
|
|
175
185
|
<div class="side-item-title">{{ t('side.docs.cliInstall') }}</div>
|
|
176
186
|
<div class="side-item-meta">
|
|
177
187
|
<span>{{ t('side.docs.cliInstall.meta') }}</span>
|
|
@@ -189,6 +199,7 @@
|
|
|
189
199
|
:class="['side-item', { active: isConfigModeNavActive('codex') }]"
|
|
190
200
|
@pointerdown="onConfigTabPointerDown('codex', $event)"
|
|
191
201
|
@click="onConfigTabClick('codex', $event)">
|
|
202
|
+
<span class="side-item-icon" aria-hidden="true">C</span>
|
|
192
203
|
<div class="side-item-title">{{ t('side.config.codex') }}</div>
|
|
193
204
|
<div class="side-item-meta">
|
|
194
205
|
<span>{{ t('side.config.codex.meta') }}</span>
|
|
@@ -203,6 +214,7 @@
|
|
|
203
214
|
:class="['side-item', { active: isConfigModeNavActive('claude') }]"
|
|
204
215
|
@pointerdown="onConfigTabPointerDown('claude', $event)"
|
|
205
216
|
@click="onConfigTabClick('claude', $event)">
|
|
217
|
+
<span class="side-item-icon" aria-hidden="true">A</span>
|
|
206
218
|
<div class="side-item-title">{{ t('side.config.claude') }}</div>
|
|
207
219
|
<div class="side-item-meta">
|
|
208
220
|
<span>{{ t('side.config.claude.meta') }}</span>
|
|
@@ -217,6 +229,7 @@
|
|
|
217
229
|
:class="['side-item', { active: isConfigModeNavActive('openclaw') }]"
|
|
218
230
|
@pointerdown="onConfigTabPointerDown('openclaw', $event)"
|
|
219
231
|
@click="onConfigTabClick('openclaw', $event)">
|
|
232
|
+
<span class="side-item-icon" aria-hidden="true">O</span>
|
|
220
233
|
<div class="side-item-title">{{ t('side.config.openclaw') }}</div>
|
|
221
234
|
<div class="side-item-meta">
|
|
222
235
|
<span>{{ t('side.config.openclaw.meta') }}</span>
|
|
@@ -231,6 +244,7 @@
|
|
|
231
244
|
:class="['side-item', { active: isConfigModeNavActive('opencode') }]"
|
|
232
245
|
@pointerdown="onConfigTabPointerDown('opencode', $event)"
|
|
233
246
|
@click="onConfigTabClick('opencode', $event)">
|
|
247
|
+
<span class="side-item-icon" aria-hidden="true">N</span>
|
|
234
248
|
<div class="side-item-title">{{ t('side.config.opencode') }}</div>
|
|
235
249
|
<div class="side-item-meta">
|
|
236
250
|
<span>{{ t('side.config.opencode.meta') }}</span>
|
|
@@ -249,6 +263,7 @@
|
|
|
249
263
|
:class="['side-item', { active: isMainTabNavActive('prompts') && promptsSubTab === 'codex' }]"
|
|
250
264
|
@pointerdown="onMainTabPointerDown('prompts', $event)"
|
|
251
265
|
@click="switchPromptsSubTab('codex'); onMainTabClick('prompts')">
|
|
266
|
+
<span class="side-item-icon" aria-hidden="true">P</span>
|
|
252
267
|
<div class="side-item-title">{{ t('side.prompts.agents') }}</div>
|
|
253
268
|
<div class="side-item-meta">
|
|
254
269
|
<span>{{ t('side.prompts.agents.meta') }}</span>
|
|
@@ -262,6 +277,7 @@
|
|
|
262
277
|
:class="['side-item', { active: isMainTabNavActive('prompts') && promptsSubTab === 'claude-project' }]"
|
|
263
278
|
@pointerdown="onMainTabPointerDown('prompts', $event)"
|
|
264
279
|
@click="switchPromptsSubTab('claude-project'); onMainTabClick('prompts')">
|
|
280
|
+
<span class="side-item-icon" aria-hidden="true">M</span>
|
|
265
281
|
<div class="side-item-title">{{ t('side.prompts.claude') }}</div>
|
|
266
282
|
<div class="side-item-meta">
|
|
267
283
|
<span>{{ t('side.prompts.claude.meta') }}</span>
|
|
@@ -278,6 +294,7 @@
|
|
|
278
294
|
:class="['side-item', { active: isMainTabNavActive('sessions') }]"
|
|
279
295
|
@pointerdown="onMainTabPointerDown('sessions', $event)"
|
|
280
296
|
@click="onMainTabClick('sessions', $event)">
|
|
297
|
+
<span class="side-item-icon" aria-hidden="true">S</span>
|
|
281
298
|
<div class="side-item-title">{{ t('side.sessions.browser') }}</div>
|
|
282
299
|
<div class="side-item-meta">
|
|
283
300
|
<span>{{ t('side.sessions.browser.meta') }}</span>
|
|
@@ -291,6 +308,7 @@
|
|
|
291
308
|
:class="['side-item', { active: isMainTabNavActive('usage') }]"
|
|
292
309
|
@pointerdown="onMainTabPointerDown('usage', $event)"
|
|
293
310
|
@click="onMainTabClick('usage', $event)">
|
|
311
|
+
<span class="side-item-icon" aria-hidden="true">↗</span>
|
|
294
312
|
<div class="side-item-title">{{ t('tab.usage') }}</div>
|
|
295
313
|
<div class="side-item-meta">
|
|
296
314
|
<span>{{ t('side.usage.meta') }}</span>
|
|
@@ -304,14 +322,15 @@
|
|
|
304
322
|
<button
|
|
305
323
|
id="side-tab-orchestration"
|
|
306
324
|
data-main-tab="orchestration"
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
325
|
+
class="side-item side-item-disabled"
|
|
326
|
+
aria-disabled="true"
|
|
327
|
+
disabled
|
|
328
|
+
:title="t('orchestration.rebuilding.body')">
|
|
329
|
+
<span class="side-item-icon" aria-hidden="true">T</span>
|
|
311
330
|
<div class="side-item-title">{{ t('tab.orchestration') }}</div>
|
|
312
331
|
<div class="side-item-meta">
|
|
313
|
-
<span>{{ t('
|
|
314
|
-
<span>{{ t('orchestration.
|
|
332
|
+
<span>{{ t('orchestration.rebuilding.status') }}</span>
|
|
333
|
+
<span>{{ t('orchestration.rebuilding.title') }}</span>
|
|
315
334
|
</div>
|
|
316
335
|
</button>
|
|
317
336
|
</div>
|
|
@@ -325,6 +344,7 @@
|
|
|
325
344
|
:class="['side-item', { active: isMainTabNavActive('market') }]"
|
|
326
345
|
@pointerdown="onMainTabPointerDown('market', $event)"
|
|
327
346
|
@click="onMainTabClick('market', $event)">
|
|
347
|
+
<span class="side-item-icon" aria-hidden="true">★</span>
|
|
328
348
|
<div class="side-item-title">{{ t('tab.market') }}</div>
|
|
329
349
|
<div class="side-item-meta">
|
|
330
350
|
<span>{{ t('skills.localLabel', { target: skillsTargetLabel }) }}</span>
|
|
@@ -342,6 +362,7 @@
|
|
|
342
362
|
:class="['side-item', { active: isMainTabNavActive('plugins') }]"
|
|
343
363
|
@pointerdown="onMainTabPointerDown('plugins', $event)"
|
|
344
364
|
@click="onMainTabClick('plugins', $event)">
|
|
365
|
+
<span class="side-item-icon" aria-hidden="true">◇</span>
|
|
345
366
|
<div class="side-item-title">{{ t('side.plugins.tools') }}</div>
|
|
346
367
|
<div class="side-item-meta">
|
|
347
368
|
<span>{{ t('side.plugins.tools.meta') }}</span>
|
|
@@ -359,6 +380,7 @@
|
|
|
359
380
|
:class="['side-item', { active: isMainTabNavActive('settings') }]"
|
|
360
381
|
@pointerdown="onMainTabPointerDown('settings', $event)"
|
|
361
382
|
@click="onMainTabClick('settings', $event)">
|
|
383
|
+
<span class="side-item-icon" aria-hidden="true">⚙</span>
|
|
362
384
|
<div class="side-item-title">{{ t('side.system.settings') }}</div>
|
|
363
385
|
<div class="side-item-meta">
|
|
364
386
|
<span>{{ t('side.system.settings.meta') }}</span>
|
|
@@ -371,6 +393,7 @@
|
|
|
371
393
|
:class="['side-item', { active: isMainTabNavActive('trash') }]"
|
|
372
394
|
@pointerdown="onMainTabPointerDown('trash', $event)"
|
|
373
395
|
@click="onMainTabClick('trash', $event)">
|
|
396
|
+
<span class="side-item-icon" aria-hidden="true">⌫</span>
|
|
374
397
|
<div class="side-item-title">{{ t('settings.trash.title') }}</div>
|
|
375
398
|
<div class="side-item-meta">
|
|
376
399
|
<span>{{ t('settings.trash.meta') }}</span>
|