@zq-silk/yui 2.16.0 → 2.18.0
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/dist/cli/commandCatalog.js +19 -12
- package/dist/cli/interactionCandidates.js +20 -5
- package/dist/cli/interactionPolicy.js +5 -4
- package/dist/cli/roleWizard.js +7 -0
- package/dist/commands/controllerCommands.js +13 -4
- package/dist/commands/durableJobCommands.js +50 -3
- package/dist/commands/globalRoleCommands.js +31 -14
- package/dist/commands/inboxCommands.js +1 -0
- package/dist/commands/operatorCommands.js +12 -2
- package/dist/commands/profileCommands.js +19 -2
- package/dist/commands/roleConfiguration.js +3 -0
- package/dist/commands/taskCommands.js +16 -0
- package/dist/commands/taskRoleRuntimeStatus.js +3 -0
- package/dist/controlPlaneCli.js +21 -4
- package/dist/controller/agentJobControl.js +9 -1
- package/dist/controller/clientRuntime.js +34 -13
- package/dist/controller/controller.js +35 -22
- package/dist/controller/diagnosticJournal.js +214 -0
- package/dist/controller/fileSchedulerStoreAdapter.js +174 -105
- package/dist/controller/globalInputDelivery.js +19 -9
- package/dist/controller/globalRuntimeAttention.js +11 -3
- package/dist/controller/jobControl.js +1 -1
- package/dist/controller/jobDefinitionControl.js +24 -13
- package/dist/controller/jobSupervisor.js +4 -0
- package/dist/controller/providerRetryAdmission.js +9 -0
- package/dist/controller/providerRetryDelivery.js +16 -0
- package/dist/controller/runtime.js +80 -4
- package/dist/controller/runtimeLaunchCoordinator.js +3 -1
- package/dist/controller/workerSchedulerStore.js +24 -0
- package/dist/core/boundedRpc.js +4 -0
- package/dist/core/controllerServer.js +1 -1
- package/dist/core/controllerTelemetry.js +92 -19
- package/dist/executor/fileRoleLaunchPlanner.js +3 -0
- package/dist/job/globalShell.js +51 -0
- package/dist/job/jobBusinessResult.js +4 -3
- package/dist/job/jobDefinition.js +6 -1
- package/dist/job/jobRunner.js +9 -0
- package/dist/job/scheduleService.js +2 -0
- package/dist/message/globalInboxRecovery.js +30 -19
- package/dist/message/globalProviderRetry.js +7 -1
- package/dist/message/messageContinuation.js +4 -0
- package/dist/output/rolePresentation.js +3 -0
- package/dist/profile/agentProfile.js +8 -0
- package/dist/profile/agentProfileRuntime.js +16 -1
- package/dist/review/reviewDecision.js +6 -0
- package/dist/role/availability.js +28 -0
- package/dist/role/role.js +6 -0
- package/dist/runtime/builtinAgentErrorMappers.js +4 -0
- package/dist/runtime/codexNativeAccess.js +21 -4
- package/dist/runtime/globalSessionHealth.js +39 -0
- package/dist/runtime/tmuxAdapters.js +5 -0
- package/dist/scheduler/activeRoleRunDelivery.js +9 -0
- package/dist/scheduler/leaderWakeupProcessor.js +8 -1
- package/dist/scheduler/roleRunLiveness.js +3 -0
- package/dist/scheduler/roleRunStall.js +10 -10
- package/dist/storage/persistenceWorker.js +41 -19
- package/dist/storage/sqliteSchema.js +43 -9
- package/dist/storage/sqliteStore.js +86 -8
- package/dist/storage/storageVersions.js +1 -1
- package/dist/storage/storeRpc.js +25 -11
- package/dist/storage/taskReadRevisionSchema.js +39 -0
- package/dist/web/assets/client/app/catalog.js +0 -29
- package/dist/web/assets/client/app/jobs.js +115 -0
- package/dist/web/assets/client/app/main.js +32 -28
- package/dist/web/assets/client/app/manage.js +1 -0
- package/dist/web/assets/client/app/settings.js +1 -5
- package/dist/web/assets/client/app/taskView.js +7 -11
- package/dist/web/assets/client/i18n/en.js +265 -36
- package/dist/web/assets/client/i18n/zh-CN.js +264 -35
- package/dist/web/assets/client/index.js +4 -0
- package/dist/web/assets/client/layout/manageShell.js +61 -15
- package/dist/web/assets/client/layout/router.js +2 -1
- package/dist/web/assets/client/layout/shortcuts.js +2 -2
- package/dist/web/assets/client/layout/workspace.js +99 -112
- package/dist/web/assets/client/lib/prefs.js +1 -1
- package/dist/web/assets/client/ui/primitives.js +15 -2
- package/dist/web/assets/client/views/dock/conversation.js +421 -123
- package/dist/web/assets/client/views/dock/session.js +229 -0
- package/dist/web/assets/client/views/dock/terminal.js +48 -39
- package/dist/web/assets/client/views/jobs.js +1042 -160
- package/dist/web/assets/client/views/overview.js +2 -2
- package/dist/web/assets/client/views/sidebar.js +3 -0
- package/dist/web/assets/client/views/task/page.js +2 -12
- package/dist/web/assets/shared/manageNav.js +3 -1
- package/dist/web/assets/shell/appRail.js +2 -1
- package/dist/web/assets/shell/dock.js +9 -27
- package/dist/web/assets/shell/manage.js +7 -2
- package/dist/web/assets/shell/models.js +4 -3
- package/dist/web/assets/shell/settingsContent.js +0 -3
- package/dist/web/assets/shell/sidebar.js +0 -1
- package/dist/web/assets/styles/views/conversation.js +96 -17
- package/dist/web/assets/styles/views/dock.js +17 -5
- package/dist/web/assets/styles/views/jobs.js +301 -12
- package/dist/web/assets/styles/views/sidebar.js +1 -2
- package/dist/web/assets/styles/views/task.js +1 -2
- package/dist/web/assets/styles/views/terminal.js +12 -8
- package/dist/web/webConversation.js +1 -0
- package/dist/web/webServer.js +28 -1
- package/dist/web/webSettings.js +10 -2
- package/docs/global-shell-jobs.md +78 -0
- package/docs/job-runs.md +6 -3
- package/docs/managed-turn-and-session-runtime.md +84 -0
- package/docs/managed-turn-and-session-runtime.zh-CN.md +57 -0
- package/docs/release-workflow.md +67 -0
- package/docs/release-workflow.zh-CN.md +48 -0
- package/docs/roles-and-configuration.md +45 -1
- package/docs/roles-and-configuration.zh-CN.md +35 -0
- package/docs/storage-baseline.md +19 -1
- package/docs/storage-baseline.zh-CN.md +10 -1
- package/docs/testing/review-evaluation.md +35 -1
- package/docs/testing/review-evaluation.zh-CN.md +25 -1
- package/docs/testing/verification-levels.md +2 -2
- package/docs/testing/verification-levels.zh-CN.md +2 -2
- package/package.json +1 -1
- package/skills/yui-leader/VERSION +1 -1
- package/skills/yui-leader/references/execution.md +19 -8
- package/skills/yui-reviewer/SKILL.md +13 -2
- package/skills/yui-reviewer/VERSION +1 -1
|
@@ -48,7 +48,6 @@ export const ZH_CN = {
|
|
|
48
48
|
"permissions.empty": "没有匹配的模板。",
|
|
49
49
|
"permissions.retry": "重新读取",
|
|
50
50
|
"tabs.jobs": "Job",
|
|
51
|
-
"settings.section.jobs": "Job 与时间计划",
|
|
52
51
|
"jobs.builtinSync": "内置 Project 同步 · 仅安全快进",
|
|
53
52
|
"jobs.automatic": "自动同步偏好",
|
|
54
53
|
"jobs.syncEvery": "同步间隔(毫秒,最少 60000)",
|
|
@@ -60,14 +59,52 @@ export const ZH_CN = {
|
|
|
60
59
|
"jobs.executor": "执行方式",
|
|
61
60
|
"jobs.executionTask": "打开执行 Task",
|
|
62
61
|
"jobs.sourceJob": "创建来源 Job / Run",
|
|
63
|
-
"jobs
|
|
64
|
-
"jobs.
|
|
65
|
-
"jobs.
|
|
66
|
-
"jobs.
|
|
67
|
-
"jobs.
|
|
68
|
-
"jobs.
|
|
69
|
-
"jobs.
|
|
70
|
-
"jobs.
|
|
62
|
+
"nav.jobs": "Job",
|
|
63
|
+
"jobs.scopeLabel": "归属",
|
|
64
|
+
"jobs.scopeHelp": "全局,或某个拥有 Job 的 Task。计数、搜索与列表只描述这一范围。",
|
|
65
|
+
"jobs.scopesError": "归属列表不可用:",
|
|
66
|
+
"jobs.search": "搜索 Job",
|
|
67
|
+
"jobs.count": "{total} 个 Job",
|
|
68
|
+
"jobs.countFiltered": "{shown} / {total} 个 Job",
|
|
69
|
+
"jobs.noMatch": "此范围内没有匹配搜索的 Job。",
|
|
70
|
+
"jobs.noSchedule": "无计划",
|
|
71
|
+
"jobs.noRunsShort": "无 Run",
|
|
72
|
+
"jobs.nextShort": "下次",
|
|
73
|
+
"jobs.plan": "计划",
|
|
74
|
+
"jobs.definition": "定义",
|
|
75
|
+
"jobs.execution": "执行",
|
|
76
|
+
"jobs.runVsPlan": "Run 状态只描述一次执行,不会开启或关闭计划。",
|
|
77
|
+
"jobs.type": "类型",
|
|
78
|
+
"jobs.type.projectSync": "Project 同步",
|
|
79
|
+
"jobs.kind.shell": "Shell 命令",
|
|
80
|
+
"jobs.form.scripts": "脚本文件",
|
|
81
|
+
"jobs.form.scriptPath": "相对路径",
|
|
82
|
+
"jobs.form.scriptContent": "脚本内容",
|
|
83
|
+
"jobs.form.addScript": "添加脚本",
|
|
84
|
+
"jobs.form.stepOptions": "超时与环境变量",
|
|
85
|
+
"jobs.form.shellHome": "命令与脚本由此 Job 管理,每次运行使用独立目录中的版本快照。可用 sh scripts/run.sh 调用脚本。命令以本机用户权限执行,不是安全沙箱;保存不会立即执行。",
|
|
86
|
+
"jobs.kind.task": "Task 委派",
|
|
87
|
+
"jobs.kind.agent": "Agent 运行",
|
|
88
|
+
"jobs.kind.builtin": "内置动作",
|
|
89
|
+
"jobs.kind.process": "进程",
|
|
90
|
+
"jobs.ownerGlobal": "全局",
|
|
91
|
+
"jobs.ownerTask": "Task",
|
|
92
|
+
"jobs.openInJobs": "在 Job 中打开",
|
|
93
|
+
"jobs.moved": "Job 已从设置移到独立入口,此链接现在在这里打开。",
|
|
94
|
+
"catalog.sourceJob": "Job",
|
|
95
|
+
"catalog.sourceRemoved": "已移除任务分类筛选:列表显示全部任务,Job 有独立入口。",
|
|
96
|
+
"schedule.enabled": "开启",
|
|
97
|
+
"schedule.disabled": "关闭",
|
|
98
|
+
"schedule.completed": "已完成",
|
|
99
|
+
"schedule.needs-attention": "需要处理",
|
|
100
|
+
"schedule.retired": "已停用",
|
|
101
|
+
"admission.admitted": "已接纳",
|
|
102
|
+
"admission.overlap": "跳过(重叠)",
|
|
103
|
+
"admission.blocked": "被阻止",
|
|
104
|
+
"trigger.manual": "手动",
|
|
105
|
+
"trigger.schedule": "计划",
|
|
106
|
+
"trigger.retry": "重试",
|
|
107
|
+
"jobs.recentSuccess": "最近成功",
|
|
71
108
|
"jobs.diagnostics": "执行诊断",
|
|
72
109
|
"jobs.artifacts": "已登记固定产物",
|
|
73
110
|
"jobs.registeredOnly": "仅可读取已登记的准确归属、Run、commit、路径及摘要。引用图片也须独立登记。",
|
|
@@ -86,7 +123,9 @@ export const ZH_CN = {
|
|
|
86
123
|
"jobs.project": "目标 Project",
|
|
87
124
|
"jobs.name": "名称",
|
|
88
125
|
"jobs.action": "受控操作",
|
|
89
|
-
"jobs.newJob": "
|
|
126
|
+
"jobs.newJob": "新建 Job",
|
|
127
|
+
"jobs.newJobIn": "新 Job 将归属于",
|
|
128
|
+
"jobs.ownerShort": "归属",
|
|
90
129
|
"jobs.editJob": "编辑 Job",
|
|
91
130
|
"jobs.runNow": "立即运行",
|
|
92
131
|
"jobs.newSchedule": "创建时间计划",
|
|
@@ -94,10 +133,11 @@ export const ZH_CN = {
|
|
|
94
133
|
"jobs.cancelRun": "取消本次 Run",
|
|
95
134
|
"jobs.disable": "停用后续计划",
|
|
96
135
|
"jobs.enable": "启用时间计划",
|
|
97
|
-
"jobs.refresh": "
|
|
136
|
+
"jobs.refresh": "刷新",
|
|
98
137
|
"jobs.save": "保存",
|
|
99
138
|
"jobs.close": "关闭编辑",
|
|
100
139
|
"jobs.discard": "放弃当前未保存的草稿?",
|
|
140
|
+
"jobs.leaveBusy": "仍有提交在进行中;收到回执前保留当前视图。",
|
|
101
141
|
"jobs.loading": "正在读取权威状态…",
|
|
102
142
|
"jobs.submitting": "提交中…",
|
|
103
143
|
"jobs.saved": "已保存;不代表已执行或执行成功。",
|
|
@@ -108,16 +148,84 @@ export const ZH_CN = {
|
|
|
108
148
|
"jobs.unknown": "提交结果未知,不会重发。请先检查当前事实和原操作,再决定后续动作。",
|
|
109
149
|
"jobs.empty": "此范围暂无 Job。创建定义不会立即执行。",
|
|
110
150
|
"jobs.configuration": "执行配置",
|
|
111
|
-
"jobs.taskConfig": "
|
|
112
|
-
"jobs.
|
|
151
|
+
"jobs.taskConfig": "保存仅更新配置,不会立即执行。请勿填写密码或密钥;运行时仍需满足对应权限与工作区要求。",
|
|
152
|
+
"jobs.saveAsNew": "另存为新 Job",
|
|
153
|
+
"jobs.kindCopyHelp": "你选择了不同的执行方式。保存将创建新的 Job;原 Job、执行历史和时间计划保持不变,不会复制或启动计划。",
|
|
154
|
+
"jobs.rebind": "保存 Project 刷新 Job 会绑定当前目录中的目标,但不会立即执行刷新。",
|
|
113
155
|
"jobs.rule": "时间规则",
|
|
114
156
|
"jobs.instant": "执行时间/周期锚点(带 UTC 偏移的 ISO 时间)",
|
|
115
157
|
"jobs.every": "周期间隔(毫秒,至少 1000)",
|
|
116
158
|
"jobs.cron": "Cron 表达式(五字段)",
|
|
117
159
|
"jobs.timezone": "时区",
|
|
118
|
-
"jobs.scheduleHelp": "
|
|
160
|
+
"jobs.scheduleHelp": "新计划保存后启用;编辑已有计划不会改变启停状态。",
|
|
161
|
+
"jobs.form.customCron": "自定义 Cron",
|
|
162
|
+
"jobs.form.cron": "重复执行",
|
|
163
|
+
"jobs.form.interval": "固定间隔",
|
|
164
|
+
"jobs.form.once": "仅执行一次",
|
|
165
|
+
"jobs.form.daily": "每天",
|
|
166
|
+
"jobs.form.weekly": "每周",
|
|
167
|
+
"jobs.form.monthly": "每月",
|
|
168
|
+
"jobs.form.advanced": "高级详情",
|
|
169
|
+
"jobs.form.frequency": "重复频率",
|
|
170
|
+
"jobs.form.time": "执行时间",
|
|
171
|
+
"jobs.form.time24": "执行时间 · 24 小时制",
|
|
172
|
+
"jobs.form.quickTime": "常用时间",
|
|
173
|
+
"jobs.form.cronRequired": "输入 Cron 表达式,或返回选择执行频率。",
|
|
174
|
+
"jobs.form.cronSymbols": "* 表示任意值,, 分隔多个值,- 表示范围,/ 表示步长。例如 0 9 * * 1-5:每周一至周五 09:00。保存时由服务端校验。",
|
|
175
|
+
"jobs.form.cron.minute": "分钟",
|
|
176
|
+
"jobs.form.cron.hour": "小时",
|
|
177
|
+
"jobs.form.cron.date": "日期",
|
|
178
|
+
"jobs.form.cron.month": "月份",
|
|
179
|
+
"jobs.form.cron.weekday": "星期",
|
|
180
|
+
"jobs.form.cron.minuteRange": "0–59",
|
|
181
|
+
"jobs.form.cron.hourRange": "0–23",
|
|
182
|
+
"jobs.form.cron.dateRange": "1–31",
|
|
183
|
+
"jobs.form.cron.monthRange": "1–12",
|
|
184
|
+
"jobs.form.cron.weekdayRange": "0–7,0/7 为周日",
|
|
185
|
+
"jobs.form.day": "每月几号",
|
|
186
|
+
"jobs.form.weekdays": "执行星期",
|
|
187
|
+
"jobs.form.monthHelp": "选择 29–31 日时,没有该日期的月份不会执行。",
|
|
188
|
+
"jobs.form.complexHelp": "自定义五字段 Cron。保存时由服务端校验;复杂规则保持原样,不自动转换。",
|
|
189
|
+
"jobs.form.replaceComplex": "此表达式不能无损转换为常见频率。改用可视化表单将替换当前规则,是否继续?",
|
|
190
|
+
"jobs.form.zonePreserved": "时间按此计划保存的时区执行,编辑不会改变时区。",
|
|
191
|
+
"jobs.form.forJob": "执行 Job",
|
|
192
|
+
"jobs.form.internalId": "内部标识",
|
|
193
|
+
"jobs.form.idHelp": "用于链接和关联记录,系统自动生成,通常无需修改。",
|
|
194
|
+
"jobs.form.paused": "已暂停后续执行,已有执行历史不受影响。",
|
|
195
|
+
"jobs.form.cronTime": "请选择有效的执行时间。",
|
|
196
|
+
"jobs.form.cronDays": "请至少选择一天。",
|
|
197
|
+
"jobs.form.cronDay": "日期应为 1–31 的整数。",
|
|
198
|
+
"jobs.form.monthRule": "每月 {day} 日 {time}",
|
|
199
|
+
"jobs.form.command": "命令",
|
|
200
|
+
"jobs.form.remove": "移除",
|
|
201
|
+
"jobs.form.addStep": "添加步骤",
|
|
202
|
+
"jobs.form.addEnv": "添加环境变量",
|
|
203
|
+
"jobs.form.envName": "变量名",
|
|
204
|
+
"jobs.form.envValue": "变量值",
|
|
205
|
+
"jobs.form.timeout": "超时(毫秒,可选)",
|
|
206
|
+
"jobs.form.target": "执行目标",
|
|
207
|
+
"jobs.form.goal": "完成目标",
|
|
208
|
+
"jobs.form.delivery": "完成交付",
|
|
209
|
+
"jobs.form.task-created": "创建任务",
|
|
210
|
+
"jobs.form.work-item": "已有工作项",
|
|
211
|
+
"jobs.form.new": "新建任务",
|
|
212
|
+
"jobs.form.operator": "全局 Operator",
|
|
213
|
+
"jobs.form.task": "任务角色",
|
|
214
|
+
"jobs.form.job": "独立 Agent",
|
|
215
|
+
"jobs.form.serial": "串行",
|
|
216
|
+
"jobs.form.isolated": "隔离执行",
|
|
217
|
+
"jobs.form.concurrency": "执行策略",
|
|
218
|
+
"jobs.form.addBinding": "添加 Project",
|
|
219
|
+
"jobs.form.directory": "目录",
|
|
220
|
+
"jobs.form.baseRef": "基准分支",
|
|
221
|
+
"jobs.form.unchanged": "未展示字段会原样保留。",
|
|
222
|
+
"jobs.form.duplicateEnv": "环境变量名不能为空或重复。",
|
|
223
|
+
"jobs.form.positiveInteger": "请输入正整数。",
|
|
224
|
+
"jobs.form.needStep": "请至少添加一个执行步骤。",
|
|
225
|
+
"jobs.form.argvHelp": "此步骤直接执行以下参数,不通过 Shell;命令字段仅作说明。",
|
|
226
|
+
"jobs.form.addArgument": "添加参数",
|
|
119
227
|
"jobs.state": "状态",
|
|
120
|
-
"jobs.recentRun": "
|
|
228
|
+
"jobs.recentRun": "最近 Run",
|
|
121
229
|
"jobs.refreshAttempt": "Project 最近尝试",
|
|
122
230
|
"jobs.refreshSuccess": "Project 最近成功刷新",
|
|
123
231
|
"jobs.onceCompleted": "一次性计划已准入;completed 不代表其 Run 已成功。",
|
|
@@ -128,7 +236,7 @@ export const ZH_CN = {
|
|
|
128
236
|
"jobs.lastAttempt": "最近准入尝试",
|
|
129
237
|
"jobs.lastSuccess": "最近成功的计划 Run",
|
|
130
238
|
"jobs.refreshFacts": "Project 刷新:最近尝试/最近成功",
|
|
131
|
-
"jobs.history": "执行历史
|
|
239
|
+
"jobs.history": "执行历史",
|
|
132
240
|
"jobs.noRuns": "尚无执行记录。",
|
|
133
241
|
"jobs.inspectRun": "查看此次尝试的 Run",
|
|
134
242
|
"jobs.trigger": "触发来源",
|
|
@@ -138,6 +246,83 @@ export const ZH_CN = {
|
|
|
138
246
|
"jobs.logs": "步骤日志",
|
|
139
247
|
"jobs.truncated": "末尾 64 KiB",
|
|
140
248
|
"jobs.noLogs": "暂无已写入检查点的步骤日志;这不代表成功。",
|
|
249
|
+
"jobs.copy": "复制",
|
|
250
|
+
"jobs.copied": "已复制",
|
|
251
|
+
"jobs.copyManual": "请手动复制:",
|
|
252
|
+
"jobs.copyJson": "复制 JSON",
|
|
253
|
+
"jobs.copyCommand": "复制命令",
|
|
254
|
+
"jobs.jsonInvalid": "配置不是有效的 JSON:",
|
|
255
|
+
"jobs.preview": "保存后显示为",
|
|
256
|
+
"jobs.basics": "基本信息",
|
|
257
|
+
"jobs.runDetail": "Run 详情",
|
|
258
|
+
"jobs.closeRun": "关闭 Run 详情",
|
|
259
|
+
"jobs.started": "开始时间",
|
|
260
|
+
"jobs.updated": "更新时间",
|
|
261
|
+
"jobs.duration": "耗时",
|
|
262
|
+
"jobs.exit": "退出",
|
|
263
|
+
"jobs.failedStep": "失败步骤",
|
|
264
|
+
"jobs.retryOf": "重试自",
|
|
265
|
+
"jobs.steps": "步骤",
|
|
266
|
+
"jobs.overview": "执行概况",
|
|
267
|
+
"jobs.successRate": "成功率",
|
|
268
|
+
"jobs.avgDuration": "平均耗时",
|
|
269
|
+
"jobs.sparkLabel": "最近 {count} 次 Run,{ok} 次成功",
|
|
270
|
+
"jobs.runCount": "共 {count} 次",
|
|
271
|
+
"jobs.showMore": "再显示 {count} 条",
|
|
272
|
+
"jobs.filterRuns": "按状态筛选 Run",
|
|
273
|
+
"jobs.filter.all": "全部",
|
|
274
|
+
"jobs.filter.active": "进行中",
|
|
275
|
+
"jobs.col.status": "状态",
|
|
276
|
+
"jobs.col.run": "Run",
|
|
277
|
+
"jobs.col.started": "开始",
|
|
278
|
+
"jobs.lastAttemptShort": "最近尝试",
|
|
279
|
+
"jobs.lastSuccessShort": "最近成功",
|
|
280
|
+
"jobs.ruleDaily": "每天 {time}",
|
|
281
|
+
"jobs.ruleWeekly": "每周 {days} {time}",
|
|
282
|
+
"jobs.ruleEvery": "每 {period}",
|
|
283
|
+
"jobs.ruleOnce": "一次 · {at}",
|
|
284
|
+
"jobs.ruleAnchor": "起点",
|
|
285
|
+
"jobs.cfg.input": "输入参数",
|
|
286
|
+
"jobs.cfg.workspace": "工作区",
|
|
287
|
+
"jobs.cfg.head": "HEAD",
|
|
288
|
+
"jobs.cfg.owner": "执行归属",
|
|
289
|
+
"jobs.cfg.ownerTask": "本 Task",
|
|
290
|
+
"jobs.cfg.env": "环境变量",
|
|
291
|
+
"jobs.cfg.noEnv": "无",
|
|
292
|
+
"jobs.cfg.goal": "目标",
|
|
293
|
+
"jobs.cfg.target": "执行目标",
|
|
294
|
+
"jobs.cfg.concurrency": "并发",
|
|
295
|
+
"jobs.cfg.agentInput": "Agent 指令",
|
|
296
|
+
"jobs.cfg.other": "其他字段",
|
|
297
|
+
"jobs.cfg.raw": "准确配置",
|
|
298
|
+
"jobs.cfg.noParams": "无参数",
|
|
299
|
+
"jobs.cfg.emptyList": "空列表",
|
|
300
|
+
"jobs.cfg.emptyText": "空",
|
|
301
|
+
"jobs.cfg.fields": "{count} 个字段",
|
|
302
|
+
"jobs.cfg.value": "值",
|
|
303
|
+
"jobs.cfg.timeout": "超时",
|
|
304
|
+
"jobs.cfg.cwd": "目录",
|
|
305
|
+
"jobs.cfg.unnamed": "未命名",
|
|
306
|
+
"jobs.cfg.description": "描述",
|
|
307
|
+
"jobs.cfg.bindings": "Project 绑定",
|
|
308
|
+
"jobs.cfg.task": "Task",
|
|
309
|
+
"jobs.cfg.workItem": "WorkItem",
|
|
310
|
+
"jobs.cfg.role": "角色",
|
|
311
|
+
"jobs.cfg.agent": "Agent",
|
|
312
|
+
"jobs.cfg.ownerRun": "所属 Run",
|
|
313
|
+
"jobs.cfg.attempt": "集成尝试",
|
|
314
|
+
"jobs.action.system.noop": "空操作检查",
|
|
315
|
+
"jobs.action.project.refresh": "Project 刷新",
|
|
316
|
+
"jobs.goal.delivery": "在新 Task 中交付",
|
|
317
|
+
"jobs.goal.task-created": "创建 Task",
|
|
318
|
+
"jobs.goal.work-item": "执行 WorkItem",
|
|
319
|
+
"jobs.target.new": "新 Task",
|
|
320
|
+
"jobs.target.work-item": "已有 WorkItem",
|
|
321
|
+
"jobs.target.operator": "Operator",
|
|
322
|
+
"jobs.target.task": "Task 角色",
|
|
323
|
+
"jobs.target.job": "Job 自有 Agent",
|
|
324
|
+
"jobs.concurrency.serial": "串行",
|
|
325
|
+
"jobs.concurrency.isolated": "隔离",
|
|
141
326
|
"models.subscriptionAuth": "官方订阅",
|
|
142
327
|
"models.account": "账号",
|
|
143
328
|
"models.providerReadOnlyHelp": "由来源服务管理,请在对应服务中修改配置。",
|
|
@@ -146,7 +331,7 @@ export const ZH_CN = {
|
|
|
146
331
|
"models.window.weekly": "每周",
|
|
147
332
|
"models.window.monthly": "每月",
|
|
148
333
|
"manage.nav": "主导航",
|
|
149
|
-
"manage.workbench": "
|
|
334
|
+
"manage.workbench": "任务",
|
|
150
335
|
"manage.sections": "分区",
|
|
151
336
|
"manage.collapseSections": "收起分区列表",
|
|
152
337
|
"manage.showSections": "展开分区列表",
|
|
@@ -857,10 +1042,7 @@ export const ZH_CN = {
|
|
|
857
1042
|
"store.job": "操作",
|
|
858
1043
|
"dock.label": "会话面板",
|
|
859
1044
|
"dock.discussion": "讨论",
|
|
860
|
-
"dock.session": "终端",
|
|
861
1045
|
"conversation.title": "会话",
|
|
862
|
-
"conversation.defaultMode": "默认展示",
|
|
863
|
-
"conversation.defaultSaved": "已保存为此浏览器今后打开时的默认展示;当前视图和 Session 未切换。",
|
|
864
1046
|
"conversation.nativeRequest": "Codex 原生请求",
|
|
865
1047
|
"conversation.nativeOmitted": "更多或较大的原生请求请在终端处理。",
|
|
866
1048
|
"conversation.leaderQuestions": "Leader 问题 · Task 输入通道",
|
|
@@ -876,15 +1058,22 @@ export const ZH_CN = {
|
|
|
876
1058
|
"conversation.input": "发送到选中的会话",
|
|
877
1059
|
"conversation.send": "发送",
|
|
878
1060
|
"conversation.model": "当前会话模型",
|
|
879
|
-
"conversation.modelsLoad": "
|
|
880
|
-
"conversation.modelApply": "
|
|
881
|
-
"conversation.
|
|
882
|
-
"conversation.
|
|
1061
|
+
"conversation.modelsLoad": "重新加载",
|
|
1062
|
+
"conversation.modelApply": "应用选择",
|
|
1063
|
+
"conversation.selectedModel": "选中模型",
|
|
1064
|
+
"conversation.modelNotSelected": "请选择",
|
|
1065
|
+
"conversation.modelsLoading": "正在加载模型…",
|
|
1066
|
+
"conversation.modelsFailed": "模型列表读取失败,请重新加载。",
|
|
1067
|
+
"conversation.modelsEmpty": "暂无可用模型",
|
|
1068
|
+
"conversation.modelBusy": "当前正在执行,结束后可应用选择。",
|
|
1069
|
+
"conversation.modelTerminalBusy": "请先在原生终端退出 Codex,再应用选择。仅关闭终端面板不会退出。",
|
|
1070
|
+
"conversation.launchModel": "启动配置",
|
|
1071
|
+
"conversation.confirmedModel": "当前执行模型",
|
|
883
1072
|
"conversation.modelBoundary": "只切换同一 Codex Thread,且必须空闲。不更改角色默认配置或当前轮次。Host 重连会恢复固定启动配置,请重新核对原生确认。不会自动重试。",
|
|
884
|
-
"conversation.modelApplying": "
|
|
885
|
-
"conversation.modelConfirmed": "
|
|
886
|
-
"conversation.modelFailed": "
|
|
887
|
-
"conversation.modelUnknown": "
|
|
1073
|
+
"conversation.modelApplying": "正在切换模型…",
|
|
1074
|
+
"conversation.modelConfirmed": "模型已切换",
|
|
1075
|
+
"conversation.modelFailed": "未能切换模型,请确认会话空闲后再试。",
|
|
1076
|
+
"conversation.modelUnknown": "切换结果待确认,暂不可重复提交。",
|
|
888
1077
|
"conversation.commands": "支持的命令",
|
|
889
1078
|
"conversation.literal": "作为普通文本发送",
|
|
890
1079
|
"conversation.command.help": "查看支持的操作",
|
|
@@ -895,7 +1084,6 @@ export const ZH_CN = {
|
|
|
895
1084
|
"conversation.command.latest": "返回最新消息",
|
|
896
1085
|
"conversation.commandHelp": "/help · /status · /model · /stop · /latest。Tab 补全唯一匹配;Ctrl/⌘+Enter 发送。这些是 Yui 操作,不是任意原生 CLI 命令。",
|
|
897
1086
|
"conversation.commandUnknown": "不支持此命令。请使用 /help,或明确选择作为普通文本发送。",
|
|
898
|
-
"conversation.draftSaved": "草稿已保存在当前浏览器标签页 · Ctrl/⌘+Enter 发送",
|
|
899
1087
|
"conversation.storageFailed": "浏览器存储不可用。离开前请保留草稿副本。",
|
|
900
1088
|
"conversation.receiptDetails": "精确回执",
|
|
901
1089
|
"conversation.receipt.sending": "正在发送,不会重复提交…",
|
|
@@ -923,13 +1111,48 @@ export const ZH_CN = {
|
|
|
923
1111
|
"conversation.empty": "此页没有公开消息,可继续读取更早的历史。",
|
|
924
1112
|
"conversation.liveUnavailable": "实时回复观测不可用,仅显示原生历史",
|
|
925
1113
|
"conversation.truncated": "长消息仅显示摘要;完整内容请打开原生入口。",
|
|
926
|
-
"conversation.placeholder": "
|
|
927
|
-
"conversation.more": "更多",
|
|
1114
|
+
"conversation.placeholder": "给当前会话发消息…(/ 查看命令)",
|
|
928
1115
|
"conversation.copy": "复制",
|
|
929
1116
|
"conversation.copied": "已复制",
|
|
930
1117
|
"conversation.jump": "回到最新",
|
|
931
1118
|
"conversation.selectModel": "选择模型",
|
|
932
1119
|
"conversation.worked": "已处理",
|
|
1120
|
+
"conversation.modelConfirmedNote": "{time} 于启动、恢复或切换时确认;非实时读取,外部 Desktop 改动可能未反映",
|
|
1121
|
+
"conversation.modelStateConfirmed": "最近确认",
|
|
1122
|
+
"conversation.modelStatePending": "待应用",
|
|
1123
|
+
"conversation.modelConfirmedShort": "最近原生确认 {time};非实时",
|
|
1124
|
+
"conversation.details": "会话详情",
|
|
1125
|
+
"conversation.copyIdentity": "复制标识",
|
|
1126
|
+
"conversation.copyFailed": "此浏览器无法复制",
|
|
1127
|
+
"conversation.modelUnconfirmed": "模型未确认",
|
|
1128
|
+
"conversation.modelUnconfirmedHint": "此会话尚无原生确认;不会把启动配置当作当前模型。",
|
|
1129
|
+
"conversation.modelPendingLabel": "应用中",
|
|
1130
|
+
"conversation.modelHistorical": "历史会话不做实时观测。",
|
|
1131
|
+
"conversation.modelNoRead": "尚未报告。",
|
|
1132
|
+
"conversation.effortUnobserved": "未报告推理强度",
|
|
1133
|
+
"conversation.launchNote": "启动时请求;非当前",
|
|
1134
|
+
"conversation.agentDefault": "Agent 默认",
|
|
1135
|
+
"conversation.sendHint": "发送(Ctrl/⌘+Enter)",
|
|
1136
|
+
"conversation.backCurrent": "回到当前会话",
|
|
1137
|
+
"conversation.backCurrentShort": "当前",
|
|
1138
|
+
"conversation.readOnlyHistory": "历史会话 · 只读",
|
|
1139
|
+
"conversation.placeholderHistory": "历史会话只读",
|
|
1140
|
+
"conversation.pendingInput": "等待上一条输入的回执",
|
|
1141
|
+
"conversation.turnUnsettled": "上一条输入的投递尚未确定",
|
|
1142
|
+
"conversation.inputUnavailable": "此会话暂不可输入",
|
|
1143
|
+
"conversation.sessionActive": "运行中",
|
|
1144
|
+
"conversation.sessionEnded": "已结束",
|
|
1145
|
+
"conversation.sessionFailed": "失败",
|
|
1146
|
+
"conversation.previousSessions": "历史",
|
|
1147
|
+
"conversation.noSessionShort": "无会话",
|
|
1148
|
+
"conversation.sessionLabel": "会话",
|
|
1149
|
+
"conversation.sessionId": "会话 ID",
|
|
1150
|
+
"conversation.authority": "执行权",
|
|
1151
|
+
"conversation.agent": "Agent",
|
|
1152
|
+
"conversation.turn": "Turn",
|
|
1153
|
+
"conversation.writer": "输入方",
|
|
1154
|
+
"conversation.stateUnknown": "未知",
|
|
1155
|
+
"conversation.disconnectedShort": "已断开",
|
|
933
1156
|
"conversation.activity.commandExecution": "运行",
|
|
934
1157
|
"conversation.activity.fileChange": "修改文件",
|
|
935
1158
|
"conversation.activity.mcpToolCall": "调用工具",
|
|
@@ -938,6 +1161,7 @@ export const ZH_CN = {
|
|
|
938
1161
|
"conversation.activity.collabAgentToolCall": "询问其他 Agent",
|
|
939
1162
|
"dock.swap": "与任务详情交换位置",
|
|
940
1163
|
"dock.hide": "隐藏会话面板",
|
|
1164
|
+
"dock.show": "显示会话面板",
|
|
941
1165
|
"dock.resize": "调整会话面板宽度",
|
|
942
1166
|
"dock.target": "会话目标",
|
|
943
1167
|
"discussion.title": "任务讨论",
|
|
@@ -995,10 +1219,15 @@ export const ZH_CN = {
|
|
|
995
1219
|
"terminal.closed": "已分离",
|
|
996
1220
|
"terminal.error": "不可用",
|
|
997
1221
|
"terminal.errorDetail": "无法打开该原生会话。请确认 Controller 正在运行且该 Role 已有会话。",
|
|
998
|
-
"
|
|
999
|
-
"
|
|
1000
|
-
"
|
|
1001
|
-
"terminal.
|
|
1222
|
+
"session.mode": "会话视图",
|
|
1223
|
+
"session.modeChat": "聊天",
|
|
1224
|
+
"session.modeTerminal": "终端",
|
|
1225
|
+
"terminal.unavailable": "不可连接",
|
|
1226
|
+
"terminal.noSessionTitle": "没有可连接的会话",
|
|
1227
|
+
"terminal.noSessionText": "该角色还没有可连接的会话;连接不会启动 Agent。",
|
|
1228
|
+
"terminal.notCurrentTitle": "不是当前会话",
|
|
1229
|
+
"terminal.notCurrentText": "终端只能连接当前会话;所选会话已不是当前会话。",
|
|
1230
|
+
"conversation.roleReadOnly": "此角色在这里只读,输入通过其分派控制。",
|
|
1002
1231
|
"terminal.cliHint": "完整终端",
|
|
1003
1232
|
"terminal.historyLimited": "这个 Role 的 tmux 历史只有 {current} 行;退出并重新进入后可使用 {target} 行。",
|
|
1004
1233
|
"global.open": "全局消息",
|
|
@@ -36,6 +36,7 @@ import { WORK_SCRIPT } from "./domain/work.js";
|
|
|
36
36
|
import { DISCUSSION_SCRIPT } from "./views/dock/discussion.js";
|
|
37
37
|
import { CONVERSATION_SCRIPT } from "./views/dock/conversation.js";
|
|
38
38
|
import { TERMINAL_SCRIPT } from "./views/dock/terminal.js";
|
|
39
|
+
import { SESSION_PAGE_SCRIPT } from "./views/dock/session.js";
|
|
39
40
|
import { PREVIEW_SCRIPT } from "./views/dock/preview.js";
|
|
40
41
|
import { GLOBAL_INPUT_SCRIPT } from "./views/globalInput.js";
|
|
41
42
|
import { CREATE_TASK_SCRIPT } from "./views/createTask.js";
|
|
@@ -67,6 +68,7 @@ import { JOBS_SCRIPT } from "./views/jobs.js";
|
|
|
67
68
|
import { PERMISSIONS_SCRIPT } from "./views/permissions.js";
|
|
68
69
|
import { MODELS_VIEW_SCRIPT } from "./views/models.js";
|
|
69
70
|
import { MODELS_SCRIPT } from "./app/models.js";
|
|
71
|
+
import { JOBS_APP_SCRIPT } from "./app/jobs.js";
|
|
70
72
|
import { MANAGE_SHELL_SCRIPT } from "./layout/manageShell.js";
|
|
71
73
|
import { MANAGE_SCRIPT } from "./app/manage.js";
|
|
72
74
|
import { LOGIN_SCRIPT } from "./app/login.js";
|
|
@@ -74,6 +76,7 @@ export { APP_SCRIPT } from "./app/main.js";
|
|
|
74
76
|
export const CLIENT_MODULES = Object.freeze({
|
|
75
77
|
"views/skills": SKILLS_SCRIPT,
|
|
76
78
|
"views/jobs": JOBS_SCRIPT,
|
|
79
|
+
"app/jobs": JOBS_APP_SCRIPT,
|
|
77
80
|
"views/permissions": PERMISSIONS_SCRIPT,
|
|
78
81
|
"views/models": MODELS_VIEW_SCRIPT,
|
|
79
82
|
"lib/dom": DOM_SCRIPT,
|
|
@@ -106,6 +109,7 @@ export const CLIENT_MODULES = Object.freeze({
|
|
|
106
109
|
"views/dock/discussion": DISCUSSION_SCRIPT,
|
|
107
110
|
"views/dock/conversation": CONVERSATION_SCRIPT,
|
|
108
111
|
"views/dock/terminal": TERMINAL_SCRIPT,
|
|
112
|
+
"views/dock/session": SESSION_PAGE_SCRIPT,
|
|
109
113
|
"views/dock/preview": PREVIEW_SCRIPT,
|
|
110
114
|
"views/task/page": TASK_PAGE_SCRIPT,
|
|
111
115
|
"views/task/actions": TASK_ACTIONS_SCRIPT,
|
|
@@ -16,22 +16,30 @@ export function manageArea(page, section) {
|
|
|
16
16
|
export function pageSections(page) {
|
|
17
17
|
return Object.values(SECTIONS).flat().filter(item => item.page === page).map(item => item.section);
|
|
18
18
|
}
|
|
19
|
+
const TASK_ID = /^task-\d+$/;
|
|
19
20
|
export function readManageRoute(url) {
|
|
20
21
|
const parts = url.pathname.split("/").filter(Boolean);
|
|
22
|
+
// Jobs has its own entry. The retired Settings section keeps its links
|
|
23
|
+
// working: it opens the same Job (canonicalized without a Back step).
|
|
24
|
+
const legacyJobs = parts[0] === "settings" && (parts[1] || url.searchParams.get("section")) === "jobs";
|
|
25
|
+
if (parts[0] === "jobs" || legacyJobs) {
|
|
26
|
+
const task = url.searchParams.get("task");
|
|
27
|
+
return { page: "jobs", section: "jobs", task: task && TASK_ID.test(task) ? task : null,
|
|
28
|
+
job: url.searchParams.get("job"), jobRun: url.searchParams.get("jobRun"),
|
|
29
|
+
artifact: url.searchParams.get("artifact"), ...(legacyJobs ? { moved: true } : {}) };
|
|
30
|
+
}
|
|
21
31
|
const area = parts[0] === "settings" ? "settings" : "models";
|
|
22
32
|
const requested = parts[1] || url.searchParams.get("section");
|
|
23
33
|
const section = (SECTIONS[area].find(item => item.section === requested) ||
|
|
24
34
|
(area === "models" && requested === "connection" ? SECTIONS.settings.at(-1) : SECTIONS[area][0])).section;
|
|
25
35
|
return { page: section === "connection" ? "models" : area, section,
|
|
26
|
-
...(section === "jobs" ? { job: url.searchParams.get("job"), jobRun: url.searchParams.get("jobRun"),
|
|
27
|
-
artifact: url.searchParams.get("artifact") } : {}),
|
|
28
36
|
source: url.searchParams.get("source") === "command-code" ? "command-code" : "factory" };
|
|
29
37
|
}
|
|
30
38
|
export function manageHref(next) {
|
|
31
|
-
if (next.
|
|
39
|
+
if (next.page === "jobs") {
|
|
32
40
|
const query = new URLSearchParams();
|
|
33
|
-
for (const key of ["job", "jobRun", "artifact"]) if (next[key]) query.set(key, next[key]);
|
|
34
|
-
return "/
|
|
41
|
+
for (const key of ["task", "job", "jobRun", "artifact"]) if (next[key]) query.set(key, next[key]);
|
|
42
|
+
return "/jobs" + (query.size ? "?" + query : "");
|
|
35
43
|
}
|
|
36
44
|
return "/" + manageArea(next.page, next.section) + "/" + next.section +
|
|
37
45
|
(next.section === "quota" && next.source === "command-code" ? "?source=command-code" : "");
|
|
@@ -53,11 +61,15 @@ function render() {
|
|
|
53
61
|
if (link.dataset.area === area) link.setAttribute("aria-current", "page"); else link.removeAttribute("aria-current");
|
|
54
62
|
});
|
|
55
63
|
// The list head and the top bar name where the reader is.
|
|
56
|
-
const areaTitle = i18n.t(area + ".title");
|
|
57
|
-
const
|
|
64
|
+
const areaTitle = i18n.t(area === "jobs" ? "nav.jobs" : area + ".title");
|
|
65
|
+
const page = pages.get(route.page);
|
|
66
|
+
const sectionTitle = page && page.crumb ? page.crumb()
|
|
67
|
+
: i18n.t((route.page === "models" ? "models" : "settings") + ".section." + route.section);
|
|
58
68
|
document.querySelector("#manage-area-title").textContent = areaTitle;
|
|
59
69
|
document.querySelector("#manage-crumb-area").textContent = areaTitle;
|
|
60
70
|
document.querySelector("#manage-crumb-section").textContent = sectionTitle;
|
|
71
|
+
// Area-only controls in the shared list head (the Jobs sync and refresh).
|
|
72
|
+
rail.querySelectorAll("[data-area-only]").forEach(node => { node.hidden = node.dataset.areaOnly !== area; });
|
|
61
73
|
rail.querySelectorAll("[data-area-group]").forEach(group => {
|
|
62
74
|
if (group.dataset.areaGroup === area) group.dataset.active = "true"; else delete group.dataset.active;
|
|
63
75
|
});
|
|
@@ -65,27 +77,60 @@ function render() {
|
|
|
65
77
|
document.title = sectionTitle + " · " + areaTitle + " · Yui";
|
|
66
78
|
}
|
|
67
79
|
function apply(next) {
|
|
80
|
+
// The page being left is told first, so it can set aside what must not
|
|
81
|
+
// outlive its visibility (a modal editor) without discarding it.
|
|
82
|
+
const previous = route && route.page !== next.page ? pages.get(route.page) : null;
|
|
83
|
+
if (previous && previous.hide) previous.hide();
|
|
68
84
|
route = next;
|
|
69
85
|
rememberPlace(manageArea(next.page, next.section), manageHref(next));
|
|
70
86
|
rememberPlace("manage", manageHref(next));
|
|
71
|
-
document.querySelector("#
|
|
72
|
-
document.querySelector("#settings-root").hidden = next.page !== "settings";
|
|
87
|
+
for (const name of ["models", "settings", "jobs"]) document.querySelector("#" + name + "-root").hidden = next.page !== name;
|
|
73
88
|
pages.get(next.page).show(next);
|
|
74
89
|
render();
|
|
75
90
|
}
|
|
76
91
|
// A section the reader switched to rises in (never on the first paint).
|
|
77
92
|
function revealSection() {
|
|
78
93
|
if (typeof enter !== "function") return;
|
|
79
|
-
enter(document.querySelector("#models-root:not([hidden]), #settings-root:not([hidden])"), "rise");
|
|
94
|
+
enter(document.querySelector("#models-root:not([hidden]), #settings-root:not([hidden]), #jobs-root:not([hidden])"), "rise");
|
|
95
|
+
}
|
|
96
|
+
// Every route change (link, control, Back/Forward) first asks the page it
|
|
97
|
+
// leaves and the page it enters; either may keep the current view.
|
|
98
|
+
function mayNavigate(next) {
|
|
99
|
+
for (const name of new Set([route.page, next.page])) {
|
|
100
|
+
const page = pages.get(name);
|
|
101
|
+
if (page && page.canNavigate && !page.canNavigate(next)) return false;
|
|
102
|
+
}
|
|
103
|
+
return true;
|
|
80
104
|
}
|
|
105
|
+
// Returns false when a page kept the current view (nothing changed).
|
|
81
106
|
export function navigateManage(next) {
|
|
82
107
|
const normalized = readManageRoute(new URL(manageHref(next), location.origin));
|
|
83
|
-
if (manageHref(normalized) === location.pathname + location.search) return;
|
|
108
|
+
if (manageHref(normalized) === location.pathname + location.search) return true;
|
|
109
|
+
if (!mayNavigate(normalized)) return false;
|
|
84
110
|
history.replaceState({ ...history.state, scroll: scroller().scrollTop }, "");
|
|
85
111
|
history.pushState({ scroll: 0 }, "", manageHref(normalized));
|
|
86
112
|
apply(normalized);
|
|
87
113
|
scroller().scrollTop = 0;
|
|
88
114
|
revealSection();
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
// A page settled on a more exact address for the current view (for example
|
|
118
|
+
// the Job it opened): record it in place, without a history step.
|
|
119
|
+
export function replaceManageRoute(next) {
|
|
120
|
+
route = next;
|
|
121
|
+
rememberPlace(manageArea(next.page, next.section), manageHref(next));
|
|
122
|
+
rememberPlace("manage", manageHref(next));
|
|
123
|
+
history.replaceState(history.state, "", manageHref(next));
|
|
124
|
+
render();
|
|
125
|
+
}
|
|
126
|
+
// A page already shows a selection the reader chose in place (for example a
|
|
127
|
+
// Run opened under its row): record it as a history step without applying it
|
|
128
|
+
// again, keeping the reading position for Back.
|
|
129
|
+
export function pushManageRoute(next) {
|
|
130
|
+
if (manageHref(next) === location.pathname + location.search) return;
|
|
131
|
+
history.replaceState({ ...history.state, scroll: scroller().scrollTop }, "");
|
|
132
|
+
history.pushState({ scroll: scroller().scrollTop }, "", manageHref(next));
|
|
133
|
+
replaceManageRoute(next);
|
|
89
134
|
}
|
|
90
135
|
export function createManageShell(options) {
|
|
91
136
|
return {
|
|
@@ -108,14 +153,15 @@ export function startManagement() {
|
|
|
108
153
|
if (!link || link.target || link.hasAttribute("download") || event.defaultPrevented ||
|
|
109
154
|
event.button > 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
110
155
|
const url = new URL(link.href);
|
|
111
|
-
|
|
112
|
-
if (url.searchParams.has("job")) return;
|
|
113
|
-
if (url.origin !== location.origin || !/^\/(models|settings)(\/|$)/.test(url.pathname)) return;
|
|
156
|
+
if (url.origin !== location.origin || !/^\/(models|settings|jobs)(\/|$)/.test(url.pathname)) return;
|
|
114
157
|
event.preventDefault();
|
|
115
158
|
navigateManage(readManageRoute(url));
|
|
116
159
|
});
|
|
117
160
|
window.addEventListener("popstate", () => {
|
|
118
|
-
|
|
161
|
+
const next = readManageRoute(new URL(location.href));
|
|
162
|
+
// A kept view restores its own address as the newest entry.
|
|
163
|
+
if (!mayNavigate(next)) { history.pushState({ scroll: scroller().scrollTop }, "", manageHref(route)); return; }
|
|
164
|
+
apply(next);
|
|
119
165
|
scroller().scrollTop = history.state?.scroll || 0;
|
|
120
166
|
revealSection();
|
|
121
167
|
});
|
|
@@ -23,7 +23,8 @@ export function syncUrl(state, replace) {
|
|
|
23
23
|
if (state.query) params.set("q", state.query); else params.delete("q");
|
|
24
24
|
if (state.attentionFilter) params.set("attention", state.attentionFilter); else params.delete("attention");
|
|
25
25
|
if (state.catalogAll) params.set("all", "true"); else params.delete("all");
|
|
26
|
-
|
|
26
|
+
// Tasks have no category filter: every real Task, Job-created ones marked.
|
|
27
|
+
params.delete("source");
|
|
27
28
|
applyUrl(params, replace);
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -7,7 +7,7 @@ import { isEditing } from "/assets/js/lib/dom.js";
|
|
|
7
7
|
const TABS = ${JSON.stringify(TASK_TABS)};
|
|
8
8
|
|
|
9
9
|
// deps: { el, state, globalInput, workspace, sidebarNav, selection, catalog, taskView }
|
|
10
|
-
// el #search, #settings-dialog and
|
|
10
|
+
// el #search, #settings-dialog and the dock (its terminal host)
|
|
11
11
|
// state read-only here: state.selected, state.detail
|
|
12
12
|
// globalInput views/globalInput (its dialog blocks shortcuts while open)
|
|
13
13
|
// workspace layout/workspace: the dock and the operator Session
|
|
@@ -20,7 +20,7 @@ export function bindShortcuts(deps) {
|
|
|
20
20
|
if (document.querySelector("dialog[open]")) return;
|
|
21
21
|
const active = document.activeElement;
|
|
22
22
|
const typing = isEditing(active);
|
|
23
|
-
const inTerminal =
|
|
23
|
+
const inTerminal = !!active && !!active.closest && !!active.closest(".terminal-host");
|
|
24
24
|
if (event.key === "Escape") { escape(deps, active, typing, inTerminal); return; }
|
|
25
25
|
if (typing || inTerminal || event.metaKey || event.ctrlKey || event.altKey) return;
|
|
26
26
|
shortcut(deps, event);
|