@cannbot-plugin/cannbot-harness 0.3.3 → 0.3.5
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/LICENSE +38 -0
- package/README.md +37 -9
- package/THIRD_PARTY_NOTICES.md +9 -7
- package/WORKFLOW_PUBLISHING.md +5 -1
- package/icon.svg +1 -1
- package/lib/client.js +550 -435
- package/lib/client.js.map +1 -1
- package/lib/index.js +1079 -151
- package/official-plugins.json +45 -11
- package/package.json +11 -8
- package/workflow-defaults.json +23 -59
- package/runtime/initializer-compat.cjs +0 -25
- package/upstream.json +0 -61
package/lib/client.js
CHANGED
|
@@ -31,10 +31,15 @@ window.__ModuleLoader__.load({
|
|
|
31
31
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
32
32
|
_deepseek_ai_dsh_client_ui_primitives = __toESM(_deepseek_ai_dsh_client_ui_primitives, 1);
|
|
33
33
|
//#region src/client/locales.ts
|
|
34
|
-
const PRODUCT = "CANNBot
|
|
34
|
+
const PRODUCT = "CANNBot";
|
|
35
35
|
const NAMESPACE = "cannbotHarness";
|
|
36
36
|
const PACKAGE = "@cannbot-plugin/cannbot-harness";
|
|
37
37
|
const zh = {
|
|
38
|
+
tasksTitle: "任务列表",
|
|
39
|
+
tasksDone: "已完成",
|
|
40
|
+
tasksRecent: "仅显示最近完成",
|
|
41
|
+
tasksAll: "查看全部任务",
|
|
42
|
+
currentWorkflow: "工作流",
|
|
38
43
|
contentCatalog: "工作流目录",
|
|
39
44
|
contentCheck: "检查工作流更新",
|
|
40
45
|
contentVersion: "当前版本",
|
|
@@ -83,27 +88,20 @@ window.__ModuleLoader__.load({
|
|
|
83
88
|
commandHint: "发送时自动应用所选工作流,只需填写需求。",
|
|
84
89
|
flash: "ops-direct-invoke-flash",
|
|
85
90
|
registry: "ops-registry-invoke",
|
|
86
|
-
model: "model-infer-optimize",
|
|
87
|
-
hccl: "hccl-op-generator",
|
|
88
|
-
triton: "triton-op-generator",
|
|
89
|
-
catlass: "catlass-op-generator",
|
|
90
|
-
performance: "ops-perf-optimize",
|
|
91
|
-
pypto: "pypto-op-orchestrator",
|
|
92
91
|
operatorDescription: "开发 Ascend C 算子,通过直调方式接入使用。",
|
|
93
92
|
flashDescription: "快速生成并验证 Ascend C 算子。",
|
|
94
93
|
registryDescription: "开发 Ascend C 注册算子,通过 ACLNN / GEIR 接入框架。",
|
|
95
|
-
modelDescription: "将模型迁移到 NPU,完成精度对齐与推理性能优化。",
|
|
96
|
-
hcclDescription: "开发 HCCL AICPU 通信算子,协同完成代码生成与验证。",
|
|
97
|
-
tritonDescription: "生成并优化 Triton-Ascend 算子代码。",
|
|
98
|
-
catlassDescription: "基于 CATLASS 模板开发矩阵计算、注意力等算子,验证精度与性能。",
|
|
99
|
-
performanceDescription: "分析并优化 Ascend C 算子性能,验证精度并检查性能退化。",
|
|
100
|
-
pyptoDescription: "开发并调优 PyPTO 算子,也支持对已有算子单独调优。",
|
|
101
94
|
chooseWorkspace: "请先选择工作目录。",
|
|
102
95
|
insertFailed: "工作流准备或设置未完成,请到插件详情查看准备日志后重试。",
|
|
103
96
|
settingsRetry: "设置连接失败,重试",
|
|
104
97
|
workflowRetry: "工作流未就绪,重试"
|
|
105
98
|
};
|
|
106
99
|
const en = {
|
|
100
|
+
tasksTitle: "Tasks",
|
|
101
|
+
tasksDone: "Completed",
|
|
102
|
+
tasksRecent: "Show recent completions",
|
|
103
|
+
tasksAll: "Show all tasks",
|
|
104
|
+
currentWorkflow: "Workflow",
|
|
107
105
|
contentCatalog: "Workflow catalog",
|
|
108
106
|
contentCheck: "Check workflow updates",
|
|
109
107
|
contentVersion: "Installed",
|
|
@@ -152,21 +150,9 @@ window.__ModuleLoader__.load({
|
|
|
152
150
|
commandHint: "The selected workflow is applied in the background when you send.",
|
|
153
151
|
flash: "ops-direct-invoke-flash",
|
|
154
152
|
registry: "ops-registry-invoke",
|
|
155
|
-
model: "model-infer-optimize",
|
|
156
|
-
hccl: "hccl-op-generator",
|
|
157
|
-
triton: "triton-op-generator",
|
|
158
|
-
catlass: "catlass-op-generator",
|
|
159
|
-
performance: "ops-perf-optimize",
|
|
160
|
-
pypto: "pypto-op-orchestrator",
|
|
161
153
|
operatorDescription: "Develop Ascend C operators and integrate them through direct invocation.",
|
|
162
154
|
flashDescription: "Quickly generate and validate Ascend C operators.",
|
|
163
155
|
registryDescription: "Develop registered Ascend C operators for framework integration through ACLNN / GEIR.",
|
|
164
|
-
modelDescription: "Migrate models to NPU, align accuracy and optimize inference performance.",
|
|
165
|
-
hcclDescription: "Develop HCCL AICPU communication operators with coordinated code generation and validation.",
|
|
166
|
-
tritonDescription: "Generate and optimize Triton-Ascend operator code.",
|
|
167
|
-
catlassDescription: "Build matrix and attention operators using CATLASS templates; validate accuracy and performance.",
|
|
168
|
-
performanceDescription: "Analyze and optimize Ascend C operator performance, checking accuracy and regressions.",
|
|
169
|
-
pyptoDescription: "Develop and tune PyPTO operators, or tune existing operators independently.",
|
|
170
156
|
chooseWorkspace: "Choose a working directory first.",
|
|
171
157
|
insertFailed: "Workflow preparation or saving failed. Check preparation logs in the plugin details and retry.",
|
|
172
158
|
settingsRetry: "Reconnect settings",
|
|
@@ -202,13 +188,13 @@ window.__ModuleLoader__.load({
|
|
|
202
188
|
function SidebarName() {
|
|
203
189
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
204
190
|
className: "cannbot-harness-name",
|
|
205
|
-
children:
|
|
191
|
+
children: "CANNBot"
|
|
206
192
|
});
|
|
207
193
|
}
|
|
208
194
|
function Hero({ size }) {
|
|
209
195
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
210
196
|
"data-cannbot-harness-hero": "",
|
|
211
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Mark, { size }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children:
|
|
197
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Mark, { size }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "CANNBot" })]
|
|
212
198
|
});
|
|
213
199
|
}
|
|
214
200
|
//#endregion
|
|
@@ -228,36 +214,6 @@ window.__ModuleLoader__.load({
|
|
|
228
214
|
id: "ops-registry-invoke",
|
|
229
215
|
label: "registry",
|
|
230
216
|
description: "registryDescription"
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
id: "model-infer-optimize",
|
|
234
|
-
label: "model",
|
|
235
|
-
description: "modelDescription"
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
id: "hccl-op-generator",
|
|
239
|
-
label: "hccl",
|
|
240
|
-
description: "hcclDescription"
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
id: "triton-op-generator",
|
|
244
|
-
label: "triton",
|
|
245
|
-
description: "tritonDescription"
|
|
246
|
-
},
|
|
247
|
-
{
|
|
248
|
-
id: "catlass-op-generator",
|
|
249
|
-
label: "catlass",
|
|
250
|
-
description: "catlassDescription"
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
id: "ops-perf-optimize",
|
|
254
|
-
label: "performance",
|
|
255
|
-
description: "performanceDescription"
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
id: "pypto-op-orchestrator",
|
|
259
|
-
label: "pypto",
|
|
260
|
-
description: "pyptoDescription"
|
|
261
217
|
}
|
|
262
218
|
];
|
|
263
219
|
//#endregion
|
|
@@ -320,7 +276,9 @@ window.__ModuleLoader__.load({
|
|
|
320
276
|
}
|
|
321
277
|
};
|
|
322
278
|
const endpoint = () => new URL(CONTENT_PATH, document.baseURI);
|
|
279
|
+
let requestSequence = 0;
|
|
323
280
|
const pull = async () => {
|
|
281
|
+
const sequence = ++requestSequence;
|
|
324
282
|
try {
|
|
325
283
|
const response = await fetch(endpoint(), {
|
|
326
284
|
credentials: "same-origin",
|
|
@@ -329,11 +287,12 @@ window.__ModuleLoader__.load({
|
|
|
329
287
|
});
|
|
330
288
|
if (response.ok) {
|
|
331
289
|
const status = await response.json();
|
|
332
|
-
if (Array.isArray(status.plugins) && status.plugins.every((item) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(item.id) && typeof item.title === "string")) publish(status);
|
|
290
|
+
if (sequence === requestSequence && Array.isArray(status.plugins) && status.plugins.every((item) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(item.id) && typeof item.title === "string")) publish(status);
|
|
333
291
|
}
|
|
334
292
|
} catch {}
|
|
335
293
|
};
|
|
336
294
|
const post = async (body) => {
|
|
295
|
+
++requestSequence;
|
|
337
296
|
if (!(await fetch(endpoint(), {
|
|
338
297
|
method: "POST",
|
|
339
298
|
credentials: "same-origin",
|
|
@@ -505,6 +464,74 @@ window.__ModuleLoader__.load({
|
|
|
505
464
|
const noSubscribe = () => () => {};
|
|
506
465
|
const noSnapshot = () => void 0;
|
|
507
466
|
//#endregion
|
|
467
|
+
//#region src/client/SessionWorkflow.tsx
|
|
468
|
+
/** Read the committed selection for this header's Session, including after reload. */
|
|
469
|
+
function SessionWorkflow({ sessionId, selection, t }) {
|
|
470
|
+
const workflow = (0, react.useSyncExternalStore)(selection.subscribe, selection.getSnapshot).values[sessionId];
|
|
471
|
+
if (!workflow) return null;
|
|
472
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
473
|
+
className: "cannbot-harness-session-workflow",
|
|
474
|
+
title: `${t("currentWorkflow")}: ${workflow}`,
|
|
475
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("currentWorkflow") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: workflow })]
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
//#endregion
|
|
479
|
+
//#region src/client/TaskList.tsx
|
|
480
|
+
/** One view of the native todos projection, including a compact completion history. */
|
|
481
|
+
function TaskList({ todos, t }) {
|
|
482
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
483
|
+
const [showAll, setShowAll] = (0, react.useState)(false);
|
|
484
|
+
if (!todos.length) return null;
|
|
485
|
+
const done = todos.filter((task) => task.status === "completed");
|
|
486
|
+
const open = todos.filter((task) => task.status !== "completed");
|
|
487
|
+
const visible = [...(showAll ? done : done.slice(-2)).reverse(), ...open];
|
|
488
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
489
|
+
className: "cannbot-task-list",
|
|
490
|
+
"aria-label": t("tasksTitle"),
|
|
491
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
492
|
+
className: "cannbot-task-list-toggle",
|
|
493
|
+
type: "button",
|
|
494
|
+
"aria-expanded": expanded,
|
|
495
|
+
onClick: () => setExpanded((value) => !value),
|
|
496
|
+
children: [
|
|
497
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("tasksTitle") }),
|
|
498
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
499
|
+
role: "status",
|
|
500
|
+
children: [
|
|
501
|
+
t("tasksDone"),
|
|
502
|
+
" ",
|
|
503
|
+
done.length,
|
|
504
|
+
" / ",
|
|
505
|
+
todos.length
|
|
506
|
+
]
|
|
507
|
+
}),
|
|
508
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
509
|
+
className: "cannbot-task-list-chevron",
|
|
510
|
+
"aria-hidden": true,
|
|
511
|
+
children: expanded ? "⌄" : "⌃"
|
|
512
|
+
})
|
|
513
|
+
]
|
|
514
|
+
}), expanded && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", { children: visible.map((task) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
515
|
+
"data-status": task.status,
|
|
516
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
517
|
+
className: "cannbot-task-list-icon",
|
|
518
|
+
"aria-hidden": true,
|
|
519
|
+
children: task.status === "in_progress" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: "ongoing" }) : task.status === "completed" ? "✓" : "○"
|
|
520
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: task.content })]
|
|
521
|
+
}, task.content)) }), done.length > 2 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
522
|
+
type: "button",
|
|
523
|
+
onClick: () => setShowAll((value) => !value),
|
|
524
|
+
children: t(showAll ? "tasksRecent" : "tasksAll")
|
|
525
|
+
})] })]
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
function TaskDock({ useProjection, t }) {
|
|
529
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TaskList, {
|
|
530
|
+
todos: useProjection("todos") ?? [],
|
|
531
|
+
t
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
//#endregion
|
|
508
535
|
//#region src/client/theme.ts
|
|
509
536
|
/** Portal design-v2 palette, applied through the documented theme override layer. */
|
|
510
537
|
const cannTheme = Object.fromEntries(Object.entries({
|
|
@@ -552,11 +579,11 @@ window.__ModuleLoader__.load({
|
|
|
552
579
|
dark: values[1]
|
|
553
580
|
}]));
|
|
554
581
|
//#endregion
|
|
555
|
-
//#region \0dsh-inline-css
|
|
582
|
+
//#region \0dsh-inline-css:/home/t00607008/cannbot-dsh/cannbot/dsh/src/client/interface.css.mjs
|
|
556
583
|
var interface_css_default = "span:has(>[data-slot=\"conversation.hero.brand.mark\"]>[data-cannbot-harness-hero]){width:auto;min-width:0;height:auto}span:has(>[data-slot=\"conversation.hero.brand.mark\"]>[data-cannbot-harness-hero])+span{display:none}[data-cannbot-harness-hero]{letter-spacing:-.6px;color:var(--dsw-alias-label-primary);justify-content:center;align-items:center;gap:12px;font-size:26px;font-weight:650;line-height:1.3;display:inline-flex}[data-cannbot-harness-hero] svg{flex-shrink:0}.cannbot-harness-name{letter-spacing:-.3px;font-weight:650}";
|
|
557
584
|
//#endregion
|
|
558
|
-
//#region \0dsh-global-css
|
|
559
|
-
const css$1 = ".cannbot-harness-workflow{flex-direction:column;align-items:flex-start;gap:4px;min-width:120px;max-width:280px;display:inline-flex;position:relative}.cannbot-harness-workflow-anchor{flex:none;min-width:120px;max-width:100%}.cannbot-harness-workflow-trigger{border-radius:var(--dsw-radius-sm);min-width:0;max-width:100%;min-height:28px;color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border:0;align-items:center;gap:4px;padding:0 8px;font-family:inherit;font-size:13px;font-weight:500;line-height:20px;display:inline-flex}.cannbot-harness-workflow-trigger svg{flex:none}.cannbot-harness-workflow-trigger svg:last-child{color:var(--dsw-alias-label-caption)}.cannbot-harness-workflow-trigger[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}.cannbot-harness-workflow-trigger:disabled{cursor:default;color:var(--dsw-alias-label-quaternary)}.cannbot-harness-workflow-trigger:focus-visible{outline:2px solid var(--dsw-focus-ring-color);outline-offset:2px}.cannbot-harness-workflow-label{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}@media (hover:hover){.cannbot-harness-workflow-trigger:not(:disabled):hover{background:var(--dsw-alias-interactive-bg-hover)}}.cannbot-harness-workflow-option{white-space:normal;flex-direction:column;gap:4px;max-width:320px;padding:5px 0;display:flex}.cannbot-harness-workflow-option small{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5}.cannbot-harness-error{color:var(--dsw-alias-label-secondary);max-width:100%;font-size:12px;line-height:18px}.cannbot-harness-error button{color:inherit;font:inherit;text-align:start;cursor:pointer;text-underline-offset:3px;background:0 0;border:0;padding:0 8px;text-decoration:underline}.cannbot-harness-toggle{box-sizing:border-box;justify-content:space-between;align-items:center;gap:8px;width:100%;padding:8px;display:flex}.cannbot-harness-toggle-name{min-width:0;color:var(--dsw-alias-label-primary);align-items:center;gap:8px;font-size:12px;line-height:20px;display:inline-flex}.cannbot-harness-toggle-name svg{flex-shrink:0}.cannbot-harness-toggle-compact{flex-direction:column;gap:6px}.cannbot-harness-switch{background:var(--dsw-alias-interactive-bg-hover,#d7dadd);cursor:pointer;border:0;border-radius:99px;flex-shrink:0;width:36px;height:20px;padding:2px}.cannbot-harness-switch[aria-checked=true]{background:#cf1740}.cannbot-harness-switch>span{background:#fff;border-radius:50%;width:16px;height:16px;display:block;transform:translate(0)}.cannbot-harness-switch[aria-checked=true]>span{transform:translate(16px)}.cannbot-harness-switch:focus-visible{outline:2px solid var(--dsw-focus-ring-color,#cf1740);outline-offset:2px}.cannbot-harness-update{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:var(--dsw-radius-md,12px);color:var(--dsw-alias-label-primary);padding:16px}.cannbot-harness-update-heading{flex-wrap:wrap;align-items:baseline;gap:12px;margin-bottom:14px;display:flex}.cannbot-harness-update h4{margin:0;font-size:14px;font-weight:600}.cannbot-harness-update-heading>span,.cannbot-harness-update p{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.6}.cannbot-harness-update-actions{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.cannbot-harness-update-button{box-sizing:border-box;background:var(--dsw-alias-brand-primary,#cf1740);color:#fff;min-height:32px;font:inherit;cursor:pointer;border:0;border-radius:8px;align-items:center;padding:5px 14px;font-size:13px;text-decoration:none;display:inline-flex}.cannbot-harness-update-button:disabled{opacity:.6;cursor:default}.cannbot-harness-update-button:focus-visible,.cannbot-harness-update-recheck:focus-visible{outline:2px solid var(--dsw-focus-ring-color,#cf1740);outline-offset:3px}.cannbot-harness-update-recheck{font:inherit;color:var(--dsw-alias-brand-primary,#cf1740);cursor:pointer;background:0 0;border:0;padding:4px;font-size:12px}.cannbot-harness-update p{margin:10px 0 0}.cannbot-harness-content{margin-top:16px}.cannbot-harness-content details{margin-top:12px;font-size:12px}.cannbot-harness-content summary{cursor:pointer}.cannbot-harness-content pre{white-space:pre-wrap;overflow-wrap:anywhere;max-height:220px;font-size:11px;line-height:1.5;overflow:auto}.cannbot-harness-workflow-package{border-bottom:1px solid var(--dsw-alias-border-l2,#eee);justify-content:space-between;align-items:center;gap:12px;padding:14px 0;display:flex}.cannbot-harness-workflow-package>div:first-child{min-width:0}.cannbot-harness-workflow-package strong{font-size:13px;font-weight:500}.cannbot-harness-workflow-package small{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;font-size:11px;line-height:1.6;display:block}.cannbot-harness-workflow-package-actions{flex-wrap:wrap;flex-shrink:0;justify-content:flex-end;gap:8px;display:flex}@media (width<=480px){.cannbot-harness-workflow-package{flex-direction:column;align-items:flex-start}}";
|
|
585
|
+
//#region \0dsh-global-css:/home/t00607008/cannbot-dsh/cannbot/dsh/src/client/controls.css.mjs
|
|
586
|
+
const css$1 = ".cannbot-harness-workflow{flex-direction:column;align-items:flex-start;gap:4px;min-width:120px;max-width:280px;display:inline-flex;position:relative}.cannbot-harness-workflow-anchor{flex:none;min-width:120px;max-width:100%}.cannbot-harness-workflow-trigger{border-radius:var(--dsw-radius-sm);min-width:0;max-width:100%;min-height:28px;color:var(--dsw-alias-label-primary);white-space:nowrap;cursor:pointer;background:0 0;border:0;align-items:center;gap:4px;padding:0 8px;font-family:inherit;font-size:13px;font-weight:500;line-height:20px;display:inline-flex}.cannbot-harness-workflow-trigger svg{flex:none}.cannbot-harness-workflow-trigger svg:last-child{color:var(--dsw-alias-label-caption)}.cannbot-harness-workflow-trigger[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}.cannbot-harness-workflow-trigger:disabled{cursor:default;color:var(--dsw-alias-label-quaternary)}.cannbot-harness-workflow-trigger:focus-visible{outline:2px solid var(--dsw-focus-ring-color);outline-offset:2px}.cannbot-harness-workflow-label{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}@media (hover:hover){.cannbot-harness-workflow-trigger:not(:disabled):hover{background:var(--dsw-alias-interactive-bg-hover)}}.cannbot-harness-workflow-option{white-space:normal;flex-direction:column;gap:4px;max-width:320px;padding:5px 0;display:flex}.cannbot-harness-workflow-option small{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5}.cannbot-harness-error{color:var(--dsw-alias-label-secondary);max-width:100%;font-size:12px;line-height:18px}.cannbot-harness-error button{color:inherit;font:inherit;text-align:start;cursor:pointer;text-underline-offset:3px;background:0 0;border:0;padding:0 8px;text-decoration:underline}.cannbot-harness-toggle{box-sizing:border-box;justify-content:space-between;align-items:center;gap:8px;width:100%;padding:8px;display:flex}.cannbot-harness-toggle-name{min-width:0;color:var(--dsw-alias-label-primary);align-items:center;gap:8px;font-size:12px;line-height:20px;display:inline-flex}.cannbot-harness-toggle-name svg{flex-shrink:0}.cannbot-harness-toggle-compact{flex-direction:column;gap:6px}.cannbot-harness-switch{background:var(--dsw-alias-interactive-bg-hover,#d7dadd);cursor:pointer;border:0;border-radius:99px;flex-shrink:0;width:36px;height:20px;padding:2px}.cannbot-harness-switch[aria-checked=true]{background:#cf1740}.cannbot-harness-switch>span{background:#fff;border-radius:50%;width:16px;height:16px;display:block;transform:translate(0)}.cannbot-harness-switch[aria-checked=true]>span{transform:translate(16px)}.cannbot-harness-switch:focus-visible{outline:2px solid var(--dsw-focus-ring-color,#cf1740);outline-offset:2px}.cannbot-harness-update{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:var(--dsw-radius-md,12px);color:var(--dsw-alias-label-primary);padding:16px}.cannbot-harness-update-heading{flex-wrap:wrap;align-items:baseline;gap:12px;margin-bottom:14px;display:flex}.cannbot-harness-update h4{margin:0;font-size:14px;font-weight:600}.cannbot-harness-update-heading>span,.cannbot-harness-update p{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.6}.cannbot-harness-update-actions{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.cannbot-harness-update-button{box-sizing:border-box;background:var(--dsw-alias-brand-primary,#cf1740);color:#fff;min-height:32px;font:inherit;cursor:pointer;border:0;border-radius:8px;align-items:center;padding:5px 14px;font-size:13px;text-decoration:none;display:inline-flex}.cannbot-harness-update-button:disabled{opacity:.6;cursor:default}.cannbot-harness-update-button:focus-visible,.cannbot-harness-update-recheck:focus-visible{outline:2px solid var(--dsw-focus-ring-color,#cf1740);outline-offset:3px}.cannbot-harness-update-recheck{font:inherit;color:var(--dsw-alias-brand-primary,#cf1740);cursor:pointer;background:0 0;border:0;padding:4px;font-size:12px}.cannbot-harness-update p{margin:10px 0 0}.cannbot-harness-content{margin-top:16px}.cannbot-harness-content details{margin-top:12px;font-size:12px}.cannbot-harness-content summary{cursor:pointer}.cannbot-harness-content pre{white-space:pre-wrap;overflow-wrap:anywhere;max-height:220px;font-size:11px;line-height:1.5;overflow:auto}.cannbot-harness-workflow-package{border-bottom:1px solid var(--dsw-alias-border-l2,#eee);justify-content:space-between;align-items:center;gap:12px;padding:14px 0;display:flex}.cannbot-harness-workflow-package>div:first-child{min-width:0}.cannbot-harness-workflow-package strong{font-size:13px;font-weight:500}.cannbot-harness-workflow-package small{color:var(--dsw-alias-label-secondary);overflow-wrap:anywhere;font-size:11px;line-height:1.6;display:block}.cannbot-harness-workflow-package-actions{flex-wrap:wrap;flex-shrink:0;justify-content:flex-end;gap:8px;display:flex}@media (width<=480px){.cannbot-harness-workflow-package{flex-direction:column;align-items:flex-start}}.cannbot-harness-session-workflow{border-radius:var(--dsw-radius-sm,6px);background:var(--dsw-alias-interactive-bg-hover);min-width:0;max-width:min(320px,40vw);color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;padding:3px 8px;font-size:12px;line-height:20px;display:inline-flex}.cannbot-harness-session-workflow>span{flex-shrink:0}.cannbot-harness-session-workflow code{text-overflow:ellipsis;white-space:nowrap;font-size:inherit;color:var(--dsw-alias-label-primary);overflow:hidden}.cannbot-task-list{width:calc(100% - 48px);max-width:var(--dsh-composer-card-max-width,760px);box-sizing:border-box;border-radius:var(--dsw-radius-lg,12px);background:var(--dsw-specific-menu);color:var(--dsw-alias-label-primary);margin:0 auto;padding:8px 12px;font-size:13px}.cannbot-task-list .cannbot-task-list-toggle{text-align:left;flex-wrap:wrap;align-items:center;gap:12px;width:100%;padding:0;display:flex}.cannbot-task-list-toggle span{color:var(--dsw-alias-label-secondary)}.cannbot-task-list-chevron{margin-left:auto}.cannbot-task-list button{color:inherit;font:inherit;cursor:pointer;background:0 0;border:0;margin-left:auto}.cannbot-task-list ul{max-height:220px;margin:8px 0 0;padding:0;list-style:none;overflow-y:auto}.cannbot-task-list li{overflow-wrap:anywhere;gap:8px;padding:3px 0;display:flex}.cannbot-task-list li[data-status=completed]{color:var(--dsw-alias-label-secondary)}.cannbot-task-list-icon{flex:none;justify-content:center;align-items:center;width:14px;display:inline-flex}";
|
|
560
587
|
const tagId$1 = "@cannbot-plugin/cannbot-harness/controls.css";
|
|
561
588
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
562
589
|
const tag = document.createElement("style");
|
|
@@ -574,7 +601,7 @@ window.__ModuleLoader__.load({
|
|
|
574
601
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
575
602
|
className: "cannbot-harness-toggle-name",
|
|
576
603
|
title: PRODUCT,
|
|
577
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Mark, { size: 20 }), wide && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "CANNBot
|
|
604
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Mark, { size: 20 }), wide && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "CANNBot" })]
|
|
578
605
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
579
606
|
type: "button",
|
|
580
607
|
role: "switch",
|
|
@@ -818,12 +845,7 @@ window.__ModuleLoader__.load({
|
|
|
818
845
|
}
|
|
819
846
|
//#endregion
|
|
820
847
|
//#region src/client/plugin-update.ts
|
|
821
|
-
const UPDATE_PACKAGES = [
|
|
822
|
-
"cannbot-harness",
|
|
823
|
-
"cannbot-dsh",
|
|
824
|
-
"dsh-cannbot",
|
|
825
|
-
"@cannbot-plugin/cannbot-harness"
|
|
826
|
-
];
|
|
848
|
+
const UPDATE_PACKAGES = ["cannbot-harness", "@cannbot-plugin/cannbot-harness"];
|
|
827
849
|
/** Only stable npm releases of our two installation entries may be selected. */
|
|
828
850
|
function newerVersion(candidate, current) {
|
|
829
851
|
const next = /^(\d+)\.(\d+)\.(\d+)$/.exec(candidate);
|
|
@@ -833,7 +855,7 @@ window.__ModuleLoader__.load({
|
|
|
833
855
|
const difference = Number(next[index]) - Number(old[index]);
|
|
834
856
|
if (difference) return difference > 0;
|
|
835
857
|
}
|
|
836
|
-
return current
|
|
858
|
+
return /^\d+\.\d+\.\d+-/.test(current);
|
|
837
859
|
}
|
|
838
860
|
async function latestRelease(name, signal) {
|
|
839
861
|
if (!UPDATE_PACKAGES.includes(name)) throw new Error("Unsupported update target");
|
|
@@ -1253,13 +1275,7 @@ window.__ModuleLoader__.load({
|
|
|
1253
1275
|
//#endregion
|
|
1254
1276
|
//#region src/client/workbench-data.ts
|
|
1255
1277
|
/** Presentation copy only. Execution and initialization remain owned by the workflow packages. */
|
|
1256
|
-
const categories = [
|
|
1257
|
-
"全部",
|
|
1258
|
-
"Ascend C",
|
|
1259
|
-
"其他算子",
|
|
1260
|
-
"通信",
|
|
1261
|
-
"性能优化"
|
|
1262
|
-
];
|
|
1278
|
+
const categories = ["全部", "Ascend C"];
|
|
1263
1279
|
const guides = {
|
|
1264
1280
|
"ops-direct-invoke": {
|
|
1265
1281
|
category: "Ascend C",
|
|
@@ -1284,58 +1300,10 @@ window.__ModuleLoader__.load({
|
|
|
1284
1300
|
inputs: ["必需:算子定义、输入输出及接入方式", "可选:现有工程、参考实现及目标环境"],
|
|
1285
1301
|
outputs: ["注册算子相关代码及接入示例", "按实际环境完成的验证与使用说明"],
|
|
1286
1302
|
example: "开发一个 Ascend C 的自定义算子,并通过 ACLNN 接入。请先检查当前工程及输入输出定义。"
|
|
1287
|
-
},
|
|
1288
|
-
"triton-op-generator": {
|
|
1289
|
-
category: "其他算子",
|
|
1290
|
-
icon: "code",
|
|
1291
|
-
scenes: ["使用 Triton-Ascend 开发算子", "优化已有 Triton 算子实现"],
|
|
1292
|
-
inputs: ["必需:功能需求或已有 Triton 代码", "可选:张量规格、目标硬件与性能目标"],
|
|
1293
|
-
outputs: ["Triton-Ascend 算子代码", "实际执行的验证与调优记录"],
|
|
1294
|
-
example: "使用 Triton-Ascend 实现一个逐元素 Add 算子,并为不同输入形状添加验证。"
|
|
1295
|
-
},
|
|
1296
|
-
"catlass-op-generator": {
|
|
1297
|
-
category: "其他算子",
|
|
1298
|
-
icon: "layers",
|
|
1299
|
-
scenes: ["基于 CATLASS 模板开发矩阵计算算子", "开发注意力相关算子并验证精度与性能"],
|
|
1300
|
-
inputs: ["必需:计算需求及张量规格", "可选:CATLASS 工程、参考实现与性能目标"],
|
|
1301
|
-
outputs: ["基于 CATLASS 的实现及调用示例", "可用环境中的精度与性能验证结果"],
|
|
1302
|
-
example: "基于 CATLASS 模板开发一个矩阵乘算子,请先检查工程环境,再验证精度与性能。"
|
|
1303
|
-
},
|
|
1304
|
-
"pypto-op-orchestrator": {
|
|
1305
|
-
category: "其他算子",
|
|
1306
|
-
icon: "nodes",
|
|
1307
|
-
scenes: ["使用 PyPTO 开发并调优算子", "单独调优已有的 PyPTO 算子"],
|
|
1308
|
-
inputs: ["必需:算子需求或已有 PyPTO 代码", "可选:测试用例、目标硬件与性能目标"],
|
|
1309
|
-
outputs: ["PyPTO 算子实现或调优修改", "按实际执行情况整理的验证与优化结果"],
|
|
1310
|
-
example: "请分析当前 PyPTO 算子,保持计算结果一致,尝试优化性能并记录验证结果。"
|
|
1311
|
-
},
|
|
1312
|
-
"hccl-op-generator": {
|
|
1313
|
-
category: "通信",
|
|
1314
|
-
icon: "arrows",
|
|
1315
|
-
scenes: ["开发 HCCL AICPU 通信算子", "生成通信代码并准备验证"],
|
|
1316
|
-
inputs: ["必需:通信操作、参与设备及数据规格", "可选:现有通信工程及运行环境"],
|
|
1317
|
-
outputs: ["通信算子相关代码", "在可用设备环境中的验证结果及运行说明"],
|
|
1318
|
-
example: "帮我开发一个 HCCL AICPU 通信算子,请先确认通信操作、设备数量和测试环境。"
|
|
1319
|
-
},
|
|
1320
|
-
"ops-perf-optimize": {
|
|
1321
|
-
category: "性能优化",
|
|
1322
|
-
icon: "chart",
|
|
1323
|
-
scenes: ["分析已有 Ascend C 算子的性能瓶颈", "在保持精度的前提下迭代调优"],
|
|
1324
|
-
inputs: ["必需:已有算子代码及复现方法", "可选:基准数据、性能分析结果与目标"],
|
|
1325
|
-
outputs: ["性能分析及代码修改", "精度检查、性能对比及退化检查记录"],
|
|
1326
|
-
example: "请分析当前 Ascend C 算子的性能瓶颈,在保持精度的前提下优化,并对比修改前后的表现。"
|
|
1327
|
-
},
|
|
1328
|
-
"model-infer-optimize": {
|
|
1329
|
-
category: "性能优化",
|
|
1330
|
-
icon: "gear",
|
|
1331
|
-
scenes: ["将模型迁移到 NPU", "对齐精度并优化推理性能"],
|
|
1332
|
-
inputs: ["必需:模型代码、依赖及运行方法", "可选:模型权重路径、测试数据和基准结果"],
|
|
1333
|
-
outputs: ["模型迁移或推理优化修改", "实际完成的精度对齐与性能验证记录"],
|
|
1334
|
-
example: "请将当前模型迁移到 NPU,先检查依赖与运行方式,再进行精度对齐和推理性能优化。"
|
|
1335
1303
|
}
|
|
1336
1304
|
};
|
|
1337
1305
|
const guideFor = (id) => guides[id] ?? {
|
|
1338
|
-
category: "
|
|
1306
|
+
category: "Ascend C",
|
|
1339
1307
|
icon: "nodes",
|
|
1340
1308
|
scenes: ["使用此工作流完成开发需求"],
|
|
1341
1309
|
inputs: ["请描述目标,并提供相关工程或代码"],
|
|
@@ -1381,6 +1349,144 @@ window.__ModuleLoader__.load({
|
|
|
1381
1349
|
});
|
|
1382
1350
|
}
|
|
1383
1351
|
//#endregion
|
|
1352
|
+
//#region src/client/WorkspaceDirectory.tsx
|
|
1353
|
+
/** Browse Host directories through the capability shared by Web and desktop pickers. */
|
|
1354
|
+
function WorkspaceDirectory({ ctx, initialPath, onSelect, onClose }) {
|
|
1355
|
+
const dialog = (0, react.useRef)(null);
|
|
1356
|
+
const lifetime = (0, react.useRef)(null);
|
|
1357
|
+
const request = (0, react.useRef)(null);
|
|
1358
|
+
const [listing, setListing] = (0, react.useState)();
|
|
1359
|
+
const [path, setPath] = (0, react.useState)(initialPath ?? "");
|
|
1360
|
+
const [loading, setLoading] = (0, react.useState)(true);
|
|
1361
|
+
const [saving, setSaving] = (0, react.useState)(false);
|
|
1362
|
+
const [error, setError] = (0, react.useState)("");
|
|
1363
|
+
const browse = async (target) => {
|
|
1364
|
+
request.current?.abort();
|
|
1365
|
+
const controller = new AbortController();
|
|
1366
|
+
request.current = controller;
|
|
1367
|
+
setLoading(true);
|
|
1368
|
+
setError("");
|
|
1369
|
+
setListing(void 0);
|
|
1370
|
+
try {
|
|
1371
|
+
const next = await ctx.uiWorkspace.listDirectory(target || void 0, controller.signal);
|
|
1372
|
+
if (!controller.signal.aborted) {
|
|
1373
|
+
setListing(next);
|
|
1374
|
+
setPath(next.path);
|
|
1375
|
+
}
|
|
1376
|
+
} catch (reason) {
|
|
1377
|
+
if (!controller.signal.aborted) setError(reason instanceof Error ? reason.message : "无法读取目录,请重试。");
|
|
1378
|
+
} finally {
|
|
1379
|
+
if (!controller.signal.aborted) setLoading(false);
|
|
1380
|
+
}
|
|
1381
|
+
};
|
|
1382
|
+
(0, react.useEffect)(() => {
|
|
1383
|
+
lifetime.current = new AbortController();
|
|
1384
|
+
dialog.current?.showModal();
|
|
1385
|
+
browse(initialPath);
|
|
1386
|
+
return () => {
|
|
1387
|
+
lifetime.current?.abort();
|
|
1388
|
+
request.current?.abort();
|
|
1389
|
+
};
|
|
1390
|
+
}, []);
|
|
1391
|
+
const choose = async () => {
|
|
1392
|
+
if (!listing || loading || saving) return;
|
|
1393
|
+
setSaving(true);
|
|
1394
|
+
setError("");
|
|
1395
|
+
try {
|
|
1396
|
+
const selected = ctx.workspaces.list.getSnapshot().items.find((item) => item.path === listing.path) ?? await ctx.workspaces.create({ path: listing.path });
|
|
1397
|
+
if (!lifetime.current?.signal.aborted) {
|
|
1398
|
+
onSelect(selected.workspaceId);
|
|
1399
|
+
onClose();
|
|
1400
|
+
}
|
|
1401
|
+
} catch (reason) {
|
|
1402
|
+
if (!lifetime.current?.signal.aborted) setError(reason instanceof Error ? reason.message : "无法选择工作区,请重试。");
|
|
1403
|
+
} finally {
|
|
1404
|
+
if (!lifetime.current?.signal.aborted) setSaving(false);
|
|
1405
|
+
}
|
|
1406
|
+
};
|
|
1407
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dialog", {
|
|
1408
|
+
ref: dialog,
|
|
1409
|
+
className: "cwb-directory",
|
|
1410
|
+
"aria-label": "选择工作区目录",
|
|
1411
|
+
onCancel: (event) => {
|
|
1412
|
+
event.preventDefault();
|
|
1413
|
+
if (!saving) onClose();
|
|
1414
|
+
},
|
|
1415
|
+
children: [
|
|
1416
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: "选择工作区" }),
|
|
1417
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "选择 DSH 所在机器上的项目目录。" }),
|
|
1418
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
1419
|
+
onSubmit: (event) => {
|
|
1420
|
+
event.preventDefault();
|
|
1421
|
+
if (!saving) browse(path);
|
|
1422
|
+
},
|
|
1423
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1424
|
+
"aria-label": "目录路径",
|
|
1425
|
+
value: path,
|
|
1426
|
+
disabled: saving,
|
|
1427
|
+
onChange: (event) => setPath(event.target.value)
|
|
1428
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1429
|
+
className: "cwb-text-button",
|
|
1430
|
+
disabled: saving,
|
|
1431
|
+
type: "submit",
|
|
1432
|
+
children: "打开目录"
|
|
1433
|
+
})]
|
|
1434
|
+
}),
|
|
1435
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("nav", {
|
|
1436
|
+
"aria-label": "目录层级",
|
|
1437
|
+
children: listing?.crumbs.map((crumb) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1438
|
+
type: "button",
|
|
1439
|
+
className: "cwb-text-button",
|
|
1440
|
+
disabled: saving,
|
|
1441
|
+
onClick: () => void browse(crumb.path),
|
|
1442
|
+
children: crumb.name || crumb.path
|
|
1443
|
+
}, crumb.path))
|
|
1444
|
+
}),
|
|
1445
|
+
loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1446
|
+
role: "status",
|
|
1447
|
+
children: "正在读取目录…"
|
|
1448
|
+
}) : listing && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1449
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
1450
|
+
className: "cwb-directory-list",
|
|
1451
|
+
children: listing.entries.map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1452
|
+
type: "button",
|
|
1453
|
+
disabled: saving,
|
|
1454
|
+
onClick: () => void browse(entry.path),
|
|
1455
|
+
children: [
|
|
1456
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, {
|
|
1457
|
+
name: "folder",
|
|
1458
|
+
size: 16
|
|
1459
|
+
}),
|
|
1460
|
+
" ",
|
|
1461
|
+
entry.name
|
|
1462
|
+
]
|
|
1463
|
+
}) }, entry.path))
|
|
1464
|
+
}),
|
|
1465
|
+
!listing.entries.length && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "此目录下没有子目录,可以直接选择当前目录。" }),
|
|
1466
|
+
listing.truncated && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "目录较多,仅显示部分结果;可输入完整路径打开。" })
|
|
1467
|
+
] }),
|
|
1468
|
+
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1469
|
+
role: "alert",
|
|
1470
|
+
className: "cwb-error",
|
|
1471
|
+
children: error
|
|
1472
|
+
}),
|
|
1473
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1474
|
+
type: "button",
|
|
1475
|
+
className: "cwb-text-button",
|
|
1476
|
+
disabled: saving,
|
|
1477
|
+
onClick: onClose,
|
|
1478
|
+
children: "取消"
|
|
1479
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1480
|
+
type: "button",
|
|
1481
|
+
className: "cwb-primary",
|
|
1482
|
+
disabled: loading || saving || !listing || path !== listing.path,
|
|
1483
|
+
onClick: () => void choose(),
|
|
1484
|
+
children: saving ? "正在选择…" : "选择此目录"
|
|
1485
|
+
})] })
|
|
1486
|
+
]
|
|
1487
|
+
});
|
|
1488
|
+
}
|
|
1489
|
+
//#endregion
|
|
1384
1490
|
//#region src/client/workbench-launch.ts
|
|
1385
1491
|
/** Transfer to the resident DSH composer; its own submit policy remains authoritative. */
|
|
1386
1492
|
async function launchWorkbench(ctx, selection, request, signal, onStage = () => {}) {
|
|
@@ -1415,8 +1521,8 @@ window.__ModuleLoader__.load({
|
|
|
1415
1521
|
if (request.files.length) {
|
|
1416
1522
|
onStage("upload");
|
|
1417
1523
|
if (typeof conversation.createDrafts !== "function") throw new Error("此 DSH 版本请进入对话后添加文件。");
|
|
1418
|
-
attachments = conversation.createDrafts(id, request.files
|
|
1419
|
-
await waitForUploads(conversation, attachments.map((item) => item.id), signal);
|
|
1524
|
+
attachments = conversation.createDrafts(id, request.files);
|
|
1525
|
+
await waitForUploads(conversation, attachments.filter((item) => item.kind === "file").map((item) => item.id), signal);
|
|
1420
1526
|
if (!input.addAttachments(attachments.map((item) => item.id))) throw new Error("文件暂时无法加入对话,请重试。");
|
|
1421
1527
|
}
|
|
1422
1528
|
signal.throwIfAborted();
|
|
@@ -1476,6 +1582,7 @@ window.__ModuleLoader__.load({
|
|
|
1476
1582
|
const saved = (0, react.useSyncExternalStore)(selection.subscribe, selection.getSnapshot);
|
|
1477
1583
|
const [category, setCategory] = (0, react.useState)("全部");
|
|
1478
1584
|
const [query, setQuery] = (0, react.useState)("");
|
|
1585
|
+
const [pickingWorkspace, setPickingWorkspace] = (0, react.useState)(false);
|
|
1479
1586
|
const input = (0, react.useRef)(null);
|
|
1480
1587
|
const files = (0, react.useRef)(null);
|
|
1481
1588
|
const visible = [...workflows].sort((a, b) => (cardOrder.indexOf(a.id) < 0 ? 999 : cardOrder.indexOf(a.id)) - (cardOrder.indexOf(b.id) < 0 ? 999 : cardOrder.indexOf(b.id))).filter((workflow) => (category === "全部" || guideFor(workflow.id).category === category) && `${workflow.id} ${copy(workflow).description}`.toLowerCase().includes(query.toLowerCase().trim()));
|
|
@@ -1487,28 +1594,6 @@ window.__ModuleLoader__.load({
|
|
|
1487
1594
|
const navigate = (panel) => ctx.layout.selectPanel(panel);
|
|
1488
1595
|
const settings = () => ctx.get("pluginNavigation")?.openBundle(PACKAGE);
|
|
1489
1596
|
const fail = (error) => store.set({ error: error instanceof Error ? error.message : "暂时无法完成,请重试。" });
|
|
1490
|
-
const addWorkspace = async () => {
|
|
1491
|
-
if (store.getSnapshot().busy) return;
|
|
1492
|
-
store.set({
|
|
1493
|
-
error: "",
|
|
1494
|
-
busy: true,
|
|
1495
|
-
stage: "workspace"
|
|
1496
|
-
});
|
|
1497
|
-
try {
|
|
1498
|
-
const path = await ctx.uiWorkspace.pickDirectory();
|
|
1499
|
-
if (path && !store.signal.aborted) {
|
|
1500
|
-
const created = await ctx.workspaces.create({ path });
|
|
1501
|
-
store.set({ workspaceId: created.workspaceId });
|
|
1502
|
-
}
|
|
1503
|
-
} catch (error) {
|
|
1504
|
-
fail(error);
|
|
1505
|
-
} finally {
|
|
1506
|
-
store.set({
|
|
1507
|
-
busy: false,
|
|
1508
|
-
stage: "idle"
|
|
1509
|
-
});
|
|
1510
|
-
}
|
|
1511
|
-
};
|
|
1512
1597
|
const start = async (event) => {
|
|
1513
1598
|
event?.preventDefault();
|
|
1514
1599
|
if (store.getSnapshot().busy) return;
|
|
@@ -1556,307 +1641,321 @@ window.__ModuleLoader__.load({
|
|
|
1556
1641
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("main", {
|
|
1557
1642
|
className: "cannbot-workbench",
|
|
1558
1643
|
"aria-label": library ? "CANNBot 工作流" : "CANNBot工作台",
|
|
1559
|
-
children: [
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1644
|
+
children: [
|
|
1645
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
1646
|
+
className: "cwb-header",
|
|
1647
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1648
|
+
className: "cwb-workspace",
|
|
1649
|
+
children: [
|
|
1650
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, { name: "folder" }),
|
|
1651
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1652
|
+
className: "cwb-workspace-info",
|
|
1653
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1654
|
+
className: "cwb-workspace-choice",
|
|
1655
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1656
|
+
"aria-label": "当前工作区",
|
|
1657
|
+
value: workspace?.workspaceId ?? "",
|
|
1658
|
+
disabled: state.busy || workspaceState.phase !== "ready",
|
|
1659
|
+
onChange: (event) => store.set({
|
|
1660
|
+
workspaceId: event.target.value,
|
|
1661
|
+
error: ""
|
|
1662
|
+
}),
|
|
1663
|
+
children: [!workspace && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1664
|
+
value: "",
|
|
1665
|
+
children: "选择工作区"
|
|
1666
|
+
}), workspaceState.items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1667
|
+
value: item.workspaceId,
|
|
1668
|
+
children: item.title === "default-workspace" ? "默认工作区" : item.title
|
|
1669
|
+
}, item.workspaceId))]
|
|
1670
|
+
}), inherited && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1671
|
+
className: "cwb-inherited",
|
|
1672
|
+
children: "沿用当前对话"
|
|
1673
|
+
})]
|
|
1674
|
+
}), workspace && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1675
|
+
className: "cwb-workspace-path",
|
|
1676
|
+
title: workspace.path,
|
|
1677
|
+
children: workspace.path
|
|
1678
|
+
})]
|
|
1679
|
+
}),
|
|
1680
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1681
|
+
className: "cwb-text-button",
|
|
1682
|
+
disabled: state.busy,
|
|
1683
|
+
onClick: () => setPickingWorkspace(true),
|
|
1684
|
+
children: "选择工作区"
|
|
1685
|
+
})
|
|
1686
|
+
]
|
|
1687
|
+
}), library && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1688
|
+
className: "cwb-text-button",
|
|
1689
|
+
onClick: settings,
|
|
1690
|
+
children: "插件设置"
|
|
1691
|
+
})]
|
|
1692
|
+
}),
|
|
1693
|
+
pickingWorkspace && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkspaceDirectory, {
|
|
1694
|
+
ctx,
|
|
1695
|
+
initialPath: workspace?.path,
|
|
1696
|
+
onSelect: (workspaceId) => {
|
|
1697
|
+
if (!store.signal.aborted) store.set({
|
|
1698
|
+
workspaceId,
|
|
1699
|
+
error: ""
|
|
1700
|
+
});
|
|
1701
|
+
},
|
|
1702
|
+
onClose: () => setPickingWorkspace(false)
|
|
1703
|
+
}),
|
|
1704
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1705
|
+
className: "cwb-content",
|
|
1563
1706
|
children: [
|
|
1564
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, { name: "folder" }),
|
|
1565
1707
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1566
|
-
className: "cwb-
|
|
1567
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1708
|
+
className: "cwb-heading",
|
|
1709
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", { children: library ? "找到适合你的工作流" : "开始你的 Ascend 开发" }), library && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "了解适用场景,准备好输入,再开始。" })]
|
|
1710
|
+
}),
|
|
1711
|
+
!library && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1712
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
1713
|
+
className: "cwb-composer",
|
|
1714
|
+
onSubmit: (event) => void start(event),
|
|
1715
|
+
onDragOver: (event) => event.preventDefault(),
|
|
1716
|
+
onDrop: (event) => {
|
|
1717
|
+
event.preventDefault();
|
|
1718
|
+
if (!state.busy) store.set({ files: [...state.files, ...Array.from(event.dataTransfer.files)] });
|
|
1719
|
+
},
|
|
1720
|
+
children: [
|
|
1721
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
1722
|
+
ref: input,
|
|
1723
|
+
"aria-label": "开发需求",
|
|
1724
|
+
placeholder: selected ? `例如:${guideFor(selected.id).example}` : "描述算子需求,或添加需要优化的代码。",
|
|
1725
|
+
value: state.prompt,
|
|
1726
|
+
disabled: state.busy,
|
|
1727
|
+
onChange: (event) => store.set({ prompt: event.target.value })
|
|
1728
|
+
}),
|
|
1729
|
+
state.files.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
1730
|
+
className: "cwb-files",
|
|
1731
|
+
children: state.files.map((file, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [
|
|
1732
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, {
|
|
1733
|
+
name: "document",
|
|
1734
|
+
size: 14
|
|
1735
|
+
}),
|
|
1736
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: file.name }),
|
|
1737
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1738
|
+
type: "button",
|
|
1739
|
+
disabled: state.busy,
|
|
1740
|
+
"aria-label": `移除 ${file.name}`,
|
|
1741
|
+
onClick: () => store.set({ files: state.files.filter((_, i) => i !== index) }),
|
|
1742
|
+
children: "×"
|
|
1743
|
+
})
|
|
1744
|
+
] }, `${file.name}-${index}`))
|
|
1576
1745
|
}),
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
children: "
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1746
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1747
|
+
className: "cwb-composer-actions",
|
|
1748
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1749
|
+
className: "cwb-composer-tools",
|
|
1750
|
+
children: [
|
|
1751
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1752
|
+
type: "file",
|
|
1753
|
+
multiple: true,
|
|
1754
|
+
hidden: true,
|
|
1755
|
+
ref: files,
|
|
1756
|
+
onChange: (event) => {
|
|
1757
|
+
store.set({ files: [...state.files, ...Array.from(event.target.files ?? [])] });
|
|
1758
|
+
event.target.value = "";
|
|
1759
|
+
}
|
|
1760
|
+
}),
|
|
1761
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1762
|
+
type: "button",
|
|
1763
|
+
className: "cwb-text-button",
|
|
1764
|
+
disabled: state.busy,
|
|
1765
|
+
onClick: () => files.current?.click(),
|
|
1766
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, {
|
|
1767
|
+
name: "clip",
|
|
1768
|
+
size: 18
|
|
1769
|
+
}), "添加文件"]
|
|
1770
|
+
}),
|
|
1771
|
+
state.workflow && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1772
|
+
className: "cwb-selection",
|
|
1773
|
+
children: [
|
|
1774
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, {
|
|
1775
|
+
name: guideFor(state.workflow).icon,
|
|
1776
|
+
size: 16
|
|
1777
|
+
}),
|
|
1778
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: state.workflow }),
|
|
1779
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1780
|
+
type: "button",
|
|
1781
|
+
disabled: state.busy,
|
|
1782
|
+
"aria-label": "取消工作流选择",
|
|
1783
|
+
onClick: () => store.set({ workflow: "" }),
|
|
1784
|
+
children: "×"
|
|
1785
|
+
})
|
|
1786
|
+
]
|
|
1787
|
+
})
|
|
1788
|
+
]
|
|
1789
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1790
|
+
className: "cwb-primary",
|
|
1791
|
+
type: "submit",
|
|
1792
|
+
disabled: state.busy || !saved.ready || saved.pending || !state.prompt.trim() && !state.files.length,
|
|
1793
|
+
children: [state.busy ? "处理中…" : "开始", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1794
|
+
"aria-hidden": "true",
|
|
1795
|
+
children: "→"
|
|
1796
|
+
})]
|
|
1797
|
+
})]
|
|
1798
|
+
})
|
|
1799
|
+
]
|
|
1800
|
+
}),
|
|
1801
|
+
(state.busy || !saved.ready || !workspace) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1802
|
+
className: "cwb-hint",
|
|
1803
|
+
role: "status",
|
|
1804
|
+
"aria-live": "polite",
|
|
1805
|
+
children: state.busy ? preparationLabels[state.stage] : !saved.ready ? "正在连接工作流设置…" : "请先选择或添加工作区。"
|
|
1806
|
+
}),
|
|
1807
|
+
saved.errorKind === "settings" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1808
|
+
className: "cwb-text-button",
|
|
1809
|
+
onClick: () => selection.retry(),
|
|
1810
|
+
children: "重试连接工作流设置"
|
|
1811
|
+
})
|
|
1812
|
+
] }),
|
|
1813
|
+
state.error && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1814
|
+
className: "cwb-error",
|
|
1815
|
+
role: "alert",
|
|
1816
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1817
|
+
className: "cwb-error-heading",
|
|
1818
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "暂时无法开始,需求和文件已保留。" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1819
|
+
type: "button",
|
|
1820
|
+
className: "cwb-text-button",
|
|
1821
|
+
disabled: state.busy || !saved.ready || saved.pending,
|
|
1822
|
+
onClick: () => void start(),
|
|
1823
|
+
children: "重试"
|
|
1587
1824
|
})]
|
|
1588
|
-
}),
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1825
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", { children: [
|
|
1826
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: "查看原因" }),
|
|
1827
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: state.error }),
|
|
1828
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1829
|
+
className: "cwb-text-button",
|
|
1830
|
+
onClick: settings,
|
|
1831
|
+
children: "打开插件设置"
|
|
1832
|
+
})
|
|
1833
|
+
] })]
|
|
1593
1834
|
}),
|
|
1594
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
className: "cwb-content",
|
|
1608
|
-
children: [
|
|
1609
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1610
|
-
className: "cwb-heading",
|
|
1611
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", { children: library ? "找到适合你的工作流" : "开始你的 Ascend 开发" }), library && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: "了解适用场景,准备好输入,再开始。" })]
|
|
1612
|
-
}),
|
|
1613
|
-
!library && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1614
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
1615
|
-
className: "cwb-composer",
|
|
1616
|
-
onSubmit: (event) => void start(event),
|
|
1617
|
-
onDragOver: (event) => event.preventDefault(),
|
|
1618
|
-
onDrop: (event) => {
|
|
1619
|
-
event.preventDefault();
|
|
1620
|
-
if (!state.busy) store.set({ files: [...state.files, ...Array.from(event.dataTransfer.files)] });
|
|
1621
|
-
},
|
|
1835
|
+
workspaceState.state === "error" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1836
|
+
role: "alert",
|
|
1837
|
+
className: "cwb-error",
|
|
1838
|
+
children: "工作区加载失败,请检查 DSH 连接。"
|
|
1839
|
+
}),
|
|
1840
|
+
!library && state.workflow && !selected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1841
|
+
role: "alert",
|
|
1842
|
+
className: "cwb-error",
|
|
1843
|
+
children: "所选工作流已不在当前目录中,请重新选择。"
|
|
1844
|
+
}),
|
|
1845
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1846
|
+
className: "cwb-catalog",
|
|
1847
|
+
"aria-label": "工作流目录",
|
|
1622
1848
|
children: [
|
|
1623
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1624
|
-
|
|
1625
|
-
"
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1849
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1850
|
+
className: "cwb-catalog-heading",
|
|
1851
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: library ? "全部工作流" : "工作流" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1852
|
+
className: "cwb-search",
|
|
1853
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, {
|
|
1854
|
+
name: "search",
|
|
1855
|
+
size: 17
|
|
1856
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1857
|
+
"aria-label": "搜索工作流",
|
|
1858
|
+
placeholder: "搜索工作流",
|
|
1859
|
+
value: query,
|
|
1860
|
+
onChange: (event) => setQuery(event.target.value)
|
|
1861
|
+
})]
|
|
1862
|
+
})]
|
|
1630
1863
|
}),
|
|
1631
|
-
|
|
1632
|
-
className: "cwb-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
type: "button",
|
|
1641
|
-
disabled: state.busy,
|
|
1642
|
-
"aria-label": `移除 ${file.name}`,
|
|
1643
|
-
onClick: () => store.set({ files: state.files.filter((_, i) => i !== index) }),
|
|
1644
|
-
children: "×"
|
|
1645
|
-
})
|
|
1646
|
-
] }, `${file.name}-${index}`))
|
|
1864
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1865
|
+
className: "cwb-categories",
|
|
1866
|
+
role: "group",
|
|
1867
|
+
"aria-label": "工作流分类",
|
|
1868
|
+
children: categories.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1869
|
+
"aria-pressed": category === item,
|
|
1870
|
+
onClick: () => setCategory(item),
|
|
1871
|
+
children: item
|
|
1872
|
+
}, item))
|
|
1647
1873
|
}),
|
|
1648
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1649
|
-
className: "cwb-
|
|
1650
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
1651
|
-
|
|
1874
|
+
library ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1875
|
+
className: "cwb-library",
|
|
1876
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
|
|
1877
|
+
"aria-label": "选择工作流详情",
|
|
1878
|
+
className: "cwb-library-list",
|
|
1879
|
+
children: [visible.map((workflow) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1880
|
+
"aria-current": detail?.id === workflow.id ? "true" : void 0,
|
|
1881
|
+
onClick: () => store.set({ detail: workflow.id }),
|
|
1882
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, { name: guideFor(workflow.id).icon }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: workflow.id }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: copy(workflow).description })] })]
|
|
1883
|
+
}, workflow.id)), !visible.length && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1884
|
+
className: "cwb-empty",
|
|
1885
|
+
children: "没有匹配的工作流"
|
|
1886
|
+
})]
|
|
1887
|
+
}), detail ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkflowDetail, {
|
|
1888
|
+
workflow: detail,
|
|
1889
|
+
content,
|
|
1890
|
+
onUse: () => useWorkflow(detail.id),
|
|
1891
|
+
onExample: () => useWorkflow(detail.id, guideFor(detail.id).example),
|
|
1892
|
+
onSettings: settings
|
|
1893
|
+
}, detail.id) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1894
|
+
className: "cwb-empty",
|
|
1895
|
+
children: "工作流目录尚未准备完成,请到插件设置查看准备状态。"
|
|
1896
|
+
})]
|
|
1897
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1898
|
+
className: "cwb-grid",
|
|
1899
|
+
children: [visible.map((workflow) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1900
|
+
type: "button",
|
|
1901
|
+
className: "cwb-card",
|
|
1902
|
+
"aria-pressed": state.workflow === workflow.id,
|
|
1903
|
+
disabled: state.busy,
|
|
1904
|
+
onClick: () => {
|
|
1905
|
+
const next = state.workflow === workflow.id ? "" : workflow.id;
|
|
1906
|
+
store.set({
|
|
1907
|
+
workflow: next,
|
|
1908
|
+
error: ""
|
|
1909
|
+
});
|
|
1910
|
+
if (next) input.current?.focus();
|
|
1911
|
+
},
|
|
1652
1912
|
children: [
|
|
1653
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
store.set({ files: [...state.files, ...Array.from(event.target.files ?? [])] });
|
|
1660
|
-
event.target.value = "";
|
|
1661
|
-
}
|
|
1913
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1914
|
+
className: "cwb-card-icon",
|
|
1915
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, {
|
|
1916
|
+
name: guideFor(workflow.id).icon,
|
|
1917
|
+
size: 23
|
|
1918
|
+
})
|
|
1662
1919
|
}),
|
|
1663
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
disabled: state.busy,
|
|
1667
|
-
onClick: () => files.current?.click(),
|
|
1668
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, {
|
|
1669
|
-
name: "clip",
|
|
1670
|
-
size: 18
|
|
1671
|
-
}), "添加文件"]
|
|
1920
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1921
|
+
className: "cwb-card-copy",
|
|
1922
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: workflow.id }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: copy(workflow).description })]
|
|
1672
1923
|
}),
|
|
1673
|
-
|
|
1674
|
-
className: "cwb-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1924
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1925
|
+
className: "cwb-card-corner",
|
|
1926
|
+
"aria-hidden": "true",
|
|
1927
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
1928
|
+
width: "18",
|
|
1929
|
+
height: "18",
|
|
1930
|
+
viewBox: "0 0 20 20",
|
|
1931
|
+
fill: "none",
|
|
1932
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
1933
|
+
cx: "10",
|
|
1934
|
+
cy: "10",
|
|
1935
|
+
r: "8",
|
|
1936
|
+
fill: state.workflow === workflow.id ? "#da203e" : "none",
|
|
1937
|
+
stroke: state.workflow === workflow.id ? "#da203e" : "currentColor",
|
|
1938
|
+
strokeWidth: "1.2"
|
|
1939
|
+
}), state.workflow === workflow.id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1940
|
+
d: "m6 10 2.6 2.6L14 7.2",
|
|
1941
|
+
stroke: "white",
|
|
1942
|
+
strokeWidth: "1.6",
|
|
1943
|
+
strokeLinecap: "round",
|
|
1944
|
+
strokeLinejoin: "round"
|
|
1945
|
+
})]
|
|
1946
|
+
})
|
|
1689
1947
|
})
|
|
1690
1948
|
]
|
|
1691
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
1692
|
-
className: "cwb-
|
|
1693
|
-
|
|
1694
|
-
disabled: state.busy || !saved.ready || saved.pending || !state.prompt.trim() && !state.files.length,
|
|
1695
|
-
children: [state.busy ? "处理中…" : "开始", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1696
|
-
"aria-hidden": "true",
|
|
1697
|
-
children: "→"
|
|
1698
|
-
})]
|
|
1949
|
+
}, workflow.id)), !visible.length && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1950
|
+
className: "cwb-empty",
|
|
1951
|
+
children: "没有匹配的工作流,请换一个关键词或分类。"
|
|
1699
1952
|
})]
|
|
1700
1953
|
})
|
|
1701
1954
|
]
|
|
1702
|
-
}),
|
|
1703
|
-
(state.busy || !saved.ready || !workspace) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1704
|
-
className: "cwb-hint",
|
|
1705
|
-
role: "status",
|
|
1706
|
-
"aria-live": "polite",
|
|
1707
|
-
children: state.busy ? preparationLabels[state.stage] : !saved.ready ? "正在连接工作流设置…" : "请先选择或添加工作区。"
|
|
1708
|
-
}),
|
|
1709
|
-
saved.errorKind === "settings" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1710
|
-
className: "cwb-text-button",
|
|
1711
|
-
onClick: () => selection.retry(),
|
|
1712
|
-
children: "重试连接工作流设置"
|
|
1713
1955
|
})
|
|
1714
|
-
]
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
role: "alert",
|
|
1718
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1719
|
-
className: "cwb-error-heading",
|
|
1720
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "暂时无法开始,需求和文件已保留。" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1721
|
-
type: "button",
|
|
1722
|
-
className: "cwb-text-button",
|
|
1723
|
-
disabled: state.busy || !saved.ready || saved.pending,
|
|
1724
|
-
onClick: () => void start(),
|
|
1725
|
-
children: "重试"
|
|
1726
|
-
})]
|
|
1727
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", { children: [
|
|
1728
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: "查看原因" }),
|
|
1729
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: state.error }),
|
|
1730
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1731
|
-
className: "cwb-text-button",
|
|
1732
|
-
onClick: settings,
|
|
1733
|
-
children: "打开插件设置"
|
|
1734
|
-
})
|
|
1735
|
-
] })]
|
|
1736
|
-
}),
|
|
1737
|
-
workspaceState.state === "error" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1738
|
-
role: "alert",
|
|
1739
|
-
className: "cwb-error",
|
|
1740
|
-
children: "工作区加载失败,请检查 DSH 连接。"
|
|
1741
|
-
}),
|
|
1742
|
-
!library && state.workflow && !selected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1743
|
-
role: "alert",
|
|
1744
|
-
className: "cwb-error",
|
|
1745
|
-
children: "所选工作流已不在当前目录中,请重新选择。"
|
|
1746
|
-
}),
|
|
1747
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1748
|
-
className: "cwb-catalog",
|
|
1749
|
-
"aria-label": "工作流目录",
|
|
1750
|
-
children: [
|
|
1751
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1752
|
-
className: "cwb-catalog-heading",
|
|
1753
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: library ? "全部工作流" : "工作流" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1754
|
-
className: "cwb-search",
|
|
1755
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, {
|
|
1756
|
-
name: "search",
|
|
1757
|
-
size: 17
|
|
1758
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1759
|
-
"aria-label": "搜索工作流",
|
|
1760
|
-
placeholder: "搜索工作流",
|
|
1761
|
-
value: query,
|
|
1762
|
-
onChange: (event) => setQuery(event.target.value)
|
|
1763
|
-
})]
|
|
1764
|
-
})]
|
|
1765
|
-
}),
|
|
1766
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1767
|
-
className: "cwb-categories",
|
|
1768
|
-
role: "group",
|
|
1769
|
-
"aria-label": "工作流分类",
|
|
1770
|
-
children: categories.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1771
|
-
"aria-pressed": category === item,
|
|
1772
|
-
onClick: () => setCategory(item),
|
|
1773
|
-
children: item
|
|
1774
|
-
}, item))
|
|
1775
|
-
}),
|
|
1776
|
-
library ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1777
|
-
className: "cwb-library",
|
|
1778
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
|
|
1779
|
-
"aria-label": "选择工作流详情",
|
|
1780
|
-
className: "cwb-library-list",
|
|
1781
|
-
children: [visible.map((workflow) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1782
|
-
"aria-current": detail?.id === workflow.id ? "true" : void 0,
|
|
1783
|
-
onClick: () => store.set({ detail: workflow.id }),
|
|
1784
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, { name: guideFor(workflow.id).icon }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: workflow.id }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: copy(workflow).description })] })]
|
|
1785
|
-
}, workflow.id)), !visible.length && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1786
|
-
className: "cwb-empty",
|
|
1787
|
-
children: "没有匹配的工作流"
|
|
1788
|
-
})]
|
|
1789
|
-
}), detail ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkflowDetail, {
|
|
1790
|
-
workflow: detail,
|
|
1791
|
-
content,
|
|
1792
|
-
onUse: () => useWorkflow(detail.id),
|
|
1793
|
-
onExample: () => useWorkflow(detail.id, guideFor(detail.id).example),
|
|
1794
|
-
onSettings: settings
|
|
1795
|
-
}, detail.id) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1796
|
-
className: "cwb-empty",
|
|
1797
|
-
children: "工作流目录尚未准备完成,请到插件设置查看准备状态。"
|
|
1798
|
-
})]
|
|
1799
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1800
|
-
className: "cwb-grid",
|
|
1801
|
-
children: [visible.map((workflow) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1802
|
-
type: "button",
|
|
1803
|
-
className: "cwb-card",
|
|
1804
|
-
"aria-pressed": state.workflow === workflow.id,
|
|
1805
|
-
disabled: state.busy,
|
|
1806
|
-
onClick: () => {
|
|
1807
|
-
const next = state.workflow === workflow.id ? "" : workflow.id;
|
|
1808
|
-
store.set({
|
|
1809
|
-
workflow: next,
|
|
1810
|
-
error: ""
|
|
1811
|
-
});
|
|
1812
|
-
if (next) input.current?.focus();
|
|
1813
|
-
},
|
|
1814
|
-
children: [
|
|
1815
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1816
|
-
className: "cwb-card-icon",
|
|
1817
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkbenchIcon, {
|
|
1818
|
-
name: guideFor(workflow.id).icon,
|
|
1819
|
-
size: 23
|
|
1820
|
-
})
|
|
1821
|
-
}),
|
|
1822
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1823
|
-
className: "cwb-card-copy",
|
|
1824
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: workflow.id }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: copy(workflow).description })]
|
|
1825
|
-
}),
|
|
1826
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1827
|
-
className: "cwb-card-corner",
|
|
1828
|
-
"aria-hidden": "true",
|
|
1829
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
1830
|
-
width: "18",
|
|
1831
|
-
height: "18",
|
|
1832
|
-
viewBox: "0 0 20 20",
|
|
1833
|
-
fill: "none",
|
|
1834
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
1835
|
-
cx: "10",
|
|
1836
|
-
cy: "10",
|
|
1837
|
-
r: "8",
|
|
1838
|
-
fill: state.workflow === workflow.id ? "#da203e" : "none",
|
|
1839
|
-
stroke: state.workflow === workflow.id ? "#da203e" : "currentColor",
|
|
1840
|
-
strokeWidth: "1.2"
|
|
1841
|
-
}), state.workflow === workflow.id && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1842
|
-
d: "m6 10 2.6 2.6L14 7.2",
|
|
1843
|
-
stroke: "white",
|
|
1844
|
-
strokeWidth: "1.6",
|
|
1845
|
-
strokeLinecap: "round",
|
|
1846
|
-
strokeLinejoin: "round"
|
|
1847
|
-
})]
|
|
1848
|
-
})
|
|
1849
|
-
})
|
|
1850
|
-
]
|
|
1851
|
-
}, workflow.id)), !visible.length && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1852
|
-
className: "cwb-empty",
|
|
1853
|
-
children: "没有匹配的工作流,请换一个关键词或分类。"
|
|
1854
|
-
})]
|
|
1855
|
-
})
|
|
1856
|
-
]
|
|
1857
|
-
})
|
|
1858
|
-
]
|
|
1859
|
-
})]
|
|
1956
|
+
]
|
|
1957
|
+
})
|
|
1958
|
+
]
|
|
1860
1959
|
});
|
|
1861
1960
|
}
|
|
1862
1961
|
function WorkflowDetail({ workflow, content, onUse, onExample, onSettings }) {
|
|
@@ -1965,8 +2064,8 @@ window.__ModuleLoader__.load({
|
|
|
1965
2064
|
}, workflow.id);
|
|
1966
2065
|
}
|
|
1967
2066
|
//#endregion
|
|
1968
|
-
//#region \0dsh-global-css
|
|
1969
|
-
const css = ".cannbot-workbench{--cwb-ink:var(--dsw-alias-label-primary,#17181d);--cwb-muted:var(--dsw-alias-label-secondary,#677185);--cwb-surface:var(--dsw-alias-bg-layer-1,#fff);--cwb-border:var(--dsw-alias-border-l2,#e2e5eb);--cwb-soft:var(--dsw-alias-bg-layer-3,#f6f8fa);--cwb-accent:var(--dsw-alias-state-business-primary,#da203e);--cwb-selected:var(--dsw-alias-state-business-tertiary,#fdeef0);color:var(--cwb-ink);background:var(--cwb-surface);height:100%;font-family:inherit;font-size:14px;overflow:auto}.cannbot-workbench *,.cannbot-workbench :before,.cannbot-workbench :after{box-sizing:border-box}.cannbot-workbench button,.cannbot-workbench input,.cannbot-workbench select,.cannbot-workbench textarea{font:inherit}.cannbot-workbench button{cursor:pointer}.cannbot-workbench button:disabled{opacity:.5;cursor:default}.cannbot-workbench :is(button,input,select,textarea):focus-visible{outline:2px solid var(--cwb-accent);outline-offset:3px}.cwb-header{border-bottom:1px solid var(--cwb-border);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;min-height:62px;padding:12px 30px;display:flex}.cwb-workspace{flex-wrap:wrap;align-items:center;gap:12px;min-width:0;display:flex}.cwb-workspace-info{min-width:0}.cwb-workspace-choice{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.cwb-inherited{color:var(--cwb-muted);background:var(--cwb-soft);border-radius:5px;padding:3px 7px;font-size:11px}.cwb-workspace-path{text-overflow:ellipsis;white-space:nowrap;max-width:min(52vw,560px);color:var(--cwb-muted);padding-left:6px;font-size:12px;line-height:1.5;display:block;overflow:hidden}.cwb-workspace select{background:var(--cwb-surface);max-width:300px;color:var(--cwb-ink);border:0;padding:6px}.cwb-content{max-width:1260px;margin:0 auto;padding:26px 32px 22px}.cwb-heading{margin-bottom:20px}.cwb-heading h1{letter-spacing:-.5px;margin:0 0 8px;font-size:28px;font-weight:650;line-height:1.3}.cwb-heading p{color:var(--cwb-muted);margin:0;font-size:15px;line-height:1.6}.cwb-text-button{color:var(--cwb-muted);text-align:start;background:0 0;border:0;align-items:center;gap:7px;padding:5px 2px;display:inline-flex}.cwb-text-button:hover:not(:disabled){color:var(--cwb-accent)}.cwb-composer{background:var(--cwb-surface);border:1px solid var(--cwb-border);border-radius:14px;padding:18px 20px 14px;box-shadow:0 5px 20px #17213b05}.cwb-composer:focus-within{border-color:var(--cwb-accent)}.cwb-composer textarea{resize:vertical;width:100%;min-height:72px;max-height:340px;color:var(--cwb-ink);background:0 0;border:0;outline:0;padding:0;font-size:15px;line-height:1.65;display:block}.cwb-composer textarea:focus-visible{outline:0}.cwb-composer textarea::placeholder{color:var(--cwb-muted)}.cwb-composer-actions,.cwb-composer-tools{flex-wrap:wrap;align-items:center;gap:16px;min-width:0;display:flex}.cwb-composer-actions{justify-content:space-between;margin-top:12px}.cwb-primary{color:#fff;white-space:nowrap;background:#da203e;border:1px solid #d91d3e;border-radius:9px;justify-content:center;align-items:center;gap:22px;min-height:42px;padding:10px 22px;font-weight:550;display:inline-flex}.cwb-primary:hover:not(:disabled){background:#b11430}.cwb-selection{color:var(--cwb-accent);background:var(--cwb-selected);border-radius:7px;align-items:center;gap:8px;min-width:0;max-width:100%;padding:6px 9px;font-size:12px;display:inline-flex}.cwb-selection>span{overflow-wrap:anywhere}.cwb-selection button,.cwb-files button{color:inherit;background:0 0;border:0;padding:0 4px;font-size:18px}.cwb-files{flex-wrap:wrap;gap:8px;margin:0;padding:10px 0;list-style:none;display:flex}.cwb-files li{border:1px solid var(--cwb-border);border-radius:6px;align-items:center;gap:6px;max-width:250px;padding:3px 6px;display:inline-flex}.cwb-files li span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.cwb-hint{color:var(--cwb-muted);margin:10px 0 0;font-size:12px;line-height:1.6}.cwb-error{border-left:3px solid var(--cwb-accent);background:var(--cwb-selected);color:var(--cwb-ink);padding:12px 14px;line-height:1.6}.cwb-error-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.cwb-error .cwb-text-button{color:var(--cwb-accent)}.cwb-error summary{cursor:pointer;color:var(--cwb-muted);font-size:12px}.cwb-error details p{white-space:pre-wrap;overflow-wrap:anywhere;margin:8px 0}.cwb-catalog-heading{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;margin:26px 0 6px;display:flex}.cwb-catalog-heading h2{margin:0;font-size:20px;font-weight:600}.cwb-search{border:1px solid var(--cwb-border);color:var(--cwb-muted);border-radius:8px;align-items:center;gap:9px;padding:8px 11px;display:flex}.cwb-search input{width:170px;color:var(--cwb-ink);background:0 0;border:0;outline:0;font-size:13px}.cwb-categories{border-bottom:1px solid var(--cwb-border);gap:22px;margin-bottom:18px;display:flex;overflow-x:auto}.cwb-categories button{color:var(--cwb-muted);white-space:nowrap;background:0 0;border:0;border-bottom:2px solid #0000;padding:12px 3px}.cwb-categories button[aria-pressed=true]{border-bottom-color:var(--cwb-accent);color:var(--cwb-accent);font-weight:550}.cwb-grid{grid-template-columns:repeat(3,minmax(0,1fr));align-items:start;gap:10px;display:grid}.cwb-card{text-align:start;border:1px solid var(--cwb-border);width:100%;min-height:96px;color:var(--cwb-ink);background:var(--cwb-surface);border-radius:9px;grid-template-columns:28px minmax(0,1fr) 18px;align-items:start;gap:10px;padding:14px;transition:border-color .15s,background .15s;display:grid}.cwb-card:hover:not(:disabled){border-color:var(--cwb-accent)}.cwb-card[aria-pressed=true]{border-color:var(--cwb-accent);background:var(--cwb-selected)}.cwb-card-icon{background:var(--cwb-selected);width:40px;height:40px;color:var(--cwb-accent);border-radius:9px;flex:none;justify-content:center;align-items:center;display:inline-flex}.cwb-card .cwb-card-icon{border-radius:6px;width:28px;height:28px}.cwb-card .cwb-card-icon svg{width:19px;height:19px}.cwb-card-copy{flex-direction:column;gap:5px;min-width:0;padding-top:3px;display:flex}.cwb-card-copy strong{overflow-wrap:anywhere;font-size:14px;font-weight:600;line-height:1.4}.cwb-card-copy>span{color:var(--cwb-muted);font-size:12px;line-height:1.55}.cwb-card-corner{width:18px;height:18px;color:var(--cwb-muted);background:0 0;border:0;justify-content:center;align-items:center;margin-top:3px;display:inline-flex}.cwb-card-corner svg{flex:none;display:block}.cwb-empty{color:var(--cwb-muted);padding:20px 0;line-height:1.7}.cwb-library{border:1px solid var(--cwb-border);border-radius:12px;grid-template-columns:minmax(220px,.85fr) minmax(0,2fr);display:grid;overflow:hidden}.cwb-library-list{background:var(--cwb-soft);border-right:1px solid var(--cwb-border);padding:10px}.cwb-library-list button{text-align:start;width:100%;color:var(--cwb-ink);background:0 0;border:1px solid #0000;border-radius:8px;gap:12px;padding:14px 12px;display:flex}.cwb-library-list button[aria-current=true]{border-color:var(--cwb-border);background:var(--cwb-surface)}.cwb-library-list button[aria-current=true]>svg{color:var(--cwb-accent)}.cwb-library-list button>svg{flex:none;margin-top:2px}.cwb-library-list button span{min-width:0}.cwb-library-list strong{overflow-wrap:anywhere;font-size:13px;font-weight:550;line-height:1.5;display:block}.cwb-library-list small{color:var(--cwb-muted);margin-top:5px;font-size:12px;line-height:1.6;display:block}.cwb-detail{min-width:0;padding:28px 30px}.cwb-detail-title{align-items:center;gap:14px;display:flex}.cwb-detail-title small{color:var(--cwb-muted);font-size:12px}.cwb-detail-title h2{overflow-wrap:anywhere;margin:5px 0 0;font-size:21px;line-height:1.4}.cwb-detail-summary{color:var(--cwb-muted);margin:17px 0 20px;line-height:1.7}.cwb-guide-sections{grid-template-columns:1fr;gap:18px;margin-top:28px;display:grid}.cwb-detail h3{margin:0 0 9px;font-size:14px;font-weight:600}.cwb-guide-sections ul{color:var(--cwb-muted);margin:0;padding-left:18px;font-size:13px;line-height:1.9}.cwb-example{border:1px solid var(--cwb-border);background:var(--cwb-soft);border-radius:9px;margin-top:24px;padding:18px}.cwb-example p{color:var(--cwb-muted);margin:8px 0;font-size:13px;line-height:1.8}.cwb-example .cwb-text-button{color:var(--cwb-accent)}.cwb-example small{color:var(--cwb-muted);margin-top:6px;font-size:11px;display:block}.cwb-version{border-top:1px solid var(--cwb-border);color:var(--cwb-muted);margin-top:24px;padding-top:18px;font-size:12px;line-height:1.8}.cwb-version summary{cursor:pointer}.cwb-version-actions{flex-wrap:wrap;gap:15px;display:flex}.cannbot-workbench{container:cwb/inline-size}@container cwb (width<=900px){.cwb-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@container cwb (width<=590px){.cwb-grid{grid-template-columns:1fr}}@media (width<=1120px){.cwb-content{padding:24px}.cwb-library{grid-template-columns:minmax(190px,.9fr) minmax(0,1.6fr)}.cwb-detail{padding:22px}}@media (width<=700px){.cwb-header{padding:12px 16px}.cwb-content{padding:22px 16px}.cwb-heading h1{font-size:25px}.cwb-grid,.cwb-library{grid-template-columns:1fr}.cwb-library-list{border-right:0;border-bottom:1px solid var(--cwb-border);max-height:220px;overflow:auto}.cwb-composer{padding:15px}.cwb-workspace select{max-width:190px}.cwb-composer-tools{gap:8px}.cwb-composer-actions{align-items:end}.cwb-primary{padding:9px 17px}.cwb-search,.cwb-search input{width:100%}}@media (prefers-reduced-motion:reduce){.cwb-card{transition:none}}";
|
|
2067
|
+
//#region \0dsh-global-css:/home/t00607008/cannbot-dsh/cannbot/dsh/src/client/workbench.css.mjs
|
|
2068
|
+
const css = ".cannbot-workbench{--cwb-ink:var(--dsw-alias-label-primary,#17181d);--cwb-muted:var(--dsw-alias-label-secondary,#677185);--cwb-surface:var(--dsw-alias-bg-layer-1,#fff);--cwb-border:var(--dsw-alias-border-l2,#e2e5eb);--cwb-soft:var(--dsw-alias-bg-layer-3,#f6f8fa);--cwb-accent:var(--dsw-alias-state-business-primary,#da203e);--cwb-selected:var(--dsw-alias-state-business-tertiary,#fdeef0);color:var(--cwb-ink);background:var(--cwb-surface);height:100%;font-family:inherit;font-size:14px;overflow:auto}.cannbot-workbench *,.cannbot-workbench :before,.cannbot-workbench :after{box-sizing:border-box}.cannbot-workbench button,.cannbot-workbench input,.cannbot-workbench select,.cannbot-workbench textarea{font:inherit}.cannbot-workbench button{cursor:pointer}.cannbot-workbench button:disabled{opacity:.5;cursor:default}.cannbot-workbench :is(button,input,select,textarea):focus-visible{outline:2px solid var(--cwb-accent);outline-offset:3px}.cwb-header{border-bottom:1px solid var(--cwb-border);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;min-height:62px;padding:12px 30px;display:flex}.cwb-workspace{flex-wrap:wrap;align-items:center;gap:12px;min-width:0;display:flex}.cwb-workspace-info{min-width:0}.cwb-workspace-choice{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.cwb-inherited{color:var(--cwb-muted);background:var(--cwb-soft);border-radius:5px;padding:3px 7px;font-size:11px}.cwb-workspace-path{text-overflow:ellipsis;white-space:nowrap;max-width:min(52vw,560px);color:var(--cwb-muted);padding-left:6px;font-size:12px;line-height:1.5;display:block;overflow:hidden}.cwb-workspace select{background:var(--cwb-surface);max-width:300px;color:var(--cwb-ink);border:0;padding:6px}.cwb-content{max-width:1260px;margin:0 auto;padding:26px 32px 22px}.cwb-heading{margin-bottom:20px}.cwb-heading h1{letter-spacing:-.5px;margin:0 0 8px;font-size:28px;font-weight:650;line-height:1.3}.cwb-heading p{color:var(--cwb-muted);margin:0;font-size:15px;line-height:1.6}.cwb-text-button{color:var(--cwb-muted);text-align:start;background:0 0;border:0;align-items:center;gap:7px;padding:5px 2px;display:inline-flex}.cwb-text-button:hover:not(:disabled){color:var(--cwb-accent)}.cwb-composer{background:var(--cwb-surface);border:1px solid var(--cwb-border);border-radius:14px;padding:18px 20px 14px;box-shadow:0 5px 20px #17213b05}.cwb-composer:focus-within{border-color:var(--cwb-accent)}.cwb-composer textarea{resize:vertical;width:100%;min-height:72px;max-height:340px;color:var(--cwb-ink);background:0 0;border:0;outline:0;padding:0;font-size:15px;line-height:1.65;display:block}.cwb-composer textarea:focus-visible{outline:0}.cwb-composer textarea::placeholder{color:var(--cwb-muted)}.cwb-composer-actions,.cwb-composer-tools{flex-wrap:wrap;align-items:center;gap:16px;min-width:0;display:flex}.cwb-composer-actions{justify-content:space-between;margin-top:12px}.cwb-primary{color:#fff;white-space:nowrap;background:#da203e;border:1px solid #d91d3e;border-radius:9px;justify-content:center;align-items:center;gap:22px;min-height:42px;padding:10px 22px;font-weight:550;display:inline-flex}.cwb-primary:hover:not(:disabled){background:#b11430}.cwb-selection{color:var(--cwb-accent);background:var(--cwb-selected);border-radius:7px;align-items:center;gap:8px;min-width:0;max-width:100%;padding:6px 9px;font-size:12px;display:inline-flex}.cwb-selection>span{overflow-wrap:anywhere}.cwb-selection button,.cwb-files button{color:inherit;background:0 0;border:0;padding:0 4px;font-size:18px}.cwb-files{flex-wrap:wrap;gap:8px;margin:0;padding:10px 0;list-style:none;display:flex}.cwb-files li{border:1px solid var(--cwb-border);border-radius:6px;align-items:center;gap:6px;max-width:250px;padding:3px 6px;display:inline-flex}.cwb-files li span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.cwb-hint{color:var(--cwb-muted);margin:10px 0 0;font-size:12px;line-height:1.6}.cwb-error{border-left:3px solid var(--cwb-accent);background:var(--cwb-selected);color:var(--cwb-ink);padding:12px 14px;line-height:1.6}.cwb-error-heading{justify-content:space-between;align-items:center;gap:12px;display:flex}.cwb-error .cwb-text-button{color:var(--cwb-accent)}.cwb-error summary{cursor:pointer;color:var(--cwb-muted);font-size:12px}.cwb-error details p{white-space:pre-wrap;overflow-wrap:anywhere;margin:8px 0}.cwb-catalog-heading{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;margin:26px 0 6px;display:flex}.cwb-catalog-heading h2{margin:0;font-size:20px;font-weight:600}.cwb-search{border:1px solid var(--cwb-border);color:var(--cwb-muted);border-radius:8px;align-items:center;gap:9px;padding:8px 11px;display:flex}.cwb-search input{width:170px;color:var(--cwb-ink);background:0 0;border:0;outline:0;font-size:13px}.cwb-categories{border-bottom:1px solid var(--cwb-border);gap:22px;margin-bottom:18px;display:flex;overflow-x:auto}.cwb-categories button{color:var(--cwb-muted);white-space:nowrap;background:0 0;border:0;border-bottom:2px solid #0000;padding:12px 3px}.cwb-categories button[aria-pressed=true]{border-bottom-color:var(--cwb-accent);color:var(--cwb-accent);font-weight:550}.cwb-grid{grid-template-columns:repeat(3,minmax(0,1fr));align-items:start;gap:10px;display:grid}.cwb-card{text-align:start;border:1px solid var(--cwb-border);width:100%;min-height:96px;color:var(--cwb-ink);background:var(--cwb-surface);border-radius:9px;grid-template-columns:28px minmax(0,1fr) 18px;align-items:start;gap:10px;padding:14px;transition:border-color .15s,background .15s;display:grid}.cwb-card:hover:not(:disabled){border-color:var(--cwb-accent)}.cwb-card[aria-pressed=true]{border-color:var(--cwb-accent);background:var(--cwb-selected)}.cwb-card-icon{background:var(--cwb-selected);width:40px;height:40px;color:var(--cwb-accent);border-radius:9px;flex:none;justify-content:center;align-items:center;display:inline-flex}.cwb-card .cwb-card-icon{border-radius:6px;width:28px;height:28px}.cwb-card .cwb-card-icon svg{width:19px;height:19px}.cwb-card-copy{flex-direction:column;gap:5px;min-width:0;padding-top:3px;display:flex}.cwb-card-copy strong{overflow-wrap:anywhere;font-size:14px;font-weight:600;line-height:1.4}.cwb-card-copy>span{color:var(--cwb-muted);font-size:12px;line-height:1.55}.cwb-card-corner{width:18px;height:18px;color:var(--cwb-muted);background:0 0;border:0;justify-content:center;align-items:center;margin-top:3px;display:inline-flex}.cwb-card-corner svg{flex:none;display:block}.cwb-empty{color:var(--cwb-muted);padding:20px 0;line-height:1.7}.cwb-library{border:1px solid var(--cwb-border);border-radius:12px;grid-template-columns:minmax(220px,.85fr) minmax(0,2fr);display:grid;overflow:hidden}.cwb-library-list{background:var(--cwb-soft);border-right:1px solid var(--cwb-border);padding:10px}.cwb-library-list button{text-align:start;width:100%;color:var(--cwb-ink);background:0 0;border:1px solid #0000;border-radius:8px;gap:12px;padding:14px 12px;display:flex}.cwb-library-list button[aria-current=true]{border-color:var(--cwb-border);background:var(--cwb-surface)}.cwb-library-list button[aria-current=true]>svg{color:var(--cwb-accent)}.cwb-library-list button>svg{flex:none;margin-top:2px}.cwb-library-list button span{min-width:0}.cwb-library-list strong{overflow-wrap:anywhere;font-size:13px;font-weight:550;line-height:1.5;display:block}.cwb-library-list small{color:var(--cwb-muted);margin-top:5px;font-size:12px;line-height:1.6;display:block}.cwb-detail{min-width:0;padding:28px 30px}.cwb-detail-title{align-items:center;gap:14px;display:flex}.cwb-detail-title small{color:var(--cwb-muted);font-size:12px}.cwb-detail-title h2{overflow-wrap:anywhere;margin:5px 0 0;font-size:21px;line-height:1.4}.cwb-detail-summary{color:var(--cwb-muted);margin:17px 0 20px;line-height:1.7}.cwb-guide-sections{grid-template-columns:1fr;gap:18px;margin-top:28px;display:grid}.cwb-detail h3{margin:0 0 9px;font-size:14px;font-weight:600}.cwb-guide-sections ul{color:var(--cwb-muted);margin:0;padding-left:18px;font-size:13px;line-height:1.9}.cwb-example{border:1px solid var(--cwb-border);background:var(--cwb-soft);border-radius:9px;margin-top:24px;padding:18px}.cwb-example p{color:var(--cwb-muted);margin:8px 0;font-size:13px;line-height:1.8}.cwb-example .cwb-text-button{color:var(--cwb-accent)}.cwb-example small{color:var(--cwb-muted);margin-top:6px;font-size:11px;display:block}.cwb-version{border-top:1px solid var(--cwb-border);color:var(--cwb-muted);margin-top:24px;padding-top:18px;font-size:12px;line-height:1.8}.cwb-version summary{cursor:pointer}.cwb-version-actions{flex-wrap:wrap;gap:15px;display:flex}.cannbot-workbench{container:cwb/inline-size}@container cwb (width<=900px){.cwb-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@container cwb (width<=590px){.cwb-grid{grid-template-columns:1fr}}@media (width<=1120px){.cwb-content{padding:24px}.cwb-library{grid-template-columns:minmax(190px,.9fr) minmax(0,1.6fr)}.cwb-detail{padding:22px}}@media (width<=700px){.cwb-header{padding:12px 16px}.cwb-content{padding:22px 16px}.cwb-heading h1{font-size:25px}.cwb-grid,.cwb-library{grid-template-columns:1fr}.cwb-library-list{border-right:0;border-bottom:1px solid var(--cwb-border);max-height:220px;overflow:auto}.cwb-composer{padding:15px}.cwb-workspace select{max-width:190px}.cwb-composer-tools{gap:8px}.cwb-composer-actions{align-items:end}.cwb-primary{padding:9px 17px}.cwb-search,.cwb-search input{width:100%}}@media (prefers-reduced-motion:reduce){.cwb-card{transition:none}}.cwb-directory{border:1px solid var(--cwb-border);width:min(600px,100vw - 40px);max-height:80vh;color:var(--cwb-ink);background:var(--cwb-surface);border-radius:12px;padding:24px;overflow:auto}.cwb-directory::backdrop{background:#00000059}.cwb-directory h2{margin:0 0 12px;font-size:20px}.cwb-directory p{color:var(--cwb-muted);font-size:13px}.cwb-directory form{gap:8px;display:flex}.cwb-directory input{border:1px solid var(--cwb-border);background:var(--cwb-surface);min-width:0;color:inherit;border-radius:6px;flex:1;padding:8px}.cwb-directory nav{flex-wrap:wrap;gap:8px;margin:12px 0;display:flex}.cwb-directory-list{max-height:35vh;padding:0;list-style:none;overflow:auto}.cwb-directory-list button{text-align:start;width:100%;color:inherit;cursor:pointer;background:0 0;border:0;border-radius:6px;padding:10px}.cwb-directory-list button:hover{background:var(--cwb-soft)}.cwb-directory footer{justify-content:flex-end;gap:16px;margin-top:20px;display:flex}";
|
|
1970
2069
|
const tagId = "@cannbot-plugin/cannbot-harness/workbench.css";
|
|
1971
2070
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
1972
2071
|
const tag = document.createElement("style");
|
|
@@ -2093,6 +2192,22 @@ window.__ModuleLoader__.load({
|
|
|
2093
2192
|
ru: en,
|
|
2094
2193
|
pt: en
|
|
2095
2194
|
}));
|
|
2195
|
+
ctx.effect(() => injectSlot(ctx, "conversation.input.dock", () => ctx.slots.register({
|
|
2196
|
+
name: "conversation.input.dock",
|
|
2197
|
+
id: "todo",
|
|
2198
|
+
priority: -100,
|
|
2199
|
+
order: 0,
|
|
2200
|
+
locale: NAMESPACE
|
|
2201
|
+
}, TaskDock)));
|
|
2202
|
+
ctx.effect(() => injectSlot(ctx, "conversation.session.header.actions", () => ctx.slots.register({
|
|
2203
|
+
name: "conversation.session.header.actions",
|
|
2204
|
+
id: "cannbot-session-workflow",
|
|
2205
|
+
order: -100,
|
|
2206
|
+
locale: NAMESPACE
|
|
2207
|
+
}, (props) => (0, react.createElement)(SessionWorkflow, {
|
|
2208
|
+
...props,
|
|
2209
|
+
selection
|
|
2210
|
+
}))));
|
|
2096
2211
|
ctx.effect(() => {
|
|
2097
2212
|
const controller = createPresentationController(() => mountInterface(ctx, selection, content));
|
|
2098
2213
|
const releaseToggle = injectSlot(ctx, "sidebar.footer.action", () => ctx.slots.register({
|