@godv61/dsh-task-engine 0.22.6 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.p0-test.mjs +20 -12
- package/.resource-test.mjs +133 -0
- package/LICENSE +21 -0
- package/README.md +216 -206
- package/docs/listing/godv61__dsh-task-engine.yml +6 -0
- package/docs/listing/submission.md +9 -0
- package/docs/manual.html +385 -382
- package/docs/release-0.23.0.md +34 -0
- package/docs/resource-install.md +18 -0
- package/docs/testing/0.23.0//346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225.md +189 -0
- package/docs/testing/0.23.0//346/265/213/350/257/225/346/212/245/345/221/212.md +42 -0
- package/lib/client.js +567 -612
- package/lib/client.js.map +4 -4
- package/lib/controller.d.ts +49 -0
- package/lib/controller.js +119 -90
- package/lib/controller.js.map +1 -1
- package/lib/dev-task.js +2 -1
- package/lib/dev-task.js.map +1 -1
- package/lib/engine.d.ts +2 -0
- package/lib/engine.js.map +1 -1
- package/lib/resource-import.d.ts +21 -0
- package/lib/resource-import.js +210 -0
- package/lib/resource-import.js.map +1 -0
- package/lib/resource-types.d.ts +25 -0
- package/lib/resource-types.js +2 -0
- package/lib/resource-types.js.map +1 -0
- package/lib/workspace-access.d.ts +6 -0
- package/lib/workspace-access.js +13 -0
- package/lib/workspace-access.js.map +1 -0
- package/package.json +94 -85
package/lib/client.js
CHANGED
|
@@ -4139,6 +4139,15 @@ var installSkillRequestSchema = external_exports.object({
|
|
|
4139
4139
|
level: external_exports.enum(["project", "user"]),
|
|
4140
4140
|
path: external_exports.string().optional()
|
|
4141
4141
|
});
|
|
4142
|
+
var listDirsRequestSchema = external_exports.object({ path: external_exports.string() });
|
|
4143
|
+
var listDirsViewSchema = external_exports.object({
|
|
4144
|
+
ok: external_exports.boolean(),
|
|
4145
|
+
path: external_exports.string(),
|
|
4146
|
+
entries: external_exports.array(external_exports.object({ name: external_exports.string(), hasSkill: external_exports.boolean() })),
|
|
4147
|
+
roots: external_exports.array(external_exports.string()),
|
|
4148
|
+
currentHasSkill: external_exports.boolean(),
|
|
4149
|
+
error: external_exports.string().optional()
|
|
4150
|
+
});
|
|
4142
4151
|
var writeRuleRequestSchema = external_exports.object({
|
|
4143
4152
|
name: external_exports.string(),
|
|
4144
4153
|
content: external_exports.string(),
|
|
@@ -4197,6 +4206,10 @@ var taskLedgerItemSchema = external_exports.object({
|
|
|
4197
4206
|
});
|
|
4198
4207
|
var taskLedgerViewSchema = external_exports.object({
|
|
4199
4208
|
tasks: external_exports.array(external_exports.object({
|
|
4209
|
+
risk_level: external_exports.string().optional(),
|
|
4210
|
+
updated_at: external_exports.string().optional(),
|
|
4211
|
+
verification_passed: external_exports.boolean().optional(),
|
|
4212
|
+
review_outcome: external_exports.string().optional(),
|
|
4200
4213
|
task_id: external_exports.string(),
|
|
4201
4214
|
title: external_exports.string(),
|
|
4202
4215
|
stage: external_exports.string(),
|
|
@@ -4229,10 +4242,37 @@ var initDraftSchema = external_exports.object({
|
|
|
4229
4242
|
lines: external_exports.number(),
|
|
4230
4243
|
error: external_exports.string().optional()
|
|
4231
4244
|
});
|
|
4245
|
+
var resourceRequestSchema = external_exports.object({
|
|
4246
|
+
kind: external_exports.enum(["skill", "rule"]),
|
|
4247
|
+
level: external_exports.enum(["project", "user"]),
|
|
4248
|
+
path: external_exports.string(),
|
|
4249
|
+
files: external_exports.array(external_exports.object({ path: external_exports.string(), base64: external_exports.string() })).max(1e3),
|
|
4250
|
+
sourceDir: external_exports.string().optional(),
|
|
4251
|
+
expectedHash: external_exports.string().optional()
|
|
4252
|
+
});
|
|
4253
|
+
var resourcePreviewSchema = external_exports.object({ ok: external_exports.boolean(), name: external_exports.string(), description: external_exports.string(), content: external_exports.string(), target: external_exports.string(), files: external_exports.number(), bytes: external_exports.number(), hash: external_exports.string(), conflict: external_exports.boolean(), error: external_exports.string().optional() });
|
|
4232
4254
|
var PACKAGE = "@godv61/dsh-task-engine";
|
|
4233
4255
|
var TYPERT_REMOTE = {
|
|
4234
4256
|
package: PACKAGE,
|
|
4235
4257
|
descriptors: [
|
|
4258
|
+
...["previewResource", "importResource"].map((method) => ({
|
|
4259
|
+
id: `${PACKAGE}#task-engine/${method}`,
|
|
4260
|
+
service: "taskEngineController",
|
|
4261
|
+
namespace: "task-engine",
|
|
4262
|
+
method,
|
|
4263
|
+
invocation: { kind: "direct" },
|
|
4264
|
+
parameters: [{ name: "request", wire: "request", source: "json", codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#ResourceImportRequest`, schema: resourceRequestSchema } }],
|
|
4265
|
+
result: { mode: "strict", typeSymbol: `${PACKAGE}/types#ResourcePreview`, schema: resourcePreviewSchema }
|
|
4266
|
+
})),
|
|
4267
|
+
{
|
|
4268
|
+
id: `${PACKAGE}#task-engine/resourceRoots`,
|
|
4269
|
+
service: "taskEngineController",
|
|
4270
|
+
namespace: "task-engine",
|
|
4271
|
+
method: "resourceRoots",
|
|
4272
|
+
invocation: { kind: "direct" },
|
|
4273
|
+
parameters: [{ name: "request", wire: "request", source: "json", codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#ResourceRootsRequest`, schema: external_exports.object({ kind: external_exports.enum(["skill", "rule"]), path: external_exports.string() }) } }],
|
|
4274
|
+
result: { mode: "strict", typeSymbol: `${PACKAGE}/types#ResourceRoots`, schema: external_exports.object({ project: external_exports.string(), user: external_exports.string() }) }
|
|
4275
|
+
},
|
|
4236
4276
|
{
|
|
4237
4277
|
id: `${PACKAGE}#task-engine/read`,
|
|
4238
4278
|
service: "taskEngineController",
|
|
@@ -4329,6 +4369,22 @@ var TYPERT_REMOTE = {
|
|
|
4329
4369
|
],
|
|
4330
4370
|
result: { mode: "strict", typeSymbol: `${PACKAGE}/types#WriteResourceResult`, schema: writeResourceResultSchema }
|
|
4331
4371
|
},
|
|
4372
|
+
{
|
|
4373
|
+
id: `${PACKAGE}#task-engine/listDirs`,
|
|
4374
|
+
service: "taskEngineController",
|
|
4375
|
+
namespace: "task-engine",
|
|
4376
|
+
method: "listDirs",
|
|
4377
|
+
invocation: { kind: "direct" },
|
|
4378
|
+
parameters: [
|
|
4379
|
+
{
|
|
4380
|
+
name: "request",
|
|
4381
|
+
wire: "request",
|
|
4382
|
+
source: "json",
|
|
4383
|
+
codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#ListDirsRequest`, schema: listDirsRequestSchema }
|
|
4384
|
+
}
|
|
4385
|
+
],
|
|
4386
|
+
result: { mode: "strict", typeSymbol: `${PACKAGE}/types#ListDirsView`, schema: listDirsViewSchema }
|
|
4387
|
+
},
|
|
4332
4388
|
{
|
|
4333
4389
|
id: `${PACKAGE}#task-engine/writeRule`,
|
|
4334
4390
|
service: "taskEngineController",
|
|
@@ -4478,8 +4534,59 @@ var TYPERT_REMOTE = {
|
|
|
4478
4534
|
var remote_default = TYPERT_REMOTE;
|
|
4479
4535
|
|
|
4480
4536
|
// src/client/Workbench.tsx
|
|
4481
|
-
var
|
|
4482
|
-
var
|
|
4537
|
+
var import_react8 = require("react");
|
|
4538
|
+
var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
4539
|
+
|
|
4540
|
+
// src/client/workbench-theme.ts
|
|
4541
|
+
var workbenchTheme = `
|
|
4542
|
+
.te-workbench { color:var(--dsw-alias-label-primary); font-size:14px; }
|
|
4543
|
+
.te-workbench *,.te-modal * { box-sizing:border-box; }
|
|
4544
|
+
.te-workbench button,.te-modal button { font-family:inherit; }
|
|
4545
|
+
.te-workbench button:focus-visible,.te-modal button:focus-visible,.te-input:focus-visible { outline:2px solid var(--dsw-alias-state-business-primary); outline-offset:3px; }
|
|
4546
|
+
.te-workbench h2 { margin:0 0 6px; font-size:24px; letter-spacing:-.5px; }
|
|
4547
|
+
.te-workbench h3,.te-modal h3 { margin:0; font-size:16px; overflow-wrap:anywhere; }
|
|
4548
|
+
.te-workbench p,.te-modal p { color:var(--dsw-alias-label-secondary); line-height:1.65; }
|
|
4549
|
+
.te-content { max-width:1120px; margin:auto; width:100%; }
|
|
4550
|
+
.te-resource { display:flex; flex-direction:column; gap:20px; }
|
|
4551
|
+
.te-section-heading { display:flex; justify-content:space-between; align-items:center; gap:16px; flex-wrap:wrap; }
|
|
4552
|
+
.te-section-heading p { margin:0; }
|
|
4553
|
+
.te-actions { display:flex; align-items:center; flex-wrap:wrap; gap:10px; }
|
|
4554
|
+
.te-toolbar { display:flex; flex-wrap:wrap; align-items:center; gap:12px; }
|
|
4555
|
+
.te-toolbar>input { flex:1; min-width:180px; }
|
|
4556
|
+
.te-input { background:var(--dsw-alias-bg-layer-1); border:1px solid var(--dsw-alias-border-l2); border-radius:10px; padding:10px 12px; font:inherit; color:var(--dsw-alias-label-primary); min-width:0; }
|
|
4557
|
+
.te-resource-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(min(100%,280px),1fr)); gap:16px; }
|
|
4558
|
+
.te-resource-card { display:flex; flex-direction:column; gap:14px; background:var(--dsw-alias-bg-layer-1); border:1px solid var(--dsw-alias-border-l2); border-radius:16px; padding:20px; transition:border-color .15s; }
|
|
4559
|
+
.te-resource-card:hover { border-color:var(--dsw-alias-state-business-primary); }
|
|
4560
|
+
.te-resource-card p { margin:0; font-size:13px; flex:1; }
|
|
4561
|
+
.te-card-top { display:flex; justify-content:space-between; align-items:center; }
|
|
4562
|
+
.te-resource-icon { display:grid; place-items:center; width:36px; height:36px; border-radius:10px; background:var(--dsw-alias-bg-layer-2); color:var(--dsw-alias-state-business-primary); font-size:25px; }
|
|
4563
|
+
.te-badge { display:inline-flex; border-radius:20px; background:var(--dsw-alias-bg-layer-2); color:var(--dsw-alias-label-secondary); padding:4px 10px; font-size:12px; }
|
|
4564
|
+
.te-delete,.te-link { border:none; background:transparent; cursor:pointer; padding:8px; color:var(--dsw-alias-label-secondary); }
|
|
4565
|
+
.te-delete { margin-left:auto; }
|
|
4566
|
+
.te-delete:hover { color:var(--dsw-alias-state-error-primary); }
|
|
4567
|
+
.te-link { text-align:left; align-self:flex-start; text-decoration:underline; }
|
|
4568
|
+
.te-danger-button { border:0; border-radius:9px; padding:10px 16px; background:var(--dsw-alias-state-error-primary); color:white; cursor:pointer; }
|
|
4569
|
+
.te-danger-button:disabled { opacity:.5; cursor:wait; }
|
|
4570
|
+
.te-alert,.te-success { padding:12px 16px; border-radius:10px; border:1px solid currentColor; overflow-wrap:anywhere; font-size:13px; }
|
|
4571
|
+
.te-alert { color:var(--dsw-alias-state-error-primary); }
|
|
4572
|
+
.te-success { color:var(--dsw-alias-state-success-primary); }
|
|
4573
|
+
.te-empty { text-align:center; padding:56px 24px; border:1px dashed var(--dsw-alias-border-l2); border-radius:16px; color:var(--dsw-alias-label-secondary); }
|
|
4574
|
+
.te-targets { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin:4px 0 16px; }
|
|
4575
|
+
.te-target { display:flex; flex-direction:column; align-items:flex-start; gap:6px; padding:16px; border-radius:12px; border:1px solid var(--dsw-alias-border-l2); background:var(--dsw-alias-bg-layer-1); color:var(--dsw-alias-label-primary); cursor:pointer; }
|
|
4576
|
+
.te-target small { color:var(--dsw-alias-label-secondary); text-align:left; }
|
|
4577
|
+
.te-target.selected { border-color:var(--dsw-alias-state-business-primary); box-shadow:0 0 0 1px var(--dsw-alias-state-business-primary); }
|
|
4578
|
+
.te-path { display:block; grid-column:1/-1; padding:10px 12px; font-size:12px; border-radius:8px; background:var(--dsw-alias-bg-layer-1); color:var(--dsw-alias-label-secondary); overflow-wrap:anywhere; white-space:pre-wrap; }
|
|
4579
|
+
.te-preview { display:flex; flex-direction:column; gap:12px; margin-top:16px; }
|
|
4580
|
+
.te-markdown { max-height:360px; overflow:auto; padding:16px; border:1px solid var(--dsw-alias-border-l2); border-radius:12px; }
|
|
4581
|
+
.te-advanced { margin-top:16px; padding:12px; border:1px dashed var(--dsw-alias-border-l2); border-radius:12px; }
|
|
4582
|
+
.te-dir-list { max-height:160px; overflow:auto; display:flex; flex-direction:column; gap:4px; }
|
|
4583
|
+
.te-dir-list button { text-align:left; border:0; background:transparent; color:var(--dsw-alias-label-primary); padding:8px; cursor:pointer; }
|
|
4584
|
+
.te-dir-list button:hover { background:var(--dsw-alias-bg-layer-1); }
|
|
4585
|
+
.te-form { display:flex; flex-direction:column; gap:16px; }
|
|
4586
|
+
.te-form label { display:flex; flex-direction:column; gap:8px; font-size:13px; }
|
|
4587
|
+
.te-editor { min-height:260px; resize:vertical; line-height:1.6; font-family:monospace; }
|
|
4588
|
+
@media(max-width:640px) { .te-targets {grid-template-columns:1fr;} .te-resource {gap:14px;} .te-section-heading h2 {font-size:21px;} .te-modal {padding:10px !important;} }
|
|
4589
|
+
`;
|
|
4483
4590
|
|
|
4484
4591
|
// src/client/styles.ts
|
|
4485
4592
|
var text = "var(--dsw-alias-label-primary)";
|
|
@@ -4873,29 +4980,39 @@ function TaskEngineSection(props) {
|
|
|
4873
4980
|
const [source, setSource] = (0, import_react.useState)("default");
|
|
4874
4981
|
const [savedAt, setSavedAt] = (0, import_react.useState)("");
|
|
4875
4982
|
const [loadError, setLoadError] = (0, import_react.useState)("");
|
|
4983
|
+
const [saving, setSaving] = (0, import_react.useState)(false);
|
|
4984
|
+
const [loading, setLoading] = (0, import_react.useState)(true);
|
|
4985
|
+
const [loadAttempt, setLoadAttempt] = (0, import_react.useState)(0);
|
|
4986
|
+
const [configProblems, setConfigProblems] = (0, import_react.useState)([]);
|
|
4876
4987
|
const [skills, setSkills] = (0, import_react.useState)([]);
|
|
4877
4988
|
const [rules, setRules] = (0, import_react.useState)([]);
|
|
4878
4989
|
(0, import_react.useEffect)(() => {
|
|
4879
4990
|
if (workspace === "") return;
|
|
4880
4991
|
let alive = true;
|
|
4881
4992
|
setLoadError("");
|
|
4993
|
+
setLoading(true);
|
|
4882
4994
|
void remote.read(workspace).then((result) => {
|
|
4883
4995
|
if (!alive) return;
|
|
4996
|
+
setLoading(false);
|
|
4884
4997
|
if (result.ok) {
|
|
4885
4998
|
setFlow(result.value.flow);
|
|
4886
4999
|
setStageBindings(result.value.config.stage_bindings ?? {});
|
|
4887
5000
|
setSource(result.value.source);
|
|
5001
|
+
setConfigProblems(result.value.problems);
|
|
4888
5002
|
setSavedAt("");
|
|
4889
5003
|
} else {
|
|
4890
5004
|
setLoadError("\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
4891
5005
|
}
|
|
4892
5006
|
}, (error) => {
|
|
4893
|
-
if (alive)
|
|
5007
|
+
if (alive) {
|
|
5008
|
+
setLoading(false);
|
|
5009
|
+
setLoadError("\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25\uFF1A" + describeError(error));
|
|
5010
|
+
}
|
|
4894
5011
|
});
|
|
4895
5012
|
return () => {
|
|
4896
5013
|
alive = false;
|
|
4897
5014
|
};
|
|
4898
|
-
}, [remote, workspace]);
|
|
5015
|
+
}, [remote, workspace, loadAttempt]);
|
|
4899
5016
|
const refreshCatalogs = (0, import_react.useCallback)(() => {
|
|
4900
5017
|
if (workspace === "") return;
|
|
4901
5018
|
void remote.listSkills(workspace).then((result) => {
|
|
@@ -4927,11 +5044,18 @@ function TaskEngineSection(props) {
|
|
|
4927
5044
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.StateDot, { state: "error" }),
|
|
4928
5045
|
"\u8BFB\u53D6\u5931\u8D25"
|
|
4929
5046
|
] }),
|
|
4930
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles.muted, children: loadError })
|
|
5047
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles.muted, children: loadError }),
|
|
5048
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { onClick: () => setLoadAttempt((n) => n + 1), children: "\u91CD\u8BD5" })
|
|
4931
5049
|
] })
|
|
4932
5050
|
] });
|
|
4933
5051
|
}
|
|
5052
|
+
if (loading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { role: "status", children: "\u6B63\u5728\u8BFB\u53D6\u6D41\u7A0B\u914D\u7F6E\u2026" });
|
|
4934
5053
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.wrap, children: [
|
|
5054
|
+
configProblems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { role: "alert", style: styles.problems, children: [
|
|
5055
|
+
"\u539F\u914D\u7F6E\u6709\u95EE\u9898\uFF1A",
|
|
5056
|
+
configProblems.join("\uFF1B"),
|
|
5057
|
+
"\u3002\u8BF7\u9009\u62E9\u6709\u6548\u9884\u8BBE\u5E76\u4FDD\u5B58\u4FEE\u590D\u3002"
|
|
5058
|
+
] }),
|
|
4935
5059
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.head, children: [
|
|
4936
5060
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { style: styles.title, children: "\u5DE5\u7A0B\u6D41\u7A0B\u914D\u7F6E" }),
|
|
4937
5061
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles.muted, children: "\u9009\u4E00\u5957\u6D41\u7A0B\uFF0C\u518D\u7ED9\u6BCF\u4E2A\u8282\u70B9\u6302\u4E0A skill / rule\u3002\u9636\u6BB5\u6D41\u8F6C\u3001\u5B88\u536B\u3001\u63D0\u4EA4\u89C4\u5219\u90FD\u7531\u6D41\u7A0B\u9884\u8BBE\u56FA\u5316\uFF0C\u65E0\u9700\u624B\u5DE5\u914D\u7F6E\u3002" })
|
|
@@ -4987,11 +5111,14 @@ function TaskEngineSection(props) {
|
|
|
4987
5111
|
variant: "primary",
|
|
4988
5112
|
size: "md",
|
|
4989
5113
|
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconCheckOutline16, { size: 16 }),
|
|
4990
|
-
disabled: problems.length > 0,
|
|
5114
|
+
disabled: problems.length > 0 || saving,
|
|
4991
5115
|
onClick: () => {
|
|
4992
|
-
|
|
5116
|
+
setSaving(true);
|
|
5117
|
+
void save(remote, flow, stageBindings, workspace, setSavedAt, setSource).then((ok) => {
|
|
5118
|
+
if (ok) setConfigProblems([]);
|
|
5119
|
+
}).finally(() => setSaving(false));
|
|
4993
5120
|
},
|
|
4994
|
-
children: "\u4FDD\u5B58\u5230 .dsh/eng.json"
|
|
5121
|
+
children: saving ? "\u6B63\u5728\u4FDD\u5B58\u2026" : "\u4FDD\u5B58\u5230 .dsh/eng.json"
|
|
4995
5122
|
}
|
|
4996
5123
|
),
|
|
4997
5124
|
savedAt !== "" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: styles.okText, children: [
|
|
@@ -5090,13 +5217,23 @@ function BindingEditor({ stages, stageBindings, setStageBindings, skills, rules
|
|
|
5090
5217
|
] });
|
|
5091
5218
|
}
|
|
5092
5219
|
async function save(remote, flow, stageBindings, workspace, setSavedAt, setSource) {
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5220
|
+
try {
|
|
5221
|
+
const result = await remote.write({ path: workspace, flow, stage_bindings: stageBindings });
|
|
5222
|
+
if (!result.ok) {
|
|
5223
|
+
setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
5224
|
+
return false;
|
|
5225
|
+
}
|
|
5226
|
+
if (!result.value.ok) {
|
|
5227
|
+
setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + result.value.problems.join("\uFF1B"));
|
|
5228
|
+
return false;
|
|
5229
|
+
}
|
|
5230
|
+
setSource(result.value.source);
|
|
5231
|
+
setSavedAt("\u5DF2\u4FDD\u5B58");
|
|
5232
|
+
return true;
|
|
5233
|
+
} catch (error) {
|
|
5234
|
+
setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(error));
|
|
5235
|
+
return false;
|
|
5097
5236
|
}
|
|
5098
|
-
setSource(result.value.source);
|
|
5099
|
-
setSavedAt(result.value.ok ? "\u5DF2\u4FDD\u5B58" : "");
|
|
5100
5237
|
}
|
|
5101
5238
|
|
|
5102
5239
|
// src/client/InitPanel.tsx
|
|
@@ -5285,6 +5422,9 @@ function InitPanel({ workspace, remote }) {
|
|
|
5285
5422
|
}
|
|
5286
5423
|
|
|
5287
5424
|
// src/client/SkillManager.tsx
|
|
5425
|
+
var import_react5 = require("react");
|
|
5426
|
+
|
|
5427
|
+
// src/client/ResourceManager.tsx
|
|
5288
5428
|
var import_react4 = require("react");
|
|
5289
5429
|
var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
5290
5430
|
|
|
@@ -5373,23 +5513,49 @@ var footerStyle = {
|
|
|
5373
5513
|
flex: "none"
|
|
5374
5514
|
};
|
|
5375
5515
|
function ResourceModal({ title, description, onClose, footer, children }) {
|
|
5516
|
+
const dialog = (0, import_react3.useRef)(null);
|
|
5517
|
+
const closer = (0, import_react3.useRef)(onClose);
|
|
5518
|
+
closer.current = onClose;
|
|
5376
5519
|
(0, import_react3.useEffect)(() => {
|
|
5520
|
+
const previous = document.activeElement;
|
|
5521
|
+
dialog.current?.focus();
|
|
5377
5522
|
const onKey = (e) => {
|
|
5378
|
-
if (
|
|
5523
|
+
if (!dialog.current?.contains(document.activeElement)) return;
|
|
5524
|
+
if (e.key === "Escape") {
|
|
5525
|
+
e.preventDefault();
|
|
5526
|
+
e.stopPropagation();
|
|
5527
|
+
closer.current();
|
|
5528
|
+
return;
|
|
5529
|
+
}
|
|
5530
|
+
if (e.key !== "Tab") return;
|
|
5531
|
+
const nodes = Array.from(dialog.current.querySelectorAll('button:not(:disabled),input:not(:disabled):not([hidden]),select:not(:disabled),textarea:not(:disabled),[tabindex="0"]')).filter((el) => el.getClientRects().length);
|
|
5532
|
+
const first = nodes[0], last = nodes[nodes.length - 1];
|
|
5533
|
+
if (!first || !last) {
|
|
5534
|
+
e.preventDefault();
|
|
5535
|
+
return;
|
|
5536
|
+
}
|
|
5537
|
+
if (e.shiftKey && (document.activeElement === first || document.activeElement === dialog.current)) {
|
|
5538
|
+
e.preventDefault();
|
|
5539
|
+
last.focus();
|
|
5540
|
+
} else if (!e.shiftKey && (document.activeElement === last || document.activeElement === dialog.current)) {
|
|
5541
|
+
e.preventDefault();
|
|
5542
|
+
first.focus();
|
|
5543
|
+
}
|
|
5379
5544
|
};
|
|
5380
5545
|
document.addEventListener("keydown", onKey);
|
|
5381
5546
|
return () => {
|
|
5382
5547
|
document.removeEventListener("keydown", onKey);
|
|
5548
|
+
if (previous?.isConnected) previous.focus();
|
|
5383
5549
|
};
|
|
5384
|
-
}, [
|
|
5550
|
+
}, []);
|
|
5385
5551
|
return (0, import_react_dom.createPortal)(
|
|
5386
5552
|
(0, import_react3.createElement)(
|
|
5387
5553
|
"div",
|
|
5388
|
-
{ style: rootStyle, role: "presentation" },
|
|
5554
|
+
{ style: rootStyle, className: "te-modal", role: "presentation" },
|
|
5389
5555
|
(0, import_react3.createElement)("div", { style: maskStyle, "aria-hidden": true, onClick: onClose }),
|
|
5390
5556
|
(0, import_react3.createElement)(
|
|
5391
5557
|
"div",
|
|
5392
|
-
{ style: dialogStyle, role: "dialog", "aria-modal": true, "aria-label": title },
|
|
5558
|
+
{ style: dialogStyle, ref: dialog, tabIndex: -1, role: "dialog", "aria-modal": true, "aria-label": title },
|
|
5393
5559
|
(0, import_react3.createElement)(
|
|
5394
5560
|
"div",
|
|
5395
5561
|
{ style: headerStyle },
|
|
@@ -5409,571 +5575,333 @@ function ResourceModal({ title, description, onClose, footer, children }) {
|
|
|
5409
5575
|
);
|
|
5410
5576
|
}
|
|
5411
5577
|
|
|
5412
|
-
// src/client/
|
|
5413
|
-
var
|
|
5414
|
-
var
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
if (source === "bundled") return "bundled";
|
|
5433
|
-
return source.startsWith("user") ? "user" : "project";
|
|
5434
|
-
}
|
|
5435
|
-
function SkillManager({ workspace, remote }) {
|
|
5436
|
-
const [skills, setSkills] = (0, import_react4.useState)([]);
|
|
5578
|
+
// src/client/ResourceManager.tsx
|
|
5579
|
+
var labels = { code: { copyLabel: "\u590D\u5236", copiedLabel: "\u5DF2\u590D\u5236" }, footnotes: "\u811A\u6CE8" };
|
|
5580
|
+
var levelOf = (row) => row.source === "bundled" ? "bundled" : row.source.startsWith("user") ? "user" : "project";
|
|
5581
|
+
var sourceText2 = (source) => source === "bundled" ? "\u5185\u7F6E" : source.startsWith("user") ? "\u4E2A\u4EBA" : "\u9879\u76EE";
|
|
5582
|
+
var sizeText = (bytes) => bytes < 1024 ? `${bytes} B` : bytes < 1024 * 1024 ? `${(bytes / 1024).toFixed(1)} KB` : `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
5583
|
+
var fail = (r) => describeError(r.error ?? "\u64CD\u4F5C\u5931\u8D25");
|
|
5584
|
+
function ResourceManager({ workspace, remote, kind }) {
|
|
5585
|
+
const noun = kind === "skill" ? "\u6280\u80FD" : "\u89C4\u5219";
|
|
5586
|
+
const [rows, setRows] = (0, import_react4.useState)([]);
|
|
5587
|
+
const [query, setQuery] = (0, import_react4.useState)("");
|
|
5588
|
+
const [filter, setFilter] = (0, import_react4.useState)("all");
|
|
5589
|
+
const [notice, setNotice] = (0, import_react4.useState)("");
|
|
5590
|
+
const [error, setError] = (0, import_react4.useState)("");
|
|
5591
|
+
const [loading, setLoading] = (0, import_react4.useState)(true);
|
|
5592
|
+
const [revision, refresh] = (0, import_react4.useState)(0);
|
|
5593
|
+
const [busy, setBusy] = (0, import_react4.useState)(false);
|
|
5594
|
+
const [roots, setRoots] = (0, import_react4.useState)(null);
|
|
5595
|
+
const [importing, setImporting] = (0, import_react4.useState)(false);
|
|
5596
|
+
const [request, setRequest] = (0, import_react4.useState)(null);
|
|
5597
|
+
const [preview, setPreview] = (0, import_react4.useState)(null);
|
|
5437
5598
|
const [level, setLevel] = (0, import_react4.useState)("project");
|
|
5599
|
+
const [manual, setManual] = (0, import_react4.useState)(false);
|
|
5600
|
+
const [sourceDir, setSourceDir] = (0, import_react4.useState)("");
|
|
5601
|
+
const [dirs, setDirs] = (0, import_react4.useState)([]);
|
|
5602
|
+
const [browsePath, setBrowsePath] = (0, import_react4.useState)("");
|
|
5438
5603
|
const [editing, setEditing] = (0, import_react4.useState)(null);
|
|
5439
|
-
const [creating, setCreating] = (0, import_react4.useState)(false);
|
|
5440
5604
|
const [viewing, setViewing] = (0, import_react4.useState)(false);
|
|
5441
|
-
const [confirming, setConfirming] = (0, import_react4.useState)(null);
|
|
5442
5605
|
const [name, setName] = (0, import_react4.useState)("");
|
|
5443
5606
|
const [description, setDescription] = (0, import_react4.useState)("");
|
|
5444
5607
|
const [whenToUse, setWhenToUse] = (0, import_react4.useState)("");
|
|
5445
5608
|
const [body2, setBody] = (0, import_react4.useState)("");
|
|
5446
|
-
const [
|
|
5447
|
-
const
|
|
5448
|
-
const
|
|
5449
|
-
const
|
|
5450
|
-
const
|
|
5451
|
-
|
|
5452
|
-
|
|
5609
|
+
const [deleting, setDeleting] = (0, import_react4.useState)(null);
|
|
5610
|
+
const input = (0, import_react4.useRef)(null);
|
|
5611
|
+
const fileEpoch = (0, import_react4.useRef)(0);
|
|
5612
|
+
const browseEpoch = (0, import_react4.useRef)(0);
|
|
5613
|
+
const readonly = editing !== null && editing !== "new" && levelOf(editing) === "bundled";
|
|
5614
|
+
(0, import_react4.useEffect)(() => {
|
|
5615
|
+
let active = true;
|
|
5616
|
+
setLoading(true);
|
|
5617
|
+
setRows([]);
|
|
5618
|
+
setError("");
|
|
5619
|
+
const run = async () => {
|
|
5620
|
+
try {
|
|
5621
|
+
const r = kind === "skill" ? await remote.listSkills(workspace) : await remote.listRules(workspace);
|
|
5622
|
+
if (!active) return;
|
|
5623
|
+
if (!r.ok) throw new Error(fail(r));
|
|
5624
|
+
setRows("skills" in r.value ? r.value.skills : r.value.rules);
|
|
5625
|
+
} catch (e) {
|
|
5626
|
+
if (active) setError("\u52A0\u8F7D\u5931\u8D25\uFF1A" + describeError(e));
|
|
5627
|
+
} finally {
|
|
5628
|
+
if (active) setLoading(false);
|
|
5629
|
+
}
|
|
5630
|
+
};
|
|
5631
|
+
void run();
|
|
5632
|
+
void remote.resourceRoots({ kind, path: workspace }).then((r) => {
|
|
5633
|
+
if (active && r.ok) setRoots(r.value);
|
|
5453
5634
|
}, () => {
|
|
5454
5635
|
});
|
|
5455
|
-
|
|
5636
|
+
return () => {
|
|
5637
|
+
active = false;
|
|
5638
|
+
fileEpoch.current++;
|
|
5639
|
+
};
|
|
5640
|
+
}, [workspace, remote, kind, revision]);
|
|
5456
5641
|
(0, import_react4.useEffect)(() => {
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
};
|
|
5481
|
-
const startInstall = () => {
|
|
5642
|
+
let active = true;
|
|
5643
|
+
setPreview(null);
|
|
5644
|
+
if (!request) return;
|
|
5645
|
+
setBusy(true);
|
|
5646
|
+
setError("");
|
|
5647
|
+
void remote.previewResource({ ...request, level, path: workspace }).then((r) => {
|
|
5648
|
+
if (!active) return;
|
|
5649
|
+
if (!r.ok) setError(fail(r));
|
|
5650
|
+
else if (!r.value.ok) setError(r.value.error ?? "\u9884\u89C8\u5931\u8D25");
|
|
5651
|
+
else setPreview(r.value);
|
|
5652
|
+
}, (e) => {
|
|
5653
|
+
if (active) setError(describeError(e));
|
|
5654
|
+
}).finally(() => {
|
|
5655
|
+
if (active) setBusy(false);
|
|
5656
|
+
});
|
|
5657
|
+
return () => {
|
|
5658
|
+
active = false;
|
|
5659
|
+
};
|
|
5660
|
+
}, [request, level, workspace, remote]);
|
|
5661
|
+
const close = () => {
|
|
5662
|
+
if (busy) return;
|
|
5663
|
+
fileEpoch.current++;
|
|
5664
|
+
setImporting(false);
|
|
5482
5665
|
setEditing(null);
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
setInstallDir("");
|
|
5487
|
-
setInstallLevel("project");
|
|
5488
|
-
setMsg("");
|
|
5666
|
+
setDeleting(null);
|
|
5667
|
+
setRequest(null);
|
|
5668
|
+
setError("");
|
|
5489
5669
|
};
|
|
5490
|
-
const
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
path: installLevel === "project" ? workspace : void 0
|
|
5496
|
-
});
|
|
5497
|
-
if (!result.ok) {
|
|
5498
|
-
setMsg("\u5B89\u88C5\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
5499
|
-
return;
|
|
5500
|
-
}
|
|
5501
|
-
if (!result.value.ok) {
|
|
5502
|
-
setMsg("\u5B89\u88C5\u5931\u8D25\uFF1A" + (result.value.error ?? "\u672A\u77E5\u9519\u8BEF"));
|
|
5503
|
-
return;
|
|
5670
|
+
const choose = () => {
|
|
5671
|
+
setError("");
|
|
5672
|
+
if (input.current) {
|
|
5673
|
+
input.current.value = "";
|
|
5674
|
+
input.current.click();
|
|
5504
5675
|
}
|
|
5505
|
-
setMsg(`\u5DF2\u5B89\u88C5 skill\u300C${result.value.name}\u300D\u2192 ${result.value.path}`);
|
|
5506
|
-
setInstalling(false);
|
|
5507
|
-
refresh();
|
|
5508
5676
|
};
|
|
5509
|
-
const
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5677
|
+
const selected = async (files) => {
|
|
5678
|
+
if (!files.length) return;
|
|
5679
|
+
const epoch = ++fileEpoch.current;
|
|
5680
|
+
setImporting(true);
|
|
5681
|
+
setManual(false);
|
|
5682
|
+
setRequest(null);
|
|
5683
|
+
setPreview(null);
|
|
5684
|
+
setBusy(true);
|
|
5685
|
+
setError("");
|
|
5686
|
+
setNotice("");
|
|
5687
|
+
try {
|
|
5688
|
+
files = files.filter((f) => !(f.webkitRelativePath || f.name).split("/").some((p) => ["node_modules", ".git", "__pycache__", ".venv", "venv", ".cache", ".DS_Store"].includes(p)));
|
|
5689
|
+
if (!files.length || files.length > 1e3 || files.reduce((n, f) => n + f.size, 0) > 100 * 1024 * 1024 || files.some((f) => f.size > 20 * 1024 * 1024)) throw new Error("\u8BF7\u9009\u62E9\u4E0D\u8D85\u8FC7 1000 \u4E2A\u6587\u4EF6 / 100 MB \u7684\u6280\u80FD\u5305\uFF0C\u5355\u6587\u4EF6\u4E0D\u8D85\u8FC7 20 MB");
|
|
5690
|
+
const entries = [];
|
|
5691
|
+
for (const file of files) {
|
|
5692
|
+
const data = new Uint8Array(await file.arrayBuffer());
|
|
5693
|
+
let binary = "";
|
|
5694
|
+
for (let i = 0; i < data.length; i += 32768) binary += String.fromCharCode(...data.subarray(i, i + 32768));
|
|
5695
|
+
entries.push({ path: file.webkitRelativePath || file.name, base64: btoa(binary) });
|
|
5519
5696
|
}
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
setCreating(false);
|
|
5526
|
-
setViewing(false);
|
|
5527
|
-
setLevel(lvl === "user" ? "user" : "project");
|
|
5528
|
-
loadSkill(sk.name, lvl);
|
|
5529
|
-
};
|
|
5530
|
-
const startView = (sk) => {
|
|
5531
|
-
setEditing(sk.name);
|
|
5532
|
-
setCreating(false);
|
|
5533
|
-
setViewing(true);
|
|
5534
|
-
loadSkill(sk.name, "bundled");
|
|
5535
|
-
};
|
|
5536
|
-
const submit = async () => {
|
|
5537
|
-
setMsg("");
|
|
5538
|
-
const target = editing ?? name;
|
|
5539
|
-
const result = await remote.writeSkill({
|
|
5540
|
-
name: target,
|
|
5541
|
-
description,
|
|
5542
|
-
whenToUse: whenToUse.trim() === "" ? void 0 : whenToUse,
|
|
5543
|
-
content: body2,
|
|
5544
|
-
level,
|
|
5545
|
-
path: level === "project" ? workspace : void 0
|
|
5546
|
-
});
|
|
5547
|
-
if (!result.ok) {
|
|
5548
|
-
setMsg("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
5549
|
-
return;
|
|
5550
|
-
}
|
|
5551
|
-
if (!result.value.ok) {
|
|
5552
|
-
setMsg("\u4FDD\u5B58\u5931\u8D25\uFF1A" + (result.value.error ?? "\u672A\u77E5\u9519\u8BEF"));
|
|
5553
|
-
return;
|
|
5697
|
+
if (epoch === fileEpoch.current) setRequest({ kind, level, path: workspace, files: entries });
|
|
5698
|
+
} catch (e) {
|
|
5699
|
+
if (epoch === fileEpoch.current) setError(describeError(e));
|
|
5700
|
+
} finally {
|
|
5701
|
+
if (epoch === fileEpoch.current) setBusy(false);
|
|
5554
5702
|
}
|
|
5555
|
-
setMsg(`\u5DF2\u4FDD\u5B58 skill\u300C${result.value.name}\u300D`);
|
|
5556
|
-
setEditing(null);
|
|
5557
|
-
setCreating(false);
|
|
5558
|
-
refresh();
|
|
5559
5703
|
};
|
|
5560
|
-
const
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5704
|
+
const install = async () => {
|
|
5705
|
+
if (!request || !preview || preview.conflict || busy) return;
|
|
5706
|
+
setBusy(true);
|
|
5707
|
+
setError("");
|
|
5708
|
+
try {
|
|
5709
|
+
const r = await remote.importResource({ ...request, level, path: workspace, expectedHash: preview.hash });
|
|
5710
|
+
if (!r.ok) throw new Error(fail(r));
|
|
5711
|
+
if (!r.value.ok) throw new Error(r.value.error ?? "\u5B89\u88C5\u5931\u8D25");
|
|
5712
|
+
setNotice(`\u5DF2\u5B89\u88C5${noun}\u300C${r.value.name}\u300D \xB7 ${r.value.target}`);
|
|
5713
|
+
setImporting(false);
|
|
5714
|
+
setRequest(null);
|
|
5715
|
+
refresh((n) => n + 1);
|
|
5716
|
+
} catch (e) {
|
|
5717
|
+
setError(describeError(e));
|
|
5718
|
+
} finally {
|
|
5719
|
+
setBusy(false);
|
|
5574
5720
|
}
|
|
5575
|
-
setMsg(`\u5DF2\u5220\u9664 skill\u300C${result.value.name}\u300D`);
|
|
5576
|
-
if (editing === sk.name) setEditing(null);
|
|
5577
|
-
setConfirming(null);
|
|
5578
|
-
refresh();
|
|
5579
5721
|
};
|
|
5580
|
-
const
|
|
5581
|
-
|
|
5582
|
-
"
|
|
5583
|
-
{
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
(
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
sk.name,
|
|
5594
|
-
sk.source !== "bundled" ? (0, import_react4.createElement)("span", { style: styles.sourceBadge }, `\uFF08${sourceLabel(sk.source)}\uFF09`) : null
|
|
5595
|
-
),
|
|
5596
|
-
(0, import_react4.createElement)("span", { style: styles.sourceBadge }, sk.description)
|
|
5597
|
-
),
|
|
5598
|
-
sk.source === "bundled" ? (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", size: "sm", onClick: () => {
|
|
5599
|
-
startView(sk);
|
|
5600
|
-
} }, "\u67E5\u770B") : (0, import_react4.createElement)(
|
|
5601
|
-
"div",
|
|
5602
|
-
{ style: { display: "flex", gap: 6 } },
|
|
5603
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", size: "sm", onClick: () => {
|
|
5604
|
-
startEdit(sk);
|
|
5605
|
-
} }, "\u7F16\u8F91"),
|
|
5606
|
-
confirming === sk.name ? (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "primary", size: "sm", onClick: () => {
|
|
5607
|
-
void remove(sk);
|
|
5608
|
-
} }, "\u786E\u8BA4\u5220\u9664") : (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "sm", onClick: () => {
|
|
5609
|
-
setConfirming(sk.name);
|
|
5610
|
-
} }, "\u5220\u9664")
|
|
5611
|
-
)
|
|
5612
|
-
);
|
|
5613
|
-
const renderForm = () => {
|
|
5614
|
-
if (viewing) {
|
|
5615
|
-
return (0, import_react4.createElement)(
|
|
5616
|
-
ResourceModal,
|
|
5617
|
-
{
|
|
5618
|
-
title: `\u67E5\u770B skill\u300C${editing ?? ""}\u300D`,
|
|
5619
|
-
description: "\u5185\u7F6E \xB7 \u53EA\u8BFB" + (whenToUse !== "" && whenToUse !== void 0 ? ` \xB7 \u4F7F\u7528\u65F6\u673A\uFF1A${whenToUse}` : ""),
|
|
5620
|
-
onClose: closeForm,
|
|
5621
|
-
footer: (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "sm", onClick: closeForm }, "\u5173\u95ED")
|
|
5622
|
-
},
|
|
5623
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.MarkdownText, { text: body2, labels: MD_LABELS2 })
|
|
5624
|
-
);
|
|
5722
|
+
const browse = async (path) => {
|
|
5723
|
+
const epoch = ++browseEpoch.current;
|
|
5724
|
+
setError("");
|
|
5725
|
+
try {
|
|
5726
|
+
const r = await remote.listDirs({ path });
|
|
5727
|
+
if (epoch !== browseEpoch.current) return;
|
|
5728
|
+
if (!r.ok) throw new Error(fail(r));
|
|
5729
|
+
if (!r.value.ok) throw new Error(r.value.error ?? "\u76EE\u5F55\u8BFB\u53D6\u5931\u8D25");
|
|
5730
|
+
setBrowsePath(r.value.path);
|
|
5731
|
+
setSourceDir(r.value.path);
|
|
5732
|
+
setDirs(r.value.entries);
|
|
5733
|
+
} catch (e) {
|
|
5734
|
+
if (epoch === browseEpoch.current) setError(describeError(e));
|
|
5625
5735
|
}
|
|
5626
|
-
return (0, import_react4.createElement)(
|
|
5627
|
-
ResourceModal,
|
|
5628
|
-
{
|
|
5629
|
-
title: editing === null ? "\u65B0\u5EFA skill" : `\u7F16\u8F91 skill\u300C${editing ?? ""}\u300D`,
|
|
5630
|
-
onClose: closeForm,
|
|
5631
|
-
footer: (0, import_react4.createElement)(
|
|
5632
|
-
"div",
|
|
5633
|
-
{ style: styles.row },
|
|
5634
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, {
|
|
5635
|
-
variant: "primary",
|
|
5636
|
-
size: "sm",
|
|
5637
|
-
disabled: editing === null && name.trim() === "" || description.trim() === "" || body2.trim() === "",
|
|
5638
|
-
onClick: () => {
|
|
5639
|
-
void submit();
|
|
5640
|
-
}
|
|
5641
|
-
}, "\u4FDD\u5B58"),
|
|
5642
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "sm", onClick: closeForm }, "\u53D6\u6D88")
|
|
5643
|
-
)
|
|
5644
|
-
},
|
|
5645
|
-
(0, import_react4.createElement)(
|
|
5646
|
-
"div",
|
|
5647
|
-
{ style: styles.chips },
|
|
5648
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Pill, { active: level === "project", onClick: () => {
|
|
5649
|
-
setLevel("project");
|
|
5650
|
-
}, title: "\u5199\u5230\u5DE5\u4F5C\u533A .dsh/skills\uFF0C\u56E2\u961F\u5171\u4EAB" }, "\u9879\u76EE\u7EA7"),
|
|
5651
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Pill, { active: level === "user", onClick: () => {
|
|
5652
|
-
setLevel("user");
|
|
5653
|
-
}, title: "\u5199\u5230 $DSH_HOME/skills\uFF0C\u4E2A\u4EBA\u6240\u6709\u9879\u76EE\u53EF\u7528" }, "\u7528\u6237\u7EA7")
|
|
5654
|
-
),
|
|
5655
|
-
editing === null ? (0, import_react4.createElement)("input", { style: control, placeholder: "name\uFF08\u5982 my-skill\uFF0C\u53EA\u542B\u5C0F\u5199\u5B57\u6BCD\u6570\u5B57\u548C -\uFF09", value: name, onChange: (ev) => {
|
|
5656
|
-
setName(ev.target.value);
|
|
5657
|
-
} }) : (0, import_react4.createElement)("span", { style: styles.sourceBadge }, `name \u56FA\u5B9A\u4E3A ${name}\uFF08\u6539\u540D\u8BF7\u5220\u9664\u540E\u91CD\u5EFA\uFF09`),
|
|
5658
|
-
(0, import_react4.createElement)("input", { style: control, placeholder: "description\uFF08\u4E00\u53E5\u8BDD\u8BF4\u660E\u5B83\u505A\u4EC0\u4E48\uFF09", value: description, onChange: (ev) => {
|
|
5659
|
-
setDescription(ev.target.value);
|
|
5660
|
-
} }),
|
|
5661
|
-
(0, import_react4.createElement)("input", { style: control, placeholder: "whenToUse\uFF08\u53EF\u9009\uFF1A\u4EC0\u4E48\u60C5\u51B5\u8BE5\u7528\uFF09", value: whenToUse, onChange: (ev) => {
|
|
5662
|
-
setWhenToUse(ev.target.value);
|
|
5663
|
-
} }),
|
|
5664
|
-
(0, import_react4.createElement)("textarea", { style: { ...styles.textarea, minHeight: 300 }, placeholder: "\u6B63\u6587\uFF08\u544A\u8BC9\u5927\u6A21\u578B\u8FD9\u4E2A\u9636\u6BB5\u600E\u4E48\u5E72\uFF09", value: body2, onChange: (ev) => {
|
|
5665
|
-
setBody(ev.target.value);
|
|
5666
|
-
} }),
|
|
5667
|
-
msg !== "" ? (0, import_react4.createElement)("p", { style: styles.status }, msg) : null
|
|
5668
|
-
);
|
|
5669
|
-
};
|
|
5670
|
-
const renderInstallForm = () => (0, import_react4.createElement)(
|
|
5671
|
-
ResourceModal,
|
|
5672
|
-
{
|
|
5673
|
-
title: "\u5B89\u88C5\u73B0\u6709 skill\uFF08\u76EE\u5F55\u578B\uFF09",
|
|
5674
|
-
description: "\u628A\u4E00\u4E2A\u672C\u673A\u5DF2\u6709\u7684 skill \u76EE\u5F55\uFF08\u542B SKILL.md\uFF0C\u53EF\u5E26 references / scripts \u7B49\u6587\u4EF6\uFF09\u5B89\u88C5\u5230\u9879\u76EE\u7EA7\u6216\u7528\u6237\u7EA7\u3002",
|
|
5675
|
-
onClose: () => {
|
|
5676
|
-
setInstalling(false);
|
|
5677
|
-
setMsg("");
|
|
5678
|
-
},
|
|
5679
|
-
footer: (0, import_react4.createElement)(
|
|
5680
|
-
"div",
|
|
5681
|
-
{ style: styles.row },
|
|
5682
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, {
|
|
5683
|
-
variant: "primary",
|
|
5684
|
-
size: "sm",
|
|
5685
|
-
disabled: installDir.trim() === "",
|
|
5686
|
-
onClick: () => {
|
|
5687
|
-
void submitInstall();
|
|
5688
|
-
}
|
|
5689
|
-
}, "\u5B89\u88C5"),
|
|
5690
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "sm", onClick: () => {
|
|
5691
|
-
setInstalling(false);
|
|
5692
|
-
setMsg("");
|
|
5693
|
-
} }, "\u53D6\u6D88")
|
|
5694
|
-
)
|
|
5695
|
-
},
|
|
5696
|
-
(0, import_react4.createElement)(
|
|
5697
|
-
"div",
|
|
5698
|
-
{ style: styles.chips },
|
|
5699
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Pill, { active: installLevel === "project", onClick: () => {
|
|
5700
|
-
setInstallLevel("project");
|
|
5701
|
-
}, title: "\u88C5\u5230\u5DE5\u4F5C\u533A .dsh/skills\uFF0C\u56E2\u961F\u5171\u4EAB" }, "\u9879\u76EE\u7EA7"),
|
|
5702
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Pill, { active: installLevel === "user", onClick: () => {
|
|
5703
|
-
setInstallLevel("user");
|
|
5704
|
-
}, title: "\u88C5\u5230 $DSH_HOME/skills\uFF0C\u4E2A\u4EBA\u6240\u6709\u9879\u76EE\u53EF\u7528" }, "\u7528\u6237\u7EA7")
|
|
5705
|
-
),
|
|
5706
|
-
(0, import_react4.createElement)("input", {
|
|
5707
|
-
style: control,
|
|
5708
|
-
placeholder: "\u6E90\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF08\u672C\u673A skill \u76EE\u5F55\uFF0C\u9700\u542B SKILL.md\uFF09",
|
|
5709
|
-
value: installDir,
|
|
5710
|
-
onChange: (ev) => {
|
|
5711
|
-
setInstallDir(ev.target.value);
|
|
5712
|
-
}
|
|
5713
|
-
}),
|
|
5714
|
-
(0, import_react4.createElement)("p", { style: styles.hint }, "\u8981\u6C42\uFF1A\u76EE\u5F55\u5185\u6709 SKILL.md\uFF08frontmatter \u542B name + description\uFF09\u3002\u5B89\u88C5\u4F1A\u590D\u5236\u6574\u4E2A\u76EE\u5F55\uFF08\u81EA\u52A8\u6392\u9664 node_modules / .git \u7B49\u7F13\u5B58\uFF09\uFF0C\u540C\u540D\u5185\u7F6E\u6280\u80FD\u62D2\u7EDD\u8986\u76D6\uFF0C\u540C\u540D\u5DF2\u88C5\u6280\u80FD\u9700\u5148\u5220\u9664\u3002"),
|
|
5715
|
-
msg !== "" ? (0, import_react4.createElement)("p", { style: styles.status }, msg) : null
|
|
5716
|
-
);
|
|
5717
|
-
return (0, import_react4.createElement)(
|
|
5718
|
-
"div",
|
|
5719
|
-
{ style: styles.section },
|
|
5720
|
-
(0, import_react4.createElement)(
|
|
5721
|
-
"div",
|
|
5722
|
-
{ style: card2 },
|
|
5723
|
-
(0, import_react4.createElement)(
|
|
5724
|
-
"div",
|
|
5725
|
-
{ style: styles.bindingStage },
|
|
5726
|
-
(0, import_react4.createElement)("span", { style: styles.bindingLabel }, "\u5DF2\u5B89\u88C5\u7684 skill"),
|
|
5727
|
-
skills.length === 0 ? (0, import_react4.createElement)("p", { style: styles.muted }, "\u6682\u65E0 skill\uFF0C\u70B9\u4E0B\u65B9\u300C\u65B0\u5EFA skill\u300D\u521B\u5EFA\uFF0C\u6216\u300C\u5B89\u88C5 skill\u300D\u5BFC\u5165\u672C\u673A\u5DF2\u6709\u7684 skill \u76EE\u5F55\u3002") : (0, import_react4.createElement)(
|
|
5728
|
-
"div",
|
|
5729
|
-
{ style: styles.section },
|
|
5730
|
-
...skills.map(renderRow)
|
|
5731
|
-
)
|
|
5732
|
-
),
|
|
5733
|
-
(0, import_react4.createElement)(
|
|
5734
|
-
"div",
|
|
5735
|
-
{ style: styles.row },
|
|
5736
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", size: "md", onClick: startCreate }, "\u65B0\u5EFA skill"),
|
|
5737
|
-
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", size: "md", onClick: startInstall }, "\u5B89\u88C5 skill")
|
|
5738
|
-
)
|
|
5739
|
-
),
|
|
5740
|
-
installing ? renderInstallForm() : null,
|
|
5741
|
-
formOpen && !installing ? renderForm() : null
|
|
5742
|
-
);
|
|
5743
|
-
}
|
|
5744
|
-
|
|
5745
|
-
// src/client/RuleManager.tsx
|
|
5746
|
-
var import_react5 = require("react");
|
|
5747
|
-
var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
5748
|
-
var MD_LABELS3 = { code: { copyLabel: "\u590D\u5236", copiedLabel: "\u5DF2\u590D\u5236" }, footnotes: "\u811A\u6CE8" };
|
|
5749
|
-
var control2 = {
|
|
5750
|
-
background: "var(--dsw-alias-bg-layer-1)",
|
|
5751
|
-
border: "1px solid var(--dsw-alias-border-l2)",
|
|
5752
|
-
borderRadius: 8,
|
|
5753
|
-
padding: "5px 8px",
|
|
5754
|
-
color: "var(--dsw-alias-label-primary)",
|
|
5755
|
-
fontSize: 13,
|
|
5756
|
-
minWidth: 0
|
|
5757
|
-
};
|
|
5758
|
-
var card3 = {
|
|
5759
|
-
display: "flex",
|
|
5760
|
-
flexDirection: "column",
|
|
5761
|
-
gap: 8,
|
|
5762
|
-
border: "1px solid var(--dsw-alias-border-l2)",
|
|
5763
|
-
borderRadius: 8,
|
|
5764
|
-
padding: "10px 12px"
|
|
5765
|
-
};
|
|
5766
|
-
function levelOf2(source) {
|
|
5767
|
-
if (source === "bundled") return "bundled";
|
|
5768
|
-
return source.startsWith("user") ? "user" : "project";
|
|
5769
|
-
}
|
|
5770
|
-
function RuleManager({ workspace, remote }) {
|
|
5771
|
-
const [rules, setRules] = (0, import_react5.useState)([]);
|
|
5772
|
-
const [level, setLevel] = (0, import_react5.useState)("project");
|
|
5773
|
-
const [editing, setEditing] = (0, import_react5.useState)(null);
|
|
5774
|
-
const [creating, setCreating] = (0, import_react5.useState)(false);
|
|
5775
|
-
const [viewing, setViewing] = (0, import_react5.useState)(false);
|
|
5776
|
-
const [confirming, setConfirming] = (0, import_react5.useState)(null);
|
|
5777
|
-
const [name, setName] = (0, import_react5.useState)("");
|
|
5778
|
-
const [body2, setBody] = (0, import_react5.useState)("");
|
|
5779
|
-
const [msg, setMsg] = (0, import_react5.useState)("");
|
|
5780
|
-
const refresh = (0, import_react5.useCallback)(() => {
|
|
5781
|
-
void remote.listRules(workspace).then((r) => {
|
|
5782
|
-
if (r.ok) setRules(r.value.rules);
|
|
5783
|
-
}, () => {
|
|
5784
|
-
});
|
|
5785
|
-
}, [remote, workspace]);
|
|
5786
|
-
(0, import_react5.useEffect)(() => {
|
|
5787
|
-
refresh();
|
|
5788
|
-
}, [refresh]);
|
|
5789
|
-
const closeForm = () => {
|
|
5790
|
-
setEditing(null);
|
|
5791
|
-
setCreating(false);
|
|
5792
|
-
setViewing(false);
|
|
5793
|
-
setName("");
|
|
5794
|
-
setBody("");
|
|
5795
|
-
setMsg("");
|
|
5796
5736
|
};
|
|
5797
|
-
const
|
|
5798
|
-
setEditing(
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5737
|
+
const edit = async (row, view = false) => {
|
|
5738
|
+
setEditing(row);
|
|
5739
|
+
setViewing(view);
|
|
5740
|
+
setName(row === "new" ? "" : row.name);
|
|
5741
|
+
setDescription("");
|
|
5742
|
+
setWhenToUse("");
|
|
5803
5743
|
setBody("");
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
setMsg("");
|
|
5808
|
-
void remote.readRule({ name: ruleName, level: lvl, path: workspace }).then((r) => {
|
|
5809
|
-
if (r.ok && r.value.ok) {
|
|
5810
|
-
setName(r.value.name);
|
|
5811
|
-
setBody(r.value.content);
|
|
5812
|
-
} else {
|
|
5813
|
-
setMsg("\u8BFB\u53D6\u5931\u8D25\uFF1A" + (r.ok ? r.value.error ?? "\u672A\u77E5\u9519\u8BEF" : describeError(r.error)));
|
|
5814
|
-
}
|
|
5815
|
-
});
|
|
5816
|
-
};
|
|
5817
|
-
const startEdit = (rule) => {
|
|
5818
|
-
const lvl = levelOf2(rule.source);
|
|
5819
|
-
setEditing(rule.name);
|
|
5820
|
-
setCreating(false);
|
|
5821
|
-
setViewing(false);
|
|
5822
|
-
setLevel(lvl === "user" ? "user" : "project");
|
|
5823
|
-
loadRule(rule.name, lvl);
|
|
5824
|
-
};
|
|
5825
|
-
const startView = (rule) => {
|
|
5826
|
-
setEditing(rule.name);
|
|
5827
|
-
setCreating(false);
|
|
5828
|
-
setViewing(true);
|
|
5829
|
-
loadRule(rule.name, "bundled");
|
|
5830
|
-
};
|
|
5831
|
-
const submit = async () => {
|
|
5832
|
-
setMsg("");
|
|
5833
|
-
const result = await remote.writeRule({
|
|
5834
|
-
name: editing ?? name,
|
|
5835
|
-
content: body2,
|
|
5836
|
-
level,
|
|
5837
|
-
path: level === "project" ? workspace : void 0
|
|
5838
|
-
});
|
|
5839
|
-
if (!result.ok) {
|
|
5840
|
-
setMsg("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
5744
|
+
setError("");
|
|
5745
|
+
if (row === "new") {
|
|
5746
|
+
setLevel("project");
|
|
5841
5747
|
return;
|
|
5842
5748
|
}
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5749
|
+
const lvl = levelOf(row);
|
|
5750
|
+
setLevel(lvl === "user" ? "user" : "project");
|
|
5751
|
+
setBusy(true);
|
|
5752
|
+
try {
|
|
5753
|
+
const r = kind === "skill" ? await remote.readSkill({ name: row.name, level: lvl, path: workspace }) : await remote.readRule({ name: row.name, level: lvl, path: workspace });
|
|
5754
|
+
if (!r.ok) throw new Error(fail(r));
|
|
5755
|
+
if (!r.value.ok) throw new Error(r.value.error ?? "\u8BFB\u53D6\u5931\u8D25");
|
|
5756
|
+
setBody(r.value.content);
|
|
5757
|
+
if (kind === "skill") {
|
|
5758
|
+
const skill = r.value;
|
|
5759
|
+
setDescription(skill.description);
|
|
5760
|
+
setWhenToUse(skill.whenToUse);
|
|
5761
|
+
}
|
|
5762
|
+
} catch (e) {
|
|
5763
|
+
setError(describeError(e));
|
|
5764
|
+
} finally {
|
|
5765
|
+
setBusy(false);
|
|
5846
5766
|
}
|
|
5847
|
-
setMsg(`\u5DF2\u4FDD\u5B58 rule\u300C${result.value.name}\u300D`);
|
|
5848
|
-
setEditing(null);
|
|
5849
|
-
setCreating(false);
|
|
5850
|
-
refresh();
|
|
5851
5767
|
};
|
|
5852
|
-
const
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5768
|
+
const save2 = async () => {
|
|
5769
|
+
if (busy) return;
|
|
5770
|
+
setBusy(true);
|
|
5771
|
+
setError("");
|
|
5772
|
+
try {
|
|
5773
|
+
if (editing === "new" && rows.some((r2) => r2.name === name && (levelOf(r2) === level || levelOf(r2) === "bundled"))) throw new Error("\u540C\u540D\u8D44\u6E90\u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u540D\u6216\u7F16\u8F91\u73B0\u6709\u8D44\u6E90");
|
|
5774
|
+
const r = kind === "skill" ? await remote.writeSkill({ name, description, whenToUse, content: body2, level, path: workspace }) : await remote.writeRule({ name, content: body2, level, path: workspace });
|
|
5775
|
+
if (!r.ok) throw new Error(fail(r));
|
|
5776
|
+
if (!r.value.ok) throw new Error(r.value.error ?? "\u4FDD\u5B58\u5931\u8D25");
|
|
5777
|
+
setNotice(`\u5DF2\u4FDD\u5B58${noun} \xB7 ${r.value.path}`);
|
|
5778
|
+
setEditing(null);
|
|
5779
|
+
refresh((n) => n + 1);
|
|
5780
|
+
} catch (e) {
|
|
5781
|
+
setError(describeError(e));
|
|
5782
|
+
} finally {
|
|
5783
|
+
setBusy(false);
|
|
5861
5784
|
}
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5785
|
+
};
|
|
5786
|
+
const remove = async () => {
|
|
5787
|
+
if (!deleting || busy) return;
|
|
5788
|
+
const lvl = levelOf(deleting);
|
|
5789
|
+
if (lvl === "bundled") return;
|
|
5790
|
+
setBusy(true);
|
|
5791
|
+
setError("");
|
|
5792
|
+
try {
|
|
5793
|
+
const r = kind === "skill" ? await remote.deleteSkill({ name: deleting.name, level: lvl, path: workspace }) : await remote.deleteRule({ name: deleting.name, level: lvl, path: workspace });
|
|
5794
|
+
if (!r.ok) throw new Error(fail(r));
|
|
5795
|
+
if (!r.value.ok) throw new Error(r.value.error ?? "\u5220\u9664\u5931\u8D25");
|
|
5796
|
+
setNotice(`\u5DF2\u5220\u9664${noun}\u300C${deleting.name}\u300D`);
|
|
5797
|
+
setDeleting(null);
|
|
5798
|
+
refresh((n) => n + 1);
|
|
5799
|
+
} catch (e) {
|
|
5800
|
+
setError(describeError(e));
|
|
5801
|
+
} finally {
|
|
5802
|
+
setBusy(false);
|
|
5866
5803
|
}
|
|
5867
|
-
setMsg(`\u5DF2\u5220\u9664 rule\u300C${result.value.name}\u300D`);
|
|
5868
|
-
if (editing === rule.name) setEditing(null);
|
|
5869
|
-
setConfirming(null);
|
|
5870
|
-
refresh();
|
|
5871
5804
|
};
|
|
5872
|
-
const
|
|
5873
|
-
const
|
|
5805
|
+
const status = () => error ? (0, import_react4.createElement)("div", { className: "te-alert", role: "alert" }, error) : null;
|
|
5806
|
+
const targets = () => (0, import_react4.createElement)(
|
|
5874
5807
|
"div",
|
|
5875
|
-
{
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
),
|
|
5885
|
-
|
|
5886
|
-
startView(rule);
|
|
5887
|
-
} }, "\u67E5\u770B") : (0, import_react5.createElement)(
|
|
5888
|
-
"div",
|
|
5889
|
-
{ style: { display: "flex", gap: 6 } },
|
|
5890
|
-
(0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", size: "sm", onClick: () => {
|
|
5891
|
-
startEdit(rule);
|
|
5892
|
-
} }, "\u7F16\u8F91"),
|
|
5893
|
-
confirming === rule.name ? (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "primary", size: "sm", onClick: () => {
|
|
5894
|
-
void remove(rule);
|
|
5895
|
-
} }, "\u786E\u8BA4\u5220\u9664") : (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", size: "sm", onClick: () => {
|
|
5896
|
-
setConfirming(rule.name);
|
|
5897
|
-
} }, "\u5220\u9664")
|
|
5898
|
-
)
|
|
5808
|
+
{ className: "te-targets" },
|
|
5809
|
+
...["project", "user"].map((lvl) => (0, import_react4.createElement)(
|
|
5810
|
+
"button",
|
|
5811
|
+
{ type: "button", key: lvl, className: `te-target ${level === lvl ? "selected" : ""}`, "aria-pressed": level === lvl, disabled: busy || editing !== null && editing !== "new", onClick: () => {
|
|
5812
|
+
setPreview(null);
|
|
5813
|
+
setLevel(lvl);
|
|
5814
|
+
} },
|
|
5815
|
+
(0, import_react4.createElement)("strong", null, lvl === "project" ? "\u9879\u76EE\u5171\u4EAB" : "\u4E2A\u4EBA\u5168\u5C40"),
|
|
5816
|
+
(0, import_react4.createElement)("small", null, lvl === "project" ? "\u4EC5\u5F53\u524D\u5DE5\u4F5C\u533A\u4F7F\u7528" : "\u6B64\u4E3B\u673A\u4E0A\u7684\u6240\u6709\u9879\u76EE\u53EF\u7528")
|
|
5817
|
+
)),
|
|
5818
|
+
(0, import_react4.createElement)("code", { className: "te-path" }, roots?.[level] ?? (level === "project" ? `${workspace}/.dsh/${kind}s` : `DSH_HOME/${kind}s`))
|
|
5899
5819
|
);
|
|
5900
|
-
const
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5820
|
+
const visible = rows.filter((r) => `${r.name} ${r.description ?? ""}`.toLowerCase().includes(query.toLowerCase()) && (filter === "all" || levelOf(r) === filter));
|
|
5821
|
+
return (0, import_react4.createElement)(
|
|
5822
|
+
"section",
|
|
5823
|
+
{ className: "te-resource" },
|
|
5824
|
+
(0, import_react4.createElement)("input", { type: "file", ref: input, hidden: true, "aria-label": kind === "skill" ? "\u9009\u62E9\u6280\u80FD\u6587\u4EF6\u5939" : "\u9009\u62E9\u89C4\u5219\u6587\u4EF6", ...kind === "skill" ? { webkitdirectory: "", multiple: true } : { accept: ".md,text/markdown" }, onChange: (e) => {
|
|
5825
|
+
void selected(Array.from(e.target.files ?? []));
|
|
5826
|
+
} }),
|
|
5827
|
+
(0, import_react4.createElement)("div", { className: "te-section-heading" }, (0, import_react4.createElement)("div", null, (0, import_react4.createElement)("h2", null, `${noun}\u5E93`), (0, import_react4.createElement)("p", null, kind === "skill" ? "\u628A\u53EF\u590D\u7528\u7684\u5DE5\u4F5C\u65B9\u6CD5\u5E26\u5165\u9879\u76EE\u3002" : "\u4E3A\u9879\u76EE\u660E\u786E\u7EA6\u5B9A\uFF0C\u8BA9\u6BCF\u6B21\u4EA4\u4ED8\u4FDD\u6301\u4E00\u81F4\u3002")), (0, import_react4.createElement)("div", { className: "te-actions" }, (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", onClick: () => {
|
|
5828
|
+
void edit("new");
|
|
5829
|
+
} }, `\u65B0\u5EFA${noun}`), (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "primary", onClick: choose }, `\u5B89\u88C5${noun}`))),
|
|
5830
|
+
(0, import_react4.createElement)("div", { className: "te-toolbar" }, (0, import_react4.createElement)("input", { className: "te-input", placeholder: `\u641C\u7D22${noun}\u540D\u79F0${kind === "skill" ? "\u6216\u63CF\u8FF0" : ""}`, value: query, onChange: (e) => setQuery(e.target.value) }), (0, import_react4.createElement)("select", { className: "te-input", "aria-label": "\u7B5B\u9009\u6765\u6E90", value: filter, onChange: (e) => setFilter(e.target.value) }, (0, import_react4.createElement)("option", { value: "all" }, `\u5168\u90E8\u6765\u6E90 \xB7 ${rows.length}`), (0, import_react4.createElement)("option", { value: "bundled" }, "\u5185\u7F6E"), (0, import_react4.createElement)("option", { value: "project" }, "\u9879\u76EE"), (0, import_react4.createElement)("option", { value: "user" }, "\u4E2A\u4EBA")), (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", onClick: () => refresh((n) => n + 1), disabled: loading }, "\u5237\u65B0")),
|
|
5831
|
+
notice ? (0, import_react4.createElement)("div", { className: "te-success", role: "status" }, notice) : null,
|
|
5832
|
+
!importing && !editing && !deleting ? status() : null,
|
|
5833
|
+
loading ? (0, import_react4.createElement)("div", { className: "te-empty", role: "status" }, "\u6B63\u5728\u52A0\u8F7D\u2026") : visible.length === 0 ? (0, import_react4.createElement)("div", { className: "te-empty" }, (0, import_react4.createElement)("h3", null, query || filter !== "all" ? "\u6CA1\u6709\u5339\u914D\u7684\u7ED3\u679C" : `\u8FD8\u6CA1\u6709${noun}`), (0, import_react4.createElement)("p", null, "\u8C03\u6574\u7B5B\u9009\uFF0C\u6216\u4F7F\u7528\u53F3\u4E0A\u89D2\u6309\u94AE\u6DFB\u52A0\u3002")) : (0, import_react4.createElement)("div", { className: "te-resource-grid" }, ...visible.map((row) => (0, import_react4.createElement)(
|
|
5834
|
+
"article",
|
|
5835
|
+
{ className: "te-resource-card", key: row.source + "/" + row.name },
|
|
5836
|
+
(0, import_react4.createElement)("div", { className: "te-card-top" }, (0, import_react4.createElement)("span", { className: "te-resource-icon", "aria-hidden": true }, kind === "skill" ? "\u25C7" : "\u2261"), (0, import_react4.createElement)("span", { className: "te-badge" }, sourceText2(row.source))),
|
|
5837
|
+
(0, import_react4.createElement)("h3", null, row.name),
|
|
5838
|
+
(0, import_react4.createElement)("p", null, row.description || "\u9879\u76EE\u7EA6\u5B9A\u4E0E\u6267\u884C\u89C4\u5219"),
|
|
5839
|
+
(0, import_react4.createElement)("div", { className: "te-actions" }, (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", size: "sm", onClick: () => {
|
|
5840
|
+
void edit(row, true);
|
|
5841
|
+
} }, "\u67E5\u770B"), levelOf(row) !== "bundled" ? (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "sm", onClick: () => {
|
|
5842
|
+
void edit(row);
|
|
5843
|
+
} }, "\u7F16\u8F91") : null, levelOf(row) !== "bundled" ? (0, import_react4.createElement)("button", { className: "te-delete", onClick: () => {
|
|
5844
|
+
setDeleting(row);
|
|
5845
|
+
setError("");
|
|
5846
|
+
} }, "\u5220\u9664") : null)
|
|
5847
|
+
))),
|
|
5848
|
+
kind === "skill" ? (0, import_react4.createElement)("button", { className: "te-link", onClick: () => {
|
|
5849
|
+
setImporting(true);
|
|
5850
|
+
setManual(true);
|
|
5851
|
+
setError("");
|
|
5852
|
+
} }, "\u9AD8\u7EA7\uFF1A\u4ECE Harness \u4E3B\u673A\u8DEF\u5F84\u5B89\u88C5") : null,
|
|
5853
|
+
importing ? (0, import_react4.createElement)(
|
|
5914
5854
|
ResourceModal,
|
|
5915
|
-
{
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
},
|
|
5932
|
-
(
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
),
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
} }),
|
|
5948
|
-
msg !== "" ? (0, import_react5.createElement)("p", { style: styles.status }, msg) : null
|
|
5949
|
-
);
|
|
5950
|
-
};
|
|
5951
|
-
return (0, import_react5.createElement)(
|
|
5952
|
-
"div",
|
|
5953
|
-
{ style: styles.section },
|
|
5954
|
-
(0, import_react5.createElement)(
|
|
5955
|
-
"div",
|
|
5956
|
-
{ style: card3 },
|
|
5957
|
-
(0, import_react5.createElement)(
|
|
5958
|
-
"div",
|
|
5959
|
-
{ style: styles.bindingStage },
|
|
5960
|
-
(0, import_react5.createElement)("span", { style: styles.bindingLabel }, "\u5DF2\u5B89\u88C5\u7684 rule"),
|
|
5961
|
-
rules.length === 0 ? (0, import_react5.createElement)("p", { style: styles.muted }, "\u6682\u65E0 rule\uFF0C\u70B9\u4E0B\u65B9\u300C\u65B0\u5EFA rule\u300D\u521B\u5EFA\u4E00\u4E2A\u3002") : (0, import_react5.createElement)(
|
|
5962
|
-
"div",
|
|
5963
|
-
{ style: styles.section },
|
|
5964
|
-
...rules.map(renderRow)
|
|
5965
|
-
)
|
|
5966
|
-
),
|
|
5967
|
-
(0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", size: "md", onClick: startCreate }, "\u65B0\u5EFA rule")
|
|
5968
|
-
),
|
|
5969
|
-
formOpen ? renderForm() : null
|
|
5855
|
+
{ title: `\u5B89\u88C5${noun}`, description: "\u5148\u68C0\u67E5\u5185\u5BB9\u548C\u5B89\u88C5\u4F4D\u7F6E\uFF0C\u786E\u8BA4\u540E\u624D\u4F1A\u5199\u5165\u3002", onClose: close, footer: (0, import_react4.createElement)("div", { className: "te-actions" }, (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", disabled: busy, onClick: close }, "\u53D6\u6D88"), (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "primary", disabled: busy || !preview || preview.conflict, onClick: () => {
|
|
5856
|
+
void install();
|
|
5857
|
+
} }, busy ? "\u5904\u7406\u4E2D\u2026" : "\u786E\u8BA4\u5B89\u88C5")) },
|
|
5858
|
+
targets(),
|
|
5859
|
+
(0, import_react4.createElement)("div", { className: "te-actions" }, (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", disabled: busy, onClick: choose }, "\u91CD\u65B0\u9009\u62E9"), kind === "skill" ? (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", disabled: busy, onClick: () => setManual(!manual) }, manual ? "\u6536\u8D77\u9AD8\u7EA7\u65B9\u5F0F" : "\u4E3B\u673A\u8DEF\u5F84") : null),
|
|
5860
|
+
manual ? (0, import_react4.createElement)("div", { className: "te-advanced" }, (0, import_react4.createElement)("p", null, "\u6B64\u8DEF\u5F84\u4F4D\u4E8E Harness \u4E3B\u673A\uFF1B\u6D4F\u89C8\u5668\u9009\u62E9\u5668\u8BFB\u53D6\u7684\u662F\u4F60\u5F53\u524D\u7535\u8111\u3002"), (0, import_react4.createElement)("div", { className: "te-toolbar" }, (0, import_react4.createElement)("input", { className: "te-input", "aria-label": "\u4E3B\u673A\u6280\u80FD\u76EE\u5F55", value: sourceDir, onChange: (e) => {
|
|
5861
|
+
setSourceDir(e.target.value);
|
|
5862
|
+
setRequest(null);
|
|
5863
|
+
} }), (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", onClick: () => {
|
|
5864
|
+
void browse(sourceDir);
|
|
5865
|
+
} }, "\u6D4F\u89C8"), (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", disabled: busy || !sourceDir.trim(), onClick: () => setRequest({ kind, level, path: workspace, files: [], sourceDir }) }, "\u9884\u89C8\u76EE\u5F55")), (0, import_react4.createElement)("div", { className: "te-dir-list" }, browsePath ? (0, import_react4.createElement)("button", { onClick: () => {
|
|
5866
|
+
void browse(browsePath.replace(/[\\/][^\\/]+[\\/]?$/u, "") || "/");
|
|
5867
|
+
} }, "\u2191 \u4E0A\u7EA7\u76EE\u5F55") : null, ...dirs.map((d) => (0, import_react4.createElement)("button", { key: d.name, onClick: () => {
|
|
5868
|
+
setRequest(null);
|
|
5869
|
+
void browse(browsePath.replace(/[\\/]+$/u, "") + "/" + d.name);
|
|
5870
|
+
} }, d.name + (d.hasSkill ? " \xB7 SKILL.md" : ""))))) : null,
|
|
5871
|
+
busy ? (0, import_react4.createElement)("p", { role: "status" }, "\u6B63\u5728\u6821\u9A8C\u6587\u4EF6\uFF0C\u8BF7\u7A0D\u5019\u2026") : null,
|
|
5872
|
+
status(),
|
|
5873
|
+
preview ? (0, import_react4.createElement)("div", { className: "te-preview" }, (0, import_react4.createElement)("h3", null, preview.name), (0, import_react4.createElement)("p", null, preview.description), (0, import_react4.createElement)("div", { className: "te-actions" }, (0, import_react4.createElement)("span", { className: "te-badge" }, `${preview.files} \u4E2A\u6587\u4EF6`), (0, import_react4.createElement)("span", { className: "te-badge" }, sizeText(preview.bytes))), (0, import_react4.createElement)("code", { className: "te-path" }, preview.target), preview.conflict ? (0, import_react4.createElement)("div", { className: "te-alert", role: "alert" }, "\u5DF2\u6709\u540C\u540D\u8D44\u6E90\u3002\u8BF7\u53D6\u6D88\u5E76\u68C0\u67E5\u73B0\u6709\u5185\u5BB9\uFF0C\u5B89\u88C5\u4E0D\u4F1A\u8986\u76D6\u5B83\u3002") : null, (0, import_react4.createElement)("div", { className: "te-markdown" }, (0, import_react4.createElement)(import_dsh_client_ui_primitives4.MarkdownText, { text: preview.content, labels }))) : null
|
|
5874
|
+
) : null,
|
|
5875
|
+
editing ? (0, import_react4.createElement)(
|
|
5876
|
+
ResourceModal,
|
|
5877
|
+
{ title: editing === "new" ? `\u65B0\u5EFA${noun}` : `${viewing ? "\u67E5\u770B" : "\u7F16\u8F91"}${noun} \xB7 ${name}`, onClose: close, footer: (0, import_react4.createElement)("div", { className: "te-actions" }, (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", disabled: busy, onClick: close }, "\u5173\u95ED"), !readonly ? (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", disabled: busy, onClick: () => setViewing(!viewing) }, viewing ? "\u7F16\u8F91\u5185\u5BB9" : "\u9884\u89C8") : null, !readonly ? (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "primary", disabled: busy || !name.trim() || !body2.trim() || kind === "skill" && !description.trim(), onClick: () => {
|
|
5878
|
+
void save2();
|
|
5879
|
+
} }, busy ? "\u5904\u7406\u4E2D\u2026" : "\u4FDD\u5B58") : null) },
|
|
5880
|
+
!readonly ? targets() : (0, import_react4.createElement)("p", { className: "te-badge" }, "\u5185\u7F6E\u8D44\u6E90 \xB7 \u53EA\u8BFB"),
|
|
5881
|
+
status(),
|
|
5882
|
+
viewing ? (0, import_react4.createElement)("div", { className: "te-markdown" }, (0, import_react4.createElement)(import_dsh_client_ui_primitives4.MarkdownText, { text: body2, labels })) : (0, import_react4.createElement)("div", { className: "te-form" }, (0, import_react4.createElement)("label", null, "\u540D\u79F0", (0, import_react4.createElement)("input", { className: "te-input", value: name, disabled: editing !== "new" || busy, onChange: (e) => setName(e.target.value), placeholder: "\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u8FDE\u5B57\u7B26" })), kind === "skill" ? (0, import_react4.createElement)("label", null, "\u63CF\u8FF0", (0, import_react4.createElement)("input", { className: "te-input", value: description, disabled: busy, onChange: (e) => setDescription(e.target.value) })) : null, kind === "skill" ? (0, import_react4.createElement)("label", null, "\u4F7F\u7528\u65F6\u673A\uFF08\u53EF\u9009\uFF09", (0, import_react4.createElement)("input", { className: "te-input", value: whenToUse, disabled: busy, onChange: (e) => setWhenToUse(e.target.value) })) : null, (0, import_react4.createElement)("label", null, "Markdown \u6B63\u6587", (0, import_react4.createElement)("textarea", { className: "te-input te-editor", value: body2, disabled: busy, onChange: (e) => setBody(e.target.value) })))
|
|
5883
|
+
) : null,
|
|
5884
|
+
deleting ? (0, import_react4.createElement)(ResourceModal, { title: `\u5220\u9664${noun}\u300C${deleting.name}\u300D\uFF1F`, description: levelOf(deleting) === "user" ? "\u8FD9\u662F\u4E2A\u4EBA\u5168\u5C40\u8D44\u6E90\uFF0C\u5220\u9664\u4F1A\u5F71\u54CD\u6B64\u4E3B\u673A\u4E0A\u7684\u6240\u6709\u9879\u76EE\u3002" : "\u5220\u9664\u5C06\u5F71\u54CD\u5F53\u524D\u9879\u76EE\u3002", onClose: close, footer: (0, import_react4.createElement)("div", { className: "te-actions" }, (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", disabled: busy, onClick: close }, "\u4FDD\u7559"), (0, import_react4.createElement)("button", { className: "te-danger-button", disabled: busy, onClick: () => {
|
|
5885
|
+
void remove();
|
|
5886
|
+
} }, busy ? "\u5220\u9664\u4E2D\u2026" : "\u786E\u8BA4\u6C38\u4E45\u5220\u9664")) }, (0, import_react4.createElement)("code", { className: "te-path" }, `${roots?.[levelOf(deleting) === "user" ? "user" : "project"] ?? "\u8D44\u6E90\u76EE\u5F55"}/${deleting.name}${kind === "rule" ? ".md" : ""}`), (0, import_react4.createElement)("p", null, "\u6B64\u64CD\u4F5C\u4E0D\u4F1A\u8FDB\u5165\u56DE\u6536\u7AD9\uFF0C\u8BF7\u786E\u8BA4\u5DF2\u6709\u5907\u4EFD\u3002"), status()) : null
|
|
5970
5887
|
);
|
|
5971
5888
|
}
|
|
5972
5889
|
|
|
5973
|
-
// src/client/
|
|
5890
|
+
// src/client/SkillManager.tsx
|
|
5891
|
+
function SkillManager(props) {
|
|
5892
|
+
return (0, import_react5.createElement)(ResourceManager, { ...props, key: props.workspace, kind: "skill" });
|
|
5893
|
+
}
|
|
5894
|
+
|
|
5895
|
+
// src/client/RuleManager.tsx
|
|
5974
5896
|
var import_react6 = require("react");
|
|
5975
|
-
|
|
5976
|
-
|
|
5897
|
+
function RuleManager(props) {
|
|
5898
|
+
return (0, import_react6.createElement)(ResourceManager, { ...props, key: props.workspace, kind: "rule" });
|
|
5899
|
+
}
|
|
5900
|
+
|
|
5901
|
+
// src/client/TaskLedger.tsx
|
|
5902
|
+
var import_react7 = require("react");
|
|
5903
|
+
var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
5904
|
+
var card2 = {
|
|
5977
5905
|
display: "flex",
|
|
5978
5906
|
flexDirection: "column",
|
|
5979
5907
|
gap: 10,
|
|
@@ -6010,10 +5938,10 @@ var badge = {
|
|
|
6010
5938
|
color: "var(--dsw-alias-label-secondary)"
|
|
6011
5939
|
};
|
|
6012
5940
|
function verdictDot(outcome) {
|
|
6013
|
-
return (0,
|
|
5941
|
+
return (0, import_react7.createElement)(import_dsh_client_ui_primitives5.StateDot, { state: outcome === "pass" ? "done" : "error" });
|
|
6014
5942
|
}
|
|
6015
5943
|
function itemStatusDot(status) {
|
|
6016
|
-
return (0,
|
|
5944
|
+
return (0, import_react7.createElement)(import_dsh_client_ui_primitives5.StateDot, { state: status === "done" ? "done" : "ongoing" });
|
|
6017
5945
|
}
|
|
6018
5946
|
function timeText(at) {
|
|
6019
5947
|
return at.slice(0, 19).replace("T", " ");
|
|
@@ -6021,92 +5949,111 @@ function timeText(at) {
|
|
|
6021
5949
|
function itemAudit(item) {
|
|
6022
5950
|
const lines = [];
|
|
6023
5951
|
if (item.dispatch !== void 0) {
|
|
6024
|
-
lines.push((0,
|
|
5952
|
+
lines.push((0, import_react7.createElement)(
|
|
6025
5953
|
"div",
|
|
6026
5954
|
{ key: "dispatch", style: metaLine },
|
|
6027
|
-
(0,
|
|
6028
|
-
(0,
|
|
6029
|
-
(0,
|
|
5955
|
+
(0, import_react7.createElement)("span", { style: badge }, "\u5DF2\u6D3E\u53D1"),
|
|
5956
|
+
(0, import_react7.createElement)("span", null, item.dispatch.description === "" ? "\uFF08\u65E0\u63CF\u8FF0\uFF09" : item.dispatch.description),
|
|
5957
|
+
(0, import_react7.createElement)("span", { style: badge }, timeText(item.dispatch.at))
|
|
6030
5958
|
));
|
|
6031
5959
|
}
|
|
6032
5960
|
if (item.review !== void 0) {
|
|
6033
5961
|
const spec = item.review.spec;
|
|
6034
5962
|
const quality = item.review.quality;
|
|
6035
|
-
lines.push((0,
|
|
5963
|
+
lines.push((0, import_react7.createElement)(
|
|
6036
5964
|
"div",
|
|
6037
5965
|
{ key: "review", style: metaLine },
|
|
6038
5966
|
verdictDot(spec.outcome),
|
|
6039
|
-
(0,
|
|
6040
|
-
(0,
|
|
5967
|
+
(0, import_react7.createElement)("span", null, `\u89C4\u683C\u7B26\u5408 ${spec.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`),
|
|
5968
|
+
(0, import_react7.createElement)("span", null, "\xB7"),
|
|
6041
5969
|
verdictDot(quality.outcome),
|
|
6042
|
-
(0,
|
|
5970
|
+
(0, import_react7.createElement)("span", null, `\u4EE3\u7801\u8D28\u91CF ${quality.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`)
|
|
6043
5971
|
));
|
|
6044
5972
|
const failNotes = [spec, quality].flatMap((stage) => stage.outcome === "fail" ? stage.notes ?? [] : []);
|
|
6045
5973
|
if (failNotes.length > 0) {
|
|
6046
|
-
lines.push((0,
|
|
5974
|
+
lines.push((0, import_react7.createElement)(
|
|
6047
5975
|
"div",
|
|
6048
5976
|
{ key: "notes", style: metaLine },
|
|
6049
|
-
...failNotes.map((note) => (0,
|
|
5977
|
+
...failNotes.map((note) => (0, import_react7.createElement)("span", { key: note, style: badge }, note))
|
|
6050
5978
|
));
|
|
6051
5979
|
}
|
|
6052
5980
|
}
|
|
6053
5981
|
if (lines.length === 0) {
|
|
6054
|
-
lines.push((0,
|
|
5982
|
+
lines.push((0, import_react7.createElement)("div", { key: "none", style: metaLine }, (0, import_react7.createElement)("span", { style: badge }, "\u672A\u6D3E\u53D1 / \u672A\u5BA1\u67E5")));
|
|
6055
5983
|
}
|
|
6056
|
-
return (0,
|
|
5984
|
+
return (0, import_react7.createElement)("div", { style: { display: "flex", flexDirection: "column", gap: 4 } }, ...lines);
|
|
6057
5985
|
}
|
|
6058
5986
|
function TaskLedger({ workspace, remote }) {
|
|
6059
|
-
const [tasks, setTasks] = (0,
|
|
6060
|
-
const [error, setError] = (0,
|
|
6061
|
-
const
|
|
5987
|
+
const [tasks, setTasks] = (0, import_react7.useState)([]);
|
|
5988
|
+
const [error, setError] = (0, import_react7.useState)("");
|
|
5989
|
+
const [loading, setLoading] = (0, import_react7.useState)(true);
|
|
5990
|
+
const [query, setQuery] = (0, import_react7.useState)("");
|
|
5991
|
+
const [risk, setRisk] = (0, import_react7.useState)("all");
|
|
5992
|
+
const [stage, setStage] = (0, import_react7.useState)("all");
|
|
5993
|
+
const refresh = (0, import_react7.useCallback)(() => {
|
|
6062
5994
|
if (workspace === "") return;
|
|
6063
5995
|
setError("");
|
|
5996
|
+
setLoading(true);
|
|
6064
5997
|
void remote.readTasks(workspace).then((result) => {
|
|
5998
|
+
setLoading(false);
|
|
6065
5999
|
if (result.ok) setTasks(result.value.tasks);
|
|
6066
6000
|
else setError("\u8BFB\u53D6\u53F0\u8D26\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
6067
6001
|
}, (reason) => {
|
|
6002
|
+
setLoading(false);
|
|
6068
6003
|
setError("\u8BFB\u53D6\u53F0\u8D26\u5931\u8D25\uFF1A" + describeError(reason));
|
|
6069
6004
|
});
|
|
6070
6005
|
}, [remote, workspace]);
|
|
6071
|
-
(0,
|
|
6006
|
+
(0, import_react7.useEffect)(() => {
|
|
6072
6007
|
refresh();
|
|
6073
6008
|
}, [refresh]);
|
|
6074
|
-
|
|
6009
|
+
const visible = tasks.filter((task) => `${task.task_id} ${task.title} ${task.branch}`.toLowerCase().includes(query.toLowerCase()) && (risk === "all" || task.risk_level === risk) && (stage === "all" || task.stage === stage));
|
|
6010
|
+
return (0, import_react7.createElement)(
|
|
6075
6011
|
"div",
|
|
6076
6012
|
{ style: styles.section },
|
|
6077
|
-
(0,
|
|
6013
|
+
(0, import_react7.createElement)(
|
|
6014
|
+
"div",
|
|
6015
|
+
{ className: "te-toolbar" },
|
|
6016
|
+
(0, import_react7.createElement)("input", { className: "te-input", placeholder: "\u641C\u7D22\u4EFB\u52A1\u3001\u6807\u9898\u6216\u5206\u652F", value: query, onChange: (e) => setQuery(e.target.value) }),
|
|
6017
|
+
(0, import_react7.createElement)("select", { className: "te-input", "aria-label": "\u98CE\u9669\u7B5B\u9009", value: risk, onChange: (e) => setRisk(e.target.value) }, (0, import_react7.createElement)("option", { value: "all" }, "\u5168\u90E8\u98CE\u9669"), (0, import_react7.createElement)("option", { value: "standard" }, "\u6807\u51C6"), (0, import_react7.createElement)("option", { value: "high_risk" }, "\u9AD8\u98CE\u9669")),
|
|
6018
|
+
(0, import_react7.createElement)("select", { className: "te-input", "aria-label": "\u9636\u6BB5\u7B5B\u9009", value: stage, onChange: (e) => setStage(e.target.value) }, (0, import_react7.createElement)("option", { value: "all" }, "\u5168\u90E8\u9636\u6BB5"), ...Array.from(new Set(tasks.map((t) => t.stage))).map((value) => (0, import_react7.createElement)("option", { key: value, value }, value)))
|
|
6019
|
+
),
|
|
6020
|
+
(0, import_react7.createElement)(
|
|
6078
6021
|
"div",
|
|
6079
6022
|
{ style: headerRow },
|
|
6080
|
-
(0,
|
|
6081
|
-
(0,
|
|
6082
|
-
(0,
|
|
6023
|
+
(0, import_react7.createElement)("span", { style: styles.bindingLabel }, "\u4EFB\u52A1\u53F0\u8D26"),
|
|
6024
|
+
(0, import_react7.createElement)("span", { style: styles.sourceBadge }, "\u53EA\u8BFB \xB7 \u6765\u81EA .dsh/task-*.json"),
|
|
6025
|
+
(0, import_react7.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", size: "sm", disabled: loading, onClick: refresh }, loading ? "\u8BFB\u53D6\u4E2D\u2026" : "\u5237\u65B0")
|
|
6083
6026
|
),
|
|
6084
|
-
error !== "" ? (0,
|
|
6027
|
+
loading ? (0, import_react7.createElement)("p", { role: "status" }, "\u6B63\u5728\u8BFB\u53D6\u4EFB\u52A1\u2026") : error !== "" ? (0, import_react7.createElement)("p", { style: styles.status }, error) : tasks.length === 0 ? (0, import_react7.createElement)("p", { style: styles.muted }, "\u5F53\u524D\u5DE5\u4F5C\u533A\u8FD8\u6CA1\u6709\u4EFB\u52A1\uFF1A\u5F00\u5DE5\u540E\uFF08dev_task create\uFF09\u4F1A\u5728\u8FD9\u91CC\u5217\u51FA\u6D3E\u53D1\u4E0E\u5BA1\u67E5\u7559\u75D5\u3002") : visible.length === 0 ? (0, import_react7.createElement)("div", { className: "te-empty" }, "\u6CA1\u6709\u5339\u914D\u7684\u4EFB\u52A1\uFF0C\u8BF7\u8C03\u6574\u7B5B\u9009\u3002") : (0, import_react7.createElement)(
|
|
6085
6028
|
"div",
|
|
6086
6029
|
{ style: { display: "flex", flexDirection: "column", gap: 12 } },
|
|
6087
|
-
...
|
|
6030
|
+
...visible.map((task) => (0, import_react7.createElement)(
|
|
6088
6031
|
"div",
|
|
6089
|
-
{ key: task.task_id, style:
|
|
6090
|
-
(0,
|
|
6032
|
+
{ key: task.task_id, style: card2 },
|
|
6033
|
+
(0, import_react7.createElement)(
|
|
6091
6034
|
"div",
|
|
6092
6035
|
{ style: headerRow },
|
|
6093
|
-
(0,
|
|
6094
|
-
(0,
|
|
6095
|
-
(0,
|
|
6096
|
-
(0,
|
|
6036
|
+
(0, import_react7.createElement)("span", { style: { fontSize: 14, fontWeight: 600, color: "var(--dsw-alias-label-primary)" } }, task.task_id),
|
|
6037
|
+
(0, import_react7.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, task.title),
|
|
6038
|
+
(0, import_react7.createElement)("span", { style: badge }, task.stage),
|
|
6039
|
+
(0, import_react7.createElement)("span", { style: badge }, task.branch),
|
|
6040
|
+
(0, import_react7.createElement)("span", { className: "te-badge", style: task.risk_level === "high_risk" ? { color: "var(--dsw-alias-state-error-primary)" } : {} }, task.risk_level === "high_risk" ? "\u9AD8\u98CE\u9669" : "\u6807\u51C6"),
|
|
6041
|
+
(0, import_react7.createElement)("span", { className: "te-badge" }, task.verification_passed ? "\u9A8C\u8BC1\u901A\u8FC7" : "\u5F85\u9A8C\u8BC1"),
|
|
6042
|
+
(0, import_react7.createElement)("span", { className: "te-badge" }, `\u5BA1\u6838\uFF1A${task.review_outcome ?? "pending"}`),
|
|
6043
|
+
task.updated_at ? (0, import_react7.createElement)("span", { style: metaLine }, "\u66F4\u65B0\u4E8E " + timeText(task.updated_at)) : null
|
|
6097
6044
|
),
|
|
6098
|
-
(0,
|
|
6045
|
+
(0, import_react7.createElement)(
|
|
6099
6046
|
"div",
|
|
6100
6047
|
{ style: { display: "flex", flexDirection: "column" } },
|
|
6101
|
-
...task.items.map((item) => (0,
|
|
6048
|
+
...task.items.map((item) => (0, import_react7.createElement)(
|
|
6102
6049
|
"div",
|
|
6103
6050
|
{ key: item.id, style: itemRow },
|
|
6104
|
-
(0,
|
|
6051
|
+
(0, import_react7.createElement)(
|
|
6105
6052
|
"div",
|
|
6106
6053
|
{ style: headerRow },
|
|
6107
6054
|
itemStatusDot(item.status),
|
|
6108
|
-
(0,
|
|
6109
|
-
(0,
|
|
6055
|
+
(0, import_react7.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, item.id),
|
|
6056
|
+
(0, import_react7.createElement)("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, item.title)
|
|
6110
6057
|
),
|
|
6111
6058
|
itemAudit(item)
|
|
6112
6059
|
))
|
|
@@ -6129,24 +6076,25 @@ var header = {
|
|
|
6129
6076
|
display: "flex",
|
|
6130
6077
|
alignItems: "center",
|
|
6131
6078
|
justifyContent: "space-between",
|
|
6132
|
-
padding: "
|
|
6079
|
+
padding: "20px 28px",
|
|
6133
6080
|
borderBottom: "1px solid var(--dsw-alias-border-l2)"
|
|
6134
6081
|
};
|
|
6135
6082
|
var headerBrand = { display: "flex", alignItems: "center", gap: 10, minWidth: 0 };
|
|
6136
6083
|
var headerText = { display: "flex", flexDirection: "column", gap: 1, minWidth: 0 };
|
|
6137
|
-
var headerTitle = { fontSize:
|
|
6084
|
+
var headerTitle = { fontSize: 20, fontWeight: 650, color: "var(--dsw-alias-label-primary)" };
|
|
6138
6085
|
var headerSub = { fontSize: 12, color: "var(--dsw-alias-label-tertiary)", margin: 0 };
|
|
6139
6086
|
var tabbar = {
|
|
6140
6087
|
display: "flex",
|
|
6141
6088
|
alignItems: "center",
|
|
6142
6089
|
gap: 8,
|
|
6143
|
-
padding: "
|
|
6090
|
+
padding: "12px 28px",
|
|
6091
|
+
flexWrap: "wrap",
|
|
6144
6092
|
borderBottom: "1px solid var(--dsw-alias-border-l2)"
|
|
6145
6093
|
};
|
|
6146
6094
|
var body = {
|
|
6147
6095
|
flex: 1,
|
|
6148
6096
|
overflowY: "auto",
|
|
6149
|
-
padding:
|
|
6097
|
+
padding: "24px clamp(12px, 3vw, 32px)"
|
|
6150
6098
|
};
|
|
6151
6099
|
var selectStyle = {
|
|
6152
6100
|
marginLeft: "auto",
|
|
@@ -6173,34 +6121,35 @@ var TABS = [
|
|
|
6173
6121
|
{ id: "init", label: "\u9879\u76EE\u521D\u59CB\u5316" },
|
|
6174
6122
|
{ id: "flow", label: "\u6D41\u7A0B\u914D\u7F6E" },
|
|
6175
6123
|
{ id: "tasks", label: "\u4EFB\u52A1\u53F0\u8D26" },
|
|
6176
|
-
{ id: "skills", label: "\u6280\u80FD
|
|
6177
|
-
{ id: "rules", label: "\u89C4\u5219
|
|
6124
|
+
{ id: "skills", label: "\u6280\u80FD" },
|
|
6125
|
+
{ id: "rules", label: "\u89C4\u5219" }
|
|
6178
6126
|
];
|
|
6179
6127
|
function Workbench({ useStore, actions, useWorkspaces, remote }) {
|
|
6180
6128
|
const open = useStore((s) => s.open);
|
|
6181
6129
|
const workspaces = useWorkspaces((s) => s.items);
|
|
6182
|
-
const [tab, setTab] = (0,
|
|
6183
|
-
const [workspace, setWorkspace] = (0,
|
|
6130
|
+
const [tab, setTab] = (0, import_react8.useState)("init");
|
|
6131
|
+
const [workspace, setWorkspace] = (0, import_react8.useState)("");
|
|
6184
6132
|
if (!open) return null;
|
|
6185
6133
|
const current = workspaces.some((w) => w.path === workspace) ? workspace : workspaces[0]?.path ?? "";
|
|
6186
|
-
return (0,
|
|
6134
|
+
return (0, import_react8.createElement)(
|
|
6187
6135
|
"div",
|
|
6188
|
-
{ style: overlay },
|
|
6189
|
-
(0,
|
|
6136
|
+
{ style: overlay, className: "te-workbench" },
|
|
6137
|
+
(0, import_react8.createElement)("style", null, workbenchTheme),
|
|
6138
|
+
(0, import_react8.createElement)(
|
|
6190
6139
|
"div",
|
|
6191
6140
|
{ style: header },
|
|
6192
|
-
(0,
|
|
6141
|
+
(0, import_react8.createElement)(
|
|
6193
6142
|
"div",
|
|
6194
6143
|
{ style: headerBrand },
|
|
6195
|
-
(0,
|
|
6196
|
-
(0,
|
|
6144
|
+
(0, import_react8.createElement)(import_dsh_client_ui_primitives6.IconSettingsOutline16, { size: 18 }),
|
|
6145
|
+
(0, import_react8.createElement)(
|
|
6197
6146
|
"div",
|
|
6198
6147
|
{ style: headerText },
|
|
6199
|
-
(0,
|
|
6200
|
-
(0,
|
|
6148
|
+
(0, import_react8.createElement)("span", { style: headerTitle }, "\u5DE5\u7A0B\u6D41\u7A0B"),
|
|
6149
|
+
(0, import_react8.createElement)("p", { style: headerSub }, "\u5DE5\u7A0B\u5316\u4EA4\u4ED8\u5DE5\u4F5C\u53F0 \xB7 \u9700\u6C42\u8BC4\u5BA1 \u2192 \u8BBE\u8BA1 \u2192 \u5F00\u53D1 \u2192 \u4EA4\u4ED8 \u2192 \u4EE3\u7801\u5BA1\u6838")
|
|
6201
6150
|
)
|
|
6202
6151
|
),
|
|
6203
|
-
(0,
|
|
6152
|
+
(0, import_react8.createElement)(
|
|
6204
6153
|
"button",
|
|
6205
6154
|
{
|
|
6206
6155
|
type: "button",
|
|
@@ -6216,38 +6165,44 @@ function Workbench({ useStore, actions, useWorkspaces, remote }) {
|
|
|
6216
6165
|
event.currentTarget.style.background = "transparent";
|
|
6217
6166
|
}
|
|
6218
6167
|
},
|
|
6219
|
-
(0,
|
|
6168
|
+
(0, import_react8.createElement)(import_dsh_client_ui_primitives6.IconCloseOutline16, { size: 16 })
|
|
6220
6169
|
)
|
|
6221
6170
|
),
|
|
6222
|
-
(0,
|
|
6171
|
+
(0, import_react8.createElement)(
|
|
6223
6172
|
"div",
|
|
6224
6173
|
{ style: tabbar },
|
|
6225
|
-
...TABS.map((t) => (0,
|
|
6174
|
+
...TABS.map((t) => (0, import_react8.createElement)(import_dsh_client_ui_primitives6.Pill, { key: t.id, active: tab === t.id, onClick: () => {
|
|
6226
6175
|
setTab(t.id);
|
|
6227
6176
|
} }, t.label)),
|
|
6228
|
-
workspaces.length > 0 ? (0,
|
|
6177
|
+
workspaces.length > 0 ? (0, import_react8.createElement)("select", {
|
|
6229
6178
|
style: selectStyle,
|
|
6179
|
+
"aria-label": "\u5F53\u524D\u5DE5\u4F5C\u533A",
|
|
6230
6180
|
value: current,
|
|
6231
6181
|
onChange: (ev) => {
|
|
6232
6182
|
setWorkspace(ev.target.value);
|
|
6233
6183
|
}
|
|
6234
|
-
}, ...workspaces.map((w) => (0,
|
|
6184
|
+
}, ...workspaces.map((w) => (0, import_react8.createElement)("option", { key: w.path, value: w.path }, w.title || w.path))) : null
|
|
6235
6185
|
),
|
|
6236
|
-
(0,
|
|
6186
|
+
(0, import_react8.createElement)(
|
|
6237
6187
|
"div",
|
|
6238
6188
|
{ style: body },
|
|
6239
|
-
|
|
6189
|
+
(0, import_react8.createElement)(
|
|
6190
|
+
"div",
|
|
6191
|
+
{ className: "te-content", key: current },
|
|
6192
|
+
(0, import_react8.createElement)("p", { style: { ...styles.hint, marginBottom: 20 }, title: current }, "\u5DE5\u4F5C\u533A \xB7 " + current),
|
|
6193
|
+
current === "" ? (0, import_react8.createElement)("p", { style: styles.muted }, "\u5F53\u524D\u6CA1\u6709\u5DE5\u4F5C\u533A\uFF1A\u8BF7\u5148\u5728\u4FA7\u680F\u521B\u5EFA\u4E00\u4E2A\u5DE5\u4F5C\u533A\uFF0C\u518D\u56DE\u6765\u914D\u7F6E\u6D41\u7A0B\u3002") : tab === "init" ? (0, import_react8.createElement)(InitPanel, { workspace: current, remote }) : tab === "flow" ? (0, import_react8.createElement)(TaskEngineSection, { workspace: current, remote }) : tab === "tasks" ? (0, import_react8.createElement)(TaskLedger, { workspace: current, remote }) : tab === "skills" ? (0, import_react8.createElement)(SkillManager, { workspace: current, remote }) : (0, import_react8.createElement)(RuleManager, { workspace: current, remote })
|
|
6194
|
+
)
|
|
6240
6195
|
)
|
|
6241
6196
|
);
|
|
6242
6197
|
}
|
|
6243
6198
|
|
|
6244
6199
|
// src/client/TriggerButton.tsx
|
|
6245
|
-
var
|
|
6246
|
-
var
|
|
6200
|
+
var import_react9 = require("react");
|
|
6201
|
+
var import_dsh_client_ui_primitives7 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
6247
6202
|
var hover = "var(--dsw-alias-bg-layer-2)";
|
|
6248
6203
|
var label = "var(--dsw-alias-label-primary)";
|
|
6249
6204
|
function TriggerButton({ wide, actions }) {
|
|
6250
|
-
return (0,
|
|
6205
|
+
return (0, import_react9.createElement)(
|
|
6251
6206
|
"button",
|
|
6252
6207
|
{
|
|
6253
6208
|
type: "button",
|
|
@@ -6287,8 +6242,8 @@ function TriggerButton({ wide, actions }) {
|
|
|
6287
6242
|
transition: "background 120ms ease"
|
|
6288
6243
|
}
|
|
6289
6244
|
},
|
|
6290
|
-
(0,
|
|
6291
|
-
wide ? (0,
|
|
6245
|
+
(0, import_react9.createElement)(import_dsh_client_ui_primitives7.IconSettingsOutline16, { size: wide ? 16 : 18 }),
|
|
6246
|
+
wide ? (0, import_react9.createElement)("span", { style: { fontSize: 14, lineHeight: "22px" } }, "\u5DE5\u7A0B\u6D41\u7A0B") : null
|
|
6292
6247
|
);
|
|
6293
6248
|
}
|
|
6294
6249
|
|