@godv61/dsh-task-engine 0.24.0 → 0.26.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/.acceptance.mjs +101 -39
- package/.assessment-batch1.mjs +32 -12
- package/.e2e-presets.mjs +40 -5
- package/.enforce-test.mjs +139 -0
- package/.evidence-test.mjs +118 -0
- package/.filter-test.mjs +93 -0
- package/.freeze-test.mjs +110 -1
- package/.hook-test.mjs +195 -190
- package/.p0-test.mjs +130 -46
- package/.preset-test.mjs +160 -160
- package/.revision-test.mjs +32 -3
- package/.roundtrip-test.mjs +178 -0
- package/.workflow-test.mjs +117 -4
- package/README.md +10 -8
- package/cordis.patch.yml +10 -10
- package/defaults/eng.json +70 -22
- package/docs/BRIEF-FOR-REVIEW.md +162 -162
- package/docs/CHANGELOG.md +49 -0
- package/docs/README.md +40 -40
- package/docs/configuration.md +14 -11
- package/docs/development.md +1 -1
- package/docs/faq.md +4 -4
- package/docs/listing/godv61__dsh-task-engine.yml +5 -5
- package/docs/listing/submission.md +83 -83
- package/docs/manual.html +31 -26
- package/docs/releases/0.23.2.md +21 -21
- package/docs/roadmap.md +34 -34
- package/docs/testing/0.23.2/R02/344/270/232/345/212/241/346/265/213/350/257/225/346/230/216/347/273/206.md +56 -56
- package/docs/testing/0.23.2/R03/344/270/232/345/212/241/346/265/213/350/257/225/346/230/216/347/273/206.md +38 -38
- package/docs/testing/0.23.2//346/265/213/350/257/225/346/212/245/345/221/212.md +65 -65
- package/hooks/commit-msg +159 -72
- package/lib/client.js +963 -571
- package/lib/client.js.map +3 -3
- package/lib/controller.d.ts +11 -2
- package/lib/controller.js +33 -5
- package/lib/controller.js.map +1 -1
- package/lib/dev-task.js +170 -28
- package/lib/dev-task.js.map +1 -1
- package/lib/engine.d.ts +105 -0
- package/lib/engine.js +93 -5
- package/lib/engine.js.map +1 -1
- package/lib/hook.js +17 -4
- package/lib/hook.js.map +1 -1
- package/lib/skill-audit.d.ts +14 -3
- package/lib/skill-audit.js +66 -3
- package/lib/skill-audit.js.map +1 -1
- package/lib/workflows.d.ts +78 -12
- package/lib/workflows.js +258 -94
- package/lib/workflows.js.map +1 -1
- package/package.json +9 -5
- package/preset/agent.cordis.yml +21 -21
- package/preset/enable.mjs +87 -87
- package/preset/persona.md +4 -4
- package/preset/preset.yml +1 -1
- package/rules/coding-conventions.md +6 -6
- package/rules/commit-conventions.md +6 -6
- package/rules/security-redlines.md +5 -5
- package/scripts/verify-dsh-compat.mjs +144 -144
- package/scripts/verify-package.mjs +1 -1
- package/skills/code-verify/SKILL.md +3 -3
package/lib/client.js
CHANGED
|
@@ -4536,8 +4536,8 @@ var TYPERT_REMOTE = {
|
|
|
4536
4536
|
var remote_default = TYPERT_REMOTE;
|
|
4537
4537
|
|
|
4538
4538
|
// src/client/Workbench.tsx
|
|
4539
|
-
var
|
|
4540
|
-
var
|
|
4539
|
+
var import_react9 = require("react");
|
|
4540
|
+
var import_dsh_client_ui_primitives7 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
4541
4541
|
|
|
4542
4542
|
// src/client/workbench-theme.ts
|
|
4543
4543
|
var workbenchTheme = `
|
|
@@ -4557,6 +4557,14 @@ var workbenchTheme = `
|
|
|
4557
4557
|
.te-binding-tools .te-input { flex:1; width:100%; min-width:120px; padding:8px 10px; font-size:13px; }
|
|
4558
4558
|
.te-binding-filter { display:flex; align-items:center; gap:5px; font-size:12px; white-space:nowrap; cursor:pointer; }
|
|
4559
4559
|
.te-binding-list { max-height:280px; overflow-y:auto; overscroll-behavior:contain; display:flex; flex-direction:column; gap:4px; scrollbar-gutter:stable; }
|
|
4560
|
+
/* Search + filter row. The catalog grows with every install, so finding one skill
|
|
4561
|
+
has to be a lookup rather than a scroll. */
|
|
4562
|
+
.te-binding-controls { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin:0 0 6px; }
|
|
4563
|
+
.te-binding-search { flex:1; min-width:120px; padding:6px 9px; font-size:12px; color:var(--dsw-alias-label-primary); background:var(--dsw-alias-bg-layer-1); border:1px solid var(--dsw-alias-border-l2); border-radius:7px; }
|
|
4564
|
+
.te-binding-search:focus-visible { outline:2px solid var(--dsw-alias-state-business-primary); outline-offset:1px; }
|
|
4565
|
+
/* Only the open skill's rules render, and inside a bounded region: expanding a
|
|
4566
|
+
second skill must not push the first off screen or grow the page without limit. */
|
|
4567
|
+
.te-rule-list { display:flex; flex-direction:column; gap:4px; margin-top:6px; padding:8px; max-height:240px; overflow-y:auto; overscroll-behavior:contain; border:1px solid var(--dsw-alias-border-l2); border-radius:8px; background:var(--dsw-alias-bg-layer-1); scrollbar-gutter:stable; }
|
|
4560
4568
|
.te-binding-option { display:flex; gap:9px; align-items:flex-start; padding:9px; border:1px solid transparent; border-radius:8px; cursor:pointer; }
|
|
4561
4569
|
.te-binding-option:hover { background:var(--dsw-alias-bg-layer-2); }
|
|
4562
4570
|
.te-binding-option.is-selected { background:var(--dsw-alias-bg-layer-2); border-color:var(--dsw-alias-border-l2); }
|
|
@@ -4568,8 +4576,35 @@ var workbenchTheme = `
|
|
|
4568
4576
|
.te-binding-name { font-size:13px; font-weight:600; overflow-wrap:anywhere; }
|
|
4569
4577
|
.te-binding-description { color:var(--dsw-alias-label-secondary); font-size:12px; line-height:1.4; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; overflow-wrap:anywhere; }
|
|
4570
4578
|
.te-binding-empty { margin:0; padding:18px 8px; font-size:13px; }
|
|
4579
|
+
.te-transfer { display:grid; grid-template-columns:minmax(0,1fr) 24px minmax(0,1fr); gap:12px; align-items:stretch; }
|
|
4580
|
+
.te-transfer-pane { display:flex; flex-direction:column; min-width:0; gap:10px; padding:14px; border:1px solid var(--dsw-alias-border-l2); border-radius:12px; background:var(--dsw-alias-bg-layer-1); }
|
|
4581
|
+
.te-transfer-pane h4 { margin:0; font-size:14px; }
|
|
4582
|
+
.te-transfer-arrow { display:grid; place-items:center; color:var(--dsw-alias-label-tertiary); font-size:20px; }
|
|
4583
|
+
.te-transfer-search,.te-transfer-caption { min-height:38px; width:100%; }
|
|
4584
|
+
.te-transfer-caption { display:flex; align-items:center; margin:0; color:var(--dsw-alias-label-secondary); font-size:12px; }
|
|
4585
|
+
.te-transfer-list { display:flex; flex-direction:column; gap:4px; min-height:180px; max-height:310px; overflow:auto; overscroll-behavior:contain; scrollbar-gutter:stable; }
|
|
4586
|
+
.te-transfer-row { width:100%; display:flex; align-items:center; justify-content:space-between; gap:12px; border:1px solid transparent; border-radius:8px; padding:9px 11px; background:var(--dsw-alias-bg-layer-2); color:var(--dsw-alias-label-primary); text-align:left; cursor:pointer; }
|
|
4587
|
+
.te-transfer-row:hover { border-color:var(--dsw-alias-state-business-primary); }
|
|
4588
|
+
.te-transfer-row.is-bound { background:var(--dsw-alias-bg-layer-1); border-color:var(--dsw-alias-border-l2); cursor:default; }
|
|
4589
|
+
.te-transfer-row-main { min-width:0; display:flex; flex-direction:column; gap:2px; }
|
|
4590
|
+
.te-transfer-row-main strong { font-size:13px; font-weight:600; overflow-wrap:anywhere; }
|
|
4591
|
+
.te-transfer-row-main small { color:var(--dsw-alias-label-secondary); font-size:11px; line-height:1.35; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
4592
|
+
.te-transfer-action { flex:none; display:grid; place-items:center; width:27px; height:27px; border-radius:7px; background:var(--dsw-alias-bg-layer-1); color:var(--dsw-alias-state-business-primary); font-size:18px; }
|
|
4593
|
+
.te-transfer-actions { flex:none; display:flex; align-items:center; gap:6px; }
|
|
4594
|
+
.te-transfer-config,.te-transfer-remove { border:0; border-radius:7px; padding:6px 8px; background:var(--dsw-alias-bg-layer-2); color:var(--dsw-alias-label-primary); cursor:pointer; font-size:12px; white-space:nowrap; }
|
|
4595
|
+
.te-transfer-config:hover,.te-transfer-remove:hover { color:var(--dsw-alias-state-business-primary); }
|
|
4596
|
+
.te-transfer-remove { width:27px; height:27px; padding:0; font-size:19px; line-height:1; }
|
|
4597
|
+
.te-dialog-error { color:var(--dsw-alias-state-error-primary); font-size:12px; margin-right:auto; }
|
|
4598
|
+
.te-skill-config { display:flex; flex:1; flex-direction:column; gap:12px; min-width:0; min-height:0; }
|
|
4599
|
+
.te-skill-evidence { display:flex; align-items:center; justify-content:space-between; gap:12px; font-size:13px; font-weight:600; }
|
|
4600
|
+
.te-skill-evidence .te-input { min-width:210px; }
|
|
4601
|
+
.te-skill-rule-list { display:flex; flex:1; flex-direction:column; gap:4px; min-height:0; overflow:auto; padding:4px; }
|
|
4602
|
+
.te-skill-rule-row { display:flex; align-items:center; gap:10px; padding:9px 10px; border:1px solid var(--dsw-alias-border-l2); border-radius:8px; cursor:pointer; }
|
|
4603
|
+
.te-skill-rule-row:hover { background:var(--dsw-alias-bg-layer-1); }
|
|
4604
|
+
.te-skill-rule-row span { flex:1; min-width:0; overflow-wrap:anywhere; }
|
|
4605
|
+
.te-skill-rule-row small { color:var(--dsw-alias-label-secondary); }
|
|
4571
4606
|
.te-workbench p,.te-modal p { color:var(--dsw-alias-label-secondary); line-height:1.65; }
|
|
4572
|
-
.te-content { max-width:
|
|
4607
|
+
.te-content { max-width:1600px; margin:auto; width:100%; }
|
|
4573
4608
|
.te-resource { display:flex; flex-direction:column; gap:20px; }
|
|
4574
4609
|
.te-section-heading { display:flex; justify-content:space-between; align-items:center; gap:16px; flex-wrap:wrap; }
|
|
4575
4610
|
.te-section-heading p { margin:0; }
|
|
@@ -4577,7 +4612,7 @@ var workbenchTheme = `
|
|
|
4577
4612
|
.te-toolbar { display:flex; flex-wrap:wrap; align-items:center; gap:12px; }
|
|
4578
4613
|
.te-toolbar>input { flex:1; min-width:180px; }
|
|
4579
4614
|
.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; }
|
|
4580
|
-
.te-resource-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(min(100%,
|
|
4615
|
+
.te-resource-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(min(100%,320px),1fr)); gap:16px; }
|
|
4581
4616
|
.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; }
|
|
4582
4617
|
.te-resource-card:hover { border-color:var(--dsw-alias-state-business-primary); }
|
|
4583
4618
|
.te-resource-card p { margin:0; font-size:13px; flex:1; }
|
|
@@ -4608,7 +4643,8 @@ var workbenchTheme = `
|
|
|
4608
4643
|
.te-form { display:flex; flex-direction:column; gap:16px; }
|
|
4609
4644
|
.te-form label { display:flex; flex-direction:column; gap:8px; font-size:13px; }
|
|
4610
4645
|
.te-editor { min-height:260px; resize:vertical; line-height:1.6; font-family:monospace; }
|
|
4611
|
-
@media(max-width:
|
|
4646
|
+
@media(max-width:760px) { .te-transfer {grid-template-columns:1fr;} .te-transfer-arrow {transform:rotate(90deg); height:20px;} .te-transfer-list {max-height:210px;} }
|
|
4647
|
+
@media(max-width:640px) { .te-targets {grid-template-columns:1fr;} .te-resource {gap:14px;} .te-section-heading h2 {font-size:21px;} .te-modal:not(.te-drawer) {padding:10px !important;} .te-drawer [role=dialog] {border-radius:0 !important;} .te-skill-evidence {align-items:stretch; flex-direction:column;} .te-skill-evidence .te-input {min-width:0;} }
|
|
4612
4648
|
`;
|
|
4613
4649
|
|
|
4614
4650
|
// src/client/styles.ts
|
|
@@ -4622,8 +4658,8 @@ var success = "var(--dsw-alias-state-success-primary)";
|
|
|
4622
4658
|
var warn = "var(--dsw-alias-state-warn-primary)";
|
|
4623
4659
|
var brand = "var(--dsw-alias-state-business-primary)";
|
|
4624
4660
|
var styles = {
|
|
4625
|
-
wrap: { display: "flex", flexDirection: "column", gap:
|
|
4626
|
-
head: { display: "flex", flexDirection: "column", gap: 4 },
|
|
4661
|
+
wrap: { display: "flex", flexDirection: "column", gap: 14, padding: "0 0 24px", width: "100%" },
|
|
4662
|
+
head: { display: "flex", flexDirection: "column", gap: 4, maxWidth: 1e3 },
|
|
4627
4663
|
title: { margin: 0, color: text },
|
|
4628
4664
|
muted: { margin: 0, color: textSecondary, fontSize: 13, lineHeight: 1.5 },
|
|
4629
4665
|
sourceRow: { display: "flex", alignItems: "center", gap: 8 },
|
|
@@ -4694,7 +4730,11 @@ var styles = {
|
|
|
4694
4730
|
borderTop: `1px solid ${border}`
|
|
4695
4731
|
},
|
|
4696
4732
|
// ── flow preset picker ────────────────────────────────────────────────────
|
|
4697
|
-
flowGrid: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(230px, 1fr))", gap: 10 },
|
|
4733
|
+
flowGrid: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(230px, 1fr))", gap: 10, maxWidth: 1200 },
|
|
4734
|
+
// The adoption row is deliberately separated from the flow picker: choosing a
|
|
4735
|
+
// skeleton and adopting a recommended setup are different decisions, and the
|
|
4736
|
+
// button is the only thing that writes method into the user's config.
|
|
4737
|
+
adoptRow: { display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap", marginBottom: 4 },
|
|
4698
4738
|
flowOption: {
|
|
4699
4739
|
display: "flex",
|
|
4700
4740
|
flexDirection: "column",
|
|
@@ -4736,8 +4776,8 @@ var styles = {
|
|
|
4736
4776
|
};
|
|
4737
4777
|
|
|
4738
4778
|
// src/client/TaskEngineSection.tsx
|
|
4739
|
-
var
|
|
4740
|
-
var
|
|
4779
|
+
var import_react3 = require("react");
|
|
4780
|
+
var import_dsh_client_ui_primitives3 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
4741
4781
|
|
|
4742
4782
|
// src/engine.ts
|
|
4743
4783
|
function formatResourceRef(ref) {
|
|
@@ -4757,7 +4797,7 @@ var GUARD_NAMES = [
|
|
|
4757
4797
|
"artifacts_present"
|
|
4758
4798
|
];
|
|
4759
4799
|
function validateWorkflow(config) {
|
|
4760
|
-
const problems = [];
|
|
4800
|
+
const problems = [...config.configuration_errors ?? []];
|
|
4761
4801
|
if (config.stages.length === 0) problems.push("stages must not be empty");
|
|
4762
4802
|
const seen = /* @__PURE__ */ new Set();
|
|
4763
4803
|
for (const stage of config.stages) {
|
|
@@ -4804,6 +4844,7 @@ function validateWorkflow(config) {
|
|
|
4804
4844
|
}
|
|
4805
4845
|
});
|
|
4806
4846
|
const bindings = config.stage_bindings ?? {};
|
|
4847
|
+
const skillMethods = /* @__PURE__ */ new Map();
|
|
4807
4848
|
for (const [stage, binding] of Object.entries(bindings)) {
|
|
4808
4849
|
if (!config.stages.includes(stage)) {
|
|
4809
4850
|
problems.push(`stage_bindings: stage "${stage}" is not a stage`);
|
|
@@ -4816,6 +4857,19 @@ function validateWorkflow(config) {
|
|
|
4816
4857
|
if (!["bundled", "project", "user"].includes(entry.skill.source)) {
|
|
4817
4858
|
problems.push(`stage_bindings "${stage}": skill "${entry.skill.name}" has unknown source "${String(entry.skill.source)}"`);
|
|
4818
4859
|
}
|
|
4860
|
+
const skillKey = formatResourceRef(entry.skill);
|
|
4861
|
+
const method = JSON.stringify({ rules: entry.rules ?? [], evidence: entry.evidence });
|
|
4862
|
+
const existing = skillMethods.get(skillKey);
|
|
4863
|
+
if (existing !== void 0 && existing !== method) {
|
|
4864
|
+
problems.push(`skill "${skillKey}" has different rules or evidence in multiple stages; copy it as a distinct skill`);
|
|
4865
|
+
}
|
|
4866
|
+
skillMethods.set(skillKey, method);
|
|
4867
|
+
if (entry.evidence === "artifact" && !config.artifacts.some((artifact) => artifact.stage === stage)) {
|
|
4868
|
+
problems.push(`skill "${skillKey}" requires artifact evidence, but stage "${stage}" declares no artifact`);
|
|
4869
|
+
}
|
|
4870
|
+
if (entry.evidence !== void 0 && !["command", "artifact", "review", "manual", "none"].includes(entry.evidence)) {
|
|
4871
|
+
problems.push(`skill "${skillKey}" has unknown evidence type "${String(entry.evidence)}"`);
|
|
4872
|
+
}
|
|
4819
4873
|
for (const rule of entry.rules ?? []) {
|
|
4820
4874
|
if (typeof rule?.name !== "string" || rule.name.trim() === "") {
|
|
4821
4875
|
problems.push(`stage_bindings "${stage}": skill "${entry.skill.name}" has a rule with no name`);
|
|
@@ -4871,19 +4925,23 @@ var STANDARD = {
|
|
|
4871
4925
|
{ from: "\u4EA4\u4ED8", to: "\u4EE3\u7801\u5BA1\u6838", requires: ["verified"] },
|
|
4872
4926
|
{ from: "\u4EE3\u7801\u5BA1\u6838", to: "\u5B8C\u6210", requires: ["review_passed", "artifacts_present"] }
|
|
4873
4927
|
],
|
|
4928
|
+
// No artifacts, no commit policy, no skills: the skeleton carries none of them.
|
|
4929
|
+
artifacts: [],
|
|
4930
|
+
commit: { policy: "task", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EE3\u7801\u5BA1\u6838"], file_scope: true },
|
|
4931
|
+
high_risk_requires_verification: true
|
|
4932
|
+
};
|
|
4933
|
+
var STANDARD_RECOMMENDATION = {
|
|
4934
|
+
commit: {
|
|
4935
|
+
// Only the TEXT conventions. Policy, checkpoints and scope stay on the
|
|
4936
|
+
// skeleton: they decide when a gate fires, not how a message reads.
|
|
4937
|
+
message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
|
|
4938
|
+
message_hint: "\u3010<task_id>\u3011\u3010TASK/T1\u3011\u8BF4\u660E \u2014\u2014 \u7B2C\u4E00\u6BB5\u586B\u672C\u4EFB\u52A1 id\uFF08\u5982 GREET-001\uFF09\uFF0C\u5199\u7ED3\u679C\u4E0D\u5199\u7A7A\u6CDB\u52A8\u4F5C"
|
|
4939
|
+
},
|
|
4874
4940
|
artifacts: [
|
|
4875
4941
|
{ stage: "\u9700\u6C42\u8BC4\u5BA1", id: "requirement", name: "\u9700\u6C42\u8BF4\u660E", fields: ["scope", "acceptance_criteria"] },
|
|
4876
4942
|
{ stage: "\u8BBE\u8BA1", id: "design", name: "\u8BBE\u8BA1\u6587\u6863", fields: ["approach", "risks", "impact"] },
|
|
4877
4943
|
{ stage: "\u4EE3\u7801\u5BA1\u6838", id: "review", name: "\u8BC4\u5BA1\u8BB0\u5F55", fields: ["conclusion", "issues"] }
|
|
4878
4944
|
],
|
|
4879
|
-
commit: {
|
|
4880
|
-
policy: "task",
|
|
4881
|
-
message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
|
|
4882
|
-
message_hint: "\u3010<task_id>\u3011\u3010TASK/T1\u3011\u8BF4\u660E \u2014\u2014 \u7B2C\u4E00\u6BB5\u586B\u672C\u4EFB\u52A1 id\uFF08\u5982 GREET-001\uFF09\uFF0C\u5199\u7ED3\u679C\u4E0D\u5199\u7A7A\u6CDB\u52A8\u4F5C",
|
|
4883
|
-
checkpoints: ["\u4EE3\u7801\u5BA1\u6838"],
|
|
4884
|
-
file_scope: true
|
|
4885
|
-
},
|
|
4886
|
-
high_risk_requires_verification: true,
|
|
4887
4945
|
stage_bindings: {
|
|
4888
4946
|
"\u9700\u6C42\u8BC4\u5BA1": { skills: [bundled("requirement-analysis", "security-redlines")] },
|
|
4889
4947
|
"\u8BBE\u8BA1": { skills: [bundled("solution-design")] },
|
|
@@ -4903,30 +4961,38 @@ var AGILE = {
|
|
|
4903
4961
|
transitions: [
|
|
4904
4962
|
{ from: "\u9700\u6C42", to: "\u5F00\u53D1", requires: ["requirement_confirmation"] },
|
|
4905
4963
|
{ from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] },
|
|
4964
|
+
// Entering 审查 is unconditional. A review guard on this edge would be
|
|
4965
|
+
// circular — it would demand the verdict BEFORE the stage that produces it —
|
|
4966
|
+
// and it would also block the commit at 交付, since a commit requires its
|
|
4967
|
+
// stage's outgoing guards. What 审查 requires is declared as completion_guards
|
|
4968
|
+
// instead, because a terminal stage has no outgoing edge to carry it.
|
|
4906
4969
|
{ from: "\u4EA4\u4ED8", to: "\u5BA1\u67E5", requires: [] }
|
|
4907
4970
|
],
|
|
4971
|
+
artifacts: [],
|
|
4972
|
+
commit: { policy: "item", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EA4\u4ED8"], file_scope: true },
|
|
4973
|
+
high_risk_requires_verification: false,
|
|
4974
|
+
// 审查 is terminal and IS the review, so there is no outgoing edge to carry
|
|
4975
|
+
// the guard. Declaring it here is what makes a blocked review prevent
|
|
4976
|
+
// completion; without it the stage could be reached and finished with the
|
|
4977
|
+
// review failing, which is what the assessment found.
|
|
4978
|
+
completion_guards: ["review_passed"]
|
|
4979
|
+
};
|
|
4980
|
+
var AGILE_RECOMMENDATION = {
|
|
4981
|
+
commit: {
|
|
4982
|
+
// `item` policy emits two label shapes: `T<n>` mid-flow and `TASK` at the
|
|
4983
|
+
// closing checkpoint. The pattern accepts BOTH, so the label the engine hands
|
|
4984
|
+
// the model always satisfies the rule that validates it.
|
|
4985
|
+
message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
|
|
4986
|
+
message_hint: "\u3010<task_id>\u3011\u3010TASK/T1\u3011\u8BF4\u660E \u2014\u2014 \u7B2C\u4E00\u6BB5\u586B\u672C\u4EFB\u52A1 id\uFF1B\u5B9E\u65BD\u9879\u63D0\u4EA4\u7528 T1\u3001T2\uFF0C\u6536\u5C3E\u63D0\u4EA4\u7528 TASK"
|
|
4987
|
+
},
|
|
4908
4988
|
artifacts: [
|
|
4909
4989
|
{ stage: "\u9700\u6C42", id: "requirement", name: "\u9700\u6C42\u8BF4\u660E", fields: ["scope"] },
|
|
4910
4990
|
// The 审查 stage binds code-review, whose instructions write this artifact with
|
|
4911
|
-
// `record artifact=review`. Declaring it
|
|
4912
|
-
//
|
|
4913
|
-
//
|
|
4991
|
+
// `record artifact=review`. Declaring it keeps that binding executable: the
|
|
4992
|
+
// engine refuses an undeclared artifact, so a bound skill pointing at one would
|
|
4993
|
+
// be a contract the recommendation made impossible to satisfy.
|
|
4914
4994
|
{ stage: "\u5BA1\u67E5", id: "review", name: "\u8BC4\u5BA1\u8BB0\u5F55", fields: ["conclusion", "issues"] }
|
|
4915
4995
|
],
|
|
4916
|
-
commit: {
|
|
4917
|
-
// `item` policy emits two label shapes: `T<n>` for a mid-flow item commit and
|
|
4918
|
-
// `TASK` for the closing commit at the checkpoint. The pattern below accepts
|
|
4919
|
-
// BOTH, so the label the engine hands the model always satisfies the preset's
|
|
4920
|
-
// own rule. Previously it accepted only `T\d+` while the checkpoint stage
|
|
4921
|
-
// returned `TASK`, which made the closing commit impossible to phrase: the
|
|
4922
|
-
// status line and the validator disagreed about the contract.
|
|
4923
|
-
policy: "item",
|
|
4924
|
-
message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
|
|
4925
|
-
message_hint: "\u3010<task_id>\u3011\u3010TASK/T1\u3011\u8BF4\u660E \u2014\u2014 \u7B2C\u4E00\u6BB5\u586B\u672C\u4EFB\u52A1 id\uFF1B\u5B9E\u65BD\u9879\u63D0\u4EA4\u7528 T1\u3001T2\uFF0C\u6536\u5C3E\u63D0\u4EA4\u7528 TASK",
|
|
4926
|
-
checkpoints: ["\u4EA4\u4ED8"],
|
|
4927
|
-
file_scope: true
|
|
4928
|
-
},
|
|
4929
|
-
high_risk_requires_verification: false,
|
|
4930
4996
|
stage_bindings: {
|
|
4931
4997
|
"\u9700\u6C42": { skills: [bundled("requirement-analysis", "security-redlines")] },
|
|
4932
4998
|
"\u5F00\u53D1": { skills: [bundled("code-implement", "coding-conventions", "security-redlines")] },
|
|
@@ -4941,18 +5007,13 @@ var MINIMAL = {
|
|
|
4941
5007
|
{ from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] }
|
|
4942
5008
|
],
|
|
4943
5009
|
artifacts: [],
|
|
4944
|
-
commit: {
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
checkpoints: ["\u4EA4\u4ED8"],
|
|
4949
|
-
file_scope: false
|
|
4950
|
-
},
|
|
4951
|
-
high_risk_requires_verification: false,
|
|
5010
|
+
commit: { policy: "task", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EA4\u4ED8"], file_scope: false },
|
|
5011
|
+
high_risk_requires_verification: false
|
|
5012
|
+
};
|
|
5013
|
+
var MINIMAL_RECOMMENDATION = {
|
|
4952
5014
|
// A fast-change flow checks each change once, not twice under two headings a
|
|
4953
5015
|
// short change rarely distinguishes. The item still has to be reviewed — what
|
|
4954
|
-
// drops is the duplicated verdict, which is where the weight actually was
|
|
4955
|
-
// flow used to carry the same per-item audit burden as the full one.
|
|
5016
|
+
// drops is the duplicated verdict, which is where the weight actually was.
|
|
4956
5017
|
review_depth: "single",
|
|
4957
5018
|
stage_bindings: {
|
|
4958
5019
|
"\u5F00\u53D1": { skills: [bundled("code-implement", "coding-conventions", "security-redlines")] },
|
|
@@ -4968,54 +5029,160 @@ function deriveCapabilities(config) {
|
|
|
4968
5029
|
if (config.commit.file_scope) caps.push("file_scope");
|
|
4969
5030
|
return caps;
|
|
4970
5031
|
}
|
|
4971
|
-
function preset(id, version, label2, description, config) {
|
|
4972
|
-
return {
|
|
5032
|
+
function preset(id, version, label2, description, config, recommendation) {
|
|
5033
|
+
return {
|
|
5034
|
+
id,
|
|
5035
|
+
version,
|
|
5036
|
+
label: label2,
|
|
5037
|
+
description,
|
|
5038
|
+
capabilities: deriveCapabilities(config),
|
|
5039
|
+
config,
|
|
5040
|
+
// exactOptionalPropertyTypes: omit rather than assign undefined.
|
|
5041
|
+
...recommendation !== void 0 ? { recommendation } : {}
|
|
5042
|
+
};
|
|
4973
5043
|
}
|
|
4974
5044
|
var FLOW_PRESETS = {
|
|
4975
|
-
standard: preset("standard",
|
|
4976
|
-
// Version
|
|
4977
|
-
//
|
|
4978
|
-
//
|
|
4979
|
-
|
|
4980
|
-
// Version
|
|
4981
|
-
//
|
|
4982
|
-
//
|
|
4983
|
-
//
|
|
4984
|
-
|
|
5045
|
+
standard: preset("standard", 3, "\u5B8C\u6574\u7814\u53D1", "\u65B0\u529F\u80FD\u3001\u67B6\u6784\u6216\u8DE8\u6A21\u5757\u6539\u52A8\u3001\u9AD8\u98CE\u9669\u4EFB\u52A1\uFF1A\u9700\u6C42\u786E\u8BA4 \u2192 \u65B9\u6848\u786E\u8BA4 \u2192 \u5B9E\u73B0 \u2192 \u9A8C\u8BC1 \u2192 \u5BA1\u6838 \u2192 \u63D0\u4EA4", STANDARD, STANDARD_RECOMMENDATION),
|
|
5046
|
+
// Version 4 for agile: 交付 → 审查 now requires review_passed, where it previously
|
|
5047
|
+
// required nothing. That is a gate-semantics change, so a task created before it
|
|
5048
|
+
// keeps its frozen version 3 config and behaves exactly as it did.
|
|
5049
|
+
//
|
|
5050
|
+
// Version 3 across all three: the preset is now a bare skeleton and its former
|
|
5051
|
+
// built-in bindings, commit rule and artifacts are a separate recommendation a
|
|
5052
|
+
// user adopts explicitly. Tasks created before this keep their frozen config and
|
|
5053
|
+
// are unaffected; a project's existing config is likewise left exactly as it is.
|
|
5054
|
+
agile: preset("agile", 4, "\u65E5\u5E38\u8FED\u4EE3", "\u76EE\u6807\u660E\u786E\u7684\u5E38\u89C4\u529F\u80FD\u4E0E\u7F3A\u9677\u4FEE\u590D\uFF1A\u76EE\u6807\u4E0E\u9A8C\u6536 \u2192 \u5B9E\u73B0 \u2192 \u9A8C\u6536\u4E0E\u5BA1\u67E5 \u2192 \u63D0\u4EA4", AGILE, AGILE_RECOMMENDATION),
|
|
5055
|
+
minimal: preset("minimal", 3, "\u5FEB\u901F\u4FEE\u6539", "\u5C40\u90E8\u3001\u4F4E\u98CE\u9669\u3001\u65B9\u6848\u660E\u786E\u7684\u6539\u52A8\uFF1A\u4FEE\u6539 \u2192 \u68C0\u67E5\u4E0E\u63D0\u4EA4\uFF0C\u6BCF\u9879\u4E00\u6B21\u68C0\u67E5", MINIMAL, MINIMAL_RECOMMENDATION)
|
|
4985
5056
|
};
|
|
4986
5057
|
function dedupe(names) {
|
|
4987
5058
|
return [...new Set(names)];
|
|
4988
5059
|
}
|
|
4989
|
-
function
|
|
4990
|
-
if (
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
const
|
|
4995
|
-
const
|
|
4996
|
-
const
|
|
4997
|
-
for (const
|
|
4998
|
-
const
|
|
4999
|
-
if (
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5060
|
+
function applyProjectConfig(base, project) {
|
|
5061
|
+
if (project === void 0) return base;
|
|
5062
|
+
const next = { ...base };
|
|
5063
|
+
if (project.stage_bindings !== void 0) {
|
|
5064
|
+
const profiles = { ...project.skill_profiles ?? {} };
|
|
5065
|
+
const explicitProfiles = new Set(Object.keys(project.skill_profiles ?? {}));
|
|
5066
|
+
const problems = [];
|
|
5067
|
+
const bindings = {};
|
|
5068
|
+
for (const [stage, binding] of Object.entries(project.stage_bindings)) {
|
|
5069
|
+
const entry = {};
|
|
5070
|
+
if (binding === null || typeof binding !== "object") {
|
|
5071
|
+
problems.push(`stage_bindings "${stage}" must be an object`);
|
|
5072
|
+
bindings[stage] = entry;
|
|
5073
|
+
continue;
|
|
5074
|
+
}
|
|
5075
|
+
if (binding.skill_refs !== void 0 && binding.skills !== void 0) {
|
|
5076
|
+
problems.push(`stage_bindings "${stage}" has both skill_refs and legacy skills`);
|
|
5077
|
+
}
|
|
5078
|
+
if (binding.skill_refs !== void 0) {
|
|
5079
|
+
if (!Array.isArray(binding.skill_refs)) {
|
|
5080
|
+
problems.push(`stage_bindings "${stage}" skill_refs must be an array`);
|
|
5081
|
+
}
|
|
5082
|
+
entry.skills = (Array.isArray(binding.skill_refs) ? binding.skill_refs : []).flatMap((ref) => {
|
|
5083
|
+
if (ref === null || typeof ref !== "object") {
|
|
5084
|
+
problems.push(`stage_bindings "${stage}" has an invalid skill reference`);
|
|
5085
|
+
return [];
|
|
5086
|
+
}
|
|
5087
|
+
const key = formatResourceRef(ref);
|
|
5088
|
+
const profile = profiles[key];
|
|
5089
|
+
if (profile === void 0) {
|
|
5090
|
+
problems.push(`skill profile "${key}" is missing`);
|
|
5091
|
+
return [];
|
|
5092
|
+
}
|
|
5093
|
+
if (profile === null || !Array.isArray(profile.rules)) {
|
|
5094
|
+
problems.push(`skill profile "${key}" must declare a rules array`);
|
|
5095
|
+
return [];
|
|
5096
|
+
}
|
|
5097
|
+
return [{ skill: ref, rules: profile.rules, ...profile.evidence !== void 0 ? { evidence: profile.evidence } : {} }];
|
|
5098
|
+
});
|
|
5099
|
+
} else if (binding.skills !== void 0) {
|
|
5100
|
+
if (!Array.isArray(binding.skills)) {
|
|
5101
|
+
problems.push(`stage_bindings "${stage}" skills must be an array`);
|
|
5102
|
+
}
|
|
5103
|
+
entry.skills = (Array.isArray(binding.skills) ? binding.skills : []).flatMap((skill) => {
|
|
5104
|
+
if (skill === null || typeof skill !== "object" || skill.skill === null || typeof skill.skill !== "object") {
|
|
5105
|
+
problems.push(`stage_bindings "${stage}" has an invalid skill binding`);
|
|
5106
|
+
return [];
|
|
5107
|
+
}
|
|
5108
|
+
const key = formatResourceRef(skill.skill);
|
|
5109
|
+
if (explicitProfiles.has(key)) {
|
|
5110
|
+
const profile = profiles[key];
|
|
5111
|
+
if (profile === null || !Array.isArray(profile?.rules)) {
|
|
5112
|
+
problems.push(`skill profile "${key}" must declare a rules array`);
|
|
5113
|
+
return [];
|
|
5114
|
+
}
|
|
5115
|
+
return [{
|
|
5116
|
+
skill: skill.skill,
|
|
5117
|
+
rules: profile.rules,
|
|
5118
|
+
...profile.evidence !== void 0 ? { evidence: profile.evidence } : {}
|
|
5119
|
+
}];
|
|
5120
|
+
}
|
|
5121
|
+
const candidate = { rules: skill.rules ?? [], ...skill.evidence !== void 0 ? { evidence: skill.evidence } : {} };
|
|
5122
|
+
const existing = profiles[key];
|
|
5123
|
+
if (existing !== void 0 && JSON.stringify(existing) !== JSON.stringify(candidate)) {
|
|
5124
|
+
problems.push(`skill "${key}" has different rules or evidence in multiple stages; copy it as a distinct skill`);
|
|
5125
|
+
} else profiles[key] = candidate;
|
|
5126
|
+
return [skill];
|
|
5127
|
+
});
|
|
5128
|
+
}
|
|
5129
|
+
const legacy = dedupe(binding.legacy_rules ?? []);
|
|
5130
|
+
if (legacy.length > 0) entry.legacy_rules = legacy;
|
|
5131
|
+
bindings[stage] = entry;
|
|
5132
|
+
}
|
|
5133
|
+
next.stage_bindings = bindings;
|
|
5134
|
+
next.skill_profiles = profiles;
|
|
5135
|
+
if (problems.length > 0) next.configuration_errors = problems;
|
|
5136
|
+
} else if (project.skill_profiles !== void 0) {
|
|
5137
|
+
next.skill_profiles = project.skill_profiles;
|
|
5138
|
+
}
|
|
5139
|
+
if (project.commit !== void 0) next.commit = project.commit;
|
|
5140
|
+
if (project.artifacts !== void 0) next.artifacts = project.artifacts;
|
|
5141
|
+
if (project.review_depth !== void 0) next.review_depth = project.review_depth;
|
|
5142
|
+
if (project.commit_required !== void 0) next.commit_required = project.commit_required;
|
|
5143
|
+
return next;
|
|
5144
|
+
}
|
|
5145
|
+
function adoptRecommendation(presetId, current) {
|
|
5146
|
+
const preset2 = FLOW_PRESETS[presetId];
|
|
5147
|
+
if (preset2 === void 0) return void 0;
|
|
5148
|
+
const rec = preset2.recommendation;
|
|
5149
|
+
if (rec === void 0) return { flow: presetId, ...current };
|
|
5150
|
+
const commit = {
|
|
5151
|
+
...preset2.config.commit,
|
|
5152
|
+
...rec.commit ?? {},
|
|
5153
|
+
...current?.commit ?? {}
|
|
5154
|
+
};
|
|
5155
|
+
const config = {
|
|
5156
|
+
flow: presetId,
|
|
5157
|
+
stage_bindings: current?.stage_bindings ?? rec.stage_bindings ?? {},
|
|
5158
|
+
...current?.skill_profiles !== void 0 ? { skill_profiles: current.skill_profiles } : {},
|
|
5159
|
+
commit,
|
|
5160
|
+
artifacts: current?.artifacts ?? rec.artifacts ?? preset2.config.artifacts,
|
|
5161
|
+
...current?.review_depth !== void 0 ? { review_depth: current.review_depth } : rec.review_depth !== void 0 ? { review_depth: rec.review_depth } : {},
|
|
5162
|
+
...current?.commit_required !== void 0 ? { commit_required: current.commit_required } : {}
|
|
5163
|
+
};
|
|
5164
|
+
return config;
|
|
5165
|
+
}
|
|
5166
|
+
function compactProjectConfig(project) {
|
|
5167
|
+
const resolved = resolveFlow(project.flow, project);
|
|
5168
|
+
if (!resolved.ok) return project;
|
|
5169
|
+
const profiles = resolved.config.skill_profiles ?? {};
|
|
5170
|
+
const bindings = {};
|
|
5171
|
+
for (const [stage, binding] of Object.entries(resolved.config.stage_bindings ?? {})) {
|
|
5172
|
+
bindings[stage] = {
|
|
5173
|
+
skill_refs: (binding.skills ?? []).map((entry) => entry.skill),
|
|
5174
|
+
...binding.legacy_rules?.length ? { legacy_rules: binding.legacy_rules } : {}
|
|
5175
|
+
};
|
|
5176
|
+
}
|
|
5177
|
+
return { ...project, stage_bindings: bindings, skill_profiles: profiles };
|
|
5012
5178
|
}
|
|
5013
|
-
function resolveFlow(flow,
|
|
5179
|
+
function resolveFlow(flow, project) {
|
|
5014
5180
|
const preset2 = FLOW_PRESETS[flow];
|
|
5015
5181
|
if (preset2 === void 0) {
|
|
5016
5182
|
return { ok: false, code: "UNKNOWN_FLOW", flow, knownFlows: Object.keys(FLOW_PRESETS) };
|
|
5017
5183
|
}
|
|
5018
|
-
|
|
5184
|
+
const { flow: _ignored, ...rest } = project ?? { flow };
|
|
5185
|
+
return { ok: true, config: applyProjectConfig(preset2.config, { flow, ...rest }), preset: preset2 };
|
|
5019
5186
|
}
|
|
5020
5187
|
|
|
5021
5188
|
// src/client/shared.ts
|
|
@@ -5025,30 +5192,296 @@ function describeError(error) {
|
|
|
5025
5192
|
return "\u672A\u77E5\u9519\u8BEF";
|
|
5026
5193
|
}
|
|
5027
5194
|
|
|
5028
|
-
// src/client/
|
|
5195
|
+
// src/client/SkillRuleDialog.tsx
|
|
5196
|
+
var import_react2 = require("react");
|
|
5197
|
+
var import_dsh_client_ui_primitives2 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
5198
|
+
|
|
5199
|
+
// src/client/ResourceModal.tsx
|
|
5200
|
+
var import_react = require("react");
|
|
5201
|
+
var import_react_dom = require("react-dom");
|
|
5202
|
+
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
5203
|
+
var rootStyle = {
|
|
5204
|
+
position: "fixed",
|
|
5205
|
+
inset: 0,
|
|
5206
|
+
zIndex: 1e3,
|
|
5207
|
+
display: "flex",
|
|
5208
|
+
alignItems: "center",
|
|
5209
|
+
justifyContent: "center",
|
|
5210
|
+
padding: 24
|
|
5211
|
+
};
|
|
5212
|
+
var maskStyle = {
|
|
5213
|
+
position: "absolute",
|
|
5214
|
+
inset: 0,
|
|
5215
|
+
background: "var(--dsw-alias-bg-mask-1)",
|
|
5216
|
+
backdropFilter: "var(--dsw-mask-blur)"
|
|
5217
|
+
};
|
|
5218
|
+
var dialogStyle = {
|
|
5219
|
+
position: "relative",
|
|
5220
|
+
zIndex: 1,
|
|
5221
|
+
display: "flex",
|
|
5222
|
+
flexDirection: "column",
|
|
5223
|
+
width: "min(760px, 100%)",
|
|
5224
|
+
maxHeight: "85vh",
|
|
5225
|
+
borderRadius: 24,
|
|
5226
|
+
background: "var(--dsw-alias-bg-layer-2)",
|
|
5227
|
+
boxShadow: "var(--dsw-elevation-prominent)",
|
|
5228
|
+
overflow: "hidden"
|
|
5229
|
+
};
|
|
5230
|
+
var drawerStyle = {
|
|
5231
|
+
...dialogStyle,
|
|
5232
|
+
width: "min(560px, 100%)",
|
|
5233
|
+
height: "100%",
|
|
5234
|
+
maxHeight: "100%",
|
|
5235
|
+
borderRadius: "16px 0 0 16px"
|
|
5236
|
+
};
|
|
5237
|
+
var headerStyle = {
|
|
5238
|
+
display: "flex",
|
|
5239
|
+
alignItems: "center",
|
|
5240
|
+
justifyContent: "space-between",
|
|
5241
|
+
gap: 8,
|
|
5242
|
+
padding: "18px 18px 10px 24px",
|
|
5243
|
+
flex: "none"
|
|
5244
|
+
};
|
|
5245
|
+
var titleStyle = {
|
|
5246
|
+
margin: 0,
|
|
5247
|
+
fontSize: 16,
|
|
5248
|
+
lineHeight: "24px",
|
|
5249
|
+
fontWeight: 500,
|
|
5250
|
+
color: "var(--dsw-alias-label-primary)"
|
|
5251
|
+
};
|
|
5252
|
+
var closeBtnStyle = {
|
|
5253
|
+
flex: "none",
|
|
5254
|
+
display: "inline-flex",
|
|
5255
|
+
alignItems: "center",
|
|
5256
|
+
justifyContent: "center",
|
|
5257
|
+
width: 28,
|
|
5258
|
+
height: 28,
|
|
5259
|
+
border: "none",
|
|
5260
|
+
borderRadius: 8,
|
|
5261
|
+
background: "transparent",
|
|
5262
|
+
cursor: "pointer",
|
|
5263
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
5264
|
+
padding: 0
|
|
5265
|
+
};
|
|
5266
|
+
var descStyle = {
|
|
5267
|
+
margin: 0,
|
|
5268
|
+
padding: "0 24px",
|
|
5269
|
+
fontSize: 13,
|
|
5270
|
+
lineHeight: "20px",
|
|
5271
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
5272
|
+
flex: "none"
|
|
5273
|
+
};
|
|
5274
|
+
var bodyStyle = {
|
|
5275
|
+
flex: "1 1 auto",
|
|
5276
|
+
minHeight: 0,
|
|
5277
|
+
overflowY: "auto",
|
|
5278
|
+
padding: "16px 24px 4px",
|
|
5279
|
+
display: "flex",
|
|
5280
|
+
flexDirection: "column"
|
|
5281
|
+
};
|
|
5282
|
+
var footerStyle = {
|
|
5283
|
+
display: "flex",
|
|
5284
|
+
alignItems: "center",
|
|
5285
|
+
justifyContent: "flex-end",
|
|
5286
|
+
gap: 8,
|
|
5287
|
+
padding: "12px 24px 20px",
|
|
5288
|
+
flex: "none"
|
|
5289
|
+
};
|
|
5290
|
+
function ResourceModal({ title, description, onClose, footer, children, placement = "center" }) {
|
|
5291
|
+
const dialog = (0, import_react.useRef)(null);
|
|
5292
|
+
const closer = (0, import_react.useRef)(onClose);
|
|
5293
|
+
closer.current = onClose;
|
|
5294
|
+
(0, import_react.useEffect)(() => {
|
|
5295
|
+
const previous = document.activeElement;
|
|
5296
|
+
dialog.current?.focus();
|
|
5297
|
+
const onKey = (e) => {
|
|
5298
|
+
if (!dialog.current?.contains(document.activeElement)) return;
|
|
5299
|
+
if (e.key === "Escape") {
|
|
5300
|
+
e.preventDefault();
|
|
5301
|
+
e.stopPropagation();
|
|
5302
|
+
closer.current();
|
|
5303
|
+
return;
|
|
5304
|
+
}
|
|
5305
|
+
if (e.key !== "Tab") return;
|
|
5306
|
+
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);
|
|
5307
|
+
const first = nodes[0], last = nodes[nodes.length - 1];
|
|
5308
|
+
if (!first || !last) {
|
|
5309
|
+
e.preventDefault();
|
|
5310
|
+
return;
|
|
5311
|
+
}
|
|
5312
|
+
if (e.shiftKey && (document.activeElement === first || document.activeElement === dialog.current)) {
|
|
5313
|
+
e.preventDefault();
|
|
5314
|
+
last.focus();
|
|
5315
|
+
} else if (!e.shiftKey && (document.activeElement === last || document.activeElement === dialog.current)) {
|
|
5316
|
+
e.preventDefault();
|
|
5317
|
+
first.focus();
|
|
5318
|
+
}
|
|
5319
|
+
};
|
|
5320
|
+
document.addEventListener("keydown", onKey);
|
|
5321
|
+
return () => {
|
|
5322
|
+
document.removeEventListener("keydown", onKey);
|
|
5323
|
+
if (previous?.isConnected) previous.focus();
|
|
5324
|
+
};
|
|
5325
|
+
}, []);
|
|
5326
|
+
return (0, import_react_dom.createPortal)(
|
|
5327
|
+
(0, import_react.createElement)(
|
|
5328
|
+
"div",
|
|
5329
|
+
{ style: placement === "right" ? { ...rootStyle, justifyContent: "flex-end", padding: 0 } : rootStyle, className: `te-modal${placement === "right" ? " te-drawer" : ""}`, role: "presentation" },
|
|
5330
|
+
(0, import_react.createElement)("div", { style: placement === "right" ? { ...maskStyle, background: "rgba(0, 0, 0, 0.18)" } : maskStyle, "aria-hidden": true, onClick: onClose }),
|
|
5331
|
+
(0, import_react.createElement)(
|
|
5332
|
+
"div",
|
|
5333
|
+
{ style: placement === "right" ? drawerStyle : dialogStyle, ref: dialog, tabIndex: -1, role: "dialog", "aria-modal": true, "aria-label": title },
|
|
5334
|
+
(0, import_react.createElement)(
|
|
5335
|
+
"div",
|
|
5336
|
+
{ style: headerStyle },
|
|
5337
|
+
(0, import_react.createElement)("h2", { style: titleStyle }, title),
|
|
5338
|
+
(0, import_react.createElement)(
|
|
5339
|
+
"button",
|
|
5340
|
+
{ type: "button", style: closeBtnStyle, "aria-label": "\u5173\u95ED", onClick: onClose },
|
|
5341
|
+
(0, import_react.createElement)(import_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 })
|
|
5342
|
+
)
|
|
5343
|
+
),
|
|
5344
|
+
description !== void 0 && description !== "" ? (0, import_react.createElement)("p", { style: descStyle }, description) : null,
|
|
5345
|
+
(0, import_react.createElement)("div", { style: bodyStyle }, children),
|
|
5346
|
+
footer !== void 0 ? (0, import_react.createElement)("div", { style: footerStyle }, footer) : null
|
|
5347
|
+
)
|
|
5348
|
+
),
|
|
5349
|
+
document.body
|
|
5350
|
+
);
|
|
5351
|
+
}
|
|
5352
|
+
|
|
5353
|
+
// src/client/SkillRuleDialog.tsx
|
|
5029
5354
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
5355
|
+
function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave, onClose }) {
|
|
5356
|
+
const [draftRules, setDraftRules] = (0, import_react2.useState)(profile?.rules ?? []);
|
|
5357
|
+
const [evidence, setEvidence] = (0, import_react2.useState)(profile?.evidence ?? "");
|
|
5358
|
+
const [query, setQuery] = (0, import_react2.useState)("");
|
|
5359
|
+
const [dirty, setDirty] = (0, import_react2.useState)(false);
|
|
5360
|
+
const [busy, setBusy] = (0, import_react2.useState)(false);
|
|
5361
|
+
const [error, setError] = (0, import_react2.useState)("");
|
|
5362
|
+
const close = () => {
|
|
5363
|
+
if (busy) return;
|
|
5364
|
+
if (dirty && !window.confirm("\u6280\u80FD\u89C4\u5219\u914D\u7F6E\u5C1A\u672A\u4FDD\u5B58\uFF0C\u786E\u5B9A\u653E\u5F03\u4FEE\u6539\uFF1F")) return;
|
|
5365
|
+
onClose();
|
|
5366
|
+
};
|
|
5367
|
+
const toggle = (rule) => {
|
|
5368
|
+
const key = formatResourceRef(rule);
|
|
5369
|
+
setDraftRules((previous) => previous.some((item) => formatResourceRef(item) === key) ? previous.filter((item) => formatResourceRef(item) !== key) : [...previous, rule].sort((a, b) => formatResourceRef(a).localeCompare(formatResourceRef(b))));
|
|
5370
|
+
setDirty(true);
|
|
5371
|
+
setError("");
|
|
5372
|
+
};
|
|
5373
|
+
const save2 = async () => {
|
|
5374
|
+
if (busy || !dirty) return;
|
|
5375
|
+
setBusy(true);
|
|
5376
|
+
setError("");
|
|
5377
|
+
try {
|
|
5378
|
+
await onSave({ rules: draftRules, ...evidence ? { evidence } : {} });
|
|
5379
|
+
} catch (failure) {
|
|
5380
|
+
setError(failure instanceof Error ? failure.message : "\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
5381
|
+
} finally {
|
|
5382
|
+
setBusy(false);
|
|
5383
|
+
}
|
|
5384
|
+
};
|
|
5385
|
+
const filtered = rules.filter((rule) => {
|
|
5386
|
+
const key = formatResourceRef(rule.ref);
|
|
5387
|
+
const chosen = draftRules.some((item) => formatResourceRef(item) === key);
|
|
5388
|
+
return chosen || `${rule.name} ${rule.sourceLabel}`.toLowerCase().includes(query.trim().toLowerCase());
|
|
5389
|
+
});
|
|
5390
|
+
const catalogKeys = new Set(rules.map((rule) => formatResourceRef(rule.ref)));
|
|
5391
|
+
const missingRules = draftRules.filter((rule) => !catalogKeys.has(formatResourceRef(rule)));
|
|
5392
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
5393
|
+
ResourceModal,
|
|
5394
|
+
{
|
|
5395
|
+
placement: "right",
|
|
5396
|
+
title: `\u914D\u7F6E\u89C4\u5219 \xB7 ${skill.name}`,
|
|
5397
|
+
description: description ?? "\u89C4\u5219\u5C5E\u4E8E\u6280\u80FD\uFF1B\u6B64\u5904\u7684\u914D\u7F6E\u4F1A\u7528\u4E8E\u6240\u6709\u7ED1\u5B9A\u8BE5\u6280\u80FD\u7684\u8282\u70B9\u3002",
|
|
5398
|
+
onClose: close,
|
|
5399
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
5400
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { role: "alert", className: "te-dialog-error", children: error }) : null,
|
|
5401
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives2.Button, { variant: "ghost", disabled: busy, onClick: close, children: "\u53D6\u6D88" }),
|
|
5402
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives2.Button, { variant: "primary", disabled: busy || !dirty, onClick: () => {
|
|
5403
|
+
void save2();
|
|
5404
|
+
}, children: busy ? "\u5904\u7406\u4E2D\u2026" : saveLabel ?? "\u4FDD\u5B58\u914D\u7F6E" })
|
|
5405
|
+
] }),
|
|
5406
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "te-skill-config", children: [
|
|
5407
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "te-skill-evidence", children: [
|
|
5408
|
+
"\u5B8C\u6210\u51ED\u8BC1",
|
|
5409
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { className: "te-input", "aria-label": "\u6280\u80FD\u5B8C\u6210\u51ED\u8BC1", value: evidence, onChange: (event) => {
|
|
5410
|
+
setEvidence(event.target.value);
|
|
5411
|
+
setDirty(true);
|
|
5412
|
+
}, children: [
|
|
5413
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "\u6CBF\u7528\u65E7\u914D\u7F6E\u9ED8\u8BA4\u503C" }),
|
|
5414
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "command", children: "\u547D\u4EE4\u6267\u884C\u8BB0\u5F55" }),
|
|
5415
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "artifact", children: "\u4EA7\u7269\u5185\u5BB9" }),
|
|
5416
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "review", children: "\u5BA1\u6838\u7ED3\u679C" }),
|
|
5417
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "manual", children: "\u4EBA\u5DE5\u786E\u8BA4" }),
|
|
5418
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "none", children: "\u65E0\u9700\u51ED\u8BC1" })
|
|
5419
|
+
] })
|
|
5420
|
+
] }),
|
|
5421
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "te-binding-heading", children: [
|
|
5422
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "\u9002\u7528\u89C4\u5219" }),
|
|
5423
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "te-binding-count", children: [
|
|
5424
|
+
"\u5DF2\u9009 ",
|
|
5425
|
+
draftRules.length
|
|
5426
|
+
] })
|
|
5427
|
+
] }),
|
|
5428
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { className: "te-input", type: "search", "aria-label": "\u641C\u7D22\u89C4\u5219", placeholder: "\u641C\u7D22\u89C4\u5219\u540D\u79F0\u6216\u6765\u6E90", value: query, onChange: (event) => setQuery(event.target.value) }),
|
|
5429
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "te-skill-rule-list", role: "group", "aria-label": "\u89C4\u5219\u5217\u8868", children: [
|
|
5430
|
+
rules.length === 0 && missingRules.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "te-binding-empty", children: "\u89C4\u5219\u5E93\u4E3A\u7A7A\uFF0C\u8BF7\u5148\u5230\u201C\u89C4\u5219\u201D\u9875\u521B\u5EFA\u6216\u5B89\u88C5\u3002" }) : null,
|
|
5431
|
+
rules.length > 0 && filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "te-binding-empty", children: "\u6CA1\u6709\u5339\u914D\u7684\u89C4\u5219\u3002" }) : null,
|
|
5432
|
+
missingRules.map((rule) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "te-skill-rule-row", children: [
|
|
5433
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked: true, onChange: () => toggle(rule) }),
|
|
5434
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: rule.name }),
|
|
5435
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { children: [
|
|
5436
|
+
rule.source,
|
|
5437
|
+
" \xB7 \u89C4\u5219\u6587\u4EF6\u672A\u627E\u5230"
|
|
5438
|
+
] })
|
|
5439
|
+
] }, formatResourceRef(rule))),
|
|
5440
|
+
filtered.map((rule) => {
|
|
5441
|
+
const key = formatResourceRef(rule.ref);
|
|
5442
|
+
const checked = draftRules.some((item) => formatResourceRef(item) === key);
|
|
5443
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "te-skill-rule-row", children: [
|
|
5444
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked, onChange: () => toggle(rule.ref) }),
|
|
5445
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: rule.name }),
|
|
5446
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: rule.sourceLabel })
|
|
5447
|
+
] }, key);
|
|
5448
|
+
})
|
|
5449
|
+
] })
|
|
5450
|
+
] })
|
|
5451
|
+
}
|
|
5452
|
+
);
|
|
5453
|
+
}
|
|
5454
|
+
|
|
5455
|
+
// src/client/TaskEngineSection.tsx
|
|
5456
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
5030
5457
|
function refFromText(text2) {
|
|
5031
5458
|
return parseResourceRef(text2) ?? { source: "bundled", name: text2 };
|
|
5032
5459
|
}
|
|
5033
|
-
function resolvedConfig(flow, stageBindings) {
|
|
5034
|
-
const resolved = resolveFlow(flow, { stage_bindings: stageBindings });
|
|
5460
|
+
function resolvedConfig(flow, stageBindings, skillProfiles) {
|
|
5461
|
+
const resolved = resolveFlow(flow, { flow, stage_bindings: stageBindings, skill_profiles: skillProfiles });
|
|
5035
5462
|
return resolved.ok ? resolved.config : FLOW_PRESETS.standard.config;
|
|
5036
5463
|
}
|
|
5037
5464
|
function TaskEngineSection(props) {
|
|
5038
5465
|
const { remote, workspace } = props;
|
|
5039
|
-
const [flow, setFlow] = (0,
|
|
5040
|
-
const [stageBindings, setStageBindings] = (0,
|
|
5041
|
-
const [
|
|
5042
|
-
const [
|
|
5043
|
-
const [
|
|
5044
|
-
const [
|
|
5045
|
-
const [
|
|
5046
|
-
const [
|
|
5047
|
-
const [
|
|
5048
|
-
const [
|
|
5049
|
-
const [
|
|
5050
|
-
const [
|
|
5051
|
-
(0,
|
|
5466
|
+
const [flow, setFlow] = (0, import_react3.useState)("standard");
|
|
5467
|
+
const [stageBindings, setStageBindings] = (0, import_react3.useState)({});
|
|
5468
|
+
const [skillProfiles, setSkillProfiles] = (0, import_react3.useState)({});
|
|
5469
|
+
const [commitRule, setCommitRule] = (0, import_react3.useState)(void 0);
|
|
5470
|
+
const [artifacts, setArtifacts] = (0, import_react3.useState)(void 0);
|
|
5471
|
+
const [reviewDepth, setReviewDepth] = (0, import_react3.useState)(void 0);
|
|
5472
|
+
const [commitRequired, setCommitRequired] = (0, import_react3.useState)(void 0);
|
|
5473
|
+
const [source, setSource] = (0, import_react3.useState)("default");
|
|
5474
|
+
const [savedAt, setSavedAt] = (0, import_react3.useState)("");
|
|
5475
|
+
const [dirty, setDirty] = (0, import_react3.useState)(false);
|
|
5476
|
+
const [loadError, setLoadError] = (0, import_react3.useState)("");
|
|
5477
|
+
const [saving, setSaving] = (0, import_react3.useState)(false);
|
|
5478
|
+
const [loading, setLoading] = (0, import_react3.useState)(true);
|
|
5479
|
+
const [loadAttempt, setLoadAttempt] = (0, import_react3.useState)(0);
|
|
5480
|
+
const [configProblems, setConfigProblems] = (0, import_react3.useState)([]);
|
|
5481
|
+
const [skills, setSkills] = (0, import_react3.useState)([]);
|
|
5482
|
+
const [rules, setRules] = (0, import_react3.useState)([]);
|
|
5483
|
+
const [configuringSkill, setConfiguringSkill] = (0, import_react3.useState)(null);
|
|
5484
|
+
(0, import_react3.useEffect)(() => {
|
|
5052
5485
|
if (workspace === "") return;
|
|
5053
5486
|
let alive = true;
|
|
5054
5487
|
setLoadError("");
|
|
@@ -5059,6 +5492,11 @@ function TaskEngineSection(props) {
|
|
|
5059
5492
|
if (result.ok) {
|
|
5060
5493
|
setFlow(result.value.flow);
|
|
5061
5494
|
setStageBindings(result.value.config.stage_bindings ?? {});
|
|
5495
|
+
setSkillProfiles(result.value.config.skill_profiles ?? {});
|
|
5496
|
+
setCommitRule(result.value.config.commit);
|
|
5497
|
+
setArtifacts(result.value.config.artifacts);
|
|
5498
|
+
setReviewDepth(result.value.config.review_depth);
|
|
5499
|
+
setCommitRequired(result.value.config.commit_required);
|
|
5062
5500
|
setSource(result.value.source);
|
|
5063
5501
|
setConfigProblems(result.value.problems);
|
|
5064
5502
|
setSavedAt("");
|
|
@@ -5075,7 +5513,7 @@ function TaskEngineSection(props) {
|
|
|
5075
5513
|
alive = false;
|
|
5076
5514
|
};
|
|
5077
5515
|
}, [remote, workspace, loadAttempt]);
|
|
5078
|
-
const refreshCatalogs = (0,
|
|
5516
|
+
const refreshCatalogs = (0, import_react3.useCallback)(() => {
|
|
5079
5517
|
if (workspace === "") return;
|
|
5080
5518
|
void remote.listSkills(workspace).then((result) => {
|
|
5081
5519
|
if (result.ok) setSkills(result.value.skills);
|
|
@@ -5086,55 +5524,88 @@ function TaskEngineSection(props) {
|
|
|
5086
5524
|
}, () => {
|
|
5087
5525
|
});
|
|
5088
5526
|
}, [remote, workspace]);
|
|
5089
|
-
(0,
|
|
5527
|
+
(0, import_react3.useEffect)(() => {
|
|
5090
5528
|
refreshCatalogs();
|
|
5091
5529
|
}, [refreshCatalogs]);
|
|
5092
|
-
const stages = (0,
|
|
5093
|
-
const problems = (0,
|
|
5094
|
-
() => validateWorkflow(resolvedConfig(flow, stageBindings)),
|
|
5095
|
-
[flow, stageBindings]
|
|
5530
|
+
const stages = (0, import_react3.useMemo)(() => (FLOW_PRESETS[flow] ?? FLOW_PRESETS.standard).config.stages, [flow]);
|
|
5531
|
+
const problems = (0, import_react3.useMemo)(
|
|
5532
|
+
() => validateWorkflow(resolvedConfig(flow, stageBindings, skillProfiles)),
|
|
5533
|
+
[flow, stageBindings, skillProfiles]
|
|
5096
5534
|
);
|
|
5097
5535
|
const selectFlow = (id) => {
|
|
5098
5536
|
if (id === flow) return;
|
|
5099
5537
|
if (dirty && !window.confirm("\u5F53\u524D\u6D41\u7A0B\u914D\u7F6E\u6709\u672A\u4FDD\u5B58\u7684\u4FEE\u6539\uFF0C\u5207\u6362\u6D41\u7A0B\u4F1A\u4E22\u5F03\u5B83\u4EEC\u3002\u7EE7\u7EED\u5207\u6362\uFF1F")) return;
|
|
5100
5538
|
setFlow(id);
|
|
5101
|
-
setStageBindings({ ...FLOW_PRESETS[id]?.config.stage_bindings ?? {} });
|
|
5102
5539
|
setDirty(true);
|
|
5103
5540
|
setSavedAt("");
|
|
5104
5541
|
};
|
|
5542
|
+
const adopt = () => {
|
|
5543
|
+
const adopted = adoptRecommendation(flow);
|
|
5544
|
+
if (adopted === void 0) return;
|
|
5545
|
+
if (dirty && !window.confirm("\u91C7\u7528\u63A8\u8350\u914D\u7F6E\u4F1A\u66FF\u6362\u5F53\u524D\u7684\u6280\u80FD\u4E0E\u89C4\u5219\u8BBE\u7F6E\u3002\u7EE7\u7EED\uFF1F")) return;
|
|
5546
|
+
setStageBindings({ ...adopted.stage_bindings ?? {} });
|
|
5547
|
+
const adoptedFlow = resolveFlow(flow, adopted);
|
|
5548
|
+
setSkillProfiles(adoptedFlow.ok ? adoptedFlow.config.skill_profiles ?? {} : {});
|
|
5549
|
+
setCommitRule(adopted.commit);
|
|
5550
|
+
setArtifacts(adopted.artifacts);
|
|
5551
|
+
setReviewDepth(adopted.review_depth);
|
|
5552
|
+
setDirty(true);
|
|
5553
|
+
setSavedAt("");
|
|
5554
|
+
};
|
|
5555
|
+
const updateSkillProfile = async (profile) => {
|
|
5556
|
+
if (!configuringSkill) return;
|
|
5557
|
+
const key = formatResourceRef(configuringSkill);
|
|
5558
|
+
const bindings = {};
|
|
5559
|
+
for (const [name, binding] of Object.entries(stageBindings)) {
|
|
5560
|
+
bindings[name] = { ...binding, skills: binding.skills?.map((entry) => formatResourceRef(entry.skill) === key ? { skill: entry.skill, rules: profile.rules, ...profile.evidence ? { evidence: profile.evidence } : {} } : entry) };
|
|
5561
|
+
}
|
|
5562
|
+
setStageBindings(bindings);
|
|
5563
|
+
setSkillProfiles({ ...skillProfiles, [key]: profile });
|
|
5564
|
+
setDirty(true);
|
|
5565
|
+
setSavedAt("");
|
|
5566
|
+
setConfiguringSkill(null);
|
|
5567
|
+
};
|
|
5105
5568
|
if (loadError !== "") {
|
|
5106
|
-
return /* @__PURE__ */ (0,
|
|
5107
|
-
/* @__PURE__ */ (0,
|
|
5108
|
-
/* @__PURE__ */ (0,
|
|
5109
|
-
/* @__PURE__ */ (0,
|
|
5110
|
-
/* @__PURE__ */ (0,
|
|
5569
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.wrap, children: [
|
|
5570
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { style: styles.title, children: "\u5DE5\u7A0B\u6D41\u7A0B\u914D\u7F6E" }),
|
|
5571
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.problems, children: [
|
|
5572
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.problemsTitle, children: [
|
|
5573
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: "error" }),
|
|
5111
5574
|
"\u8BFB\u53D6\u5931\u8D25"
|
|
5112
5575
|
] }),
|
|
5113
|
-
/* @__PURE__ */ (0,
|
|
5114
|
-
/* @__PURE__ */ (0,
|
|
5576
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: loadError }),
|
|
5577
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.Button, { onClick: () => setLoadAttempt((n) => n + 1), children: "\u91CD\u8BD5" })
|
|
5115
5578
|
] })
|
|
5116
5579
|
] });
|
|
5117
5580
|
}
|
|
5118
|
-
if (loading) return /* @__PURE__ */ (0,
|
|
5119
|
-
return /* @__PURE__ */ (0,
|
|
5120
|
-
configProblems.length > 0 && /* @__PURE__ */ (0,
|
|
5581
|
+
if (loading) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", children: "\u6B63\u5728\u8BFB\u53D6\u6D41\u7A0B\u914D\u7F6E\u2026" });
|
|
5582
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.wrap, children: [
|
|
5583
|
+
configProblems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { role: "alert", style: styles.problems, children: [
|
|
5121
5584
|
"\u539F\u914D\u7F6E\u6709\u95EE\u9898\uFF1A",
|
|
5122
5585
|
configProblems.join("\uFF1B"),
|
|
5123
5586
|
"\u3002\u8BF7\u9009\u62E9\u6709\u6548\u9884\u8BBE\u5E76\u4FDD\u5B58\u4FEE\u590D\u3002"
|
|
5124
5587
|
] }),
|
|
5125
|
-
/* @__PURE__ */ (0,
|
|
5126
|
-
/* @__PURE__ */ (0,
|
|
5127
|
-
/* @__PURE__ */ (0,
|
|
5588
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.head, children: [
|
|
5589
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { style: styles.title, children: "\u5DE5\u7A0B\u6D41\u7A0B\u914D\u7F6E" }),
|
|
5590
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: "\u6D41\u7A0B\u51B3\u5B9A\u5DE5\u4F5C\u600E\u4E48\u6D41\u8F6C\uFF08\u9636\u6BB5\u4E0E\u95E8\u7981\uFF09\uFF1B\u6280\u80FD\u3001\u89C4\u5219\u3001\u63D0\u4EA4\u683C\u5F0F\u548C\u4EA7\u7269\u5B57\u6BB5\u7531\u4F60\u81EA\u5DF1\u914D\u7F6E\u3002 \u9700\u8981\u4E00\u4EFD\u73B0\u6210\u7684\u8D77\u70B9\u65F6\uFF0C\u53EF\u4EE5\u300C\u91C7\u7528\u63A8\u8350\u914D\u7F6E\u300D\u2014\u2014\u91C7\u7528\u540E\u8FD9\u4E9B\u5C31\u5B8C\u5168\u5C5E\u4E8E\u4F60\uFF0C\u53EF\u968F\u610F\u4FEE\u6539\u6216\u5220\u9664\u3002" })
|
|
5128
5591
|
] }),
|
|
5129
|
-
/* @__PURE__ */ (0,
|
|
5130
|
-
/* @__PURE__ */ (0,
|
|
5131
|
-
|
|
5592
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.adoptRow, children: [
|
|
5593
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dsh_client_ui_primitives3.Button, { size: "sm", onClick: adopt, children: [
|
|
5594
|
+
"\u91C7\u7528\u300C",
|
|
5595
|
+
FLOW_PRESETS[flow]?.label ?? flow,
|
|
5596
|
+
"\u300D\u7684\u63A8\u8350\u914D\u7F6E"
|
|
5597
|
+
] }),
|
|
5598
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.muted, children: "\u5199\u5165\u63A8\u8350\u6280\u80FD\u3001\u63D0\u4EA4\u4FE1\u606F\u683C\u5F0F\u4E0E\u4EA7\u7269\u5B57\u6BB5\u3002\u4EC5\u5728\u4F60\u70B9\u51FB\u65F6\u53D1\u751F\u4E00\u6B21\uFF1B\u5220\u9664\u540E\u4E0D\u4F1A\u81EA\u52A8\u8865\u56DE\u3002" })
|
|
5599
|
+
] }),
|
|
5600
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.sourceRow, children: [
|
|
5601
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: source === "project" ? "done" : source === "invalid" ? "warning" : "ongoing" }),
|
|
5602
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.sourceText, children: sourceText(source) })
|
|
5132
5603
|
] }),
|
|
5133
|
-
/* @__PURE__ */ (0,
|
|
5134
|
-
/* @__PURE__ */ (0,
|
|
5135
|
-
/* @__PURE__ */ (0,
|
|
5604
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.field, children: [
|
|
5605
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u6D41\u7A0B\u9884\u8BBE" }),
|
|
5606
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.flowGrid, children: FLOW_OPTIONS.map((option) => {
|
|
5136
5607
|
const active = flow === option.id;
|
|
5137
|
-
return /* @__PURE__ */ (0,
|
|
5608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
5138
5609
|
"button",
|
|
5139
5610
|
{
|
|
5140
5611
|
type: "button",
|
|
@@ -5144,45 +5615,49 @@ function TaskEngineSection(props) {
|
|
|
5144
5615
|
},
|
|
5145
5616
|
style: { ...styles.flowOption, ...active ? styles.flowOptionActive : {} },
|
|
5146
5617
|
children: [
|
|
5147
|
-
/* @__PURE__ */ (0,
|
|
5148
|
-
/* @__PURE__ */ (0,
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.flowOptionTitle, children: [
|
|
5619
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: active ? "done" : "ongoing", size: 8 }),
|
|
5149
5620
|
option.label
|
|
5150
5621
|
] }),
|
|
5151
|
-
/* @__PURE__ */ (0,
|
|
5622
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.flowOptionDesc, children: option.description })
|
|
5152
5623
|
]
|
|
5153
5624
|
},
|
|
5154
5625
|
option.id
|
|
5155
5626
|
);
|
|
5156
5627
|
}) })
|
|
5157
5628
|
] }),
|
|
5158
|
-
/* @__PURE__ */ (0,
|
|
5629
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.IconSettingsOutline16, { size: 16 }), title: "\u9636\u6BB5\u6280\u80FD", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BindingEditor, { stages, stageBindings, setStageBindings: (next) => {
|
|
5159
5630
|
setStageBindings(next);
|
|
5160
5631
|
setDirty(true);
|
|
5161
5632
|
setSavedAt("");
|
|
5162
|
-
},
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5633
|
+
}, skillProfiles, setSkillProfiles: (next) => {
|
|
5634
|
+
setSkillProfiles(next);
|
|
5635
|
+
setDirty(true);
|
|
5636
|
+
setSavedAt("");
|
|
5637
|
+
}, skills, onConfigureSkill: setConfiguringSkill }) }),
|
|
5638
|
+
problems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.problems, children: [
|
|
5639
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.problemsTitle, children: [
|
|
5640
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: "error" }),
|
|
5166
5641
|
"\u6709 ",
|
|
5167
5642
|
problems.length,
|
|
5168
5643
|
" \u4E2A\u95EE\u9898\uFF08\u4FDD\u5B58\u4F1A\u88AB\u62D2\u7EDD\uFF09"
|
|
5169
5644
|
] }),
|
|
5170
|
-
/* @__PURE__ */ (0,
|
|
5171
|
-
] }) : /* @__PURE__ */ (0,
|
|
5172
|
-
/* @__PURE__ */ (0,
|
|
5173
|
-
source === "project" ? "\u914D\u7F6E\u6709\u6548" : "\u4F7F\u7528\u6D41\u7A0B\
|
|
5645
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { style: styles.problemsList, children: problems.map((p) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: p }, p)) })
|
|
5646
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.okText, children: [
|
|
5647
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: "done" }),
|
|
5648
|
+
source === "project" ? "\u914D\u7F6E\u6709\u6548" : "\u4F7F\u7528\u7A7A\u767D\u6D41\u7A0B\u914D\u7F6E\uFF08\u5C1A\u672A\u4FDD\u5B58\uFF09"
|
|
5174
5649
|
] }),
|
|
5175
|
-
/* @__PURE__ */ (0,
|
|
5176
|
-
/* @__PURE__ */ (0,
|
|
5177
|
-
|
|
5650
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.actions, children: [
|
|
5651
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5652
|
+
import_dsh_client_ui_primitives3.Button,
|
|
5178
5653
|
{
|
|
5179
5654
|
variant: "primary",
|
|
5180
5655
|
size: "md",
|
|
5181
|
-
icon: /* @__PURE__ */ (0,
|
|
5656
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.IconCheckOutline16, { size: 16 }),
|
|
5182
5657
|
disabled: problems.length > 0 || saving,
|
|
5183
5658
|
onClick: () => {
|
|
5184
5659
|
setSaving(true);
|
|
5185
|
-
void save(remote, flow, stageBindings, workspace, setSavedAt, setSource).then((ok) => {
|
|
5660
|
+
void save(remote, { flow, stage_bindings: stageBindings, skill_profiles: skillProfiles, ...commitRule !== void 0 ? { commit: commitRule } : {}, ...artifacts !== void 0 ? { artifacts } : {}, ...reviewDepth !== void 0 ? { review_depth: reviewDepth } : {}, ...commitRequired !== void 0 ? { commit_required: commitRequired } : {} }, workspace, setSavedAt, setSource).then((ok) => {
|
|
5186
5661
|
if (ok) {
|
|
5187
5662
|
setConfigProblems([]);
|
|
5188
5663
|
setDirty(false);
|
|
@@ -5192,11 +5667,24 @@ function TaskEngineSection(props) {
|
|
|
5192
5667
|
children: saving ? "\u6B63\u5728\u4FDD\u5B58\u2026" : dirty ? "\u4FDD\u5B58\u5230 .dsh/eng.json" : "\u5DF2\u4FDD\u5B58 \xB7 \u65E0\u9700\u4FDD\u5B58"
|
|
5193
5668
|
}
|
|
5194
5669
|
),
|
|
5195
|
-
savedAt !== "" ? /* @__PURE__ */ (0,
|
|
5196
|
-
/* @__PURE__ */ (0,
|
|
5670
|
+
savedAt !== "" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.okText, children: [
|
|
5671
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: savedAt.startsWith("\u5DF2") ? "done" : "error" }),
|
|
5197
5672
|
savedAt
|
|
5198
5673
|
] }) : null
|
|
5199
|
-
] })
|
|
5674
|
+
] }),
|
|
5675
|
+
configuringSkill ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5676
|
+
SkillRuleDialog,
|
|
5677
|
+
{
|
|
5678
|
+
skill: configuringSkill,
|
|
5679
|
+
profile: skillProfiles[formatResourceRef(configuringSkill)],
|
|
5680
|
+
rules,
|
|
5681
|
+
description: "\u89C4\u5219\u5C5E\u4E8E\u6280\u80FD\uFF0C\u6240\u6709\u5F15\u7528\u6B64\u6280\u80FD\u7684\u8282\u70B9\u90FD\u4F1A\u540C\u6B65\u3002\u5E94\u7528\u540E\u8BF7\u70B9\u51FB\u9875\u9762\u5E95\u90E8\u4FDD\u5B58\u3002",
|
|
5682
|
+
saveLabel: "\u5E94\u7528\u5230\u5F53\u524D\u914D\u7F6E",
|
|
5683
|
+
onSave: updateSkillProfile,
|
|
5684
|
+
onClose: () => setConfiguringSkill(null)
|
|
5685
|
+
},
|
|
5686
|
+
formatResourceRef(configuringSkill)
|
|
5687
|
+
) : null
|
|
5200
5688
|
] });
|
|
5201
5689
|
}
|
|
5202
5690
|
function sourceText(source) {
|
|
@@ -5210,9 +5698,9 @@ function sourceText(source) {
|
|
|
5210
5698
|
}
|
|
5211
5699
|
}
|
|
5212
5700
|
function SectionCard({ icon, title, hint, children }) {
|
|
5213
|
-
const [open, setOpen] = (0,
|
|
5214
|
-
return /* @__PURE__ */ (0,
|
|
5215
|
-
|
|
5701
|
+
const [open, setOpen] = (0, import_react3.useState)(true);
|
|
5702
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.section, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5703
|
+
import_dsh_client_ui_primitives3.DisclosureRow,
|
|
5216
5704
|
{
|
|
5217
5705
|
icon,
|
|
5218
5706
|
title,
|
|
@@ -5224,125 +5712,120 @@ function SectionCard({ icon, title, hint, children }) {
|
|
|
5224
5712
|
setOpen(!open);
|
|
5225
5713
|
},
|
|
5226
5714
|
keepContentWhenOpen: true,
|
|
5227
|
-
children: /* @__PURE__ */ (0,
|
|
5228
|
-
hint !== void 0 ? /* @__PURE__ */ (0,
|
|
5715
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.cardBody, children: [
|
|
5716
|
+
hint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: hint }) : null,
|
|
5229
5717
|
children
|
|
5230
5718
|
] })
|
|
5231
5719
|
}
|
|
5232
5720
|
) });
|
|
5233
5721
|
}
|
|
5234
|
-
function BindingEditor({ stages,
|
|
5235
|
-
const [stage, setStage] = (0,
|
|
5236
|
-
const [
|
|
5722
|
+
function BindingEditor({ stages, stageBindings, setStageBindings, skillProfiles, setSkillProfiles, skills, onConfigureSkill }) {
|
|
5723
|
+
const [stage, setStage] = (0, import_react3.useState)(stages[0] ?? "");
|
|
5724
|
+
const [query, setQuery] = (0, import_react3.useState)("");
|
|
5237
5725
|
const currentStage = stages.includes(stage) ? stage : stages[0] ?? "";
|
|
5238
5726
|
const bindingFor = (name) => stageBindings[name] ?? {};
|
|
5239
|
-
const presetSkills = (name) => defaults[name]?.skills ?? [];
|
|
5240
|
-
const isPresetSkill = (name, raw) => presetSkills(name).some((entry) => formatResourceRef(entry.skill) === raw);
|
|
5241
5727
|
const setSkills = (name, next) => {
|
|
5242
5728
|
setStageBindings({ ...stageBindings, [name]: { ...bindingFor(name), skills: next } });
|
|
5243
5729
|
};
|
|
5244
5730
|
const toggleSkill = (raw) => {
|
|
5245
|
-
if (currentStage === "" || isPresetSkill(currentStage, raw)) return;
|
|
5246
|
-
const current = bindingFor(currentStage).skills ?? [];
|
|
5247
|
-
const next = current.some((entry) => formatResourceRef(entry.skill) === raw) ? current.filter((entry) => formatResourceRef(entry.skill) !== raw) : [...current, { skill: refFromText(raw), rules: [] }].sort((a, b) => formatResourceRef(a.skill).localeCompare(formatResourceRef(b.skill)));
|
|
5248
|
-
setSkills(currentStage, next);
|
|
5249
|
-
};
|
|
5250
|
-
const toggleRule = (skillRaw, ruleRaw) => {
|
|
5251
5731
|
if (currentStage === "") return;
|
|
5252
5732
|
const current = bindingFor(currentStage).skills ?? [];
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
}));
|
|
5733
|
+
const profile = skillProfiles[raw];
|
|
5734
|
+
const alreadyBound = current.some((entry) => formatResourceRef(entry.skill) === raw);
|
|
5735
|
+
const next = alreadyBound ? current.filter((entry) => formatResourceRef(entry.skill) !== raw) : [...current, { skill: refFromText(raw), rules: profile?.rules ?? [], ...profile?.evidence !== void 0 ? { evidence: profile.evidence } : {} }].sort((a, b) => formatResourceRef(a.skill).localeCompare(formatResourceRef(b.skill)));
|
|
5736
|
+
if (!alreadyBound && profile === void 0) setSkillProfiles({ ...skillProfiles, [raw]: { rules: [] } });
|
|
5737
|
+
setSkills(currentStage, next);
|
|
5259
5738
|
};
|
|
5260
5739
|
if (currentStage === "") {
|
|
5261
|
-
return /* @__PURE__ */ (0,
|
|
5740
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: "\u5F53\u524D\u6D41\u7A0B\u6CA1\u6709\u8282\u70B9\u3002" });
|
|
5262
5741
|
}
|
|
5263
5742
|
const boundSkills = bindingFor(currentStage).skills ?? [];
|
|
5264
5743
|
const unassigned = bindingFor(currentStage).legacy_rules ?? [];
|
|
5265
|
-
const
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
/* @__PURE__ */ (0,
|
|
5744
|
+
const boundKeys = new Set(boundSkills.map((entry) => formatResourceRef(entry.skill)));
|
|
5745
|
+
const needle = query.trim().toLowerCase();
|
|
5746
|
+
const available = skills.filter((entry) => !boundKeys.has(formatResourceRef(entry.ref)) && `${entry.name} ${entry.description} ${entry.sourceLabel}`.toLowerCase().includes(needle));
|
|
5747
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.section, children: [
|
|
5748
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.field, children: [
|
|
5749
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.bindingLabel, children: "\u9009\u62E9\u8282\u70B9" }),
|
|
5750
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.chips, children: stages.map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.Pill, { active: s === currentStage, onClick: () => {
|
|
5271
5751
|
setStage(s);
|
|
5272
5752
|
}, children: s }, s)) })
|
|
5273
5753
|
] }),
|
|
5274
|
-
unassigned.length > 0 ? /* @__PURE__ */ (0,
|
|
5754
|
+
unassigned.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-alert", children: [
|
|
5275
5755
|
"\u4EE5\u4E0B\u89C4\u5219\u5C5E\u4E8E",
|
|
5276
|
-
/* @__PURE__ */ (0,
|
|
5756
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u8282\u70B9" }),
|
|
5277
5757
|
"\u800C\u4E0D\u662F\u4EFB\u4F55\u6280\u80FD\uFF08\u65E7\u914D\u7F6E\uFF09\uFF1A",
|
|
5278
5758
|
unassigned.join("\u3001"),
|
|
5279
5759
|
"\u3002 \u5B83\u4EEC\u4ECD\u7136\u751F\u6548\uFF0C\u4F46\u9700\u8981\u6307\u5B9A\u5F52\u5C5E\u2014\u2014\u628A\u6BCF\u6761\u89C4\u5219\u52A0\u5230\u4F60\u5E0C\u671B\u627F\u8F7D\u5B83\u7684\u6280\u80FD\u4E0B\uFF0C\u7136\u540E\u4ECE\u8FD9\u91CC\u79FB\u9664\uFF1B \u82E5\u540C\u4E00\u6280\u80FD\u5728\u4E0D\u540C\u8282\u70B9\u9700\u8981\u4E0D\u540C\u89C4\u5219\uFF0C\u8BF7\u590D\u5236\u8BE5\u6280\u80FD\u518D\u5206\u522B\u914D\u7F6E\u3002"
|
|
5280
5760
|
] }) : null,
|
|
5281
|
-
/* @__PURE__ */ (0,
|
|
5282
|
-
/* @__PURE__ */ (0,
|
|
5283
|
-
/* @__PURE__ */ (0,
|
|
5284
|
-
|
|
5285
|
-
"
|
|
5286
|
-
|
|
5287
|
-
|
|
5761
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer", children: [
|
|
5762
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "te-transfer-pane", "aria-label": "\u53EF\u7528\u6280\u80FD", children: [
|
|
5763
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-binding-heading", children: [
|
|
5764
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h4", { children: "\u53EF\u7528\u6280\u80FD" }),
|
|
5765
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-binding-count", children: [
|
|
5766
|
+
skills.filter((entry) => !boundKeys.has(formatResourceRef(entry.ref))).length,
|
|
5767
|
+
" \u9879"
|
|
5768
|
+
] })
|
|
5769
|
+
] }),
|
|
5770
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { className: "te-input te-transfer-search", type: "search", value: query, placeholder: "\u641C\u7D22\u6280\u80FD\u540D\u79F0\u6216\u8BF4\u660E", "aria-label": "\u641C\u7D22\u53EF\u7528\u6280\u80FD", onChange: (event) => setQuery(event.target.value) }),
|
|
5771
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer-list", role: "group", "aria-label": "\u53EF\u7528\u6280\u80FD\u5217\u8868", children: [
|
|
5772
|
+
skills.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "te-binding-empty", children: "\u6682\u65E0\u6280\u80FD\uFF0C\u8BF7\u5148\u5728\u201C\u6280\u80FD\u201D\u9875\u6DFB\u52A0\u3002" }) : null,
|
|
5773
|
+
skills.length > 0 && available.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "te-binding-empty", children: "\u6CA1\u6709\u53EF\u6DFB\u52A0\u7684\u6280\u80FD\u3002" }) : null,
|
|
5774
|
+
available.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "te-transfer-row", onClick: () => toggleSkill(formatResourceRef(entry.ref)), "aria-label": `\u6DFB\u52A0\u6280\u80FD ${entry.name}`, children: [
|
|
5775
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-transfer-row-main", children: [
|
|
5776
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: entry.name }),
|
|
5777
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("small", { children: [
|
|
5778
|
+
entry.sourceLabel,
|
|
5779
|
+
entry.description ? ` \xB7 ${entry.description}` : ""
|
|
5780
|
+
] })
|
|
5781
|
+
] }),
|
|
5782
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "te-transfer-action", "aria-hidden": "true", children: "\uFF0B" })
|
|
5783
|
+
] }, formatResourceRef(entry.ref)))
|
|
5288
5784
|
] })
|
|
5289
5785
|
] }),
|
|
5290
|
-
/* @__PURE__ */ (0,
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
)
|
|
5308
|
-
/* @__PURE__ */ (0,
|
|
5309
|
-
/* @__PURE__ */ (0,
|
|
5310
|
-
entry.name,
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5786
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "te-transfer-arrow", "aria-hidden": "true", children: "\u2192" }),
|
|
5787
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "te-transfer-pane", "aria-label": "\u5F53\u524D\u8282\u70B9\u6280\u80FD", children: [
|
|
5788
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-binding-heading", children: [
|
|
5789
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h4", { children: [
|
|
5790
|
+
currentStage,
|
|
5791
|
+
" \xB7 \u5DF2\u7ED1\u5B9A"
|
|
5792
|
+
] }),
|
|
5793
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-binding-count", children: [
|
|
5794
|
+
boundSkills.length,
|
|
5795
|
+
" \u9879"
|
|
5796
|
+
] })
|
|
5797
|
+
] }),
|
|
5798
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "te-transfer-caption", children: "\u89C4\u5219\u5C5E\u4E8E\u6280\u80FD\uFF1B\u70B9\u201C\u914D\u7F6E\u89C4\u5219\u201D\u5373\u53EF\u7EDF\u4E00\u4FEE\u6539\u3002" }),
|
|
5799
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer-list", role: "group", "aria-label": "\u5DF2\u7ED1\u5B9A\u6280\u80FD\u5217\u8868", children: [
|
|
5800
|
+
boundSkills.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "te-binding-empty", children: "\u6B64\u8282\u70B9\u5C1A\u672A\u7ED1\u5B9A\u6280\u80FD\u3002\u70B9\u51FB\u5DE6\u4FA7 \uFF0B \u6DFB\u52A0\u3002" }) : null,
|
|
5801
|
+
boundSkills.map((entry) => {
|
|
5802
|
+
const raw = formatResourceRef(entry.skill);
|
|
5803
|
+
const catalog = skills.find((skill) => formatResourceRef(skill.ref) === raw);
|
|
5804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer-row is-bound", children: [
|
|
5805
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-transfer-row-main", children: [
|
|
5806
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: entry.skill.name }),
|
|
5807
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("small", { children: [
|
|
5808
|
+
catalog?.sourceLabel ?? entry.skill.source,
|
|
5809
|
+
" \xB7 ",
|
|
5810
|
+
entry.rules.length,
|
|
5811
|
+
" \u6761\u89C4\u5219",
|
|
5812
|
+
catalog ? "" : " \xB7 \u8D44\u6E90\u672A\u627E\u5230"
|
|
5813
|
+
] })
|
|
5317
5814
|
] }),
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked: on, onChange: () => toggleRule(raw, ruleRaw) }),
|
|
5326
|
-
" ",
|
|
5327
|
-
rule.name,
|
|
5328
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "te-binding-meta", children: [
|
|
5329
|
-
"\uFF08",
|
|
5330
|
-
rule.sourceLabel,
|
|
5331
|
-
"\uFF09"
|
|
5332
|
-
] })
|
|
5333
|
-
] }, ruleRaw);
|
|
5334
|
-
})
|
|
5335
|
-
] }) : null
|
|
5336
|
-
] })
|
|
5337
|
-
] }, raw);
|
|
5338
|
-
})
|
|
5815
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-transfer-actions", children: [
|
|
5816
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "te-transfer-config", onClick: () => onConfigureSkill(entry.skill), children: "\u914D\u7F6E\u89C4\u5219" }),
|
|
5817
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "te-transfer-remove", onClick: () => toggleSkill(raw), "aria-label": `\u79FB\u9664\u6280\u80FD ${entry.skill.name}`, children: "\xD7" })
|
|
5818
|
+
] })
|
|
5819
|
+
] }, raw);
|
|
5820
|
+
})
|
|
5821
|
+
] })
|
|
5339
5822
|
] })
|
|
5340
|
-
] }
|
|
5823
|
+
] }, currentStage)
|
|
5341
5824
|
] });
|
|
5342
5825
|
}
|
|
5343
|
-
async function save(remote,
|
|
5826
|
+
async function save(remote, config, workspace, setSavedAt, setSource) {
|
|
5344
5827
|
try {
|
|
5345
|
-
const result = await remote.write({ path: workspace,
|
|
5828
|
+
const result = await remote.write({ path: workspace, ...config });
|
|
5346
5829
|
if (!result.ok) {
|
|
5347
5830
|
setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
5348
5831
|
return false;
|
|
@@ -5361,8 +5844,8 @@ async function save(remote, flow, stageBindings, workspace, setSavedAt, setSourc
|
|
|
5361
5844
|
}
|
|
5362
5845
|
|
|
5363
5846
|
// src/client/InitPanel.tsx
|
|
5364
|
-
var
|
|
5365
|
-
var
|
|
5847
|
+
var import_react4 = require("react");
|
|
5848
|
+
var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
5366
5849
|
var MD_LABELS = { code: { copyLabel: "\u590D\u5236", copiedLabel: "\u5DF2\u590D\u5236" }, footnotes: "\u811A\u6CE8" };
|
|
5367
5850
|
var INIT_TIMEOUT_S = 150;
|
|
5368
5851
|
var card = {
|
|
@@ -5374,14 +5857,14 @@ var card = {
|
|
|
5374
5857
|
padding: "12px 14px"
|
|
5375
5858
|
};
|
|
5376
5859
|
function InitPanel({ workspace, remote }) {
|
|
5377
|
-
const [view, setView] = (0,
|
|
5378
|
-
const [generating, setGenerating] = (0,
|
|
5379
|
-
const [elapsed, setElapsed] = (0,
|
|
5380
|
-
const [draft, setDraft] = (0,
|
|
5381
|
-
const [editing, setEditing] = (0,
|
|
5382
|
-
const [body2, setBody] = (0,
|
|
5383
|
-
const [msg, setMsg] = (0,
|
|
5384
|
-
(0,
|
|
5860
|
+
const [view, setView] = (0, import_react4.useState)(null);
|
|
5861
|
+
const [generating, setGenerating] = (0, import_react4.useState)(false);
|
|
5862
|
+
const [elapsed, setElapsed] = (0, import_react4.useState)(0);
|
|
5863
|
+
const [draft, setDraft] = (0, import_react4.useState)(null);
|
|
5864
|
+
const [editing, setEditing] = (0, import_react4.useState)(false);
|
|
5865
|
+
const [body2, setBody] = (0, import_react4.useState)("");
|
|
5866
|
+
const [msg, setMsg] = (0, import_react4.useState)("");
|
|
5867
|
+
(0, import_react4.useEffect)(() => {
|
|
5385
5868
|
if (!generating) {
|
|
5386
5869
|
setElapsed(0);
|
|
5387
5870
|
return;
|
|
@@ -5395,13 +5878,13 @@ function InitPanel({ workspace, remote }) {
|
|
|
5395
5878
|
clearInterval(timer);
|
|
5396
5879
|
};
|
|
5397
5880
|
}, [generating]);
|
|
5398
|
-
const refresh = (0,
|
|
5881
|
+
const refresh = (0, import_react4.useCallback)(() => {
|
|
5399
5882
|
void remote.readInit(workspace).then((r) => {
|
|
5400
5883
|
if (r.ok) setView(r.value);
|
|
5401
5884
|
}, () => {
|
|
5402
5885
|
});
|
|
5403
5886
|
}, [remote, workspace]);
|
|
5404
|
-
(0,
|
|
5887
|
+
(0, import_react4.useEffect)(() => {
|
|
5405
5888
|
refresh();
|
|
5406
5889
|
}, [refresh]);
|
|
5407
5890
|
const generate = async () => {
|
|
@@ -5444,45 +5927,45 @@ function InitPanel({ workspace, remote }) {
|
|
|
5444
5927
|
setMsg("");
|
|
5445
5928
|
};
|
|
5446
5929
|
const exists = view?.exists === true;
|
|
5447
|
-
return (0,
|
|
5930
|
+
return (0, import_react4.createElement)(
|
|
5448
5931
|
"div",
|
|
5449
5932
|
{ style: styles.section },
|
|
5450
|
-
(0,
|
|
5933
|
+
(0, import_react4.createElement)(
|
|
5451
5934
|
"div",
|
|
5452
5935
|
{ style: card },
|
|
5453
|
-
(0,
|
|
5936
|
+
(0, import_react4.createElement)(
|
|
5454
5937
|
"div",
|
|
5455
5938
|
{ style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" } },
|
|
5456
|
-
(0,
|
|
5457
|
-
(0,
|
|
5458
|
-
view?.path !== void 0 ? (0,
|
|
5939
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.StateDot, { state: exists ? "done" : "ongoing" }),
|
|
5940
|
+
(0, import_react4.createElement)("span", { style: styles.bindingLabel }, exists ? `\u5DF2\u521D\u59CB\u5316 \xB7 ${view.lines} \u884C\uFF08\u4E0A\u9650 200\uFF09` : "\u672A\u521D\u59CB\u5316"),
|
|
5941
|
+
view?.path !== void 0 ? (0, import_react4.createElement)("span", { style: styles.sourceBadge }, `\u5DF2\u5B9A\u4F4D\u5230 ${view.path}`) : null
|
|
5459
5942
|
),
|
|
5460
|
-
(0,
|
|
5943
|
+
(0, import_react4.createElement)(
|
|
5461
5944
|
"p",
|
|
5462
5945
|
{ style: styles.muted },
|
|
5463
5946
|
"\u9879\u76EE\u6839 AGENTS.md \u4F1A\u88AB DSH \u81EA\u52A8\u6CE8\u5165\u5230\u6BCF\u4E2A\u4F1A\u8BDD\u3002\u521D\u59CB\u5316\u4E00\u6B21\uFF0C\u4E4B\u540E\u6BCF\u6B21\u4EFB\u52A1\u5F00\u5DE5 AI \u90FD\u81EA\u5E26\u8FD9\u4EFD\u9879\u76EE\u8BA4\u77E5\uFF08\u9879\u76EE\u662F\u4EC0\u4E48 \u2192 \u600E\u4E48\u8DD1 \u2192 \u7ED3\u6784 \u2192 \u7EA6\u5B9A \u2192 \u5751\uFF09\u3002"
|
|
5464
5947
|
),
|
|
5465
|
-
exists && !editing && draft === null ? (0,
|
|
5948
|
+
exists && !editing && draft === null ? (0, import_react4.createElement)(
|
|
5466
5949
|
"div",
|
|
5467
5950
|
{ style: styles.mdPreview },
|
|
5468
|
-
(0,
|
|
5951
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.MarkdownText, { text: view.content, labels: MD_LABELS })
|
|
5469
5952
|
) : null,
|
|
5470
|
-
draft !== null ? (0,
|
|
5953
|
+
draft !== null ? (0, import_react4.createElement)(
|
|
5471
5954
|
"div",
|
|
5472
5955
|
{ style: styles.section },
|
|
5473
|
-
(0,
|
|
5956
|
+
(0, import_react4.createElement)(
|
|
5474
5957
|
"div",
|
|
5475
5958
|
{ style: styles.sourceRow },
|
|
5476
|
-
(0,
|
|
5477
|
-
(0,
|
|
5959
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.StateDot, { state: "ongoing", size: 8 }),
|
|
5960
|
+
(0, import_react4.createElement)("span", { style: styles.sourceBadge }, `AI \u8349\u7A3F \xB7 ${draft.lines} \u884C \xB7 \u5C1A\u672A\u5199\u5165`)
|
|
5478
5961
|
),
|
|
5479
|
-
(0,
|
|
5962
|
+
(0, import_react4.createElement)(
|
|
5480
5963
|
"div",
|
|
5481
5964
|
{ style: styles.mdPreview },
|
|
5482
|
-
(0,
|
|
5965
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.MarkdownText, { text: draft.content, labels: MD_LABELS })
|
|
5483
5966
|
)
|
|
5484
5967
|
) : null,
|
|
5485
|
-
editing ? (0,
|
|
5968
|
+
editing ? (0, import_react4.createElement)("textarea", {
|
|
5486
5969
|
style: { ...styles.textarea, minHeight: 300 },
|
|
5487
5970
|
placeholder: "AGENTS.md \u6B63\u6587\uFF08Markdown\uFF0C\u2264200 \u884C\uFF09",
|
|
5488
5971
|
value: body2,
|
|
@@ -5490,16 +5973,16 @@ function InitPanel({ workspace, remote }) {
|
|
|
5490
5973
|
setBody(ev.target.value);
|
|
5491
5974
|
}
|
|
5492
5975
|
}) : null,
|
|
5493
|
-
generating ? (0,
|
|
5976
|
+
generating ? (0, import_react4.createElement)(
|
|
5494
5977
|
"p",
|
|
5495
5978
|
{ style: styles.status },
|
|
5496
5979
|
`AI \u6B63\u5728\u626B\u63CF\u9879\u76EE\u5E76\u751F\u6210\u8349\u7A3F\u2026 \u5DF2\u8017\u65F6 ${elapsed} \u79D2\uFF08\u6700\u957F ${INIT_TIMEOUT_S} \u79D2\uFF09\uFF0C\u8BF7\u7A0D\u5019`
|
|
5497
5980
|
) : null,
|
|
5498
|
-
msg !== "" ? (0,
|
|
5499
|
-
draft !== null ? (0,
|
|
5981
|
+
msg !== "" ? (0, import_react4.createElement)("p", { style: styles.status }, msg) : null,
|
|
5982
|
+
draft !== null ? (0, import_react4.createElement)(
|
|
5500
5983
|
"div",
|
|
5501
5984
|
{ style: styles.row },
|
|
5502
|
-
(0,
|
|
5985
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, {
|
|
5503
5986
|
variant: "primary",
|
|
5504
5987
|
size: "md",
|
|
5505
5988
|
disabled: draft.lines > 200,
|
|
@@ -5508,14 +5991,14 @@ function InitPanel({ workspace, remote }) {
|
|
|
5508
5991
|
void write(draft.content, exists);
|
|
5509
5992
|
}
|
|
5510
5993
|
}, exists ? "\u4FDD\u5B58\u5E76\u8986\u76D6" : "\u4FDD\u5B58"),
|
|
5511
|
-
draft.lines > 200 ? (0,
|
|
5512
|
-
(0,
|
|
5994
|
+
draft.lines > 200 ? (0, import_react4.createElement)("span", { style: styles.sourceBadge }, `\u8349\u7A3F ${draft.lines} \u884C\u8D85\u9650\uFF0C\u8BF7\u70B9\u300C\u653E\u5F03\u300D\u540E\u91CD\u8BD5`) : null,
|
|
5995
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "md", onClick: () => {
|
|
5513
5996
|
setDraft(null);
|
|
5514
5997
|
} }, "\u653E\u5F03")
|
|
5515
|
-
) : editing ? (0,
|
|
5998
|
+
) : editing ? (0, import_react4.createElement)(
|
|
5516
5999
|
"div",
|
|
5517
6000
|
{ style: styles.row },
|
|
5518
|
-
(0,
|
|
6001
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, {
|
|
5519
6002
|
variant: "primary",
|
|
5520
6003
|
size: "md",
|
|
5521
6004
|
disabled: body2.trim() === "",
|
|
@@ -5524,13 +6007,13 @@ function InitPanel({ workspace, remote }) {
|
|
|
5524
6007
|
void write(body2, exists);
|
|
5525
6008
|
}
|
|
5526
6009
|
}, exists ? "\u4FDD\u5B58\u5E76\u8986\u76D6" : "\u4FDD\u5B58"),
|
|
5527
|
-
(0,
|
|
6010
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "md", onClick: () => {
|
|
5528
6011
|
setEditing(false);
|
|
5529
6012
|
} }, "\u53D6\u6D88")
|
|
5530
|
-
) : (0,
|
|
6013
|
+
) : (0, import_react4.createElement)(
|
|
5531
6014
|
"div",
|
|
5532
6015
|
{ style: styles.row },
|
|
5533
|
-
(0,
|
|
6016
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, {
|
|
5534
6017
|
variant: "primary",
|
|
5535
6018
|
size: "md",
|
|
5536
6019
|
disabled: generating,
|
|
@@ -5539,203 +6022,54 @@ function InitPanel({ workspace, remote }) {
|
|
|
5539
6022
|
void generate();
|
|
5540
6023
|
}
|
|
5541
6024
|
}, exists ? "\u91CD\u65B0\u521D\u59CB\u5316\uFF08AI \u626B\u63CF\u8986\u76D6\uFF09" : "\u8BA9 AI \u521D\u59CB\u5316"),
|
|
5542
|
-
exists ? (0,
|
|
6025
|
+
exists ? (0, import_react4.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", size: "md", onClick: startEdit }, "\u624B\u52A8\u7F16\u8F91") : null
|
|
5543
6026
|
)
|
|
5544
6027
|
)
|
|
5545
6028
|
);
|
|
5546
6029
|
}
|
|
5547
6030
|
|
|
5548
6031
|
// src/client/SkillManager.tsx
|
|
5549
|
-
var
|
|
5550
|
-
|
|
5551
|
-
// src/client/ResourceManager.tsx
|
|
5552
|
-
var import_react4 = require("react");
|
|
5553
|
-
var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
5554
|
-
|
|
5555
|
-
// src/client/ResourceModal.tsx
|
|
5556
|
-
var import_react3 = require("react");
|
|
5557
|
-
var import_react_dom = require("react-dom");
|
|
5558
|
-
var import_dsh_client_ui_primitives3 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
5559
|
-
var rootStyle = {
|
|
5560
|
-
position: "fixed",
|
|
5561
|
-
inset: 0,
|
|
5562
|
-
zIndex: 1e3,
|
|
5563
|
-
display: "flex",
|
|
5564
|
-
alignItems: "center",
|
|
5565
|
-
justifyContent: "center",
|
|
5566
|
-
padding: 24
|
|
5567
|
-
};
|
|
5568
|
-
var maskStyle = {
|
|
5569
|
-
position: "absolute",
|
|
5570
|
-
inset: 0,
|
|
5571
|
-
background: "var(--dsw-alias-bg-mask-1)",
|
|
5572
|
-
backdropFilter: "var(--dsw-mask-blur)"
|
|
5573
|
-
};
|
|
5574
|
-
var dialogStyle = {
|
|
5575
|
-
position: "relative",
|
|
5576
|
-
zIndex: 1,
|
|
5577
|
-
display: "flex",
|
|
5578
|
-
flexDirection: "column",
|
|
5579
|
-
width: "min(760px, 100%)",
|
|
5580
|
-
maxHeight: "85vh",
|
|
5581
|
-
borderRadius: 24,
|
|
5582
|
-
background: "var(--dsw-alias-bg-layer-2)",
|
|
5583
|
-
boxShadow: "var(--dsw-elevation-prominent)",
|
|
5584
|
-
overflow: "hidden"
|
|
5585
|
-
};
|
|
5586
|
-
var headerStyle = {
|
|
5587
|
-
display: "flex",
|
|
5588
|
-
alignItems: "center",
|
|
5589
|
-
justifyContent: "space-between",
|
|
5590
|
-
gap: 8,
|
|
5591
|
-
padding: "18px 18px 10px 24px",
|
|
5592
|
-
flex: "none"
|
|
5593
|
-
};
|
|
5594
|
-
var titleStyle = {
|
|
5595
|
-
margin: 0,
|
|
5596
|
-
fontSize: 16,
|
|
5597
|
-
lineHeight: "24px",
|
|
5598
|
-
fontWeight: 500,
|
|
5599
|
-
color: "var(--dsw-alias-label-primary)"
|
|
5600
|
-
};
|
|
5601
|
-
var closeBtnStyle = {
|
|
5602
|
-
flex: "none",
|
|
5603
|
-
display: "inline-flex",
|
|
5604
|
-
alignItems: "center",
|
|
5605
|
-
justifyContent: "center",
|
|
5606
|
-
width: 28,
|
|
5607
|
-
height: 28,
|
|
5608
|
-
border: "none",
|
|
5609
|
-
borderRadius: 8,
|
|
5610
|
-
background: "transparent",
|
|
5611
|
-
cursor: "pointer",
|
|
5612
|
-
color: "var(--dsw-alias-label-secondary)",
|
|
5613
|
-
padding: 0
|
|
5614
|
-
};
|
|
5615
|
-
var descStyle = {
|
|
5616
|
-
margin: 0,
|
|
5617
|
-
padding: "0 24px",
|
|
5618
|
-
fontSize: 13,
|
|
5619
|
-
lineHeight: "20px",
|
|
5620
|
-
color: "var(--dsw-alias-label-secondary)",
|
|
5621
|
-
flex: "none"
|
|
5622
|
-
};
|
|
5623
|
-
var bodyStyle = {
|
|
5624
|
-
flex: "1 1 auto",
|
|
5625
|
-
minHeight: 0,
|
|
5626
|
-
overflowY: "auto",
|
|
5627
|
-
padding: "16px 24px 4px",
|
|
5628
|
-
display: "flex",
|
|
5629
|
-
flexDirection: "column"
|
|
5630
|
-
};
|
|
5631
|
-
var footerStyle = {
|
|
5632
|
-
display: "flex",
|
|
5633
|
-
alignItems: "center",
|
|
5634
|
-
justifyContent: "flex-end",
|
|
5635
|
-
gap: 8,
|
|
5636
|
-
padding: "12px 24px 20px",
|
|
5637
|
-
flex: "none"
|
|
5638
|
-
};
|
|
5639
|
-
function ResourceModal({ title, description, onClose, footer, children }) {
|
|
5640
|
-
const dialog = (0, import_react3.useRef)(null);
|
|
5641
|
-
const closer = (0, import_react3.useRef)(onClose);
|
|
5642
|
-
closer.current = onClose;
|
|
5643
|
-
(0, import_react3.useEffect)(() => {
|
|
5644
|
-
const previous = document.activeElement;
|
|
5645
|
-
dialog.current?.focus();
|
|
5646
|
-
const onKey = (e) => {
|
|
5647
|
-
if (!dialog.current?.contains(document.activeElement)) return;
|
|
5648
|
-
if (e.key === "Escape") {
|
|
5649
|
-
e.preventDefault();
|
|
5650
|
-
e.stopPropagation();
|
|
5651
|
-
closer.current();
|
|
5652
|
-
return;
|
|
5653
|
-
}
|
|
5654
|
-
if (e.key !== "Tab") return;
|
|
5655
|
-
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);
|
|
5656
|
-
const first = nodes[0], last = nodes[nodes.length - 1];
|
|
5657
|
-
if (!first || !last) {
|
|
5658
|
-
e.preventDefault();
|
|
5659
|
-
return;
|
|
5660
|
-
}
|
|
5661
|
-
if (e.shiftKey && (document.activeElement === first || document.activeElement === dialog.current)) {
|
|
5662
|
-
e.preventDefault();
|
|
5663
|
-
last.focus();
|
|
5664
|
-
} else if (!e.shiftKey && (document.activeElement === last || document.activeElement === dialog.current)) {
|
|
5665
|
-
e.preventDefault();
|
|
5666
|
-
first.focus();
|
|
5667
|
-
}
|
|
5668
|
-
};
|
|
5669
|
-
document.addEventListener("keydown", onKey);
|
|
5670
|
-
return () => {
|
|
5671
|
-
document.removeEventListener("keydown", onKey);
|
|
5672
|
-
if (previous?.isConnected) previous.focus();
|
|
5673
|
-
};
|
|
5674
|
-
}, []);
|
|
5675
|
-
return (0, import_react_dom.createPortal)(
|
|
5676
|
-
(0, import_react3.createElement)(
|
|
5677
|
-
"div",
|
|
5678
|
-
{ style: rootStyle, className: "te-modal", role: "presentation" },
|
|
5679
|
-
(0, import_react3.createElement)("div", { style: maskStyle, "aria-hidden": true, onClick: onClose }),
|
|
5680
|
-
(0, import_react3.createElement)(
|
|
5681
|
-
"div",
|
|
5682
|
-
{ style: dialogStyle, ref: dialog, tabIndex: -1, role: "dialog", "aria-modal": true, "aria-label": title },
|
|
5683
|
-
(0, import_react3.createElement)(
|
|
5684
|
-
"div",
|
|
5685
|
-
{ style: headerStyle },
|
|
5686
|
-
(0, import_react3.createElement)("h2", { style: titleStyle }, title),
|
|
5687
|
-
(0, import_react3.createElement)(
|
|
5688
|
-
"button",
|
|
5689
|
-
{ type: "button", style: closeBtnStyle, "aria-label": "\u5173\u95ED", onClick: onClose },
|
|
5690
|
-
(0, import_react3.createElement)(import_dsh_client_ui_primitives3.IconCloseOutline16, { size: 14 })
|
|
5691
|
-
)
|
|
5692
|
-
),
|
|
5693
|
-
description !== void 0 && description !== "" ? (0, import_react3.createElement)("p", { style: descStyle }, description) : null,
|
|
5694
|
-
(0, import_react3.createElement)("div", { style: bodyStyle }, children),
|
|
5695
|
-
footer !== void 0 ? (0, import_react3.createElement)("div", { style: footerStyle }, footer) : null
|
|
5696
|
-
)
|
|
5697
|
-
),
|
|
5698
|
-
document.body
|
|
5699
|
-
);
|
|
5700
|
-
}
|
|
6032
|
+
var import_react6 = require("react");
|
|
5701
6033
|
|
|
5702
6034
|
// src/client/ResourceManager.tsx
|
|
6035
|
+
var import_react5 = require("react");
|
|
6036
|
+
var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
5703
6037
|
var labels = { code: { copyLabel: "\u590D\u5236", copiedLabel: "\u5DF2\u590D\u5236" }, footnotes: "\u811A\u6CE8" };
|
|
5704
6038
|
var levelOf = (row) => row.source === "bundled" ? "bundled" : row.source.startsWith("user") ? "user" : "project";
|
|
5705
6039
|
var sourceText2 = (source) => source === "bundled" ? "\u5185\u7F6E" : source.startsWith("user") ? "\u4E2A\u4EBA" : "\u9879\u76EE";
|
|
5706
6040
|
var sizeText = (bytes) => bytes < 1024 ? `${bytes} B` : bytes < 1024 * 1024 ? `${(bytes / 1024).toFixed(1)} KB` : `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
5707
6041
|
var fail = (r) => describeError(r.error ?? "\u64CD\u4F5C\u5931\u8D25");
|
|
5708
|
-
function ResourceManager({ workspace, remote, kind }) {
|
|
6042
|
+
function ResourceManager({ workspace, remote, kind, onConfigureSkill }) {
|
|
5709
6043
|
const noun = kind === "skill" ? "\u6280\u80FD" : "\u89C4\u5219";
|
|
5710
|
-
const [rows, setRows] = (0,
|
|
5711
|
-
const [query, setQuery] = (0,
|
|
5712
|
-
const [filter, setFilter] = (0,
|
|
5713
|
-
const [notice, setNotice] = (0,
|
|
5714
|
-
const [error, setError] = (0,
|
|
5715
|
-
const [loading, setLoading] = (0,
|
|
5716
|
-
const [revision, refresh] = (0,
|
|
5717
|
-
const [busy, setBusy] = (0,
|
|
5718
|
-
const [roots, setRoots] = (0,
|
|
5719
|
-
const [importing, setImporting] = (0,
|
|
5720
|
-
const [request, setRequest] = (0,
|
|
5721
|
-
const [preview, setPreview] = (0,
|
|
5722
|
-
const [level, setLevel] = (0,
|
|
5723
|
-
const [manual, setManual] = (0,
|
|
5724
|
-
const [sourceDir, setSourceDir] = (0,
|
|
5725
|
-
const [dirs, setDirs] = (0,
|
|
5726
|
-
const [browsePath, setBrowsePath] = (0,
|
|
5727
|
-
const [editing, setEditing] = (0,
|
|
5728
|
-
const [viewing, setViewing] = (0,
|
|
5729
|
-
const [name, setName] = (0,
|
|
5730
|
-
const [description, setDescription] = (0,
|
|
5731
|
-
const [whenToUse, setWhenToUse] = (0,
|
|
5732
|
-
const [body2, setBody] = (0,
|
|
5733
|
-
const [deleting, setDeleting] = (0,
|
|
5734
|
-
const input = (0,
|
|
5735
|
-
const fileEpoch = (0,
|
|
5736
|
-
const browseEpoch = (0,
|
|
6044
|
+
const [rows, setRows] = (0, import_react5.useState)([]);
|
|
6045
|
+
const [query, setQuery] = (0, import_react5.useState)("");
|
|
6046
|
+
const [filter, setFilter] = (0, import_react5.useState)("all");
|
|
6047
|
+
const [notice, setNotice] = (0, import_react5.useState)("");
|
|
6048
|
+
const [error, setError] = (0, import_react5.useState)("");
|
|
6049
|
+
const [loading, setLoading] = (0, import_react5.useState)(true);
|
|
6050
|
+
const [revision, refresh] = (0, import_react5.useState)(0);
|
|
6051
|
+
const [busy, setBusy] = (0, import_react5.useState)(false);
|
|
6052
|
+
const [roots, setRoots] = (0, import_react5.useState)(null);
|
|
6053
|
+
const [importing, setImporting] = (0, import_react5.useState)(false);
|
|
6054
|
+
const [request, setRequest] = (0, import_react5.useState)(null);
|
|
6055
|
+
const [preview, setPreview] = (0, import_react5.useState)(null);
|
|
6056
|
+
const [level, setLevel] = (0, import_react5.useState)("project");
|
|
6057
|
+
const [manual, setManual] = (0, import_react5.useState)(false);
|
|
6058
|
+
const [sourceDir, setSourceDir] = (0, import_react5.useState)("");
|
|
6059
|
+
const [dirs, setDirs] = (0, import_react5.useState)([]);
|
|
6060
|
+
const [browsePath, setBrowsePath] = (0, import_react5.useState)("");
|
|
6061
|
+
const [editing, setEditing] = (0, import_react5.useState)(null);
|
|
6062
|
+
const [viewing, setViewing] = (0, import_react5.useState)(false);
|
|
6063
|
+
const [name, setName] = (0, import_react5.useState)("");
|
|
6064
|
+
const [description, setDescription] = (0, import_react5.useState)("");
|
|
6065
|
+
const [whenToUse, setWhenToUse] = (0, import_react5.useState)("");
|
|
6066
|
+
const [body2, setBody] = (0, import_react5.useState)("");
|
|
6067
|
+
const [deleting, setDeleting] = (0, import_react5.useState)(null);
|
|
6068
|
+
const input = (0, import_react5.useRef)(null);
|
|
6069
|
+
const fileEpoch = (0, import_react5.useRef)(0);
|
|
6070
|
+
const browseEpoch = (0, import_react5.useRef)(0);
|
|
5737
6071
|
const readonly = editing !== null && editing !== "new" && levelOf(editing) === "bundled";
|
|
5738
|
-
(0,
|
|
6072
|
+
(0, import_react5.useEffect)(() => {
|
|
5739
6073
|
let active = true;
|
|
5740
6074
|
setLoading(true);
|
|
5741
6075
|
setRows([]);
|
|
@@ -5762,7 +6096,7 @@ function ResourceManager({ workspace, remote, kind }) {
|
|
|
5762
6096
|
fileEpoch.current++;
|
|
5763
6097
|
};
|
|
5764
6098
|
}, [workspace, remote, kind, revision]);
|
|
5765
|
-
(0,
|
|
6099
|
+
(0, import_react5.useEffect)(() => {
|
|
5766
6100
|
let active = true;
|
|
5767
6101
|
setPreview(null);
|
|
5768
6102
|
if (!request) return;
|
|
@@ -5926,105 +6260,163 @@ function ResourceManager({ workspace, remote, kind }) {
|
|
|
5926
6260
|
setBusy(false);
|
|
5927
6261
|
}
|
|
5928
6262
|
};
|
|
5929
|
-
const status = () => error ? (0,
|
|
5930
|
-
const targets = () => (0,
|
|
6263
|
+
const status = () => error ? (0, import_react5.createElement)("div", { className: "te-alert", role: "alert" }, error) : null;
|
|
6264
|
+
const targets = () => (0, import_react5.createElement)(
|
|
5931
6265
|
"div",
|
|
5932
6266
|
{ className: "te-targets" },
|
|
5933
|
-
...["project", "user"].map((lvl) => (0,
|
|
6267
|
+
...["project", "user"].map((lvl) => (0, import_react5.createElement)(
|
|
5934
6268
|
"button",
|
|
5935
6269
|
{ type: "button", key: lvl, className: `te-target ${level === lvl ? "selected" : ""}`, "aria-pressed": level === lvl, disabled: busy || editing !== null && editing !== "new", onClick: () => {
|
|
5936
6270
|
setPreview(null);
|
|
5937
6271
|
setLevel(lvl);
|
|
5938
6272
|
} },
|
|
5939
|
-
(0,
|
|
5940
|
-
(0,
|
|
6273
|
+
(0, import_react5.createElement)("strong", null, lvl === "project" ? "\u9879\u76EE\u5171\u4EAB" : "\u4E2A\u4EBA\u5168\u5C40"),
|
|
6274
|
+
(0, import_react5.createElement)("small", null, lvl === "project" ? "\u4EC5\u5F53\u524D\u5DE5\u4F5C\u533A\u4F7F\u7528" : "\u6B64\u4E3B\u673A\u4E0A\u7684\u6240\u6709\u9879\u76EE\u53EF\u7528")
|
|
5941
6275
|
)),
|
|
5942
|
-
(0,
|
|
6276
|
+
(0, import_react5.createElement)("code", { className: "te-path" }, roots?.[level] ?? (level === "project" ? `${workspace}/.dsh/${kind}s` : `DSH_HOME/${kind}s`))
|
|
5943
6277
|
);
|
|
5944
6278
|
const visible = rows.filter((r) => `${r.name} ${r.description ?? ""}`.toLowerCase().includes(query.toLowerCase()) && (filter === "all" || levelOf(r) === filter));
|
|
5945
|
-
return (0,
|
|
6279
|
+
return (0, import_react5.createElement)(
|
|
5946
6280
|
"section",
|
|
5947
6281
|
{ className: "te-resource" },
|
|
5948
|
-
(0,
|
|
6282
|
+
(0, import_react5.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) => {
|
|
5949
6283
|
void selected(Array.from(e.target.files ?? []));
|
|
5950
6284
|
} }),
|
|
5951
|
-
(0,
|
|
6285
|
+
(0, import_react5.createElement)("div", { className: "te-section-heading" }, (0, import_react5.createElement)("div", null, (0, import_react5.createElement)("h2", null, `${noun}\u5E93`), (0, import_react5.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_react5.createElement)("div", { className: "te-actions" }, (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", onClick: () => {
|
|
5952
6286
|
void edit("new");
|
|
5953
|
-
} }, `\u65B0\u5EFA${noun}`), (0,
|
|
5954
|
-
(0,
|
|
5955
|
-
notice ? (0,
|
|
6287
|
+
} }, `\u65B0\u5EFA${noun}`), (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "primary", onClick: choose }, `\u5B89\u88C5${noun}`))),
|
|
6288
|
+
(0, import_react5.createElement)("div", { className: "te-toolbar" }, (0, import_react5.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_react5.createElement)("select", { className: "te-input", "aria-label": "\u7B5B\u9009\u6765\u6E90", value: filter, onChange: (e) => setFilter(e.target.value) }, (0, import_react5.createElement)("option", { value: "all" }, `\u5168\u90E8\u6765\u6E90 \xB7 ${rows.length}`), (0, import_react5.createElement)("option", { value: "bundled" }, "\u5185\u7F6E"), (0, import_react5.createElement)("option", { value: "project" }, "\u9879\u76EE"), (0, import_react5.createElement)("option", { value: "user" }, "\u4E2A\u4EBA")), (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", onClick: () => refresh((n) => n + 1), disabled: loading }, "\u5237\u65B0")),
|
|
6289
|
+
notice ? (0, import_react5.createElement)("div", { className: "te-success", role: "status" }, notice) : null,
|
|
5956
6290
|
!importing && !editing && !deleting ? status() : null,
|
|
5957
|
-
loading ? (0,
|
|
6291
|
+
loading ? (0, import_react5.createElement)("div", { className: "te-empty", role: "status" }, "\u6B63\u5728\u52A0\u8F7D\u2026") : visible.length === 0 ? (0, import_react5.createElement)("div", { className: "te-empty" }, (0, import_react5.createElement)("h3", null, query || filter !== "all" ? "\u6CA1\u6709\u5339\u914D\u7684\u7ED3\u679C" : `\u8FD8\u6CA1\u6709${noun}`), (0, import_react5.createElement)("p", null, "\u8C03\u6574\u7B5B\u9009\uFF0C\u6216\u4F7F\u7528\u53F3\u4E0A\u89D2\u6309\u94AE\u6DFB\u52A0\u3002")) : (0, import_react5.createElement)("div", { className: "te-resource-grid" }, ...visible.map((row) => (0, import_react5.createElement)(
|
|
5958
6292
|
"article",
|
|
5959
6293
|
{ className: "te-resource-card", key: row.source + "/" + row.name },
|
|
5960
|
-
(0,
|
|
5961
|
-
(0,
|
|
5962
|
-
(0,
|
|
5963
|
-
(0,
|
|
6294
|
+
(0, import_react5.createElement)("div", { className: "te-card-top" }, (0, import_react5.createElement)("span", { className: "te-resource-icon", "aria-hidden": true }, kind === "skill" ? "\u25C7" : "\u2261"), (0, import_react5.createElement)("span", { className: "te-badge" }, sourceText2(row.source))),
|
|
6295
|
+
(0, import_react5.createElement)("h3", null, row.name),
|
|
6296
|
+
(0, import_react5.createElement)("p", null, row.description || "\u9879\u76EE\u7EA6\u5B9A\u4E0E\u6267\u884C\u89C4\u5219"),
|
|
6297
|
+
(0, import_react5.createElement)("div", { className: "te-actions" }, kind === "skill" && onConfigureSkill ? (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "primary", size: "sm", onClick: () => onConfigureSkill({ source: levelOf(row), name: row.name }) }, "\u914D\u7F6E\u89C4\u5219") : null, (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", size: "sm", onClick: () => {
|
|
5964
6298
|
void edit(row, true);
|
|
5965
|
-
} }, "\u67E5\u770B"), levelOf(row) !== "bundled" ? (0,
|
|
6299
|
+
} }, "\u67E5\u770B"), levelOf(row) !== "bundled" ? (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", size: "sm", onClick: () => {
|
|
5966
6300
|
void edit(row);
|
|
5967
|
-
} }, "\u7F16\u8F91") : null, levelOf(row) !== "bundled" ? (0,
|
|
6301
|
+
} }, "\u7F16\u8F91") : null, levelOf(row) !== "bundled" ? (0, import_react5.createElement)("button", { className: "te-delete", onClick: () => {
|
|
5968
6302
|
setDeleting(row);
|
|
5969
6303
|
setError("");
|
|
5970
6304
|
} }, "\u5220\u9664") : null)
|
|
5971
6305
|
))),
|
|
5972
|
-
kind === "skill" ? (0,
|
|
6306
|
+
kind === "skill" ? (0, import_react5.createElement)("button", { className: "te-link", onClick: () => {
|
|
5973
6307
|
setImporting(true);
|
|
5974
6308
|
setManual(true);
|
|
5975
6309
|
setError("");
|
|
5976
6310
|
} }, "\u9AD8\u7EA7\uFF1A\u4ECE Harness \u4E3B\u673A\u8DEF\u5F84\u5B89\u88C5") : null,
|
|
5977
|
-
importing ? (0,
|
|
6311
|
+
importing ? (0, import_react5.createElement)(
|
|
5978
6312
|
ResourceModal,
|
|
5979
|
-
{ 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,
|
|
6313
|
+
{ 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_react5.createElement)("div", { className: "te-actions" }, (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: busy, onClick: close }, "\u53D6\u6D88"), (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "primary", disabled: busy || !preview || preview.conflict, onClick: () => {
|
|
5980
6314
|
void install();
|
|
5981
6315
|
} }, busy ? "\u5904\u7406\u4E2D\u2026" : "\u786E\u8BA4\u5B89\u88C5")) },
|
|
5982
6316
|
targets(),
|
|
5983
|
-
(0,
|
|
5984
|
-
manual ? (0,
|
|
6317
|
+
(0, import_react5.createElement)("div", { className: "te-actions" }, (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", disabled: busy, onClick: choose }, "\u91CD\u65B0\u9009\u62E9"), kind === "skill" ? (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: busy, onClick: () => setManual(!manual) }, manual ? "\u6536\u8D77\u9AD8\u7EA7\u65B9\u5F0F" : "\u4E3B\u673A\u8DEF\u5F84") : null),
|
|
6318
|
+
manual ? (0, import_react5.createElement)("div", { className: "te-advanced" }, (0, import_react5.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_react5.createElement)("div", { className: "te-toolbar" }, (0, import_react5.createElement)("input", { className: "te-input", "aria-label": "\u4E3B\u673A\u6280\u80FD\u76EE\u5F55", value: sourceDir, onChange: (e) => {
|
|
5985
6319
|
setSourceDir(e.target.value);
|
|
5986
6320
|
setRequest(null);
|
|
5987
|
-
} }), (0,
|
|
6321
|
+
} }), (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", onClick: () => {
|
|
5988
6322
|
void browse(sourceDir);
|
|
5989
|
-
} }, "\u6D4F\u89C8"), (0,
|
|
6323
|
+
} }, "\u6D4F\u89C8"), (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", disabled: busy || !sourceDir.trim(), onClick: () => setRequest({ kind, level, path: workspace, files: [], sourceDir }) }, "\u9884\u89C8\u76EE\u5F55")), (0, import_react5.createElement)("div", { className: "te-dir-list" }, browsePath ? (0, import_react5.createElement)("button", { onClick: () => {
|
|
5990
6324
|
void browse(browsePath.replace(/[\\/][^\\/]+[\\/]?$/u, "") || "/");
|
|
5991
|
-
} }, "\u2191 \u4E0A\u7EA7\u76EE\u5F55") : null, ...dirs.map((d) => (0,
|
|
6325
|
+
} }, "\u2191 \u4E0A\u7EA7\u76EE\u5F55") : null, ...dirs.map((d) => (0, import_react5.createElement)("button", { key: d.name, onClick: () => {
|
|
5992
6326
|
setRequest(null);
|
|
5993
6327
|
void browse(browsePath.replace(/[\\/]+$/u, "") + "/" + d.name);
|
|
5994
6328
|
} }, d.name + (d.hasSkill ? " \xB7 SKILL.md" : ""))))) : null,
|
|
5995
|
-
busy ? (0,
|
|
6329
|
+
busy ? (0, import_react5.createElement)("p", { role: "status" }, "\u6B63\u5728\u6821\u9A8C\u6587\u4EF6\uFF0C\u8BF7\u7A0D\u5019\u2026") : null,
|
|
5996
6330
|
status(),
|
|
5997
|
-
preview ? (0,
|
|
6331
|
+
preview ? (0, import_react5.createElement)("div", { className: "te-preview" }, (0, import_react5.createElement)("h3", null, preview.name), (0, import_react5.createElement)("p", null, preview.description), (0, import_react5.createElement)("div", { className: "te-actions" }, (0, import_react5.createElement)("span", { className: "te-badge" }, `${preview.files} \u4E2A\u6587\u4EF6`), (0, import_react5.createElement)("span", { className: "te-badge" }, sizeText(preview.bytes))), (0, import_react5.createElement)("code", { className: "te-path" }, preview.target), preview.conflict ? (0, import_react5.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_react5.createElement)("div", { className: "te-markdown" }, (0, import_react5.createElement)(import_dsh_client_ui_primitives5.MarkdownText, { text: preview.content, labels }))) : null
|
|
5998
6332
|
) : null,
|
|
5999
|
-
editing ? (0,
|
|
6333
|
+
editing ? (0, import_react5.createElement)(
|
|
6000
6334
|
ResourceModal,
|
|
6001
|
-
{ title: editing === "new" ? `\u65B0\u5EFA${noun}` : `${viewing ? "\u67E5\u770B" : "\u7F16\u8F91"}${noun} \xB7 ${name}`, onClose: close, footer: (0,
|
|
6335
|
+
{ title: editing === "new" ? `\u65B0\u5EFA${noun}` : `${viewing ? "\u67E5\u770B" : "\u7F16\u8F91"}${noun} \xB7 ${name}`, onClose: close, footer: (0, import_react5.createElement)("div", { className: "te-actions" }, (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: busy, onClick: close }, "\u5173\u95ED"), !readonly ? (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", disabled: busy, onClick: () => setViewing(!viewing) }, viewing ? "\u7F16\u8F91\u5185\u5BB9" : "\u9884\u89C8") : null, !readonly ? (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "primary", disabled: busy || !name.trim() || !body2.trim() || kind === "skill" && !description.trim(), onClick: () => {
|
|
6002
6336
|
void save2();
|
|
6003
6337
|
} }, busy ? "\u5904\u7406\u4E2D\u2026" : "\u4FDD\u5B58") : null) },
|
|
6004
|
-
!readonly ? targets() : (0,
|
|
6338
|
+
!readonly ? targets() : (0, import_react5.createElement)("p", { className: "te-badge" }, "\u5185\u7F6E\u8D44\u6E90 \xB7 \u53EA\u8BFB"),
|
|
6005
6339
|
status(),
|
|
6006
|
-
viewing ? (0,
|
|
6340
|
+
viewing ? (0, import_react5.createElement)("div", { className: "te-markdown" }, (0, import_react5.createElement)(import_dsh_client_ui_primitives5.MarkdownText, { text: body2, labels })) : (0, import_react5.createElement)("div", { className: "te-form" }, (0, import_react5.createElement)("label", null, "\u540D\u79F0", (0, import_react5.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_react5.createElement)("label", null, "\u63CF\u8FF0", (0, import_react5.createElement)("input", { className: "te-input", value: description, disabled: busy, onChange: (e) => setDescription(e.target.value) })) : null, kind === "skill" ? (0, import_react5.createElement)("label", null, "\u4F7F\u7528\u65F6\u673A\uFF08\u53EF\u9009\uFF09", (0, import_react5.createElement)("input", { className: "te-input", value: whenToUse, disabled: busy, onChange: (e) => setWhenToUse(e.target.value) })) : null, (0, import_react5.createElement)("label", null, "Markdown \u6B63\u6587", (0, import_react5.createElement)("textarea", { className: "te-input te-editor", value: body2, disabled: busy, onChange: (e) => setBody(e.target.value) })))
|
|
6007
6341
|
) : null,
|
|
6008
|
-
deleting ? (0,
|
|
6342
|
+
deleting ? (0, import_react5.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_react5.createElement)("div", { className: "te-actions" }, (0, import_react5.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", disabled: busy, onClick: close }, "\u4FDD\u7559"), (0, import_react5.createElement)("button", { className: "te-danger-button", disabled: busy, onClick: () => {
|
|
6009
6343
|
void remove();
|
|
6010
|
-
} }, busy ? "\u5220\u9664\u4E2D\u2026" : "\u786E\u8BA4\u6C38\u4E45\u5220\u9664")) }, (0,
|
|
6344
|
+
} }, busy ? "\u5220\u9664\u4E2D\u2026" : "\u786E\u8BA4\u6C38\u4E45\u5220\u9664")) }, (0, import_react5.createElement)("code", { className: "te-path" }, `${roots?.[levelOf(deleting) === "user" ? "user" : "project"] ?? "\u8D44\u6E90\u76EE\u5F55"}/${deleting.name}${kind === "rule" ? ".md" : ""}`), (0, import_react5.createElement)("p", null, "\u6B64\u64CD\u4F5C\u4E0D\u4F1A\u8FDB\u5165\u56DE\u6536\u7AD9\uFF0C\u8BF7\u786E\u8BA4\u5DF2\u6709\u5907\u4EFD\u3002"), status()) : null
|
|
6011
6345
|
);
|
|
6012
6346
|
}
|
|
6013
6347
|
|
|
6014
6348
|
// src/client/SkillManager.tsx
|
|
6015
|
-
|
|
6016
|
-
|
|
6349
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
6350
|
+
function SkillManager({ workspace, remote }) {
|
|
6351
|
+
const [config, setConfig] = (0, import_react6.useState)(null);
|
|
6352
|
+
const [rules, setRules] = (0, import_react6.useState)([]);
|
|
6353
|
+
const [selected, setSelected] = (0, import_react6.useState)(null);
|
|
6354
|
+
const [message, setMessage] = (0, import_react6.useState)("");
|
|
6355
|
+
(0, import_react6.useEffect)(() => {
|
|
6356
|
+
let active = true;
|
|
6357
|
+
void Promise.all([remote.read(workspace), remote.listRules(workspace)]).then(([saved, availableRules]) => {
|
|
6358
|
+
if (!active) return;
|
|
6359
|
+
if (!saved.ok || !saved.value.ok || !availableRules.ok) {
|
|
6360
|
+
setMessage("\u8BFB\u53D6\u6280\u80FD\u89C4\u5219\u914D\u7F6E\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u6280\u80FD\u9875\u3002");
|
|
6361
|
+
return;
|
|
6362
|
+
}
|
|
6363
|
+
const effective = saved.value.config;
|
|
6364
|
+
setConfig(compactProjectConfig({
|
|
6365
|
+
flow: saved.value.flow,
|
|
6366
|
+
stage_bindings: effective.stage_bindings,
|
|
6367
|
+
skill_profiles: effective.skill_profiles,
|
|
6368
|
+
commit: effective.commit,
|
|
6369
|
+
artifacts: effective.artifacts,
|
|
6370
|
+
review_depth: effective.review_depth,
|
|
6371
|
+
commit_required: effective.commit_required
|
|
6372
|
+
}));
|
|
6373
|
+
setRules(availableRules.value.rules);
|
|
6374
|
+
}).catch(() => {
|
|
6375
|
+
if (active) setMessage("\u8BFB\u53D6\u6280\u80FD\u89C4\u5219\u914D\u7F6E\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u6280\u80FD\u9875\u3002");
|
|
6376
|
+
});
|
|
6377
|
+
return () => {
|
|
6378
|
+
active = false;
|
|
6379
|
+
};
|
|
6380
|
+
}, [remote, workspace]);
|
|
6381
|
+
const saveProfile = async (profile) => {
|
|
6382
|
+
if (!config || !selected) throw new Error("\u914D\u7F6E\u5C1A\u672A\u52A0\u8F7D\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
|
|
6383
|
+
const key = formatResourceRef(selected);
|
|
6384
|
+
const next = { ...config, skill_profiles: { ...config.skill_profiles, [key]: profile } };
|
|
6385
|
+
const result = await remote.write({ path: workspace, ...next });
|
|
6386
|
+
if (!result.ok || !result.value.ok) throw new Error(result.ok ? result.value.problems.join("\uFF1B") : "\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
6387
|
+
setConfig(next);
|
|
6388
|
+
setMessage(`\u5DF2\u4FDD\u5B58 ${selected.name} \u7684\u89C4\u5219\u914D\u7F6E\u3002`);
|
|
6389
|
+
setSelected(null);
|
|
6390
|
+
};
|
|
6391
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
|
|
6392
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ResourceManager, { workspace, remote, kind: "skill", onConfigureSkill: config ? (ref) => {
|
|
6393
|
+
setMessage("");
|
|
6394
|
+
setSelected(ref);
|
|
6395
|
+
} : void 0 }),
|
|
6396
|
+
selected === null && message ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { role: "status", className: "te-success", children: message }) : null,
|
|
6397
|
+
selected !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
6398
|
+
SkillRuleDialog,
|
|
6399
|
+
{
|
|
6400
|
+
skill: selected,
|
|
6401
|
+
profile: config?.skill_profiles?.[formatResourceRef(selected)],
|
|
6402
|
+
rules,
|
|
6403
|
+
onSave: saveProfile,
|
|
6404
|
+
onClose: () => setSelected(null)
|
|
6405
|
+
},
|
|
6406
|
+
formatResourceRef(selected)
|
|
6407
|
+
) : null
|
|
6408
|
+
] });
|
|
6017
6409
|
}
|
|
6018
6410
|
|
|
6019
6411
|
// src/client/RuleManager.tsx
|
|
6020
|
-
var
|
|
6412
|
+
var import_react7 = require("react");
|
|
6021
6413
|
function RuleManager(props) {
|
|
6022
|
-
return (0,
|
|
6414
|
+
return (0, import_react7.createElement)(ResourceManager, { ...props, key: props.workspace, kind: "rule" });
|
|
6023
6415
|
}
|
|
6024
6416
|
|
|
6025
6417
|
// src/client/TaskLedger.tsx
|
|
6026
|
-
var
|
|
6027
|
-
var
|
|
6418
|
+
var import_react8 = require("react");
|
|
6419
|
+
var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
6028
6420
|
var card2 = {
|
|
6029
6421
|
display: "flex",
|
|
6030
6422
|
flexDirection: "column",
|
|
@@ -6062,10 +6454,10 @@ var badge = {
|
|
|
6062
6454
|
color: "var(--dsw-alias-label-secondary)"
|
|
6063
6455
|
};
|
|
6064
6456
|
function verdictDot(outcome) {
|
|
6065
|
-
return (0,
|
|
6457
|
+
return (0, import_react8.createElement)(import_dsh_client_ui_primitives6.StateDot, { state: outcome === "pass" ? "done" : "error" });
|
|
6066
6458
|
}
|
|
6067
6459
|
function itemStatusDot(status) {
|
|
6068
|
-
return (0,
|
|
6460
|
+
return (0, import_react8.createElement)(import_dsh_client_ui_primitives6.StateDot, { state: status === "done" ? "done" : "ongoing" });
|
|
6069
6461
|
}
|
|
6070
6462
|
function timeText(at) {
|
|
6071
6463
|
return at.slice(0, 19).replace("T", " ");
|
|
@@ -6073,48 +6465,48 @@ function timeText(at) {
|
|
|
6073
6465
|
function itemAudit(item) {
|
|
6074
6466
|
const lines = [];
|
|
6075
6467
|
if (item.dispatch !== void 0) {
|
|
6076
|
-
lines.push((0,
|
|
6468
|
+
lines.push((0, import_react8.createElement)(
|
|
6077
6469
|
"div",
|
|
6078
6470
|
{ key: "dispatch", style: metaLine },
|
|
6079
|
-
(0,
|
|
6080
|
-
(0,
|
|
6081
|
-
(0,
|
|
6471
|
+
(0, import_react8.createElement)("span", { style: badge }, "\u5DF2\u6D3E\u53D1"),
|
|
6472
|
+
(0, import_react8.createElement)("span", null, item.dispatch.description === "" ? "\uFF08\u65E0\u63CF\u8FF0\uFF09" : item.dispatch.description),
|
|
6473
|
+
(0, import_react8.createElement)("span", { style: badge }, timeText(item.dispatch.at))
|
|
6082
6474
|
));
|
|
6083
6475
|
}
|
|
6084
6476
|
if (item.review !== void 0) {
|
|
6085
6477
|
const spec = item.review.spec;
|
|
6086
6478
|
const quality = item.review.quality;
|
|
6087
|
-
lines.push((0,
|
|
6479
|
+
lines.push((0, import_react8.createElement)(
|
|
6088
6480
|
"div",
|
|
6089
6481
|
{ key: "review", style: metaLine },
|
|
6090
6482
|
verdictDot(spec.outcome),
|
|
6091
|
-
(0,
|
|
6092
|
-
(0,
|
|
6483
|
+
(0, import_react8.createElement)("span", null, `\u89C4\u683C\u7B26\u5408 ${spec.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`),
|
|
6484
|
+
(0, import_react8.createElement)("span", null, "\xB7"),
|
|
6093
6485
|
verdictDot(quality.outcome),
|
|
6094
|
-
(0,
|
|
6486
|
+
(0, import_react8.createElement)("span", null, `\u4EE3\u7801\u8D28\u91CF ${quality.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`)
|
|
6095
6487
|
));
|
|
6096
6488
|
const failNotes = [spec, quality].flatMap((stage) => stage.outcome === "fail" ? stage.notes ?? [] : []);
|
|
6097
6489
|
if (failNotes.length > 0) {
|
|
6098
|
-
lines.push((0,
|
|
6490
|
+
lines.push((0, import_react8.createElement)(
|
|
6099
6491
|
"div",
|
|
6100
6492
|
{ key: "notes", style: metaLine },
|
|
6101
|
-
...failNotes.map((note) => (0,
|
|
6493
|
+
...failNotes.map((note) => (0, import_react8.createElement)("span", { key: note, style: badge }, note))
|
|
6102
6494
|
));
|
|
6103
6495
|
}
|
|
6104
6496
|
}
|
|
6105
6497
|
if (lines.length === 0) {
|
|
6106
|
-
lines.push((0,
|
|
6498
|
+
lines.push((0, import_react8.createElement)("div", { key: "none", style: metaLine }, (0, import_react8.createElement)("span", { style: badge }, "\u672A\u6D3E\u53D1 / \u672A\u5BA1\u67E5")));
|
|
6107
6499
|
}
|
|
6108
|
-
return (0,
|
|
6500
|
+
return (0, import_react8.createElement)("div", { style: { display: "flex", flexDirection: "column", gap: 4 } }, ...lines);
|
|
6109
6501
|
}
|
|
6110
6502
|
function TaskLedger({ workspace, remote }) {
|
|
6111
|
-
const [tasks, setTasks] = (0,
|
|
6112
|
-
const [error, setError] = (0,
|
|
6113
|
-
const [loading, setLoading] = (0,
|
|
6114
|
-
const [query, setQuery] = (0,
|
|
6115
|
-
const [risk, setRisk] = (0,
|
|
6116
|
-
const [stage, setStage] = (0,
|
|
6117
|
-
const refresh = (0,
|
|
6503
|
+
const [tasks, setTasks] = (0, import_react8.useState)([]);
|
|
6504
|
+
const [error, setError] = (0, import_react8.useState)("");
|
|
6505
|
+
const [loading, setLoading] = (0, import_react8.useState)(true);
|
|
6506
|
+
const [query, setQuery] = (0, import_react8.useState)("");
|
|
6507
|
+
const [risk, setRisk] = (0, import_react8.useState)("all");
|
|
6508
|
+
const [stage, setStage] = (0, import_react8.useState)("all");
|
|
6509
|
+
const refresh = (0, import_react8.useCallback)(() => {
|
|
6118
6510
|
if (workspace === "") return;
|
|
6119
6511
|
setError("");
|
|
6120
6512
|
setLoading(true);
|
|
@@ -6127,57 +6519,57 @@ function TaskLedger({ workspace, remote }) {
|
|
|
6127
6519
|
setError("\u8BFB\u53D6\u53F0\u8D26\u5931\u8D25\uFF1A" + describeError(reason));
|
|
6128
6520
|
});
|
|
6129
6521
|
}, [remote, workspace]);
|
|
6130
|
-
(0,
|
|
6522
|
+
(0, import_react8.useEffect)(() => {
|
|
6131
6523
|
refresh();
|
|
6132
6524
|
}, [refresh]);
|
|
6133
6525
|
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));
|
|
6134
|
-
return (0,
|
|
6526
|
+
return (0, import_react8.createElement)(
|
|
6135
6527
|
"div",
|
|
6136
6528
|
{ style: styles.section },
|
|
6137
|
-
(0,
|
|
6529
|
+
(0, import_react8.createElement)(
|
|
6138
6530
|
"div",
|
|
6139
6531
|
{ className: "te-toolbar" },
|
|
6140
|
-
(0,
|
|
6141
|
-
(0,
|
|
6142
|
-
(0,
|
|
6532
|
+
(0, import_react8.createElement)("input", { className: "te-input", placeholder: "\u641C\u7D22\u4EFB\u52A1\u3001\u6807\u9898\u6216\u5206\u652F", value: query, onChange: (e) => setQuery(e.target.value) }),
|
|
6533
|
+
(0, import_react8.createElement)("select", { className: "te-input", "aria-label": "\u98CE\u9669\u7B5B\u9009", value: risk, onChange: (e) => setRisk(e.target.value) }, (0, import_react8.createElement)("option", { value: "all" }, "\u5168\u90E8\u98CE\u9669"), (0, import_react8.createElement)("option", { value: "standard" }, "\u6807\u51C6"), (0, import_react8.createElement)("option", { value: "high_risk" }, "\u9AD8\u98CE\u9669")),
|
|
6534
|
+
(0, import_react8.createElement)("select", { className: "te-input", "aria-label": "\u9636\u6BB5\u7B5B\u9009", value: stage, onChange: (e) => setStage(e.target.value) }, (0, import_react8.createElement)("option", { value: "all" }, "\u5168\u90E8\u9636\u6BB5"), ...Array.from(new Set(tasks.map((t) => t.stage))).map((value) => (0, import_react8.createElement)("option", { key: value, value }, value)))
|
|
6143
6535
|
),
|
|
6144
|
-
(0,
|
|
6536
|
+
(0, import_react8.createElement)(
|
|
6145
6537
|
"div",
|
|
6146
6538
|
{ style: headerRow },
|
|
6147
|
-
(0,
|
|
6148
|
-
(0,
|
|
6149
|
-
(0,
|
|
6539
|
+
(0, import_react8.createElement)("span", { style: styles.bindingLabel }, "\u4EFB\u52A1\u53F0\u8D26"),
|
|
6540
|
+
(0, import_react8.createElement)("span", { style: styles.sourceBadge }, "\u53EA\u8BFB \xB7 \u6765\u81EA .dsh/task-*.json"),
|
|
6541
|
+
(0, import_react8.createElement)(import_dsh_client_ui_primitives6.Button, { variant: "outline", size: "sm", disabled: loading, onClick: refresh }, loading ? "\u8BFB\u53D6\u4E2D\u2026" : "\u5237\u65B0")
|
|
6150
6542
|
),
|
|
6151
|
-
loading ? (0,
|
|
6543
|
+
loading ? (0, import_react8.createElement)("p", { role: "status" }, "\u6B63\u5728\u8BFB\u53D6\u4EFB\u52A1\u2026") : error !== "" ? (0, import_react8.createElement)("p", { style: styles.status }, error) : tasks.length === 0 ? (0, import_react8.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_react8.createElement)("div", { className: "te-empty" }, "\u6CA1\u6709\u5339\u914D\u7684\u4EFB\u52A1\uFF0C\u8BF7\u8C03\u6574\u7B5B\u9009\u3002") : (0, import_react8.createElement)(
|
|
6152
6544
|
"div",
|
|
6153
6545
|
{ style: { display: "flex", flexDirection: "column", gap: 12 } },
|
|
6154
|
-
...visible.map((task) => (0,
|
|
6546
|
+
...visible.map((task) => (0, import_react8.createElement)(
|
|
6155
6547
|
"div",
|
|
6156
6548
|
{ key: task.task_id, style: card2 },
|
|
6157
|
-
(0,
|
|
6549
|
+
(0, import_react8.createElement)(
|
|
6158
6550
|
"div",
|
|
6159
6551
|
{ style: headerRow },
|
|
6160
|
-
(0,
|
|
6161
|
-
(0,
|
|
6162
|
-
(0,
|
|
6163
|
-
(0,
|
|
6164
|
-
(0,
|
|
6165
|
-
(0,
|
|
6166
|
-
(0,
|
|
6167
|
-
task.updated_at ? (0,
|
|
6552
|
+
(0, import_react8.createElement)("span", { style: { fontSize: 14, fontWeight: 600, color: "var(--dsw-alias-label-primary)" } }, task.task_id),
|
|
6553
|
+
(0, import_react8.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, task.title),
|
|
6554
|
+
(0, import_react8.createElement)("span", { style: badge }, task.stage),
|
|
6555
|
+
(0, import_react8.createElement)("span", { style: badge }, task.branch),
|
|
6556
|
+
(0, import_react8.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"),
|
|
6557
|
+
(0, import_react8.createElement)("span", { className: "te-badge" }, task.verification_passed ? "\u9A8C\u8BC1\u901A\u8FC7" : "\u5F85\u9A8C\u8BC1"),
|
|
6558
|
+
(0, import_react8.createElement)("span", { className: "te-badge" }, `\u5BA1\u6838\uFF1A${task.review_outcome ?? "pending"}`),
|
|
6559
|
+
task.updated_at ? (0, import_react8.createElement)("span", { style: metaLine }, "\u66F4\u65B0\u4E8E " + timeText(task.updated_at)) : null
|
|
6168
6560
|
),
|
|
6169
|
-
(0,
|
|
6561
|
+
(0, import_react8.createElement)(
|
|
6170
6562
|
"div",
|
|
6171
6563
|
{ style: { display: "flex", flexDirection: "column" } },
|
|
6172
|
-
...task.items.map((item) => (0,
|
|
6564
|
+
...task.items.map((item) => (0, import_react8.createElement)(
|
|
6173
6565
|
"div",
|
|
6174
6566
|
{ key: item.id, style: itemRow },
|
|
6175
|
-
(0,
|
|
6567
|
+
(0, import_react8.createElement)(
|
|
6176
6568
|
"div",
|
|
6177
6569
|
{ style: headerRow },
|
|
6178
6570
|
itemStatusDot(item.status),
|
|
6179
|
-
(0,
|
|
6180
|
-
(0,
|
|
6571
|
+
(0, import_react8.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, item.id),
|
|
6572
|
+
(0, import_react8.createElement)("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, item.title)
|
|
6181
6573
|
),
|
|
6182
6574
|
itemAudit(item)
|
|
6183
6575
|
))
|
|
@@ -6218,7 +6610,7 @@ var tabbar = {
|
|
|
6218
6610
|
var body = {
|
|
6219
6611
|
flex: 1,
|
|
6220
6612
|
overflowY: "auto",
|
|
6221
|
-
padding: "
|
|
6613
|
+
padding: "16px clamp(12px, 2vw, 28px)"
|
|
6222
6614
|
};
|
|
6223
6615
|
var selectStyle = {
|
|
6224
6616
|
marginLeft: "auto",
|
|
@@ -6251,29 +6643,29 @@ var TABS = [
|
|
|
6251
6643
|
function Workbench({ useStore, actions, useWorkspaces, remote }) {
|
|
6252
6644
|
const open = useStore((s) => s.open);
|
|
6253
6645
|
const workspaces = useWorkspaces((s) => s.items);
|
|
6254
|
-
const [tab, setTab] = (0,
|
|
6255
|
-
const [workspace, setWorkspace] = (0,
|
|
6646
|
+
const [tab, setTab] = (0, import_react9.useState)("init");
|
|
6647
|
+
const [workspace, setWorkspace] = (0, import_react9.useState)("");
|
|
6256
6648
|
if (!open) return null;
|
|
6257
6649
|
const current = workspaces.some((w) => w.path === workspace) ? workspace : workspaces[0]?.path ?? "";
|
|
6258
|
-
return (0,
|
|
6650
|
+
return (0, import_react9.createElement)(
|
|
6259
6651
|
"div",
|
|
6260
6652
|
{ style: overlay, className: "te-workbench" },
|
|
6261
|
-
(0,
|
|
6262
|
-
(0,
|
|
6653
|
+
(0, import_react9.createElement)("style", null, workbenchTheme),
|
|
6654
|
+
(0, import_react9.createElement)(
|
|
6263
6655
|
"div",
|
|
6264
6656
|
{ style: header },
|
|
6265
|
-
(0,
|
|
6657
|
+
(0, import_react9.createElement)(
|
|
6266
6658
|
"div",
|
|
6267
6659
|
{ style: headerBrand },
|
|
6268
|
-
(0,
|
|
6269
|
-
(0,
|
|
6660
|
+
(0, import_react9.createElement)(import_dsh_client_ui_primitives7.IconSettingsOutline16, { size: 18 }),
|
|
6661
|
+
(0, import_react9.createElement)(
|
|
6270
6662
|
"div",
|
|
6271
6663
|
{ style: headerText },
|
|
6272
|
-
(0,
|
|
6273
|
-
(0,
|
|
6664
|
+
(0, import_react9.createElement)("span", { style: headerTitle }, "\u5DE5\u7A0B\u6D41\u7A0B"),
|
|
6665
|
+
(0, import_react9.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")
|
|
6274
6666
|
)
|
|
6275
6667
|
),
|
|
6276
|
-
(0,
|
|
6668
|
+
(0, import_react9.createElement)(
|
|
6277
6669
|
"button",
|
|
6278
6670
|
{
|
|
6279
6671
|
type: "button",
|
|
@@ -6289,44 +6681,44 @@ function Workbench({ useStore, actions, useWorkspaces, remote }) {
|
|
|
6289
6681
|
event.currentTarget.style.background = "transparent";
|
|
6290
6682
|
}
|
|
6291
6683
|
},
|
|
6292
|
-
(0,
|
|
6684
|
+
(0, import_react9.createElement)(import_dsh_client_ui_primitives7.IconCloseOutline16, { size: 16 })
|
|
6293
6685
|
)
|
|
6294
6686
|
),
|
|
6295
|
-
(0,
|
|
6687
|
+
(0, import_react9.createElement)(
|
|
6296
6688
|
"div",
|
|
6297
6689
|
{ style: tabbar },
|
|
6298
|
-
...TABS.map((t) => (0,
|
|
6690
|
+
...TABS.map((t) => (0, import_react9.createElement)(import_dsh_client_ui_primitives7.Pill, { key: t.id, active: tab === t.id, onClick: () => {
|
|
6299
6691
|
setTab(t.id);
|
|
6300
6692
|
} }, t.label)),
|
|
6301
|
-
workspaces.length > 0 ? (0,
|
|
6693
|
+
workspaces.length > 0 ? (0, import_react9.createElement)("select", {
|
|
6302
6694
|
style: selectStyle,
|
|
6303
6695
|
"aria-label": "\u5F53\u524D\u5DE5\u4F5C\u533A",
|
|
6304
6696
|
value: current,
|
|
6305
6697
|
onChange: (ev) => {
|
|
6306
6698
|
setWorkspace(ev.target.value);
|
|
6307
6699
|
}
|
|
6308
|
-
}, ...workspaces.map((w) => (0,
|
|
6700
|
+
}, ...workspaces.map((w) => (0, import_react9.createElement)("option", { key: w.path, value: w.path }, w.title || w.path))) : null
|
|
6309
6701
|
),
|
|
6310
|
-
(0,
|
|
6702
|
+
(0, import_react9.createElement)(
|
|
6311
6703
|
"div",
|
|
6312
6704
|
{ style: body },
|
|
6313
|
-
(0,
|
|
6705
|
+
(0, import_react9.createElement)(
|
|
6314
6706
|
"div",
|
|
6315
6707
|
{ className: "te-content", key: current },
|
|
6316
|
-
(0,
|
|
6317
|
-
current === "" ? (0,
|
|
6708
|
+
(0, import_react9.createElement)("p", { style: { ...styles.hint, marginBottom: 10 }, title: current }, "\u5DE5\u4F5C\u533A \xB7 " + current),
|
|
6709
|
+
current === "" ? (0, import_react9.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_react9.createElement)(InitPanel, { workspace: current, remote }) : tab === "flow" ? (0, import_react9.createElement)(TaskEngineSection, { workspace: current, remote }) : tab === "tasks" ? (0, import_react9.createElement)(TaskLedger, { workspace: current, remote }) : tab === "skills" ? (0, import_react9.createElement)(SkillManager, { workspace: current, remote }) : (0, import_react9.createElement)(RuleManager, { workspace: current, remote })
|
|
6318
6710
|
)
|
|
6319
6711
|
)
|
|
6320
6712
|
);
|
|
6321
6713
|
}
|
|
6322
6714
|
|
|
6323
6715
|
// src/client/TriggerButton.tsx
|
|
6324
|
-
var
|
|
6325
|
-
var
|
|
6716
|
+
var import_react10 = require("react");
|
|
6717
|
+
var import_dsh_client_ui_primitives8 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
6326
6718
|
var hover = "var(--dsw-alias-bg-layer-2)";
|
|
6327
6719
|
var label = "var(--dsw-alias-label-primary)";
|
|
6328
6720
|
function TriggerButton({ wide, actions }) {
|
|
6329
|
-
return (0,
|
|
6721
|
+
return (0, import_react10.createElement)(
|
|
6330
6722
|
"button",
|
|
6331
6723
|
{
|
|
6332
6724
|
type: "button",
|
|
@@ -6366,8 +6758,8 @@ function TriggerButton({ wide, actions }) {
|
|
|
6366
6758
|
transition: "background 120ms ease"
|
|
6367
6759
|
}
|
|
6368
6760
|
},
|
|
6369
|
-
(0,
|
|
6370
|
-
wide ? (0,
|
|
6761
|
+
(0, import_react10.createElement)(import_dsh_client_ui_primitives8.IconSettingsOutline16, { size: wide ? 16 : 18 }),
|
|
6762
|
+
wide ? (0, import_react10.createElement)("span", { style: { fontSize: 14, lineHeight: "22px" } }, "\u5DE5\u7A0B\u6D41\u7A0B") : null
|
|
6371
6763
|
);
|
|
6372
6764
|
}
|
|
6373
6765
|
|