dsh-task-dispatch-table 0.1.2 → 0.1.4
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/client.js +228 -55
- package/dist/client.js.map +1 -1
- package/dist/dispatch.js +4 -0
- package/dist/index.js +0 -0
- package/dist/receipt.js +67 -20
- package/dist/reconcile.d.ts +1 -1
- package/dist/reconcile.js +21 -10
- package/dist/runtime-index.d.ts +1 -0
- package/dist/scheduler.js +3 -0
- package/dist/store.d.ts +11 -4
- package/dist/store.js +10 -5
- package/dist/task-assets.d.ts +2 -0
- package/dist/tasks.d.ts +1 -0
- package/dist/tasks.js +2 -0
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -169,6 +169,8 @@ window.__ModuleLoader__.load({
|
|
|
169
169
|
*
|
|
170
170
|
* ⚠️ 2026-10-04 从 `task-list.tsx` 上提到这里:卡片「执行记录」面板与**执行记录总查询页**都要用,
|
|
171
171
|
* 同一解析写两遍就是违规(本仓规矩:一类东西一个实现)。
|
|
172
|
+
*
|
|
173
|
+
* ⚠️ 2026-10-10:`process_outputs`(过程文件桶)**同一个形状**,因此继续用它解析,不另写一份。
|
|
172
174
|
*/
|
|
173
175
|
function outputsOf(raw) {
|
|
174
176
|
if (raw === null || raw === void 0 || raw === "") return [];
|
|
@@ -503,7 +505,9 @@ window.__ModuleLoader__.load({
|
|
|
503
505
|
explorerRootName: "(工作区根目录)",
|
|
504
506
|
explorerExpand: "展开目录",
|
|
505
507
|
explorerCollapse: "收起目录",
|
|
508
|
+
explorerEnter: "进入",
|
|
506
509
|
colOutputs: "产出",
|
|
510
|
+
procFilesTitle: "过程文件 · {count} 项",
|
|
507
511
|
deliverRowTitle: "交付文件",
|
|
508
512
|
deliverRowPreparing: "准备交付",
|
|
509
513
|
deliverRowRunning: "正在交付",
|
|
@@ -605,6 +609,7 @@ window.__ModuleLoader__.load({
|
|
|
605
609
|
editorAttachmentsHint: "附加文件会随任务一起派发给执行的 Agent:任务执行过程中,Agent 可读取或操作这些文件的内容。也可从工作区选择整个目录(连带其下所有文件):Agent 拿到的是这个目录的路径,自己在里面找文件,提示词里写「附件里的 目录名/子文件路径」即可指定其中某一个。",
|
|
606
610
|
editorPickerPick: "选择此文件",
|
|
607
611
|
editorPickerPickDir: "选择此目录(连带其下所有文件)",
|
|
612
|
+
editorPickerSelect: "选择",
|
|
608
613
|
editorOpenEditor: "全屏编辑",
|
|
609
614
|
editorPromptEditorTitle: "提示词编辑器(.md)",
|
|
610
615
|
editorNoVersions: "暂无版本,保存后可在此回滚",
|
|
@@ -633,6 +638,7 @@ window.__ModuleLoader__.load({
|
|
|
633
638
|
editorFullPermB2: "执行命令、发起网络请求等敏感操作",
|
|
634
639
|
editorFullPermCheck: "我已了解风险,并愿意为该任务的执行结果负责。",
|
|
635
640
|
editorTaskSaved: "任务已保存",
|
|
641
|
+
editorTaskDeleted: "任务已删除",
|
|
636
642
|
editorSchedHourlyOnce: "每小时执行一次",
|
|
637
643
|
editorSchedNoDaySuffix: ",但还没选生效日",
|
|
638
644
|
editorSchedWeeklyDayPrefix: "每周",
|
|
@@ -770,6 +776,9 @@ window.__ModuleLoader__.load({
|
|
|
770
776
|
listNextFullTitle: "下次执行:{when}",
|
|
771
777
|
listEmpty: "还没有任务。点右上角「+ 新建任务」创建第一个。",
|
|
772
778
|
listEmptyFiltered: "没有符合当前筛选的任务。",
|
|
779
|
+
listEmptyTitle: "创建你的第一个定时任务",
|
|
780
|
+
listEmptyHint: "写好提示词,到点自动执行;支持每天 / 每周 / 间隔循环。",
|
|
781
|
+
listEmptyAction: "+ 新建定时任务",
|
|
773
782
|
listSectionAttachments: "附加文件",
|
|
774
783
|
listSectionDepends: "前置任务",
|
|
775
784
|
listFieldWorkspace: "工作区",
|
|
@@ -1165,7 +1174,9 @@ window.__ModuleLoader__.load({
|
|
|
1165
1174
|
explorerRootName: "(workspace root)",
|
|
1166
1175
|
explorerExpand: "Expand directory",
|
|
1167
1176
|
explorerCollapse: "Collapse directory",
|
|
1177
|
+
explorerEnter: "Open",
|
|
1168
1178
|
colOutputs: "Outputs",
|
|
1179
|
+
procFilesTitle: "Process files · {count}",
|
|
1169
1180
|
deliverRowTitle: "Deliver files",
|
|
1170
1181
|
deliverRowPreparing: "Preparing delivery",
|
|
1171
1182
|
deliverRowRunning: "Delivering",
|
|
@@ -1267,6 +1278,7 @@ window.__ModuleLoader__.load({
|
|
|
1267
1278
|
editorAttachmentsHint: "Attachments are dispatched along with the task: while it runs, the agent can read and operate on their contents. You can also pick a whole folder: the agent gets the folder path and explores it itself, so refer to a file inside as \"<folder name>/<relative path>\" in the prompt.",
|
|
1268
1279
|
editorPickerPick: "Pick this file",
|
|
1269
1280
|
editorPickerPickDir: "Pick this folder (with everything under it)",
|
|
1281
|
+
editorPickerSelect: "Select",
|
|
1270
1282
|
editorOpenEditor: "Full-screen edit",
|
|
1271
1283
|
editorPromptEditorTitle: "Prompt editor (.md)",
|
|
1272
1284
|
editorNoVersions: "No versions yet — save one to roll back here",
|
|
@@ -1295,6 +1307,7 @@ window.__ModuleLoader__.load({
|
|
|
1295
1307
|
editorFullPermB2: "run commands, make network requests and other sensitive operations",
|
|
1296
1308
|
editorFullPermCheck: "I understand the risk and accept responsibility for this task's results.",
|
|
1297
1309
|
editorTaskSaved: "Task saved",
|
|
1310
|
+
editorTaskDeleted: "Task deleted",
|
|
1298
1311
|
editorSchedHourlyOnce: "runs hourly",
|
|
1299
1312
|
editorSchedNoDaySuffix: ", but no active day is selected",
|
|
1300
1313
|
editorSchedWeeklyDayPrefix: "every ",
|
|
@@ -1432,6 +1445,9 @@ window.__ModuleLoader__.load({
|
|
|
1432
1445
|
listNextFullTitle: "Next run: {when}",
|
|
1433
1446
|
listEmpty: "No tasks yet. Use “+ New task” to create the first one.",
|
|
1434
1447
|
listEmptyFiltered: "No task matches the current filter.",
|
|
1448
|
+
listEmptyTitle: "Create your first scheduled task",
|
|
1449
|
+
listEmptyHint: "Write a prompt and it runs automatically on time — every day, every week, or on an interval.",
|
|
1450
|
+
listEmptyAction: "+ New scheduled task",
|
|
1435
1451
|
listSectionAttachments: "Attachments",
|
|
1436
1452
|
listSectionDepends: "Preceding tasks",
|
|
1437
1453
|
listFieldWorkspace: "Workspace",
|
|
@@ -2214,6 +2230,22 @@ body[data-ds-dark-theme]{
|
|
|
2214
2230
|
内层盒子裁了、按「半截文本」平移导致的)。鼠标移开 ⇒ :hover 失效 ⇒ 自动复位回省略号态。 */
|
|
2215
2231
|
.dsh-tdt-mq-run:hover .dsh-tdt-mq-in{max-width:none;overflow:visible;animation:dsh-tdt-mq-scroll var(--dsh-tdt-mq-dur,6s) linear .4s 1 forwards;}
|
|
2216
2232
|
@keyframes dsh-tdt-mq-scroll{from{transform:translateX(0)}to{transform:translateX(var(--dsh-tdt-mq-dist,-40px))}}
|
|
2233
|
+
`;
|
|
2234
|
+
/** 「过程文件」块的皮肤规则(2026-10-10:回执过程文件桶的次级展示件)。 */
|
|
2235
|
+
const PROCESS_FILES_CSS = `
|
|
2236
|
+
/* ── 「过程文件」块:会话弹窗交付卡下方 / 执行记录展开区 / 查看档产出清单三处共用 ──────────
|
|
2237
|
+
(结构在 client/process-files.tsx)。观感纪律 = **次级**:小字浅灰标题 + 数量、默认收起,
|
|
2238
|
+
不许抢主文件(交付卡 / 产出物清单)的视线;展开后的文件行复用 .dsh-tdt-filechip--inline。 */
|
|
2239
|
+
.dsh-tdt-proc{display:flex;flex-direction:column;gap:4px;margin-top:10px;min-width:0;}
|
|
2240
|
+
.dsh-tdt-proc-head{appearance:none;-webkit-appearance:none;align-self:flex-start;display:inline-flex;align-items:center;
|
|
2241
|
+
gap:6px;padding:2px 6px;border:0;border-radius:var(--tdt-radius-xs);background:transparent;color:var(--tdt-fg-3);
|
|
2242
|
+
font:inherit;font-size:var(--tdt-font-xs);line-height:var(--tdt-line-sm);cursor:pointer;
|
|
2243
|
+
transition:background-color var(--tdt-dur) var(--tdt-ease),color var(--tdt-dur) var(--tdt-ease);}
|
|
2244
|
+
.dsh-tdt-proc-head:hover{background:var(--tdt-chip-bg);color:var(--tdt-fg-2);}
|
|
2245
|
+
.dsh-tdt-proc-head:focus-visible{outline:2px solid var(--tdt-focus);outline-offset:1px;}
|
|
2246
|
+
.dsh-tdt-proc-list{display:flex;flex-wrap:wrap;gap:2px 4px;min-width:0;}
|
|
2247
|
+
|
|
2248
|
+
@media (prefers-reduced-motion: reduce){.dsh-tdt-proc-head{transition:none;}}
|
|
2217
2249
|
`;
|
|
2218
2250
|
/** 控件皮肤域的固定名(注入顺序在 tokens 之后)。 */
|
|
2219
2251
|
const CONTROLS_DOMAIN = "controls";
|
|
@@ -2221,7 +2253,7 @@ body[data-ds-dark-theme]{
|
|
|
2221
2253
|
* 确保控件皮肤已登记并注入(幂等;组件渲染时调用一次即可)。
|
|
2222
2254
|
*/
|
|
2223
2255
|
function ensureControlsStyle() {
|
|
2224
|
-
applyStyle(CONTROLS_DOMAIN, SEGMENTED_CSS + BUTTON_CSS + FIELD_CSS + DATETIME_CSS + SELECT_CSS);
|
|
2256
|
+
applyStyle(CONTROLS_DOMAIN, SEGMENTED_CSS + BUTTON_CSS + FIELD_CSS + DATETIME_CSS + SELECT_CSS + PROCESS_FILES_CSS);
|
|
2225
2257
|
}
|
|
2226
2258
|
//#endregion
|
|
2227
2259
|
//#region src/client/ui/Segmented.tsx
|
|
@@ -50179,8 +50211,12 @@ body[data-ds-dark-theme]{
|
|
|
50179
50211
|
.dsh-tdt-sv-crumbs-menu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
|
|
50180
50212
|
/* 目录树:行内 ▸ 开关(内联展开/收起),点它只切展开、不导航。 */
|
|
50181
50213
|
.dsh-tdt-sv-tree-toggle{appearance:none;background:0 0;border:none;flex:none;width:20px;height:20px;padding:0;margin:0;border-radius:var(--tdt-radius-sm,6px);cursor:pointer;color:var(--tdt-fg-2,rgba(128,128,128,.95));display:inline-flex;align-items:center;justify-content:center;transition:transform var(--tdt-dur,.15s) var(--tdt-ease,ease),background var(--tdt-dur,.15s) var(--tdt-ease,ease);}
|
|
50182
|
-
.dsh-tdt-sv-tree-toggle:hover{background:var(--tdt-hover,rgba(38,49,72,.06));}
|
|
50183
50214
|
.dsh-tdt-sv-tree-toggle-open{transform:rotate(90deg);}
|
|
50215
|
+
/* 目录树:行尾「选择」按钮(仅选择器形态,用户 2026-10-10)——平时藏起来,悬停或聚焦该行才出现,
|
|
50216
|
+
点它才把整个文件夹选为附件;平时隐形但保留尺寸,出现时不会顶动行内布局。 */
|
|
50217
|
+
.dsh-tdt-sv-tree-act{flex:none;margin-left:auto;appearance:none;background:0 0;border:1px solid var(--tdt-border,rgba(128,128,128,.35));border-radius:var(--tdt-radius-sm,6px);padding:2px 8px;font-size:var(--tdt-font-sm);line-height:1.4;color:var(--tdt-fg-2,rgba(128,128,128,.95));cursor:pointer;opacity:0;pointer-events:none;transition:opacity var(--tdt-dur,.15s) var(--tdt-ease,ease);}
|
|
50218
|
+
.dsh-tdt-sv-tree-row:hover .dsh-tdt-sv-tree-act,.dsh-tdt-sv-tree-act:focus-visible{opacity:1;pointer-events:auto;}
|
|
50219
|
+
.dsh-tdt-sv-tree-act:hover{background:var(--tdt-hover,rgba(38,49,72,.06));color:var(--tdt-fg);}
|
|
50184
50220
|
/* 内联展开子层:左缩进 + 淡竖线引导层级。 */
|
|
50185
50221
|
.dsh-tdt-sv-tree-children{margin-left:9px;padding-left:7px;border-left:1px solid var(--tdt-border,rgba(128,128,128,.28));display:flex;flex-direction:column;}
|
|
50186
50222
|
.dsh-tdt-sv-tree-loading,.dsh-tdt-sv-tree-err{padding:4px 8px 4px 36px;font-size:var(--tdt-font-sm);color:var(--tdt-fg-3,rgba(128,128,128,.8));}
|
|
@@ -52252,6 +52288,54 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
52252
52288
|
}, (0, react$1.createElement)("span", null, t(expanded ? "deliverCollapse" : "deliverAll", { count: files.length })), expanded ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconChevronUpOutlineRegular, {}) : (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, {})) : null);
|
|
52253
52289
|
}
|
|
52254
52290
|
//#endregion
|
|
52291
|
+
//#region src/client/process-files.tsx
|
|
52292
|
+
/** 目录以尾斜杠表达(与 `normalizeOutputs` / `baseNameOf` 同一约定)。 */
|
|
52293
|
+
const isDirPath$1 = (path) => path.endsWith("/");
|
|
52294
|
+
function ProcessFiles(props) {
|
|
52295
|
+
const { paths, onOpen, className, t } = props;
|
|
52296
|
+
const [open, setOpen] = (0, react$1.useState)(false);
|
|
52297
|
+
ensureControlsStyle();
|
|
52298
|
+
const list = paths ?? [];
|
|
52299
|
+
if (list.length === 0) return null;
|
|
52300
|
+
return (0, react$1.createElement)("div", {
|
|
52301
|
+
className: className === void 0 ? "dsh-tdt-proc" : `dsh-tdt-proc ${className}`,
|
|
52302
|
+
"data-process-files": true
|
|
52303
|
+
}, (0, react$1.createElement)("button", {
|
|
52304
|
+
type: "button",
|
|
52305
|
+
className: "dsh-tdt-proc-head",
|
|
52306
|
+
"aria-expanded": open,
|
|
52307
|
+
onClick: () => {
|
|
52308
|
+
setOpen((value) => !value);
|
|
52309
|
+
}
|
|
52310
|
+
}, (0, react$1.createElement)("span", null, t("procFilesTitle", { count: list.length })), open ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconChevronUpOutlineRegular, { size: 12 }) : (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { size: 12 })), open ? (0, react$1.createElement)("div", { className: "dsh-tdt-proc-list" }, list.map((path) => {
|
|
52311
|
+
const body = [isDirPath$1(path) ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconFolderCloseRegular, { size: 14 }) : (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
52312
|
+
path,
|
|
52313
|
+
size: 14
|
|
52314
|
+
}), (0, react$1.createElement)(MarqueeText, {
|
|
52315
|
+
text: baseNameOf(path),
|
|
52316
|
+
title: path,
|
|
52317
|
+
style: {
|
|
52318
|
+
maxWidth: "40ch",
|
|
52319
|
+
minWidth: 0
|
|
52320
|
+
}
|
|
52321
|
+
})];
|
|
52322
|
+
return onOpen === void 0 ? (0, react$1.createElement)("span", {
|
|
52323
|
+
key: path,
|
|
52324
|
+
className: "dsh-tdt-filechip dsh-tdt-filechip--inline",
|
|
52325
|
+
title: path,
|
|
52326
|
+
"data-noclick": true
|
|
52327
|
+
}, ...body) : (0, react$1.createElement)("button", {
|
|
52328
|
+
key: path,
|
|
52329
|
+
type: "button",
|
|
52330
|
+
className: "dsh-tdt-filechip dsh-tdt-filechip--inline",
|
|
52331
|
+
title: path,
|
|
52332
|
+
onClick: () => {
|
|
52333
|
+
onOpen(path);
|
|
52334
|
+
}
|
|
52335
|
+
}, ...body);
|
|
52336
|
+
})) : null);
|
|
52337
|
+
}
|
|
52338
|
+
//#endregion
|
|
52255
52339
|
//#region src/client/task-file-context.tsx
|
|
52256
52340
|
/**
|
|
52257
52341
|
* 实例快照 → 本任务工作区 path(判上游目录是否跨区用)。
|
|
@@ -52736,7 +52820,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
52736
52820
|
* @param groupPart - 过程分组侧('response' | 'reasoning')。
|
|
52737
52821
|
* @returns 节点视图;null = 决策 28 过滤的噪音 kind。
|
|
52738
52822
|
*/
|
|
52739
|
-
function renderKeyedNode(node, turnProcess, t, onBranchAt, fileOpen, groupPart, deliverFiles, lastTailTurn, host, attachedNames) {
|
|
52823
|
+
function renderKeyedNode(node, turnProcess, t, onBranchAt, fileOpen, groupPart, deliverFiles, lastTailTurn, host, attachedNames, processFiles) {
|
|
52740
52824
|
switch (node.kind) {
|
|
52741
52825
|
case "turn-trigger": return (0, react$1.createElement)(TurnTriggerNodeViewMirror, {
|
|
52742
52826
|
data: node.data,
|
|
@@ -52750,14 +52834,21 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
52750
52834
|
case "turn-tail": {
|
|
52751
52835
|
const data = node.data;
|
|
52752
52836
|
const turn = data?.turn ?? turnLocationOf(node)?.turn;
|
|
52753
|
-
const
|
|
52837
|
+
const atLastTail = turn !== void 0 && lastTailTurn !== void 0 && turn === lastTailTurn;
|
|
52838
|
+
const showGrid = deliverFiles !== void 0 && deliverFiles.length > 0 && atLastTail;
|
|
52839
|
+
const showProc = processFiles !== void 0 && processFiles.length > 0 && atLastTail;
|
|
52840
|
+
const tailSlot = showGrid || showProc ? (0, react$1.createElement)(react$1.Fragment, null, showGrid && host !== void 0 && host !== null && host !== "error" && !host.available ? (0, react$1.createElement)("span", {
|
|
52754
52841
|
className: ocOr("Deliverables", "hostStatus", "dsh-tdt-sv-host-status"),
|
|
52755
52842
|
"data-host-unavailable": true
|
|
52756
|
-
}, t("presented.unavailable")) : null, (0, react$1.createElement)(DeliverablesGridMirror, {
|
|
52843
|
+
}, t("presented.unavailable")) : null, showGrid ? (0, react$1.createElement)(DeliverablesGridMirror, {
|
|
52757
52844
|
files: deliverFiles,
|
|
52758
52845
|
onOpen: fileOpen?.open,
|
|
52759
52846
|
t
|
|
52760
|
-
})
|
|
52847
|
+
}) : null, showProc ? (0, react$1.createElement)(ProcessFiles, {
|
|
52848
|
+
paths: processFiles,
|
|
52849
|
+
onOpen: fileOpen?.open,
|
|
52850
|
+
t
|
|
52851
|
+
}) : null) : null;
|
|
52761
52852
|
return data === void 0 || data.closing === null || data.closing === void 0 ? null : (0, react$1.createElement)(TurnTailNodeViewMirror, {
|
|
52762
52853
|
data,
|
|
52763
52854
|
onBranchAt,
|
|
@@ -53135,7 +53226,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
53135
53226
|
* forkSession / openHostSession 缺一即不渲染按钮(服务未就位时功能降级)。
|
|
53136
53227
|
*/
|
|
53137
53228
|
function SessionViewModal(props) {
|
|
53138
|
-
const { t, heading, sessionId, view, onClose, forkSession, openHostSession, workspaceFiles, onOpenFile, outputs, upstream, attached, workspacePath, headingTask, headingRest, taskId, onOpenTask } = props;
|
|
53229
|
+
const { t, heading, sessionId, view, onClose, forkSession, openHostSession, workspaceFiles, onOpenFile, outputs, processOutputs, upstream, attached, workspacePath, headingTask, headingRest, taskId, onOpenTask } = props;
|
|
53139
53230
|
const tt = (0, react$1.useMemo)(() => interpolateTranslate(t), [t]);
|
|
53140
53231
|
const attachedNames = (0, react$1.useMemo)(() => new Set((attached ?? []).filter((file) => file.path !== null).map((file) => file.name)), [attached]);
|
|
53141
53232
|
const subscribe = (0, react$1.useMemo)(() => (onChange) => view.target.subscribe(onChange), [view]);
|
|
@@ -53236,14 +53327,15 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
53236
53327
|
store
|
|
53237
53328
|
]);
|
|
53238
53329
|
const host = usePresentedHost();
|
|
53239
|
-
const renderNode = (0, react$1.useCallback)((node, turnProcess, groupPart) => renderKeyedNode(node, turnProcess, tt, onBranchAt, fileOpen, groupPart, deliverFiles, lastTailTurn, host, attachedNames), [
|
|
53330
|
+
const renderNode = (0, react$1.useCallback)((node, turnProcess, groupPart) => renderKeyedNode(node, turnProcess, tt, onBranchAt, fileOpen, groupPart, deliverFiles, lastTailTurn, host, attachedNames, processOutputs), [
|
|
53240
53331
|
tt,
|
|
53241
53332
|
onBranchAt,
|
|
53242
53333
|
fileOpen,
|
|
53243
53334
|
deliverFiles,
|
|
53244
53335
|
lastTailTurn,
|
|
53245
53336
|
host,
|
|
53246
|
-
attachedNames
|
|
53337
|
+
attachedNames,
|
|
53338
|
+
processOutputs
|
|
53247
53339
|
]);
|
|
53248
53340
|
const isTurnClosed = (0, react$1.useCallback)((turn) => (turns?.get(turn) ?? turns?.get(String(turn)))?.status !== "open", [turns]);
|
|
53249
53341
|
const groupedView = (0, react$1.useMemo)(() => keyed ? buildProcessGroups(order, (key) => store?.get(key), isTurnClosed) : void 0, [
|
|
@@ -53924,7 +54016,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
53924
54016
|
* ▾ 下拉条目构造(**picker 与 dock 共用同一段代码**,差别只在入参——用户 2026-09-29 点名提炼,
|
|
53925
54017
|
* 严禁两处各写一份):
|
|
53926
54018
|
* - 当前工作区排第一(打开文件夹图标 + 加粗),**其下路径紧跟**(每层一个右箭头位缩进),
|
|
53927
|
-
* 再列其他工作区(关合图标 +
|
|
54019
|
+
* 再列其他工作区(关合图标 + 灰)——「打开哪个就跟在哪个下面」;点当前工作区 = 回到其根目录。
|
|
53928
54020
|
* - 当前工作区未知(rootName 空或不在清单)时路径段置顶、全部工作区按「其他」罗列;
|
|
53929
54021
|
* - workspaces 不传 = 不显示工作区段(旧形态兜底:根无箭头、其下逐层缩进)。
|
|
53930
54022
|
*/
|
|
@@ -53943,7 +54035,8 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
53943
54035
|
},
|
|
53944
54036
|
title: ws,
|
|
53945
54037
|
onClick: () => {
|
|
53946
|
-
if (
|
|
54038
|
+
if (current) onLoadDir("");
|
|
54039
|
+
else onPickWorkspace?.(ws);
|
|
53947
54040
|
}
|
|
53948
54041
|
}, (0, react$1.createElement)("span", { style: {
|
|
53949
54042
|
display: "inline-flex",
|
|
@@ -54424,7 +54517,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
54424
54517
|
if (!(entry.type === "directory")) {
|
|
54425
54518
|
const pick = () => {
|
|
54426
54519
|
if (picker && onPick !== void 0) {
|
|
54427
|
-
onPick(relativizeToRoot(childPath, sessionId));
|
|
54520
|
+
onPick(relativizeToRoot(childPath, sessionId), false);
|
|
54428
54521
|
return;
|
|
54429
54522
|
}
|
|
54430
54523
|
setViewing(childPath);
|
|
@@ -54448,23 +54541,28 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
54448
54541
|
}
|
|
54449
54542
|
const cached = childCache[childPath];
|
|
54450
54543
|
const isOpen = openDirs.has(childPath);
|
|
54451
|
-
const
|
|
54452
|
-
|
|
54453
|
-
|
|
54544
|
+
const rowAction = () => {
|
|
54545
|
+
toggleDir(childPath);
|
|
54546
|
+
};
|
|
54547
|
+
/** 行尾动作按钮(stopPropagation 防触发展开):选择器选中整个文件夹;浏览则进入该目录。 */
|
|
54548
|
+
const actThisDir = (event) => {
|
|
54549
|
+
event.stopPropagation();
|
|
54550
|
+
if (picker === true) {
|
|
54551
|
+
if (onPick !== void 0) onPick(relativizeToRoot(childPath, sessionId), true);
|
|
54454
54552
|
return;
|
|
54455
54553
|
}
|
|
54456
54554
|
loadDir(childPath);
|
|
54457
54555
|
};
|
|
54458
54556
|
return (0, react$1.createElement)(react$1.Fragment, { key: childPath }, (0, react$1.createElement)("div", {
|
|
54459
|
-
className: "dsh-tdt-sv-tree-row"
|
|
54557
|
+
className: "dsh-tdt-sv-tree-row",
|
|
54460
54558
|
role: "button",
|
|
54461
54559
|
tabIndex: 0,
|
|
54462
|
-
title:
|
|
54463
|
-
onClick:
|
|
54560
|
+
title: childPath,
|
|
54561
|
+
onClick: rowAction,
|
|
54464
54562
|
onKeyDown: (event) => {
|
|
54465
|
-
if (event.key === "Enter" || event.key === " ")
|
|
54563
|
+
if (event.key === "Enter" || event.key === " ") rowAction();
|
|
54466
54564
|
}
|
|
54467
|
-
},
|
|
54565
|
+
}, (0, react$1.createElement)("button", {
|
|
54468
54566
|
type: "button",
|
|
54469
54567
|
className: "dsh-tdt-sv-tree-toggle" + (isOpen ? " dsh-tdt-sv-tree-toggle-open" : ""),
|
|
54470
54568
|
"aria-expanded": isOpen,
|
|
@@ -54473,7 +54571,12 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
54473
54571
|
event.stopPropagation();
|
|
54474
54572
|
toggleDir(childPath);
|
|
54475
54573
|
}
|
|
54476
|
-
}, (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, { size: 16 }))
|
|
54574
|
+
}, (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, { size: 16 })), (0, react$1.createElement)("span", { className: "dsh-tdt-sv-tree-name" }, entry.name), picker === true && onPick === void 0 ? null : (0, react$1.createElement)("button", {
|
|
54575
|
+
type: "button",
|
|
54576
|
+
className: "dsh-tdt-sv-tree-act",
|
|
54577
|
+
"aria-label": picker === true ? t("editorPickerPickDir") : t("explorerEnter"),
|
|
54578
|
+
onClick: actThisDir
|
|
54579
|
+
}, t(picker === true ? "editorPickerSelect" : "explorerEnter"))), isOpen ? (0, react$1.createElement)("div", { className: "dsh-tdt-sv-tree-children" }, cached === void 0 || cached.status === "loading" ? null : cached.status === "error" ? (0, react$1.createElement)("div", { className: "dsh-tdt-sv-tree-err" }, t(cached.error.key, cached.error.params)) : (0, react$1.createElement)(react$1.Fragment, null, renderTree(cached.entries, childPath), cached.truncated ? (0, react$1.createElement)("div", { className: "dsh-tdt-sv-tree-truncated" }, t("explorerTruncated")) : null)) : null);
|
|
54477
54580
|
});
|
|
54478
54581
|
};
|
|
54479
54582
|
const rootAbs = workspaceRoots.get(sessionId);
|
|
@@ -64599,7 +64702,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
64599
64702
|
const absPath = item.path;
|
|
64600
64703
|
const anchor = item.anchorSessionId;
|
|
64601
64704
|
const key = item.key ?? item.name;
|
|
64602
|
-
const icon = (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
64705
|
+
const icon = item.isDir === true ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconFolderCloseRegular, { size: 14 }) : (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
64603
64706
|
path: item.name,
|
|
64604
64707
|
size: 14
|
|
64605
64708
|
});
|
|
@@ -64685,6 +64788,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
64685
64788
|
const canOpenSession = sid !== null && onOpenSession !== void 0;
|
|
64686
64789
|
const canOpenFile = sid !== null && onOpenFile !== void 0;
|
|
64687
64790
|
const outputs = outputsOf(instance.outputs);
|
|
64791
|
+
const processOutputs = outputsOf(instance.process_outputs);
|
|
64688
64792
|
const dur = durationMsOf(instance);
|
|
64689
64793
|
const tokens = instance.token_in === null && instance.token_out === null ? null : formatTokenCount((instance.token_in ?? 0) + (instance.token_out ?? 0));
|
|
64690
64794
|
const note = instance.note === null || instance.note === void 0 ? "" : instance.note;
|
|
@@ -64768,10 +64872,16 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
64768
64872
|
onClick: () => {
|
|
64769
64873
|
if (canOpenFile && onOpenFile !== void 0 && sid !== null) onOpenFile(sid, output);
|
|
64770
64874
|
}
|
|
64771
|
-
}, (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
64875
|
+
}, output.endsWith("/") ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconFolderCloseRegular, { size: 14 }) : (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
64772
64876
|
path: output,
|
|
64773
64877
|
size: 14
|
|
64774
|
-
}), (0, react$1.createElement)("span", { className: "dsh-tdt-ellipsis" }, baseNameOf(output)))))))
|
|
64878
|
+
}), (0, react$1.createElement)("span", { className: "dsh-tdt-ellipsis" }, baseNameOf(output)))))), (0, react$1.createElement)(ProcessFiles, {
|
|
64879
|
+
paths: processOutputs,
|
|
64880
|
+
onOpen: canOpenFile && onOpenFile !== void 0 ? (path) => {
|
|
64881
|
+
onOpenFile(sid, path);
|
|
64882
|
+
} : void 0,
|
|
64883
|
+
t
|
|
64884
|
+
}));
|
|
64775
64885
|
}
|
|
64776
64886
|
//#endregion
|
|
64777
64887
|
//#region src/client/event-subscribe.ts
|
|
@@ -65014,7 +65124,8 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
65014
65124
|
name: item.name,
|
|
65015
65125
|
key: item.id,
|
|
65016
65126
|
path: resolved?.path ?? null,
|
|
65017
|
-
anchorSessionId: resolved?.anchorSessionId ?? null
|
|
65127
|
+
anchorSessionId: resolved?.anchorSessionId ?? null,
|
|
65128
|
+
isDir: item.isDir
|
|
65018
65129
|
};
|
|
65019
65130
|
}),
|
|
65020
65131
|
depends: draft.deps.map((dep) => {
|
|
@@ -65390,7 +65501,8 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
65390
65501
|
name: item.name,
|
|
65391
65502
|
kind: item.kind,
|
|
65392
65503
|
ref: item.ref,
|
|
65393
|
-
...typeof item.workspace === "string" ? { workspace: item.workspace } : {}
|
|
65504
|
+
...typeof item.workspace === "string" ? { workspace: item.workspace } : {},
|
|
65505
|
+
...typeof item.isDir === "boolean" ? { isDir: item.isDir } : {}
|
|
65394
65506
|
})) : [],
|
|
65395
65507
|
versions: [],
|
|
65396
65508
|
...typeof definition.createdAt === "string" && definition.createdAt !== "" ? { createdAt: definition.createdAt } : {}
|
|
@@ -66626,7 +66738,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
66626
66738
|
flex: "none",
|
|
66627
66739
|
display: "flex",
|
|
66628
66740
|
alignItems: "center"
|
|
66629
|
-
} }, (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
66741
|
+
} }, att.isDir === true ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconFolderCloseRegular, { size: 16 }) : (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
66630
66742
|
path: att.name,
|
|
66631
66743
|
size: 16
|
|
66632
66744
|
})), (0, react$1.createElement)("span", {
|
|
@@ -67413,14 +67525,15 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
67413
67525
|
setPickerOpen(false);
|
|
67414
67526
|
},
|
|
67415
67527
|
picker: true,
|
|
67416
|
-
onPick: (p) => {
|
|
67528
|
+
onPick: (p, isDir) => {
|
|
67417
67529
|
const name = p.slice(Math.max(p.lastIndexOf("/"), p.lastIndexOf("\\")) + 1);
|
|
67418
67530
|
addAttachment({
|
|
67419
67531
|
id: makeId(),
|
|
67420
67532
|
name,
|
|
67421
67533
|
kind: "link",
|
|
67422
67534
|
ref: p,
|
|
67423
|
-
workspace: pickerWs
|
|
67535
|
+
workspace: pickerWs,
|
|
67536
|
+
isDir
|
|
67424
67537
|
});
|
|
67425
67538
|
setPickerOpen(false);
|
|
67426
67539
|
},
|
|
@@ -67794,6 +67907,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
67794
67907
|
minWidth: 0
|
|
67795
67908
|
} }, (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconAlarmClockOutlineRegular, { size: 12 }), renderNextExec(row.scheduled_at, t))) : null;
|
|
67796
67909
|
const outputs = outputsOf(row.outputs);
|
|
67910
|
+
const processOutputs = outputsOf(row.process_outputs);
|
|
67797
67911
|
const sid = row.session_id;
|
|
67798
67912
|
const canOpenSession = sid !== null && sid !== "";
|
|
67799
67913
|
const canOpenFile = canOpenSession && openFile !== void 0;
|
|
@@ -67806,8 +67920,9 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
67806
67920
|
const actual = clockLabelOf(row.dispatched_at, dayKey, crossFmt, t("recPrevDay"), t("recNextDay"));
|
|
67807
67921
|
const deps = isPlanned ? plannedDeps ?? [] : resolvedDepsOf(snapshot);
|
|
67808
67922
|
const hasOutputs = outputs.length > 0;
|
|
67923
|
+
const hasProcess = processOutputs.length > 0;
|
|
67809
67924
|
const hasDeps = deps.length > 0;
|
|
67810
|
-
const hasExpand = hasOutputs || hasDeps || !isPlanned;
|
|
67925
|
+
const hasExpand = hasOutputs || hasProcess || hasDeps || !isPlanned;
|
|
67811
67926
|
/** token 三段之一:null 给占位(不编造 0)。 */
|
|
67812
67927
|
const tokenPart = (v) => v === null ? "—" : formatTokenCount(v);
|
|
67813
67928
|
/**
|
|
@@ -67921,7 +68036,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
67921
68036
|
event.stopPropagation();
|
|
67922
68037
|
if (canOpenFile) openFile?.(sid, path);
|
|
67923
68038
|
}
|
|
67924
|
-
}, (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
68039
|
+
}, path.endsWith("/") ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconFolderCloseRegular, { size: 16 }) : (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
67925
68040
|
path,
|
|
67926
68041
|
size: 16
|
|
67927
68042
|
})))), outputs.length > 3 ? (0, react$1.createElement)("button", {
|
|
@@ -67950,7 +68065,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
67950
68065
|
},
|
|
67951
68066
|
"aria-expanded": open,
|
|
67952
68067
|
style: { transform: open ? "rotate(180deg)" : "none" }
|
|
67953
|
-
})) : null)), open && (hasOutputs || hasDeps || eventsError !== null || events !== null && events.length > 0) ? (0, react$1.createElement)("div", { className: "dsh-tdt-rec-exp" }, outputs.length === 0 ? null : (0, react$1.createElement)("div", { className: "dsh-tdt-rec-expouts" }, outputs.map((path) => (0, react$1.createElement)("button", {
|
|
68068
|
+
})) : null)), open && (hasOutputs || hasProcess || hasDeps || eventsError !== null || events !== null && events.length > 0) ? (0, react$1.createElement)("div", { className: "dsh-tdt-rec-exp" }, outputs.length === 0 ? null : (0, react$1.createElement)("div", { className: "dsh-tdt-rec-expouts" }, outputs.map((path) => (0, react$1.createElement)("button", {
|
|
67954
68069
|
key: path,
|
|
67955
68070
|
type: "button",
|
|
67956
68071
|
title: path,
|
|
@@ -67959,7 +68074,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
67959
68074
|
onClick: () => {
|
|
67960
68075
|
if (canOpenFile) openFile?.(sid, path);
|
|
67961
68076
|
}
|
|
67962
|
-
}, (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
68077
|
+
}, path.endsWith("/") ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconFolderCloseRegular, { size: 14 }) : (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
67963
68078
|
path,
|
|
67964
68079
|
size: 14
|
|
67965
68080
|
}), (0, react$1.createElement)(MarqueeText, {
|
|
@@ -67969,7 +68084,13 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
67969
68084
|
maxWidth: "40ch",
|
|
67970
68085
|
minWidth: 0
|
|
67971
68086
|
}
|
|
67972
|
-
})))),
|
|
68087
|
+
})))), (0, react$1.createElement)(ProcessFiles, {
|
|
68088
|
+
paths: processOutputs,
|
|
68089
|
+
onOpen: canOpenFile ? (path) => {
|
|
68090
|
+
openFile?.(sid, path);
|
|
68091
|
+
} : void 0,
|
|
68092
|
+
t
|
|
68093
|
+
}), deps.length === 0 ? null : (0, react$1.createElement)("div", { className: "dsh-tdt-rec-depsec" }, (0, react$1.createElement)("div", { className: "dsh-tdt-rec-evtitle" }, t("listSectionDepends")), (0, react$1.createElement)("div", { className: "dsh-tdt-rec-depgrid" }, deps.map((dep, index) => {
|
|
67973
68094
|
const depOuts = Array.isArray(dep.outputs) ? dep.outputs : [];
|
|
67974
68095
|
const depSid = dep.sessionId;
|
|
67975
68096
|
const depHasSid = depSid !== null && depSid !== "";
|
|
@@ -68016,7 +68137,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
68016
68137
|
event.stopPropagation();
|
|
68017
68138
|
if (depCanOpen) openFile?.(depSid, path);
|
|
68018
68139
|
}
|
|
68019
|
-
}, (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
68140
|
+
}, path.endsWith("/") ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconFolderCloseRegular, { size: 16 }) : (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
68020
68141
|
path,
|
|
68021
68142
|
size: 16
|
|
68022
68143
|
})))), depOuts.length > DEP_OUT_MAX ? (0, react$1.createElement)("button", {
|
|
@@ -69779,7 +69900,8 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
69779
69900
|
name: item.name,
|
|
69780
69901
|
key: `${item.kind}:${item.name}`,
|
|
69781
69902
|
path: item.path ?? null,
|
|
69782
|
-
anchorSessionId: item.anchorSessionId ?? null
|
|
69903
|
+
anchorSessionId: item.anchorSessionId ?? null,
|
|
69904
|
+
isDir: item.isDir
|
|
69783
69905
|
})),
|
|
69784
69906
|
depends: row.depends.map((dep) => ({
|
|
69785
69907
|
id: dep.id,
|
|
@@ -69935,7 +70057,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
69935
70057
|
event.stopPropagation();
|
|
69936
70058
|
if (canOpenFile && openFile !== void 0 && sid !== null) openFile(sid, output);
|
|
69937
70059
|
}
|
|
69938
|
-
}, (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
70060
|
+
}, output.endsWith("/") ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconFolderCloseRegular, { size: 16 }) : (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
69939
70061
|
path: output,
|
|
69940
70062
|
size: 16
|
|
69941
70063
|
})))), outputs.length > 3 ? (0, react$1.createElement)("button", {
|
|
@@ -70264,7 +70386,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
70264
70386
|
}) : null);
|
|
70265
70387
|
}
|
|
70266
70388
|
function TaskListView(props) {
|
|
70267
|
-
const { t, rows, ready, onEdit, onViewTask, onDelete, onRunNow, onOpenFile, onOpenSession, onToggleEnabled, refresh, workspaces } = props;
|
|
70389
|
+
const { t, rows, ready, onEdit, onViewTask, onDelete, onRunNow, onOpenFile, onOpenSession, onToggleEnabled, refresh, workspaces, onCreate } = props;
|
|
70268
70390
|
const tt = (0, react$1.useMemo)(() => interpolateTranslate(t), [t]);
|
|
70269
70391
|
ensureTaskListStyle();
|
|
70270
70392
|
ensureTaskInfoStyle();
|
|
@@ -70372,10 +70494,38 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
70372
70494
|
size: "md",
|
|
70373
70495
|
width: WS_WIDTH,
|
|
70374
70496
|
marquee: true
|
|
70375
|
-
}))), visible.length === 0 ? (0, react$1.createElement)("
|
|
70497
|
+
}))), visible.length === 0 ? rows.length === 0 && !ready ? null : rows.length === 0 ? (0, react$1.createElement)("div", { style: {
|
|
70498
|
+
display: "flex",
|
|
70499
|
+
flexDirection: "column",
|
|
70500
|
+
alignItems: "center",
|
|
70501
|
+
justifyContent: "center",
|
|
70502
|
+
margin: "24px auto 0",
|
|
70503
|
+
padding: "48px 32px",
|
|
70504
|
+
textAlign: "center",
|
|
70505
|
+
border: "1px dashed var(--tdt-border-heavy)",
|
|
70506
|
+
borderRadius: "var(--tdt-radius-md)",
|
|
70507
|
+
background: "var(--tdt-surface-1)"
|
|
70508
|
+
} }, (0, react$1.createElement)("div", { style: { color: "var(--tdt-fg-3)" } }, (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.IconAlarmClockOutlineRegular, { size: 40 })), (0, react$1.createElement)("div", { style: {
|
|
70509
|
+
marginTop: "12px",
|
|
70510
|
+
fontSize: "var(--tdt-font-lg)",
|
|
70511
|
+
fontWeight: 600
|
|
70512
|
+
} }, t("listEmptyTitle")), (0, react$1.createElement)("div", { style: {
|
|
70513
|
+
marginTop: "6px",
|
|
70514
|
+
maxWidth: "360px",
|
|
70515
|
+
fontSize: "var(--tdt-font-sm)",
|
|
70516
|
+
color: "var(--tdt-fg-2)",
|
|
70517
|
+
lineHeight: "var(--tdt-line-sm)"
|
|
70518
|
+
} }, t("listEmptyHint")), (0, react$1.createElement)(Button$2, {
|
|
70519
|
+
variant: "primary",
|
|
70520
|
+
size: "md",
|
|
70521
|
+
style: { marginTop: "16px" },
|
|
70522
|
+
onClick: () => {
|
|
70523
|
+
onCreate();
|
|
70524
|
+
}
|
|
70525
|
+
}, t("listEmptyAction"))) : (0, react$1.createElement)("p", { style: {
|
|
70376
70526
|
...metaStyle,
|
|
70377
70527
|
marginTop: "8px"
|
|
70378
|
-
} },
|
|
70528
|
+
} }, t("listEmptyFiltered")) : (0, react$1.createElement)("div", { style: { position: "relative" } }, visible.map((row) => (0, react$1.createElement)(TaskCard, {
|
|
70379
70529
|
key: row.id,
|
|
70380
70530
|
row,
|
|
70381
70531
|
t,
|
|
@@ -71421,7 +71571,10 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
71421
71571
|
const avail = Math.min(Math.floor(window.innerWidth * PREVIEW_MAX_RATIO), window.innerWidth - 760 - reserved);
|
|
71422
71572
|
return Math.min(Math.max(Math.round(value), PREVIEW_MIN), Math.max(PREVIEW_MIN, Math.floor(avail)));
|
|
71423
71573
|
}
|
|
71424
|
-
/**
|
|
71574
|
+
/**
|
|
71575
|
+
* 实例行的产出物(决策 32③写回的列:JSON 数组,兼容逗号串)。
|
|
71576
|
+
* 2026-10-10 起 `outputs`(主文件)与 `process_outputs`(过程文件)**同一形状**,共用这一个解析器。
|
|
71577
|
+
*/
|
|
71425
71578
|
function parseOutputs(raw) {
|
|
71426
71579
|
if (typeof raw === "string" && raw.trim() !== "") {
|
|
71427
71580
|
try {
|
|
@@ -71513,11 +71666,14 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
71513
71666
|
const [saving, setSaving] = (0, react$1.useState)(false);
|
|
71514
71667
|
const [failed, setFailed] = (0, react$1.useState)(null);
|
|
71515
71668
|
const [failedKey, setFailedKey] = (0, react$1.useState)(0);
|
|
71516
|
-
const [
|
|
71517
|
-
const
|
|
71518
|
-
const
|
|
71519
|
-
|
|
71520
|
-
|
|
71669
|
+
const [successToast, setSuccessToast] = (0, react$1.useState)(null);
|
|
71670
|
+
const successSeq = (0, react$1.useRef)(0);
|
|
71671
|
+
const notify = (text) => {
|
|
71672
|
+
successSeq.current += 1;
|
|
71673
|
+
setSuccessToast({
|
|
71674
|
+
text,
|
|
71675
|
+
seq: successSeq.current
|
|
71676
|
+
});
|
|
71521
71677
|
};
|
|
71522
71678
|
const [invalidToast, setInvalidToast] = (0, react$1.useState)({
|
|
71523
71679
|
on: false,
|
|
@@ -71564,10 +71720,11 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
71564
71720
|
const openFile = (0, react$1.useCallback)((sessionId, path) => {
|
|
71565
71721
|
if (!canPreview) return;
|
|
71566
71722
|
lastWorkspaceSessionId.current = sessionId;
|
|
71567
|
-
setPreview({
|
|
71723
|
+
setPreview((prev) => ({
|
|
71568
71724
|
sessionId,
|
|
71569
|
-
path
|
|
71570
|
-
|
|
71725
|
+
path,
|
|
71726
|
+
seq: (prev?.seq ?? 0) + 1
|
|
71727
|
+
}));
|
|
71571
71728
|
}, [canPreview]);
|
|
71572
71729
|
const closePreview = (0, react$1.useCallback)(() => {
|
|
71573
71730
|
setPreview(null);
|
|
@@ -71785,7 +71942,8 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
71785
71942
|
/**
|
|
71786
71943
|
* 删除任务(决策 55,卡片右下角快捷删除):DELETE /tasks { id }。
|
|
71787
71944
|
* 服务端语义:摘定义 + 整删任务目录(附件 / 版本 / 快照),实例 / 事件保留做审计;
|
|
71788
|
-
* 成功后 overview.refresh()
|
|
71945
|
+
* 成功后 overview.refresh() 让列表立刻少一行;若右侧正在编辑 / 查看该任务则一并关窗;
|
|
71946
|
+
* 失败走 viewErr 条(操作类失败留时间读)。
|
|
71789
71947
|
*/
|
|
71790
71948
|
const deleteTask = async (id) => {
|
|
71791
71949
|
try {
|
|
@@ -71801,6 +71959,8 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
71801
71959
|
return message;
|
|
71802
71960
|
}
|
|
71803
71961
|
overview.refresh();
|
|
71962
|
+
if (editor?.id === id) setEditor(null);
|
|
71963
|
+
notify(t("editorTaskDeleted"));
|
|
71804
71964
|
return null;
|
|
71805
71965
|
} catch (error) {
|
|
71806
71966
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -71859,7 +72019,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
71859
72019
|
}
|
|
71860
72020
|
const missing = Array.isArray(body.missingAttachments) ? body.missingAttachments.filter((item) => typeof item === "string") : [];
|
|
71861
72021
|
setEditor(null);
|
|
71862
|
-
|
|
72022
|
+
notify(t("editorTaskSaved"));
|
|
71863
72023
|
if (typeof body.id === "string" && body.id !== "") overview.patchRow(body.id, rowPatchOf(definition));
|
|
71864
72024
|
overview.refresh();
|
|
71865
72025
|
if (missing.length > 0) setViewErr(`已保存,但以下附加文件已不在盘上,请重新上传:${missing.join("、")}`);
|
|
@@ -71885,6 +72045,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
71885
72045
|
}
|
|
71886
72046
|
setEditor(null);
|
|
71887
72047
|
overview.refresh();
|
|
72048
|
+
notify(t("editorTaskDeleted"));
|
|
71888
72049
|
} catch (error) {
|
|
71889
72050
|
setEditorError(humanizeTaskError(error instanceof Error ? error.message : String(error)));
|
|
71890
72051
|
}
|
|
@@ -72080,6 +72241,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
72080
72241
|
view: target,
|
|
72081
72242
|
didUnarchive,
|
|
72082
72243
|
outputs: row === null ? void 0 : parseOutputs(row.outputs),
|
|
72244
|
+
processOutputs: row === null ? void 0 : parseOutputs(row.process_outputs),
|
|
72083
72245
|
upstream: upstreamOf(row?.snapshot ?? null),
|
|
72084
72246
|
attached: row === null ? [] : attachmentsOf(row.snapshot ?? null, row.attachmentPaths),
|
|
72085
72247
|
workspacePath: workspacePathOf(row?.snapshot ?? null)
|
|
@@ -72183,7 +72345,8 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
72183
72345
|
onToggleEnabled: toggleTaskEnabled,
|
|
72184
72346
|
onRunNow: runTaskNow,
|
|
72185
72347
|
onViewTask: openViewer,
|
|
72186
|
-
workspaces: editorOptions.workspaces
|
|
72348
|
+
workspaces: editorOptions.workspaces,
|
|
72349
|
+
onCreate: openCreate
|
|
72187
72350
|
}) : tab === "settings" ? (0, react$1.createElement)(SettingsPage, { t }) : data === void 0 ? (0, react$1.createElement)("div", null, (0, react$1.createElement)("p", { style: hintStyle }, hasRaw ? t("debugRaw") : t("debugEmpty")), hasRaw ? (0, react$1.createElement)("pre", { style: preStyle }, raw) : null) : null, (0, react$1.createElement)(BackToTop, null)), viewing !== null ? (0, react$1.createElement)(SessionViewModal, {
|
|
72188
72351
|
t,
|
|
72189
72352
|
heading: viewing.heading,
|
|
@@ -72194,6 +72357,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
72194
72357
|
sessionId: viewing.sessionId,
|
|
72195
72358
|
view: viewing.view,
|
|
72196
72359
|
outputs: viewing.outputs,
|
|
72360
|
+
processOutputs: viewing.processOutputs,
|
|
72197
72361
|
forkSession: forkSession ?? void 0,
|
|
72198
72362
|
openHostSession: openHostSession ?? void 0,
|
|
72199
72363
|
workspaceFiles: workspaceFiles ?? void 0,
|
|
@@ -72219,6 +72383,14 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
72219
72383
|
onDone: () => {
|
|
72220
72384
|
setViewErr(null);
|
|
72221
72385
|
}
|
|
72386
|
+
}) : null, successToast !== null ? (0, react$1.createElement)(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
72387
|
+
key: successToast.seq,
|
|
72388
|
+
text: successToast.text,
|
|
72389
|
+
tone: "success",
|
|
72390
|
+
holdMs: 2500,
|
|
72391
|
+
onDone: () => {
|
|
72392
|
+
setSuccessToast(null);
|
|
72393
|
+
}
|
|
72222
72394
|
}) : null, editor !== null ? (0, react$1.createElement)(TaskEditorDrawer, {
|
|
72223
72395
|
key: editor.id,
|
|
72224
72396
|
t,
|
|
@@ -72281,7 +72453,7 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
72281
72453
|
officeToPdf,
|
|
72282
72454
|
workspaceAnchors: editorOptions.workspaceAnchors
|
|
72283
72455
|
}) : null, preview !== null && workspaceFiles !== null ? (0, react$1.createElement)(FileBrowser, {
|
|
72284
|
-
key: `${preview.sessionId}:${preview.path}`,
|
|
72456
|
+
key: `${preview.sessionId}:${preview.path}:${preview.seq}`,
|
|
72285
72457
|
workspaceFiles,
|
|
72286
72458
|
officeToPdf,
|
|
72287
72459
|
sessionId: preview.sessionId,
|
|
@@ -72294,9 +72466,10 @@ button.dsh-tdt-sv-tfc-file:focus-visible{box-shadow:inset 0 0 0 2px var(--tdt-fo
|
|
|
72294
72466
|
workspaces: editorOptions.workspaces.map((w) => w.value),
|
|
72295
72467
|
onSelectWorkspace: (name) => {
|
|
72296
72468
|
const anchor = editorOptions.workspaceAnchors[name];
|
|
72297
|
-
if (anchor !== void 0 && anchor !== preview.sessionId) setPreview({
|
|
72469
|
+
if (anchor !== void 0 && anchor !== preview.sessionId) setPreview((prev) => prev === null ? null : {
|
|
72298
72470
|
sessionId: anchor,
|
|
72299
|
-
path: ""
|
|
72471
|
+
path: "",
|
|
72472
|
+
seq: prev.seq + 1
|
|
72300
72473
|
});
|
|
72301
72474
|
}
|
|
72302
72475
|
}) : null);
|