@godv61/dsh-task-engine 0.29.1 → 0.29.3
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/.codex-project-test.mjs +18 -2
- package/README.md +4 -13
- package/docs/CHANGELOG.md +10 -0
- package/docs/adaptive-workflows.md +6 -2
- package/docs/faq.md +8 -4
- package/docs/getting-started.md +4 -5
- package/docs/manual.html +6 -10
- package/lib/client.js +674 -1170
- package/lib/client.js.map +3 -3
- package/lib/controller.d.ts +2 -0
- package/lib/controller.js +3 -6
- package/lib/controller.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -4167,7 +4167,8 @@ var writeSkillRequestSchema = external_exports.object({
|
|
|
4167
4167
|
whenToUse: external_exports.string().optional(),
|
|
4168
4168
|
content: external_exports.string(),
|
|
4169
4169
|
level: external_exports.enum(["project", "user"]),
|
|
4170
|
-
path: external_exports.string().optional()
|
|
4170
|
+
path: external_exports.string().optional(),
|
|
4171
|
+
createOnly: external_exports.boolean().optional()
|
|
4171
4172
|
});
|
|
4172
4173
|
var installSkillRequestSchema = external_exports.object({
|
|
4173
4174
|
sourceDir: external_exports.string(),
|
|
@@ -4668,14 +4669,13 @@ var TYPERT_REMOTE = {
|
|
|
4668
4669
|
var remote_default = TYPERT_REMOTE;
|
|
4669
4670
|
|
|
4670
4671
|
// src/client/Workbench.tsx
|
|
4671
|
-
var
|
|
4672
|
-
var
|
|
4672
|
+
var import_react9 = require("react");
|
|
4673
|
+
var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
4673
4674
|
|
|
4674
4675
|
// src/client/icons.ts
|
|
4675
4676
|
var primitives = __toESM(require("@deepseek-ai/dsh-client-ui-primitives"), 1);
|
|
4676
4677
|
var IconSettings = primitives.IconSettingsOutlineRegular ?? primitives.IconSettingsOutline16;
|
|
4677
4678
|
var IconClose = primitives.IconCloseOutlineRegular ?? primitives.IconCloseOutline16;
|
|
4678
|
-
var IconCheck = primitives.IconCheckOutlineRegular ?? primitives.IconCheckOutline16;
|
|
4679
4679
|
|
|
4680
4680
|
// src/client/workbench-theme.ts
|
|
4681
4681
|
var workbenchTheme = `
|
|
@@ -4919,468 +4919,91 @@ var styles = {
|
|
|
4919
4919
|
}
|
|
4920
4920
|
};
|
|
4921
4921
|
|
|
4922
|
-
// src/client/
|
|
4922
|
+
// src/client/AdaptivePanel.tsx
|
|
4923
4923
|
var import_react3 = require("react");
|
|
4924
4924
|
var import_dsh_client_ui_primitives2 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
4925
4925
|
|
|
4926
|
-
// src/
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
}
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
"
|
|
4940
|
-
"
|
|
4941
|
-
"artifacts_present"
|
|
4942
|
-
];
|
|
4943
|
-
function validateWorkflow(config) {
|
|
4944
|
-
const problems = [...config.configuration_errors ?? []];
|
|
4945
|
-
if (config.stages.length === 0) problems.push("stages must not be empty");
|
|
4946
|
-
const seen = /* @__PURE__ */ new Set();
|
|
4947
|
-
for (const stage of config.stages) {
|
|
4948
|
-
if (seen.has(stage)) problems.push(`duplicate stage "${stage}"`);
|
|
4949
|
-
seen.add(stage);
|
|
4950
|
-
}
|
|
4951
|
-
if (!config.stages.includes(config.start_stage)) {
|
|
4952
|
-
problems.push(`start_stage "${config.start_stage}" is not in stages`);
|
|
4953
|
-
}
|
|
4954
|
-
const edges = /* @__PURE__ */ new Set();
|
|
4955
|
-
config.transitions.forEach((transition, index) => {
|
|
4956
|
-
if (!config.stages.includes(transition.from)) {
|
|
4957
|
-
problems.push(`transition ${index + 1}: from "${transition.from}" is not a stage`);
|
|
4958
|
-
}
|
|
4959
|
-
if (!config.stages.includes(transition.to)) {
|
|
4960
|
-
problems.push(`transition ${index + 1}: to "${transition.to}" is not a stage`);
|
|
4961
|
-
}
|
|
4962
|
-
const edge = `${transition.from}->${transition.to}`;
|
|
4963
|
-
if (edges.has(edge)) problems.push(`duplicate transition "${edge}"`);
|
|
4964
|
-
edges.add(edge);
|
|
4965
|
-
for (const guard of transition.requires ?? []) {
|
|
4966
|
-
if (!GUARD_NAMES.includes(guard)) {
|
|
4967
|
-
problems.push(`transition ${index + 1}: unknown guard "${String(guard)}"`);
|
|
4968
|
-
}
|
|
4969
|
-
}
|
|
4970
|
-
});
|
|
4971
|
-
const artifactKeys = /* @__PURE__ */ new Set();
|
|
4972
|
-
config.artifacts.forEach((artifact, index) => {
|
|
4973
|
-
if (!config.stages.includes(artifact.stage)) {
|
|
4974
|
-
problems.push(`artifact ${index + 1}: stage "${artifact.stage}" is not a stage`);
|
|
4975
|
-
}
|
|
4976
|
-
const key = artifact.id;
|
|
4977
|
-
if (artifactKeys.has(key)) problems.push(`duplicate artifact id "${key}" (ids are unique across all stages)`);
|
|
4978
|
-
artifactKeys.add(key);
|
|
4979
|
-
if (artifact.fields.length === 0) {
|
|
4980
|
-
problems.push(`artifact ${index + 1} ("${artifact.id}"): fields must not be empty`);
|
|
4981
|
-
}
|
|
4982
|
-
const fieldSet = /* @__PURE__ */ new Set();
|
|
4983
|
-
for (const field of artifact.fields) {
|
|
4984
|
-
if (fieldSet.has(field)) {
|
|
4985
|
-
problems.push(`artifact ${index + 1} ("${artifact.id}"): duplicate field "${field}"`);
|
|
4986
|
-
}
|
|
4987
|
-
fieldSet.add(field);
|
|
4988
|
-
}
|
|
4989
|
-
});
|
|
4990
|
-
const bindings = config.stage_bindings ?? {};
|
|
4991
|
-
const skillMethods = /* @__PURE__ */ new Map();
|
|
4992
|
-
for (const [stage, binding] of Object.entries(bindings)) {
|
|
4993
|
-
if (!config.stages.includes(stage)) {
|
|
4994
|
-
problems.push(`stage_bindings: stage "${stage}" is not a stage`);
|
|
4995
|
-
}
|
|
4996
|
-
for (const [index, entry] of (binding.skills ?? []).entries()) {
|
|
4997
|
-
if (typeof entry?.skill?.name !== "string" || entry.skill.name.trim() === "") {
|
|
4998
|
-
problems.push(`stage_bindings "${stage}": skill ${index + 1} has no name`);
|
|
4999
|
-
continue;
|
|
5000
|
-
}
|
|
5001
|
-
if (!["bundled", "project", "codex-project", "user"].includes(entry.skill.source)) {
|
|
5002
|
-
problems.push(`stage_bindings "${stage}": skill "${entry.skill.name}" has unknown source "${String(entry.skill.source)}"`);
|
|
5003
|
-
}
|
|
5004
|
-
const skillKey = formatResourceRef(entry.skill);
|
|
5005
|
-
const method = JSON.stringify({ rules: entry.rules ?? [], evidence: entry.evidence });
|
|
5006
|
-
const existing = skillMethods.get(skillKey);
|
|
5007
|
-
if (existing !== void 0 && existing !== method) {
|
|
5008
|
-
problems.push(`skill "${skillKey}" has different rules or evidence in multiple stages; copy it as a distinct skill`);
|
|
5009
|
-
}
|
|
5010
|
-
skillMethods.set(skillKey, method);
|
|
5011
|
-
if (entry.evidence === "artifact" && !config.artifacts.some((artifact) => artifact.stage === stage)) {
|
|
5012
|
-
problems.push(`skill "${skillKey}" requires artifact evidence, but stage "${stage}" declares no artifact`);
|
|
5013
|
-
}
|
|
5014
|
-
if (entry.evidence !== void 0 && !["command", "artifact", "review", "manual", "none"].includes(entry.evidence)) {
|
|
5015
|
-
problems.push(`skill "${skillKey}" has unknown evidence type "${String(entry.evidence)}"`);
|
|
5016
|
-
}
|
|
5017
|
-
for (const rule of entry.rules ?? []) {
|
|
5018
|
-
if (typeof rule?.name !== "string" || rule.name.trim() === "") {
|
|
5019
|
-
problems.push(`stage_bindings "${stage}": skill "${entry.skill.name}" has a rule with no name`);
|
|
5020
|
-
continue;
|
|
5021
|
-
}
|
|
5022
|
-
if (!["bundled", "project", "user"].includes(rule.source)) {
|
|
5023
|
-
problems.push(`stage_bindings "${stage}": skill "${entry.skill.name}" rule "${rule.name}" has unknown source "${String(rule.source)}"`);
|
|
5024
|
-
}
|
|
5025
|
-
}
|
|
5026
|
-
}
|
|
5027
|
-
if ((binding.legacy_rules ?? []).length > 0) {
|
|
5028
|
-
problems.push(`stage_bindings "${stage}": ${binding.legacy_rules.length} legacy stage-level rule(s) are unassigned and still in force; assign each to the skill that should carry it`);
|
|
5029
|
-
}
|
|
5030
|
-
}
|
|
5031
|
-
if (!["task", "item", "manual"].includes(config.commit.policy)) {
|
|
5032
|
-
problems.push(`commit.policy "${config.commit.policy}" is not task|item|manual`);
|
|
5033
|
-
}
|
|
5034
|
-
for (const checkpoint of config.commit.checkpoints) {
|
|
5035
|
-
if (!config.stages.includes(checkpoint)) {
|
|
5036
|
-
problems.push(`commit.checkpoint "${checkpoint}" is not a stage`);
|
|
5037
|
-
}
|
|
5038
|
-
}
|
|
5039
|
-
if (config.commit.message_pattern !== "") {
|
|
5040
|
-
try {
|
|
5041
|
-
new RegExp(config.commit.message_pattern);
|
|
5042
|
-
} catch {
|
|
5043
|
-
problems.push("commit.message_pattern is not a valid regular expression");
|
|
5044
|
-
}
|
|
5045
|
-
}
|
|
5046
|
-
if (config.review_depth !== void 0 && config.review_depth !== "two-stage" && config.review_depth !== "single") {
|
|
5047
|
-
problems.push(`review_depth "${String(config.review_depth)}" is not one of: two-stage, single`);
|
|
5048
|
-
}
|
|
5049
|
-
return problems;
|
|
4926
|
+
// src/adaptive.ts
|
|
4927
|
+
var META_STAGES = {
|
|
4928
|
+
"requirements-analysis": "\u9700\u6C42\u5206\u6790",
|
|
4929
|
+
"architecture-design": "\u67B6\u6784\u8BBE\u8BA1",
|
|
4930
|
+
"task-orchestration": "\u4EFB\u52A1\u7F16\u6392",
|
|
4931
|
+
"code-development": "\u4EE3\u7801\u5F00\u53D1",
|
|
4932
|
+
"test-validation": "\u6D4B\u8BD5",
|
|
4933
|
+
"code-review": "\u4EE3\u7801\u5BA1\u6838"
|
|
4934
|
+
};
|
|
4935
|
+
|
|
4936
|
+
// src/client/shared.ts
|
|
4937
|
+
function describeError(error) {
|
|
4938
|
+
if (error instanceof Error) return error.message;
|
|
4939
|
+
if (typeof error === "string") return error;
|
|
4940
|
+
return "\u672A\u77E5\u9519\u8BEF";
|
|
5050
4941
|
}
|
|
5051
4942
|
|
|
5052
|
-
// src/
|
|
5053
|
-
var
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
var
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
],
|
|
5068
|
-
// No artifacts, no commit policy, no skills: the skeleton carries none of them.
|
|
5069
|
-
artifacts: [],
|
|
5070
|
-
commit: { policy: "task", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EE3\u7801\u5BA1\u6838"], file_scope: true },
|
|
5071
|
-
high_risk_requires_verification: true
|
|
4943
|
+
// src/client/SkillRuleDialog.tsx
|
|
4944
|
+
var import_react2 = require("react");
|
|
4945
|
+
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
4946
|
+
|
|
4947
|
+
// src/client/ResourceModal.tsx
|
|
4948
|
+
var import_react = require("react");
|
|
4949
|
+
var import_react_dom = require("react-dom");
|
|
4950
|
+
var rootStyle = {
|
|
4951
|
+
position: "fixed",
|
|
4952
|
+
inset: 0,
|
|
4953
|
+
zIndex: 1e3,
|
|
4954
|
+
display: "flex",
|
|
4955
|
+
alignItems: "center",
|
|
4956
|
+
justifyContent: "center",
|
|
4957
|
+
padding: 24
|
|
5072
4958
|
};
|
|
5073
|
-
var
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
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"
|
|
5079
|
-
},
|
|
5080
|
-
artifacts: [
|
|
5081
|
-
{ stage: "\u9700\u6C42\u8BC4\u5BA1", id: "requirement", name: "\u9700\u6C42\u8BF4\u660E", fields: ["scope", "acceptance_criteria"] },
|
|
5082
|
-
{ stage: "\u8BBE\u8BA1", id: "design", name: "\u8BBE\u8BA1\u6587\u6863", fields: ["approach", "risks", "impact"] },
|
|
5083
|
-
{ stage: "\u4EE3\u7801\u5BA1\u6838", id: "review", name: "\u8BC4\u5BA1\u8BB0\u5F55", fields: ["conclusion", "issues"] }
|
|
5084
|
-
]
|
|
4959
|
+
var maskStyle = {
|
|
4960
|
+
position: "absolute",
|
|
4961
|
+
inset: 0,
|
|
4962
|
+
background: "var(--dsw-alias-bg-mask-1)",
|
|
4963
|
+
backdropFilter: "var(--dsw-mask-blur)"
|
|
5085
4964
|
};
|
|
5086
|
-
var
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
{ from: "\u4EA4\u4ED8", to: "\u5BA1\u67E5", requires: [] }
|
|
5098
|
-
],
|
|
5099
|
-
artifacts: [],
|
|
5100
|
-
commit: { policy: "item", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EA4\u4ED8"], file_scope: true },
|
|
5101
|
-
high_risk_requires_verification: false,
|
|
5102
|
-
// 审查 is terminal and IS the review, so there is no outgoing edge to carry
|
|
5103
|
-
// the guard. Declaring it here is what makes a blocked review prevent
|
|
5104
|
-
// completion; without it the stage could be reached and finished with the
|
|
5105
|
-
// review failing, which is what the assessment found.
|
|
5106
|
-
completion_guards: ["review_passed"]
|
|
4965
|
+
var dialogStyle = {
|
|
4966
|
+
position: "relative",
|
|
4967
|
+
zIndex: 1,
|
|
4968
|
+
display: "flex",
|
|
4969
|
+
flexDirection: "column",
|
|
4970
|
+
width: "min(760px, 100%)",
|
|
4971
|
+
maxHeight: "85vh",
|
|
4972
|
+
borderRadius: 24,
|
|
4973
|
+
background: "var(--dsw-alias-bg-layer-2)",
|
|
4974
|
+
boxShadow: "var(--dsw-elevation-prominent)",
|
|
4975
|
+
overflow: "hidden"
|
|
5107
4976
|
};
|
|
5108
|
-
var
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
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"
|
|
5115
|
-
},
|
|
5116
|
-
artifacts: [
|
|
5117
|
-
{ stage: "\u9700\u6C42", id: "requirement", name: "\u9700\u6C42\u8BF4\u660E", fields: ["scope"] },
|
|
5118
|
-
// Optional review record; the flow's review gate itself does not require a skill.
|
|
5119
|
-
{ stage: "\u5BA1\u67E5", id: "review", name: "\u8BC4\u5BA1\u8BB0\u5F55", fields: ["conclusion", "issues"] }
|
|
5120
|
-
]
|
|
4977
|
+
var drawerStyle = {
|
|
4978
|
+
...dialogStyle,
|
|
4979
|
+
width: "min(560px, 100%)",
|
|
4980
|
+
height: "100%",
|
|
4981
|
+
maxHeight: "100%",
|
|
4982
|
+
borderRadius: "16px 0 0 16px"
|
|
5121
4983
|
};
|
|
5122
|
-
var
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
high_risk_requires_verification: false
|
|
4984
|
+
var inlineStyle = {
|
|
4985
|
+
...dialogStyle,
|
|
4986
|
+
width: "100%",
|
|
4987
|
+
height: "min(720px, calc(100vh - 32px))",
|
|
4988
|
+
maxHeight: "calc(100vh - 32px)",
|
|
4989
|
+
borderRadius: 12,
|
|
4990
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
4991
|
+
boxShadow: "none"
|
|
5131
4992
|
};
|
|
5132
|
-
var
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
4993
|
+
var headerStyle = {
|
|
4994
|
+
display: "flex",
|
|
4995
|
+
alignItems: "center",
|
|
4996
|
+
justifyContent: "space-between",
|
|
4997
|
+
gap: 8,
|
|
4998
|
+
padding: "18px 18px 10px 24px",
|
|
4999
|
+
flex: "none"
|
|
5137
5000
|
};
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
if (config.commit.file_scope) caps.push("file_scope");
|
|
5145
|
-
return caps;
|
|
5146
|
-
}
|
|
5147
|
-
function preset(id, version, label3, description, config, recommendation) {
|
|
5148
|
-
return {
|
|
5149
|
-
id,
|
|
5150
|
-
version,
|
|
5151
|
-
label: label3,
|
|
5152
|
-
description,
|
|
5153
|
-
capabilities: deriveCapabilities(config),
|
|
5154
|
-
config,
|
|
5155
|
-
// exactOptionalPropertyTypes: omit rather than assign undefined.
|
|
5156
|
-
...recommendation !== void 0 ? { recommendation } : {}
|
|
5157
|
-
};
|
|
5158
|
-
}
|
|
5159
|
-
var FLOW_PRESETS = {
|
|
5160
|
-
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),
|
|
5161
|
-
// Version 4 for agile: 交付 → 审查 now requires review_passed, where it previously
|
|
5162
|
-
// required nothing. That is a gate-semantics change, so a task created before it
|
|
5163
|
-
// keeps its frozen version 3 config and behaves exactly as it did.
|
|
5164
|
-
//
|
|
5165
|
-
// Version 3 across all three: the preset is now a bare skeleton and its former
|
|
5166
|
-
// built-in bindings, commit rule and artifacts are a separate recommendation a
|
|
5167
|
-
// user adopts explicitly. Tasks created before this keep their frozen config and
|
|
5168
|
-
// are unaffected; a project's existing config is likewise left exactly as it is.
|
|
5169
|
-
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),
|
|
5170
|
-
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)
|
|
5171
|
-
};
|
|
5172
|
-
function retainStageBindings(flow, bindings) {
|
|
5173
|
-
const stages = new Set(FLOW_PRESETS[flow]?.config.stages ?? []);
|
|
5174
|
-
const kept = {};
|
|
5175
|
-
const dropped = [];
|
|
5176
|
-
for (const [stage, binding] of Object.entries(bindings)) {
|
|
5177
|
-
if (stages.has(stage)) kept[stage] = binding;
|
|
5178
|
-
else dropped.push(stage);
|
|
5179
|
-
}
|
|
5180
|
-
return { bindings: kept, dropped };
|
|
5181
|
-
}
|
|
5182
|
-
function dedupe(names) {
|
|
5183
|
-
return [...new Set(names)];
|
|
5184
|
-
}
|
|
5185
|
-
function applyProjectConfig(base, project) {
|
|
5186
|
-
if (project === void 0) return base;
|
|
5187
|
-
const next = { ...base };
|
|
5188
|
-
if (project.stage_bindings !== void 0) {
|
|
5189
|
-
const profiles = { ...project.skill_profiles ?? {} };
|
|
5190
|
-
const explicitProfiles = new Set(Object.keys(project.skill_profiles ?? {}));
|
|
5191
|
-
const problems = [];
|
|
5192
|
-
const bindings = {};
|
|
5193
|
-
for (const [stage, binding] of Object.entries(project.stage_bindings)) {
|
|
5194
|
-
const entry = {};
|
|
5195
|
-
if (binding === null || typeof binding !== "object") {
|
|
5196
|
-
problems.push(`stage_bindings "${stage}" must be an object`);
|
|
5197
|
-
bindings[stage] = entry;
|
|
5198
|
-
continue;
|
|
5199
|
-
}
|
|
5200
|
-
if (binding.skill_refs !== void 0 && binding.skills !== void 0) {
|
|
5201
|
-
problems.push(`stage_bindings "${stage}" has both skill_refs and legacy skills`);
|
|
5202
|
-
}
|
|
5203
|
-
if (binding.skill_refs !== void 0) {
|
|
5204
|
-
if (!Array.isArray(binding.skill_refs)) {
|
|
5205
|
-
problems.push(`stage_bindings "${stage}" skill_refs must be an array`);
|
|
5206
|
-
}
|
|
5207
|
-
entry.skills = (Array.isArray(binding.skill_refs) ? binding.skill_refs : []).flatMap((ref) => {
|
|
5208
|
-
if (ref === null || typeof ref !== "object") {
|
|
5209
|
-
problems.push(`stage_bindings "${stage}" has an invalid skill reference`);
|
|
5210
|
-
return [];
|
|
5211
|
-
}
|
|
5212
|
-
const key = formatResourceRef(ref);
|
|
5213
|
-
const profile = profiles[key];
|
|
5214
|
-
if (profile === void 0) {
|
|
5215
|
-
problems.push(`skill profile "${key}" is missing`);
|
|
5216
|
-
return [];
|
|
5217
|
-
}
|
|
5218
|
-
if (profile === null || !Array.isArray(profile.rules)) {
|
|
5219
|
-
problems.push(`skill profile "${key}" must declare a rules array`);
|
|
5220
|
-
return [];
|
|
5221
|
-
}
|
|
5222
|
-
return [{ skill: ref, rules: profile.rules, ...profile.evidence !== void 0 ? { evidence: profile.evidence } : {} }];
|
|
5223
|
-
});
|
|
5224
|
-
} else if (binding.skills !== void 0) {
|
|
5225
|
-
if (!Array.isArray(binding.skills)) {
|
|
5226
|
-
problems.push(`stage_bindings "${stage}" skills must be an array`);
|
|
5227
|
-
}
|
|
5228
|
-
entry.skills = (Array.isArray(binding.skills) ? binding.skills : []).flatMap((skill) => {
|
|
5229
|
-
if (skill === null || typeof skill !== "object" || skill.skill === null || typeof skill.skill !== "object") {
|
|
5230
|
-
problems.push(`stage_bindings "${stage}" has an invalid skill binding`);
|
|
5231
|
-
return [];
|
|
5232
|
-
}
|
|
5233
|
-
const key = formatResourceRef(skill.skill);
|
|
5234
|
-
if (explicitProfiles.has(key)) {
|
|
5235
|
-
const profile = profiles[key];
|
|
5236
|
-
if (profile === null || !Array.isArray(profile?.rules)) {
|
|
5237
|
-
problems.push(`skill profile "${key}" must declare a rules array`);
|
|
5238
|
-
return [];
|
|
5239
|
-
}
|
|
5240
|
-
return [{
|
|
5241
|
-
skill: skill.skill,
|
|
5242
|
-
rules: profile.rules,
|
|
5243
|
-
...profile.evidence !== void 0 ? { evidence: profile.evidence } : {}
|
|
5244
|
-
}];
|
|
5245
|
-
}
|
|
5246
|
-
const candidate = { rules: skill.rules ?? [], ...skill.evidence !== void 0 ? { evidence: skill.evidence } : {} };
|
|
5247
|
-
const existing = profiles[key];
|
|
5248
|
-
if (existing !== void 0 && JSON.stringify(existing) !== JSON.stringify(candidate)) {
|
|
5249
|
-
problems.push(`skill "${key}" has different rules or evidence in multiple stages; copy it as a distinct skill`);
|
|
5250
|
-
} else profiles[key] = candidate;
|
|
5251
|
-
return [skill];
|
|
5252
|
-
});
|
|
5253
|
-
}
|
|
5254
|
-
const legacy = dedupe(binding.legacy_rules ?? []);
|
|
5255
|
-
if (legacy.length > 0) entry.legacy_rules = legacy;
|
|
5256
|
-
bindings[stage] = entry;
|
|
5257
|
-
}
|
|
5258
|
-
next.stage_bindings = bindings;
|
|
5259
|
-
next.skill_profiles = profiles;
|
|
5260
|
-
if (problems.length > 0) next.configuration_errors = problems;
|
|
5261
|
-
} else if (project.skill_profiles !== void 0) {
|
|
5262
|
-
next.skill_profiles = project.skill_profiles;
|
|
5263
|
-
}
|
|
5264
|
-
if (project.commit !== void 0) next.commit = project.commit;
|
|
5265
|
-
if (project.artifacts !== void 0) next.artifacts = project.artifacts;
|
|
5266
|
-
if (project.review_depth !== void 0) next.review_depth = project.review_depth;
|
|
5267
|
-
if (project.commit_required !== void 0) next.commit_required = project.commit_required;
|
|
5268
|
-
return next;
|
|
5269
|
-
}
|
|
5270
|
-
function adoptRecommendation(presetId, current) {
|
|
5271
|
-
const preset2 = FLOW_PRESETS[presetId];
|
|
5272
|
-
if (preset2 === void 0) return void 0;
|
|
5273
|
-
const rec = preset2.recommendation;
|
|
5274
|
-
if (rec === void 0) return { flow: presetId, ...current };
|
|
5275
|
-
const commit = {
|
|
5276
|
-
...preset2.config.commit,
|
|
5277
|
-
...rec.commit ?? {},
|
|
5278
|
-
...current?.commit ?? {}
|
|
5279
|
-
};
|
|
5280
|
-
const config = {
|
|
5281
|
-
flow: presetId,
|
|
5282
|
-
stage_bindings: current?.stage_bindings ?? rec.stage_bindings ?? {},
|
|
5283
|
-
...current?.skill_profiles !== void 0 ? { skill_profiles: current.skill_profiles } : {},
|
|
5284
|
-
commit,
|
|
5285
|
-
artifacts: current?.artifacts ?? rec.artifacts ?? preset2.config.artifacts,
|
|
5286
|
-
...current?.review_depth !== void 0 ? { review_depth: current.review_depth } : rec.review_depth !== void 0 ? { review_depth: rec.review_depth } : {},
|
|
5287
|
-
...current?.commit_required !== void 0 ? { commit_required: current.commit_required } : {}
|
|
5288
|
-
};
|
|
5289
|
-
return config;
|
|
5290
|
-
}
|
|
5291
|
-
function compactProjectConfig(project) {
|
|
5292
|
-
const resolved = resolveFlow(project.flow, project);
|
|
5293
|
-
if (!resolved.ok) return project;
|
|
5294
|
-
const profiles = resolved.config.skill_profiles ?? {};
|
|
5295
|
-
const bindings = {};
|
|
5296
|
-
for (const [stage, binding] of Object.entries(resolved.config.stage_bindings ?? {})) {
|
|
5297
|
-
bindings[stage] = {
|
|
5298
|
-
skill_refs: (binding.skills ?? []).map((entry) => entry.skill),
|
|
5299
|
-
...binding.legacy_rules?.length ? { legacy_rules: binding.legacy_rules } : {}
|
|
5300
|
-
};
|
|
5301
|
-
}
|
|
5302
|
-
return { ...project, stage_bindings: bindings, skill_profiles: profiles };
|
|
5303
|
-
}
|
|
5304
|
-
function resolveFlow(flow, project) {
|
|
5305
|
-
const preset2 = FLOW_PRESETS[flow];
|
|
5306
|
-
if (preset2 === void 0) {
|
|
5307
|
-
return { ok: false, code: "UNKNOWN_FLOW", flow, knownFlows: Object.keys(FLOW_PRESETS) };
|
|
5308
|
-
}
|
|
5309
|
-
const { flow: _ignored, ...rest } = project ?? { flow };
|
|
5310
|
-
return { ok: true, config: applyProjectConfig(preset2.config, { flow, ...rest }), preset: preset2 };
|
|
5311
|
-
}
|
|
5312
|
-
|
|
5313
|
-
// src/client/shared.ts
|
|
5314
|
-
function describeError(error) {
|
|
5315
|
-
if (error instanceof Error) return error.message;
|
|
5316
|
-
if (typeof error === "string") return error;
|
|
5317
|
-
return "\u672A\u77E5\u9519\u8BEF";
|
|
5318
|
-
}
|
|
5319
|
-
|
|
5320
|
-
// src/client/SkillRuleDialog.tsx
|
|
5321
|
-
var import_react2 = require("react");
|
|
5322
|
-
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
5323
|
-
|
|
5324
|
-
// src/client/ResourceModal.tsx
|
|
5325
|
-
var import_react = require("react");
|
|
5326
|
-
var import_react_dom = require("react-dom");
|
|
5327
|
-
var rootStyle = {
|
|
5328
|
-
position: "fixed",
|
|
5329
|
-
inset: 0,
|
|
5330
|
-
zIndex: 1e3,
|
|
5331
|
-
display: "flex",
|
|
5332
|
-
alignItems: "center",
|
|
5333
|
-
justifyContent: "center",
|
|
5334
|
-
padding: 24
|
|
5335
|
-
};
|
|
5336
|
-
var maskStyle = {
|
|
5337
|
-
position: "absolute",
|
|
5338
|
-
inset: 0,
|
|
5339
|
-
background: "var(--dsw-alias-bg-mask-1)",
|
|
5340
|
-
backdropFilter: "var(--dsw-mask-blur)"
|
|
5341
|
-
};
|
|
5342
|
-
var dialogStyle = {
|
|
5343
|
-
position: "relative",
|
|
5344
|
-
zIndex: 1,
|
|
5345
|
-
display: "flex",
|
|
5346
|
-
flexDirection: "column",
|
|
5347
|
-
width: "min(760px, 100%)",
|
|
5348
|
-
maxHeight: "85vh",
|
|
5349
|
-
borderRadius: 24,
|
|
5350
|
-
background: "var(--dsw-alias-bg-layer-2)",
|
|
5351
|
-
boxShadow: "var(--dsw-elevation-prominent)",
|
|
5352
|
-
overflow: "hidden"
|
|
5353
|
-
};
|
|
5354
|
-
var drawerStyle = {
|
|
5355
|
-
...dialogStyle,
|
|
5356
|
-
width: "min(560px, 100%)",
|
|
5357
|
-
height: "100%",
|
|
5358
|
-
maxHeight: "100%",
|
|
5359
|
-
borderRadius: "16px 0 0 16px"
|
|
5360
|
-
};
|
|
5361
|
-
var inlineStyle = {
|
|
5362
|
-
...dialogStyle,
|
|
5363
|
-
width: "100%",
|
|
5364
|
-
height: "min(720px, calc(100vh - 32px))",
|
|
5365
|
-
maxHeight: "calc(100vh - 32px)",
|
|
5366
|
-
borderRadius: 12,
|
|
5367
|
-
border: "1px solid var(--dsw-alias-border-l2)",
|
|
5368
|
-
boxShadow: "none"
|
|
5369
|
-
};
|
|
5370
|
-
var headerStyle = {
|
|
5371
|
-
display: "flex",
|
|
5372
|
-
alignItems: "center",
|
|
5373
|
-
justifyContent: "space-between",
|
|
5374
|
-
gap: 8,
|
|
5375
|
-
padding: "18px 18px 10px 24px",
|
|
5376
|
-
flex: "none"
|
|
5377
|
-
};
|
|
5378
|
-
var titleStyle = {
|
|
5379
|
-
margin: 0,
|
|
5380
|
-
fontSize: 16,
|
|
5381
|
-
lineHeight: "24px",
|
|
5382
|
-
fontWeight: 500,
|
|
5383
|
-
color: "var(--dsw-alias-label-primary)"
|
|
5001
|
+
var titleStyle = {
|
|
5002
|
+
margin: 0,
|
|
5003
|
+
fontSize: 16,
|
|
5004
|
+
lineHeight: "24px",
|
|
5005
|
+
fontWeight: 500,
|
|
5006
|
+
color: "var(--dsw-alias-label-primary)"
|
|
5384
5007
|
};
|
|
5385
5008
|
var closeBtnStyle = {
|
|
5386
5009
|
flex: "none",
|
|
@@ -5494,6 +5117,11 @@ function ResourceModal({ title, description, onClose, footer, children, placemen
|
|
|
5494
5117
|
);
|
|
5495
5118
|
}
|
|
5496
5119
|
|
|
5120
|
+
// src/engine.ts
|
|
5121
|
+
function formatResourceRef(ref) {
|
|
5122
|
+
return `${ref.source}:${ref.name}`;
|
|
5123
|
+
}
|
|
5124
|
+
|
|
5497
5125
|
// src/client/SkillRuleDialog.tsx
|
|
5498
5126
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
5499
5127
|
function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave, onClose }) {
|
|
@@ -5514,7 +5142,7 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
|
|
|
5514
5142
|
setDirty(true);
|
|
5515
5143
|
setError("");
|
|
5516
5144
|
};
|
|
5517
|
-
const
|
|
5145
|
+
const save = async () => {
|
|
5518
5146
|
if (busy || !dirty) return;
|
|
5519
5147
|
setBusy(true);
|
|
5520
5148
|
setError("");
|
|
@@ -5544,7 +5172,7 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
|
|
|
5544
5172
|
error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { role: "alert", className: "te-dialog-error", children: error }) : null,
|
|
5545
5173
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "ghost", disabled: busy, onClick: close, children: "\u53D6\u6D88" }),
|
|
5546
5174
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", disabled: busy || !dirty, onClick: () => {
|
|
5547
|
-
void
|
|
5175
|
+
void save();
|
|
5548
5176
|
}, children: busy ? "\u5904\u7406\u4E2D\u2026" : saveLabel ?? "\u4FDD\u5B58\u914D\u7F6E" })
|
|
5549
5177
|
] }),
|
|
5550
5178
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "te-skill-config", children: [
|
|
@@ -5596,447 +5224,6 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
|
|
|
5596
5224
|
);
|
|
5597
5225
|
}
|
|
5598
5226
|
|
|
5599
|
-
// src/client/TaskEngineSection.tsx
|
|
5600
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
5601
|
-
function refFromText(text2) {
|
|
5602
|
-
return parseResourceRef(text2) ?? { source: "bundled", name: text2 };
|
|
5603
|
-
}
|
|
5604
|
-
function resolvedConfig(flow, stageBindings, skillProfiles) {
|
|
5605
|
-
const resolved = resolveFlow(flow, { flow, stage_bindings: stageBindings, skill_profiles: skillProfiles });
|
|
5606
|
-
return resolved.ok ? resolved.config : FLOW_PRESETS.standard.config;
|
|
5607
|
-
}
|
|
5608
|
-
function TaskEngineSection(props) {
|
|
5609
|
-
const { remote, workspace } = props;
|
|
5610
|
-
const [flow, setFlow] = (0, import_react3.useState)("standard");
|
|
5611
|
-
const [stageBindings, setStageBindings] = (0, import_react3.useState)({});
|
|
5612
|
-
const [skillProfiles, setSkillProfiles] = (0, import_react3.useState)({});
|
|
5613
|
-
const [commitRule, setCommitRule] = (0, import_react3.useState)(void 0);
|
|
5614
|
-
const [artifacts, setArtifacts] = (0, import_react3.useState)(void 0);
|
|
5615
|
-
const [reviewDepth, setReviewDepth] = (0, import_react3.useState)(void 0);
|
|
5616
|
-
const [commitRequired, setCommitRequired] = (0, import_react3.useState)(void 0);
|
|
5617
|
-
const [source, setSource] = (0, import_react3.useState)("default");
|
|
5618
|
-
const [savedAt, setSavedAt] = (0, import_react3.useState)("");
|
|
5619
|
-
const [dirty, setDirty] = (0, import_react3.useState)(false);
|
|
5620
|
-
const [loadError, setLoadError] = (0, import_react3.useState)("");
|
|
5621
|
-
const [saving, setSaving] = (0, import_react3.useState)(false);
|
|
5622
|
-
const [loading, setLoading] = (0, import_react3.useState)(true);
|
|
5623
|
-
const [loadAttempt, setLoadAttempt] = (0, import_react3.useState)(0);
|
|
5624
|
-
const [configProblems, setConfigProblems] = (0, import_react3.useState)([]);
|
|
5625
|
-
const [flowNotice, setFlowNotice] = (0, import_react3.useState)("");
|
|
5626
|
-
const [pendingAdoption, setPendingAdoption] = (0, import_react3.useState)(false);
|
|
5627
|
-
const [skills, setSkills] = (0, import_react3.useState)([]);
|
|
5628
|
-
const [rules, setRules] = (0, import_react3.useState)([]);
|
|
5629
|
-
const [configuringSkill, setConfiguringSkill] = (0, import_react3.useState)(null);
|
|
5630
|
-
(0, import_react3.useEffect)(() => {
|
|
5631
|
-
if (workspace === "") return;
|
|
5632
|
-
let alive = true;
|
|
5633
|
-
setLoadError("");
|
|
5634
|
-
setLoading(true);
|
|
5635
|
-
void remote.read(workspace).then((result) => {
|
|
5636
|
-
if (!alive) return;
|
|
5637
|
-
setLoading(false);
|
|
5638
|
-
if (result.ok) {
|
|
5639
|
-
setFlow(result.value.flow);
|
|
5640
|
-
setStageBindings(result.value.config.stage_bindings ?? {});
|
|
5641
|
-
setSkillProfiles(result.value.config.skill_profiles ?? {});
|
|
5642
|
-
setCommitRule(result.value.config.commit);
|
|
5643
|
-
setArtifacts(result.value.config.artifacts);
|
|
5644
|
-
setReviewDepth(result.value.config.review_depth);
|
|
5645
|
-
setCommitRequired(result.value.config.commit_required);
|
|
5646
|
-
setSource(result.value.source);
|
|
5647
|
-
setConfigProblems(result.value.problems);
|
|
5648
|
-
setFlowNotice("");
|
|
5649
|
-
setPendingAdoption(false);
|
|
5650
|
-
setSavedAt("");
|
|
5651
|
-
} else {
|
|
5652
|
-
setLoadError("\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
5653
|
-
}
|
|
5654
|
-
}, (error) => {
|
|
5655
|
-
if (alive) {
|
|
5656
|
-
setLoading(false);
|
|
5657
|
-
setLoadError("\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25\uFF1A" + describeError(error));
|
|
5658
|
-
}
|
|
5659
|
-
});
|
|
5660
|
-
return () => {
|
|
5661
|
-
alive = false;
|
|
5662
|
-
};
|
|
5663
|
-
}, [remote, workspace, loadAttempt]);
|
|
5664
|
-
const refreshCatalogs = (0, import_react3.useCallback)(() => {
|
|
5665
|
-
if (workspace === "") return;
|
|
5666
|
-
void remote.listSkills(workspace).then((result) => {
|
|
5667
|
-
if (result.ok) setSkills(result.value.skills);
|
|
5668
|
-
}, () => {
|
|
5669
|
-
});
|
|
5670
|
-
void remote.listRules(workspace).then((result) => {
|
|
5671
|
-
if (result.ok) setRules(result.value.rules);
|
|
5672
|
-
}, () => {
|
|
5673
|
-
});
|
|
5674
|
-
}, [remote, workspace]);
|
|
5675
|
-
(0, import_react3.useEffect)(() => {
|
|
5676
|
-
refreshCatalogs();
|
|
5677
|
-
}, [refreshCatalogs]);
|
|
5678
|
-
const stages = (0, import_react3.useMemo)(() => (FLOW_PRESETS[flow] ?? FLOW_PRESETS.standard).config.stages, [flow]);
|
|
5679
|
-
const problems = (0, import_react3.useMemo)(
|
|
5680
|
-
() => validateWorkflow(resolvedConfig(flow, stageBindings, skillProfiles)),
|
|
5681
|
-
[flow, stageBindings, skillProfiles]
|
|
5682
|
-
);
|
|
5683
|
-
const hasBundledReferences = (0, import_react3.useMemo)(
|
|
5684
|
-
() => Object.values(stageBindings).some((binding) => (binding.skills ?? []).some((entry) => entry.skill.source === "bundled" || entry.skill.source !== "user" && entry.rules.some((rule) => rule.source === "bundled")) || (binding.skill_refs ?? []).some((ref) => ref.source === "bundled")) || Object.entries(skillProfiles).some(([key, profile]) => key.startsWith("bundled:") || !key.startsWith("user:") && profile.rules.some((rule) => rule.source === "bundled")),
|
|
5685
|
-
[stageBindings, skillProfiles]
|
|
5686
|
-
);
|
|
5687
|
-
const selectFlow = (id) => {
|
|
5688
|
-
if (id === flow) return;
|
|
5689
|
-
const { bindings, dropped } = retainStageBindings(id, stageBindings);
|
|
5690
|
-
if (dirty && dropped.length > 0 && !window.confirm(`\u5207\u6362\u540E\u5C06\u79FB\u9664\u4E0D\u5C5E\u4E8E\u65B0\u6D41\u7A0B\u7684\u8282\u70B9\u7ED1\u5B9A\uFF1A${dropped.join("\u3001")}\u3002\u7EE7\u7EED\uFF1F`)) return;
|
|
5691
|
-
setStageBindings(bindings);
|
|
5692
|
-
setFlowNotice(dropped.length > 0 ? `\u5DF2\u79FB\u9664\u4E0D\u5C5E\u4E8E\u300C${FLOW_PRESETS[id]?.label ?? id}\u300D\u7684\u8282\u70B9\u7ED1\u5B9A\uFF1A${dropped.join("\u3001")}\u3002\u4FDD\u5B58\u540E\u624D\u4F1A\u5199\u5165\u9879\u76EE\u914D\u7F6E\u3002` : "");
|
|
5693
|
-
setFlow(id);
|
|
5694
|
-
setPendingAdoption(false);
|
|
5695
|
-
setDirty(true);
|
|
5696
|
-
setSavedAt("");
|
|
5697
|
-
};
|
|
5698
|
-
const adopt = () => {
|
|
5699
|
-
const adopted = adoptRecommendation(flow, {
|
|
5700
|
-
flow,
|
|
5701
|
-
stage_bindings: stageBindings,
|
|
5702
|
-
skill_profiles: skillProfiles,
|
|
5703
|
-
...commitRequired !== void 0 ? { commit_required: commitRequired } : {}
|
|
5704
|
-
});
|
|
5705
|
-
if (adopted === void 0) return;
|
|
5706
|
-
if (dirty && !window.confirm("\u91C7\u7528\u63A8\u8350\u7684\u63D0\u4EA4\u6587\u672C\u3001\u4EA7\u7269\u5B57\u6BB5\u548C\u8BC4\u5BA1\u6DF1\u5EA6\uFF1F\u73B0\u6709\u6280\u80FD\u4E0E\u89C4\u5219\u4F1A\u4FDD\u7559\u3002")) return;
|
|
5707
|
-
setFlowNotice("");
|
|
5708
|
-
setCommitRule(adopted.commit);
|
|
5709
|
-
setArtifacts(adopted.artifacts);
|
|
5710
|
-
setReviewDepth(adopted.review_depth);
|
|
5711
|
-
setDirty(true);
|
|
5712
|
-
setSavedAt("");
|
|
5713
|
-
};
|
|
5714
|
-
const updateSkillProfile = async (profile) => {
|
|
5715
|
-
if (!configuringSkill) return;
|
|
5716
|
-
if (configuringSkill.source === "user") {
|
|
5717
|
-
const result = await remote.writeUserSkillProfile({ name: configuringSkill.name, profile });
|
|
5718
|
-
if (!result.ok || !result.value.ok) throw new Error(result.ok ? result.value.error : "\u4FDD\u5B58\u7528\u6237\u7EA7\u6280\u80FD\u89C4\u5219\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
|
|
5719
|
-
}
|
|
5720
|
-
const key = formatResourceRef(configuringSkill);
|
|
5721
|
-
const bindings = {};
|
|
5722
|
-
for (const [name, binding] of Object.entries(stageBindings)) {
|
|
5723
|
-
bindings[name] = { ...binding, skills: binding.skills?.map((entry) => formatResourceRef(entry.skill) === key ? { skill: entry.skill, rules: profile.rules, ...profile.evidence ? { evidence: profile.evidence } : {} } : entry) };
|
|
5724
|
-
}
|
|
5725
|
-
setStageBindings(bindings);
|
|
5726
|
-
setSkillProfiles({ ...skillProfiles, [key]: profile });
|
|
5727
|
-
setDirty(true);
|
|
5728
|
-
setSavedAt("");
|
|
5729
|
-
setConfiguringSkill(null);
|
|
5730
|
-
};
|
|
5731
|
-
if (loadError !== "") {
|
|
5732
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.wrap, children: [
|
|
5733
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { style: styles.title, children: "\u5DE5\u7A0B\u6D41\u7A0B\u914D\u7F6E" }),
|
|
5734
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.problems, children: [
|
|
5735
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.problemsTitle, children: [
|
|
5736
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: "error" }),
|
|
5737
|
-
"\u8BFB\u53D6\u5931\u8D25"
|
|
5738
|
-
] }),
|
|
5739
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: loadError }),
|
|
5740
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.Button, { onClick: () => setLoadAttempt((n) => n + 1), children: "\u91CD\u8BD5" })
|
|
5741
|
-
] })
|
|
5742
|
-
] });
|
|
5743
|
-
}
|
|
5744
|
-
if (loading) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", children: "\u6B63\u5728\u8BFB\u53D6\u6D41\u7A0B\u914D\u7F6E\u2026" });
|
|
5745
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `te-config-layout${configuringSkill ? " is-open" : ""}`, children: [
|
|
5746
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-config-main", style: styles.wrap, children: [
|
|
5747
|
-
configProblems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { role: "alert", style: styles.problems, children: [
|
|
5748
|
-
"\u539F\u914D\u7F6E\u6709\u95EE\u9898\uFF1A",
|
|
5749
|
-
configProblems.join("\uFF1B"),
|
|
5750
|
-
"\u3002\u8BF7\u9009\u62E9\u6709\u6548\u9884\u8BBE\u5E76\u4FDD\u5B58\u4FEE\u590D\u3002"
|
|
5751
|
-
] }),
|
|
5752
|
-
flowNotice && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", className: "te-flow-notice", children: flowNotice }),
|
|
5753
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.head, children: [
|
|
5754
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { style: styles.title, children: "\u5DE5\u7A0B\u6D41\u7A0B\u914D\u7F6E" }),
|
|
5755
|
-
/* @__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\u63D0\u4EA4\u6587\u672C\u3001\u4EA7\u7269\u5B57\u6BB5\u548C\u8BC4\u5BA1\u6DF1\u5EA6\u7684\u8D77\u70B9\u65F6\uFF0C\u53EF\u4EE5\u300C\u91C7\u7528\u63A8\u8350\u914D\u7F6E\u300D\u3002\u6280\u80FD\u4E0E\u89C4\u5219\u8BF7\u6309\u9879\u76EE\u9700\u8981\u81EA\u884C\u521B\u5EFA\u5E76\u7ED1\u5B9A\u3002" })
|
|
5756
|
-
] }),
|
|
5757
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.adoptRow, children: [
|
|
5758
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dsh_client_ui_primitives2.Button, { size: "sm", onClick: adopt, children: [
|
|
5759
|
-
"\u91C7\u7528\u300C",
|
|
5760
|
-
FLOW_PRESETS[flow]?.label ?? flow,
|
|
5761
|
-
"\u300D\u7684\u63A8\u8350\u914D\u7F6E"
|
|
5762
|
-
] }),
|
|
5763
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.muted, children: "\u4EC5\u5199\u5165\u53EF\u4FEE\u6539\u7684\u6587\u672C\u4E0E\u5B57\u6BB5\uFF0C\u4E0D\u589E\u5220\u73B0\u6709\u6280\u80FD\u548C\u89C4\u5219\u7ED1\u5B9A\u3002" })
|
|
5764
|
-
] }),
|
|
5765
|
-
hasBundledReferences && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.adoptRow, children: [
|
|
5766
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.Button, { size: "sm", onClick: () => {
|
|
5767
|
-
setPendingAdoption(true);
|
|
5768
|
-
setDirty(true);
|
|
5769
|
-
setSavedAt("");
|
|
5770
|
-
setFlowNotice("\u4FDD\u5B58\u540E\u4F1A\u628A\u5F53\u524D\u914D\u7F6E\u4E2D\u7684\u5185\u7F6E\u5F15\u7528\u590D\u5236\u5230\u9879\u76EE\uFF0C\u4FDD\u7559\u5DF2\u6709\u9879\u76EE\u526F\u672C\u53CA\u5176\u4ED6\u914D\u7F6E\u3002");
|
|
5771
|
-
}, children: "\u628A\u5F53\u524D\u5185\u7F6E\u5F15\u7528\u8FC1\u79FB\u5230\u9879\u76EE" }),
|
|
5772
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.muted, children: "\u5C06\u5F53\u524D\u5185\u7F6E\u5F15\u7528\u590D\u5236\u4E3A\u9879\u76EE\u8D44\u6E90\u3002" })
|
|
5773
|
-
] }),
|
|
5774
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.sourceRow, children: [
|
|
5775
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: source === "project" ? "done" : source === "invalid" ? "warning" : "ongoing" }),
|
|
5776
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.sourceText, children: sourceText(source) })
|
|
5777
|
-
] }),
|
|
5778
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.field, children: [
|
|
5779
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u6D41\u7A0B\u9884\u8BBE" }),
|
|
5780
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.flowGrid, children: FLOW_OPTIONS.map((option) => {
|
|
5781
|
-
const active = flow === option.id;
|
|
5782
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
5783
|
-
"button",
|
|
5784
|
-
{
|
|
5785
|
-
type: "button",
|
|
5786
|
-
"aria-pressed": active,
|
|
5787
|
-
onClick: () => {
|
|
5788
|
-
selectFlow(option.id);
|
|
5789
|
-
},
|
|
5790
|
-
style: { ...styles.flowOption, ...active ? styles.flowOptionActive : {} },
|
|
5791
|
-
children: [
|
|
5792
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.flowOptionTitle, children: [
|
|
5793
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: active ? "done" : "ongoing", size: 8 }),
|
|
5794
|
-
option.label
|
|
5795
|
-
] }),
|
|
5796
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.flowOptionDesc, children: option.description })
|
|
5797
|
-
]
|
|
5798
|
-
},
|
|
5799
|
-
option.id
|
|
5800
|
-
);
|
|
5801
|
-
}) })
|
|
5802
|
-
] }),
|
|
5803
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconSettings, { size: 16 }), title: "\u9636\u6BB5\u6280\u80FD", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BindingEditor, { stages, stageBindings, setStageBindings: (next) => {
|
|
5804
|
-
setStageBindings(next);
|
|
5805
|
-
setDirty(true);
|
|
5806
|
-
setSavedAt("");
|
|
5807
|
-
}, skillProfiles, setSkillProfiles: (next) => {
|
|
5808
|
-
setSkillProfiles(next);
|
|
5809
|
-
setDirty(true);
|
|
5810
|
-
setSavedAt("");
|
|
5811
|
-
}, skills, onConfigureSkill: setConfiguringSkill }) }),
|
|
5812
|
-
problems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.problems, children: [
|
|
5813
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.problemsTitle, children: [
|
|
5814
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: "error" }),
|
|
5815
|
-
"\u6709 ",
|
|
5816
|
-
problems.length,
|
|
5817
|
-
" \u4E2A\u95EE\u9898\uFF08\u4FDD\u5B58\u4F1A\u88AB\u62D2\u7EDD\uFF09"
|
|
5818
|
-
] }),
|
|
5819
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { style: styles.problemsList, children: problems.map((p) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: p }, p)) })
|
|
5820
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.okText, children: [
|
|
5821
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: "done" }),
|
|
5822
|
-
source === "project" ? "\u914D\u7F6E\u6709\u6548" : "\u4F7F\u7528\u7A7A\u767D\u6D41\u7A0B\u914D\u7F6E\uFF08\u5C1A\u672A\u4FDD\u5B58\uFF09"
|
|
5823
|
-
] }),
|
|
5824
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.actions, children: [
|
|
5825
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5826
|
-
import_dsh_client_ui_primitives2.Button,
|
|
5827
|
-
{
|
|
5828
|
-
variant: "primary",
|
|
5829
|
-
size: "md",
|
|
5830
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheck, { size: 16 }),
|
|
5831
|
-
disabled: problems.length > 0 || saving,
|
|
5832
|
-
onClick: () => {
|
|
5833
|
-
setSaving(true);
|
|
5834
|
-
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 } : {}, ...pendingAdoption ? { materialize_bundled: "project" } : {} }, workspace, setSavedAt, setSource).then((view) => {
|
|
5835
|
-
if (view) {
|
|
5836
|
-
setConfigProblems([]);
|
|
5837
|
-
setDirty(false);
|
|
5838
|
-
setPendingAdoption(false);
|
|
5839
|
-
setStageBindings(view.config.stage_bindings ?? {});
|
|
5840
|
-
setSkillProfiles(view.config.skill_profiles ?? {});
|
|
5841
|
-
refreshCatalogs();
|
|
5842
|
-
}
|
|
5843
|
-
}).finally(() => setSaving(false));
|
|
5844
|
-
},
|
|
5845
|
-
children: saving ? "\u6B63\u5728\u4FDD\u5B58\u2026" : dirty ? "\u4FDD\u5B58\u5230 .dsh/eng.json" : "\u5DF2\u4FDD\u5B58 \xB7 \u65E0\u9700\u4FDD\u5B58"
|
|
5846
|
-
}
|
|
5847
|
-
),
|
|
5848
|
-
savedAt !== "" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.okText, children: [
|
|
5849
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: savedAt.startsWith("\u5DF2") ? "done" : "error" }),
|
|
5850
|
-
savedAt
|
|
5851
|
-
] }) : null
|
|
5852
|
-
] })
|
|
5853
|
-
] }),
|
|
5854
|
-
configuringSkill ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5855
|
-
SkillRuleDialog,
|
|
5856
|
-
{
|
|
5857
|
-
skill: configuringSkill,
|
|
5858
|
-
profile: skillProfiles[formatResourceRef(configuringSkill)],
|
|
5859
|
-
rules: configuringSkill.source === "user" ? rules.filter((rule) => rule.ref.source !== "project") : rules,
|
|
5860
|
-
description: configuringSkill.source === "user" ? "\u7528\u6237\u7EA7\u6280\u80FD\u7684\u89C4\u5219\u914D\u7F6E\u7ACB\u5373\u4FDD\u5B58\u5230\u7528\u6237\u76EE\u5F55\uFF0C\u6240\u6709\u9879\u76EE\u4E0E\u4F1A\u8BDD\u5171\u7528\uFF1B\u8282\u70B9\u9009\u62E9\u4ECD\u9700\u5728\u9875\u9762\u5E95\u90E8\u4FDD\u5B58\u3002" : "\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",
|
|
5861
|
-
saveLabel: configuringSkill.source === "user" ? "\u4FDD\u5B58\u7528\u6237\u7EA7\u89C4\u5219" : "\u5E94\u7528\u5230\u5F53\u524D\u914D\u7F6E",
|
|
5862
|
-
onSave: updateSkillProfile,
|
|
5863
|
-
onClose: () => setConfiguringSkill(null)
|
|
5864
|
-
},
|
|
5865
|
-
formatResourceRef(configuringSkill)
|
|
5866
|
-
) : null
|
|
5867
|
-
] });
|
|
5868
|
-
}
|
|
5869
|
-
function sourceText(source) {
|
|
5870
|
-
switch (source) {
|
|
5871
|
-
case "project":
|
|
5872
|
-
return "\u9879\u76EE\u914D\u7F6E\uFF08.dsh/eng.json\uFF09";
|
|
5873
|
-
case "invalid":
|
|
5874
|
-
return "\u539F\u6587\u4EF6\u65E0\u6CD5\u89E3\u6790\uFF0C\u663E\u793A\u6807\u51C6\u9884\u8BBE";
|
|
5875
|
-
default:
|
|
5876
|
-
return "\u6807\u51C6\u9884\u8BBE\uFF08\u5DE5\u4F5C\u533A\u5C1A\u65E0 .dsh/eng.json\uFF09";
|
|
5877
|
-
}
|
|
5878
|
-
}
|
|
5879
|
-
function SectionCard({ icon, title, hint, children }) {
|
|
5880
|
-
const [open, setOpen] = (0, import_react3.useState)(true);
|
|
5881
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.section, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5882
|
-
import_dsh_client_ui_primitives2.DisclosureRow,
|
|
5883
|
-
{
|
|
5884
|
-
icon,
|
|
5885
|
-
title,
|
|
5886
|
-
titleClassName: "te-disclosure-title",
|
|
5887
|
-
open,
|
|
5888
|
-
expandable: true,
|
|
5889
|
-
expandOnRowClick: true,
|
|
5890
|
-
onToggle: () => {
|
|
5891
|
-
setOpen(!open);
|
|
5892
|
-
},
|
|
5893
|
-
keepContentWhenOpen: true,
|
|
5894
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.cardBody, children: [
|
|
5895
|
-
hint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: hint }) : null,
|
|
5896
|
-
children
|
|
5897
|
-
] })
|
|
5898
|
-
}
|
|
5899
|
-
) });
|
|
5900
|
-
}
|
|
5901
|
-
function BindingEditor({ stages, stageBindings, setStageBindings, skillProfiles, setSkillProfiles, skills, onConfigureSkill }) {
|
|
5902
|
-
const [stage, setStage] = (0, import_react3.useState)(stages[0] ?? "");
|
|
5903
|
-
const [query, setQuery] = (0, import_react3.useState)("");
|
|
5904
|
-
const currentStage = stages.includes(stage) ? stage : stages[0] ?? "";
|
|
5905
|
-
const bindingFor = (name) => stageBindings[name] ?? {};
|
|
5906
|
-
const setSkills = (name, next) => {
|
|
5907
|
-
setStageBindings({ ...stageBindings, [name]: { ...bindingFor(name), skills: next } });
|
|
5908
|
-
};
|
|
5909
|
-
const toggleSkill = (raw) => {
|
|
5910
|
-
if (currentStage === "") return;
|
|
5911
|
-
const current = bindingFor(currentStage).skills ?? [];
|
|
5912
|
-
const profile = skillProfiles[raw];
|
|
5913
|
-
const alreadyBound = current.some((entry) => formatResourceRef(entry.skill) === raw);
|
|
5914
|
-
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)));
|
|
5915
|
-
if (!alreadyBound && profile === void 0) setSkillProfiles({ ...skillProfiles, [raw]: { rules: [] } });
|
|
5916
|
-
setSkills(currentStage, next);
|
|
5917
|
-
};
|
|
5918
|
-
if (currentStage === "") {
|
|
5919
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: "\u5F53\u524D\u6D41\u7A0B\u6CA1\u6709\u8282\u70B9\u3002" });
|
|
5920
|
-
}
|
|
5921
|
-
const boundSkills = bindingFor(currentStage).skills ?? [];
|
|
5922
|
-
const unassigned = bindingFor(currentStage).legacy_rules ?? [];
|
|
5923
|
-
const boundKeys = new Set(boundSkills.map((entry) => formatResourceRef(entry.skill)));
|
|
5924
|
-
const needle = query.trim().toLowerCase();
|
|
5925
|
-
const available = skills.filter((entry) => !boundKeys.has(formatResourceRef(entry.ref)) && `${entry.name} ${entry.description} ${entry.sourceLabel}`.toLowerCase().includes(needle));
|
|
5926
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.section, children: [
|
|
5927
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.field, children: [
|
|
5928
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.bindingLabel, children: "\u9009\u62E9\u8282\u70B9" }),
|
|
5929
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.chips, children: stages.map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.Pill, { active: s === currentStage, onClick: () => {
|
|
5930
|
-
setStage(s);
|
|
5931
|
-
}, children: s }, s)) })
|
|
5932
|
-
] }),
|
|
5933
|
-
unassigned.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-alert", children: [
|
|
5934
|
-
"\u4EE5\u4E0B\u89C4\u5219\u5C5E\u4E8E",
|
|
5935
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u8282\u70B9" }),
|
|
5936
|
-
"\u800C\u4E0D\u662F\u4EFB\u4F55\u6280\u80FD\uFF08\u65E7\u914D\u7F6E\uFF09\uFF1A",
|
|
5937
|
-
unassigned.join("\u3001"),
|
|
5938
|
-
"\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"
|
|
5939
|
-
] }) : null,
|
|
5940
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer", children: [
|
|
5941
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "te-transfer-pane", "aria-label": "\u53EF\u7528\u6280\u80FD", children: [
|
|
5942
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-binding-heading", children: [
|
|
5943
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h4", { children: "\u53EF\u7528\u6280\u80FD" }),
|
|
5944
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-binding-count", children: [
|
|
5945
|
-
skills.filter((entry) => !boundKeys.has(formatResourceRef(entry.ref))).length,
|
|
5946
|
-
" \u9879"
|
|
5947
|
-
] })
|
|
5948
|
-
] }),
|
|
5949
|
-
/* @__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) }),
|
|
5950
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer-list", role: "group", "aria-label": "\u53EF\u7528\u6280\u80FD\u5217\u8868", children: [
|
|
5951
|
-
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,
|
|
5952
|
-
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,
|
|
5953
|
-
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: [
|
|
5954
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-transfer-row-main", children: [
|
|
5955
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: entry.name }),
|
|
5956
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("small", { children: [
|
|
5957
|
-
entry.sourceLabel,
|
|
5958
|
-
entry.description ? ` \xB7 ${entry.description}` : ""
|
|
5959
|
-
] })
|
|
5960
|
-
] }),
|
|
5961
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "te-transfer-action", "aria-hidden": "true", children: "\uFF0B" })
|
|
5962
|
-
] }, formatResourceRef(entry.ref)))
|
|
5963
|
-
] })
|
|
5964
|
-
] }),
|
|
5965
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "te-transfer-arrow", "aria-hidden": "true", children: "\u2192" }),
|
|
5966
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "te-transfer-pane", "aria-label": "\u5F53\u524D\u8282\u70B9\u6280\u80FD", children: [
|
|
5967
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-binding-heading", children: [
|
|
5968
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h4", { children: [
|
|
5969
|
-
currentStage,
|
|
5970
|
-
" \xB7 \u5DF2\u7ED1\u5B9A"
|
|
5971
|
-
] }),
|
|
5972
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-binding-count", children: [
|
|
5973
|
-
boundSkills.length,
|
|
5974
|
-
" \u9879"
|
|
5975
|
-
] })
|
|
5976
|
-
] }),
|
|
5977
|
-
/* @__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" }),
|
|
5978
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer-list", role: "group", "aria-label": "\u5DF2\u7ED1\u5B9A\u6280\u80FD\u5217\u8868", children: [
|
|
5979
|
-
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,
|
|
5980
|
-
boundSkills.map((entry) => {
|
|
5981
|
-
const raw = formatResourceRef(entry.skill);
|
|
5982
|
-
const catalog = skills.find((skill) => formatResourceRef(skill.ref) === raw);
|
|
5983
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer-row is-bound", children: [
|
|
5984
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-transfer-row-main", children: [
|
|
5985
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: entry.skill.name }),
|
|
5986
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("small", { children: [
|
|
5987
|
-
catalog?.sourceLabel ?? entry.skill.source,
|
|
5988
|
-
" \xB7 ",
|
|
5989
|
-
entry.rules.length,
|
|
5990
|
-
" \u6761\u89C4\u5219",
|
|
5991
|
-
catalog ? "" : " \xB7 \u8D44\u6E90\u672A\u627E\u5230"
|
|
5992
|
-
] })
|
|
5993
|
-
] }),
|
|
5994
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-transfer-actions", children: [
|
|
5995
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "te-transfer-config", onClick: () => onConfigureSkill(entry.skill), children: "\u914D\u7F6E\u89C4\u5219" }),
|
|
5996
|
-
/* @__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" })
|
|
5997
|
-
] })
|
|
5998
|
-
] }, raw);
|
|
5999
|
-
})
|
|
6000
|
-
] })
|
|
6001
|
-
] })
|
|
6002
|
-
] }, currentStage)
|
|
6003
|
-
] });
|
|
6004
|
-
}
|
|
6005
|
-
async function save(remote, config, workspace, setSavedAt, setSource) {
|
|
6006
|
-
try {
|
|
6007
|
-
const result = await remote.write({ path: workspace, ...config });
|
|
6008
|
-
if (!result.ok) {
|
|
6009
|
-
setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
6010
|
-
return void 0;
|
|
6011
|
-
}
|
|
6012
|
-
if (!result.value.ok) {
|
|
6013
|
-
setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + result.value.problems.join("\uFF1B"));
|
|
6014
|
-
return void 0;
|
|
6015
|
-
}
|
|
6016
|
-
setSource(result.value.source);
|
|
6017
|
-
const reused = result.value.adoption?.reused.length ?? 0;
|
|
6018
|
-
setSavedAt(reused > 0 ? `\u5DF2\u4FDD\u5B58\uFF1B\u4FDD\u7559\u4E86 ${reused} \u4EFD\u5DF2\u6709\u9879\u76EE\u8D44\u6E90` : "\u5DF2\u4FDD\u5B58");
|
|
6019
|
-
return result.value;
|
|
6020
|
-
} catch (error) {
|
|
6021
|
-
setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(error));
|
|
6022
|
-
return void 0;
|
|
6023
|
-
}
|
|
6024
|
-
}
|
|
6025
|
-
|
|
6026
|
-
// src/client/AdaptivePanel.tsx
|
|
6027
|
-
var import_react4 = require("react");
|
|
6028
|
-
var import_dsh_client_ui_primitives3 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
6029
|
-
|
|
6030
|
-
// src/adaptive.ts
|
|
6031
|
-
var META_STAGES = {
|
|
6032
|
-
"requirements-analysis": "\u9700\u6C42\u5206\u6790",
|
|
6033
|
-
"architecture-design": "\u67B6\u6784\u8BBE\u8BA1",
|
|
6034
|
-
"task-orchestration": "\u4EFB\u52A1\u7F16\u6392",
|
|
6035
|
-
"code-development": "\u4EE3\u7801\u5F00\u53D1",
|
|
6036
|
-
"test-validation": "\u6D4B\u8BD5",
|
|
6037
|
-
"code-review": "\u4EE3\u7801\u5BA1\u6838"
|
|
6038
|
-
};
|
|
6039
|
-
|
|
6040
5227
|
// src/client/AdaptivePanel.tsx
|
|
6041
5228
|
var card = {
|
|
6042
5229
|
border: "1px solid var(--dsw-alias-border-l2)",
|
|
@@ -6061,17 +5248,17 @@ var SOURCE_ORDER = ["project", "codex-project", "user", "bundled"];
|
|
|
6061
5248
|
function effectiveSource(entries, name) {
|
|
6062
5249
|
return entries.filter((entry) => entry.name === name).sort((a, b) => SOURCE_ORDER.indexOf(a.source) - SOURCE_ORDER.indexOf(b.source))[0]?.source ?? "\u7F3A\u5931";
|
|
6063
5250
|
}
|
|
6064
|
-
function AdaptivePanel({ workspace, remote }) {
|
|
6065
|
-
const [view, setView] = (0,
|
|
6066
|
-
const [draft, setDraft] = (0,
|
|
6067
|
-
const [skills, setSkills] = (0,
|
|
6068
|
-
const [rules, setRules] = (0,
|
|
6069
|
-
const [selected, setSelected] = (0,
|
|
6070
|
-
const [loading, setLoading] = (0,
|
|
6071
|
-
const [saving, setSaving] = (0,
|
|
6072
|
-
const [dirty, setDirty] = (0,
|
|
6073
|
-
const [message, setMessage] = (0,
|
|
6074
|
-
const refresh = (0,
|
|
5251
|
+
function AdaptivePanel({ workspace, remote, onOpenInit }) {
|
|
5252
|
+
const [view, setView] = (0, import_react3.useState)(null);
|
|
5253
|
+
const [draft, setDraft] = (0, import_react3.useState)({});
|
|
5254
|
+
const [skills, setSkills] = (0, import_react3.useState)([]);
|
|
5255
|
+
const [rules, setRules] = (0, import_react3.useState)([]);
|
|
5256
|
+
const [selected, setSelected] = (0, import_react3.useState)(null);
|
|
5257
|
+
const [loading, setLoading] = (0, import_react3.useState)(true);
|
|
5258
|
+
const [saving, setSaving] = (0, import_react3.useState)(false);
|
|
5259
|
+
const [dirty, setDirty] = (0, import_react3.useState)(false);
|
|
5260
|
+
const [message, setMessage] = (0, import_react3.useState)("");
|
|
5261
|
+
const refresh = (0, import_react3.useCallback)(() => {
|
|
6075
5262
|
setLoading(true);
|
|
6076
5263
|
setMessage("");
|
|
6077
5264
|
void Promise.all([remote.readAdaptive(workspace), remote.listSkills(workspace), remote.listRules(workspace)]).then(([config, catalog, ruleCatalog]) => {
|
|
@@ -6098,7 +5285,7 @@ function AdaptivePanel({ workspace, remote }) {
|
|
|
6098
5285
|
setMessage("\u8BFB\u53D6\u5931\u8D25\uFF1A" + describeError(error));
|
|
6099
5286
|
});
|
|
6100
5287
|
}, [remote, workspace]);
|
|
6101
|
-
(0,
|
|
5288
|
+
(0, import_react3.useEffect)(() => {
|
|
6102
5289
|
refresh();
|
|
6103
5290
|
}, [refresh]);
|
|
6104
5291
|
const update = (config) => {
|
|
@@ -6119,31 +5306,76 @@ function AdaptivePanel({ workspace, remote }) {
|
|
|
6119
5306
|
update({ ...draft, sonar: { mode: "branch", token_env: "SONAR_TOKEN", ...draft.sonar, ...patch } });
|
|
6120
5307
|
};
|
|
6121
5308
|
const openRules = (name) => {
|
|
6122
|
-
|
|
6123
|
-
|
|
5309
|
+
setMessage("");
|
|
5310
|
+
const source = skills.filter((skill) => skill.name === name).sort((a, b) => SOURCE_ORDER.indexOf(a.source) - SOURCE_ORDER.indexOf(b.source))[0]?.ref.source;
|
|
5311
|
+
if (!source) {
|
|
5312
|
+
setMessage(`\u6280\u80FD ${name} \u4E0D\u5728\u5F53\u524D\u76EE\u5F55\u4E2D\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u8BD5\u3002`);
|
|
5313
|
+
return;
|
|
5314
|
+
}
|
|
5315
|
+
if (source === "project") {
|
|
5316
|
+
void remote.readProjectSkillProfile({ path: workspace, name }).then((result) => {
|
|
5317
|
+
if (!result.ok) {
|
|
5318
|
+
setMessage("\u8BFB\u53D6\u6280\u80FD\u89C4\u5219\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
5319
|
+
return;
|
|
5320
|
+
}
|
|
5321
|
+
setSelected({ skill: { source: "project", name }, profile: result.value.profile, hash: result.value.hash });
|
|
5322
|
+
}, (error) => setMessage("\u8BFB\u53D6\u6280\u80FD\u89C4\u5219\u5931\u8D25\uFF1A" + describeError(error)));
|
|
6124
5323
|
return;
|
|
6125
5324
|
}
|
|
6126
|
-
void remote.
|
|
5325
|
+
void remote.readSkill({ path: workspace, name, level: source }).then((result) => {
|
|
6127
5326
|
if (!result.ok) {
|
|
6128
|
-
setMessage("\u8BFB\u53D6\u6280\u80FD\
|
|
5327
|
+
setMessage("\u8BFB\u53D6\u6280\u80FD\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
6129
5328
|
return;
|
|
6130
5329
|
}
|
|
6131
|
-
|
|
6132
|
-
|
|
5330
|
+
if (!result.value.ok) {
|
|
5331
|
+
setMessage("\u8BFB\u53D6\u6280\u80FD\u5931\u8D25\uFF1A" + describeError(result.value.error));
|
|
5332
|
+
return;
|
|
5333
|
+
}
|
|
5334
|
+
setSelected({
|
|
5335
|
+
skill: { source: "project", name },
|
|
5336
|
+
profile: { rules: [] },
|
|
5337
|
+
hash: "",
|
|
5338
|
+
template: result.value,
|
|
5339
|
+
templateSource: source
|
|
5340
|
+
});
|
|
5341
|
+
}, (error) => setMessage("\u8BFB\u53D6\u6280\u80FD\u5931\u8D25\uFF1A" + describeError(error)));
|
|
6133
5342
|
};
|
|
6134
5343
|
const saveRules = async (profile) => {
|
|
6135
5344
|
if (!selected) return;
|
|
5345
|
+
let hash = selected.hash;
|
|
5346
|
+
if (selected.template) {
|
|
5347
|
+
const template = selected.template;
|
|
5348
|
+
const created = await remote.writeSkill({
|
|
5349
|
+
path: workspace,
|
|
5350
|
+
level: "project",
|
|
5351
|
+
name: selected.skill.name,
|
|
5352
|
+
description: template.description,
|
|
5353
|
+
whenToUse: template.whenToUse,
|
|
5354
|
+
content: template.content,
|
|
5355
|
+
createOnly: true
|
|
5356
|
+
});
|
|
5357
|
+
if (!created.ok) throw new Error("\u521B\u5EFA\u9879\u76EE\u6280\u80FD\u5931\u8D25\uFF1A" + describeError(created.error));
|
|
5358
|
+
if (!created.value.ok) throw new Error("\u521B\u5EFA\u9879\u76EE\u6280\u80FD\u5931\u8D25\uFF1A" + describeError(created.value.error));
|
|
5359
|
+
const initial = await remote.readProjectSkillProfile({ path: workspace, name: selected.skill.name });
|
|
5360
|
+
if (!initial.ok) throw new Error("\u8BFB\u53D6\u65B0\u9879\u76EE\u6280\u80FD\u5931\u8D25\uFF1A" + describeError(initial.error));
|
|
5361
|
+
hash = initial.value.hash;
|
|
5362
|
+
setSelected({ ...selected, hash, template: void 0, templateSource: void 0 });
|
|
5363
|
+
}
|
|
6136
5364
|
const result = await remote.writeProjectSkillProfile({
|
|
6137
5365
|
path: workspace,
|
|
6138
5366
|
name: selected.skill.name,
|
|
6139
5367
|
profile,
|
|
6140
|
-
expected_hash:
|
|
5368
|
+
expected_hash: hash
|
|
6141
5369
|
});
|
|
6142
5370
|
if (!result.ok) throw new Error("\u4FDD\u5B58\u6280\u80FD\u89C4\u5219\u5931\u8D25\uFF1A" + describeError(result.error));
|
|
5371
|
+
void remote.listSkills(workspace).then((catalog) => {
|
|
5372
|
+
if (catalog.ok) setSkills(catalog.value.skills);
|
|
5373
|
+
}, () => {
|
|
5374
|
+
});
|
|
6143
5375
|
setSelected(null);
|
|
6144
5376
|
setMessage(`\u5DF2\u4FDD\u5B58 ${selected.skill.name} \u7684\u9879\u76EE Rule\uFF1B\u65B0\u4EFB\u52A1\u5C06\u8BFB\u53D6\u6B64\u914D\u7F6E\u3002`);
|
|
6145
5377
|
};
|
|
6146
|
-
const
|
|
5378
|
+
const save = () => {
|
|
6147
5379
|
if (!view) return;
|
|
6148
5380
|
setSaving(true);
|
|
6149
5381
|
void remote.writeAdaptive({ path: workspace, config: draft, expected_hash: view.hash }).then((result) => {
|
|
@@ -6167,54 +5399,60 @@ function AdaptivePanel({ workspace, remote }) {
|
|
|
6167
5399
|
};
|
|
6168
5400
|
const candidates = [...new Set(skills.map((skill) => skill.name))].filter((name) => name !== "eng-delivery" && !(name in META_STAGES)).sort();
|
|
6169
5401
|
const sonar = draft.sonar ?? {};
|
|
6170
|
-
return (0,
|
|
5402
|
+
return (0, import_react3.createElement)(
|
|
6171
5403
|
"div",
|
|
6172
5404
|
{ style: { ...styles.section, display: "flex", flexDirection: "column", gap: 16 } },
|
|
6173
|
-
(0,
|
|
5405
|
+
(0, import_react3.createElement)(
|
|
5406
|
+
"div",
|
|
5407
|
+
{ style: row },
|
|
5408
|
+
(0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", onClick: onOpenInit }, "\u521D\u59CB\u5316\u9879\u76EE Skill / Rule"),
|
|
5409
|
+
(0, import_react3.createElement)("span", { style: label }, "\u626B\u63CF\u9879\u76EE\u540E\u5148\u9884\u89C8\uFF0C\u786E\u8BA4\u540E\u5199\u5165\u3002")
|
|
5410
|
+
),
|
|
5411
|
+
(0, import_react3.createElement)(
|
|
6174
5412
|
"div",
|
|
6175
5413
|
{ style: card },
|
|
6176
|
-
(0,
|
|
6177
|
-
(0,
|
|
6178
|
-
(0,
|
|
5414
|
+
(0, import_react3.createElement)("strong", null, "\u6309\u9700\u6C42\u9009\u62E9\u6D41\u7A0B"),
|
|
5415
|
+
(0, import_react3.createElement)("span", { style: label }, "\u6BCF\u4E2A\u4EFB\u52A1\u7531\u5927\u6A21\u578B\u5206\u6790\u540E\u9009\u62E9\u590D\u6742\u5EA6\uFF0C\u4EFB\u52A1\u521B\u5EFA\u65F6\u51BB\u7ED3\u9636\u6BB5\u548C\u751F\u6548\u6280\u80FD\uFF1B\u4E0D\u540C\u4F1A\u8BDD\u53EF\u8D70\u4E0D\u540C\u6D41\u7A0B\u3002\u98CE\u9669\u7B49\u7EA7\u72EC\u7ACB\u5224\u65AD\u3002"),
|
|
5416
|
+
(0, import_react3.createElement)("div", { style: grid }, ...(view?.grades ?? []).map((grade) => (0, import_react3.createElement)(
|
|
6179
5417
|
"div",
|
|
6180
5418
|
{ key: grade.id, style: { ...card, gap: 5 } },
|
|
6181
|
-
(0,
|
|
6182
|
-
(0,
|
|
6183
|
-
(0,
|
|
5419
|
+
(0, import_react3.createElement)("strong", null, `${grade.label} \xB7 ${grade.id}`),
|
|
5420
|
+
(0, import_react3.createElement)("span", { style: label }, grade.guidance),
|
|
5421
|
+
(0, import_react3.createElement)("span", { style: { fontSize: 12 } }, grade.stages.join(" \u2192 "))
|
|
6184
5422
|
)))
|
|
6185
5423
|
),
|
|
6186
|
-
(0,
|
|
5424
|
+
(0, import_react3.createElement)(
|
|
6187
5425
|
"div",
|
|
6188
5426
|
{ style: card },
|
|
6189
|
-
(0,
|
|
6190
|
-
(0,
|
|
5427
|
+
(0, import_react3.createElement)("strong", null, "\u5143\u6280\u80FD\u4E0E\u9879\u76EE\u6280\u80FD"),
|
|
5428
|
+
(0, import_react3.createElement)("span", { style: label }, "\u6BCF\u4E2A\u5143\u6280\u80FD\u59CB\u7EC8\u52A0\u8F7D\u540C\u540D\u6838\u5FC3 Skill\uFF1B\u540C\u540D\u9879\u76EE Skill \u8986\u76D6\u7528\u6237\u4E0E\u5185\u7F6E\u7248\u672C\u3002\u9644\u52A0\u6280\u80FD\u6309\u540D\u79F0\u6302\u8F7D\uFF0C\u5B9E\u9645\u6765\u6E90\u5728\u4EFB\u52A1\u521B\u5EFA\u65F6\u89E3\u6790\u3002Rule \u4FDD\u5B58\u5728\u5BF9\u5E94 Skill \u7684 profile.json\u3002"),
|
|
6191
5429
|
...Object.entries(META_STAGES).map(([id, stage]) => {
|
|
6192
5430
|
const meta = id;
|
|
6193
5431
|
const selected2 = draft.meta_bindings?.[meta] ?? [];
|
|
6194
|
-
return (0,
|
|
5432
|
+
return (0, import_react3.createElement)(
|
|
6195
5433
|
"div",
|
|
6196
5434
|
{ key: id, style: { ...card, gap: 6 } },
|
|
6197
|
-
(0,
|
|
6198
|
-
(0,
|
|
6199
|
-
(0,
|
|
6200
|
-
(0,
|
|
5435
|
+
(0, import_react3.createElement)("strong", null, stage),
|
|
5436
|
+
(0, import_react3.createElement)("span", { style: label }, `\u6838\u5FC3\uFF1A${id} \xB7 \u751F\u6548\u6765\u6E90\uFF1A${effectiveSource(skills, id)}`),
|
|
5437
|
+
(0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", onClick: () => openRules(id) }, "\u914D\u7F6E\u6838\u5FC3 Skill \u7684 Rule"),
|
|
5438
|
+
(0, import_react3.createElement)(
|
|
6201
5439
|
"div",
|
|
6202
5440
|
{ style: row },
|
|
6203
|
-
...selected2.map((name) => (0,
|
|
5441
|
+
...selected2.map((name) => (0, import_react3.createElement)("button", {
|
|
6204
5442
|
key: name,
|
|
6205
5443
|
type: "button",
|
|
6206
5444
|
title: "\u79FB\u9664\u6302\u8F7D",
|
|
6207
5445
|
style: { ...input, minWidth: 0, cursor: "pointer" },
|
|
6208
5446
|
onClick: () => removeSkill(meta, name)
|
|
6209
5447
|
}, `${name} \xB7 ${effectiveSource(skills, name)} \xD7`)),
|
|
6210
|
-
...selected2.map((name) => (0,
|
|
5448
|
+
...selected2.map((name) => (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, {
|
|
6211
5449
|
key: `rules-${name}`,
|
|
6212
5450
|
variant: "outline",
|
|
6213
5451
|
size: "sm",
|
|
6214
5452
|
onClick: () => openRules(name)
|
|
6215
5453
|
}, `\u914D\u7F6E ${name} \u7684 Rule`))
|
|
6216
5454
|
),
|
|
6217
|
-
(0,
|
|
5455
|
+
(0, import_react3.createElement)(
|
|
6218
5456
|
"select",
|
|
6219
5457
|
{
|
|
6220
5458
|
style: input,
|
|
@@ -6222,23 +5460,23 @@ function AdaptivePanel({ workspace, remote }) {
|
|
|
6222
5460
|
value: "",
|
|
6223
5461
|
onChange: (event) => addSkill(meta, event.target.value)
|
|
6224
5462
|
},
|
|
6225
|
-
(0,
|
|
6226
|
-
...candidates.filter((name) => !selected2.includes(name)).map((name) => (0,
|
|
5463
|
+
(0, import_react3.createElement)("option", { value: "" }, "\u6302\u8F7D\u9644\u52A0\u6280\u80FD\u2026"),
|
|
5464
|
+
...candidates.filter((name) => !selected2.includes(name)).map((name) => (0, import_react3.createElement)("option", { key: name, value: name }, `${name} \xB7 ${effectiveSource(skills, name)}`))
|
|
6227
5465
|
)
|
|
6228
5466
|
);
|
|
6229
5467
|
})
|
|
6230
5468
|
),
|
|
6231
|
-
(0,
|
|
5469
|
+
(0, import_react3.createElement)(
|
|
6232
5470
|
"div",
|
|
6233
5471
|
{ style: card },
|
|
6234
|
-
(0,
|
|
5472
|
+
(0, import_react3.createElement)(
|
|
6235
5473
|
"div",
|
|
6236
5474
|
{ style: row },
|
|
6237
|
-
(0,
|
|
6238
|
-
(0,
|
|
5475
|
+
(0, import_react3.createElement)("strong", null, "SonarQube \u5BA1\u6838"),
|
|
5476
|
+
(0, import_react3.createElement)(
|
|
6239
5477
|
"label",
|
|
6240
5478
|
{ style: row },
|
|
6241
|
-
(0,
|
|
5479
|
+
(0, import_react3.createElement)("input", {
|
|
6242
5480
|
type: "checkbox",
|
|
6243
5481
|
checked: sonar.enabled === true,
|
|
6244
5482
|
onChange: (event) => updateSonar({ enabled: event.target.checked })
|
|
@@ -6246,61 +5484,62 @@ function AdaptivePanel({ workspace, remote }) {
|
|
|
6246
5484
|
"\u542F\u7528\uFF08\u4EC5\u4EE3\u7801\u5BA1\u6838\u9636\u6BB5\uFF09"
|
|
6247
5485
|
)
|
|
6248
5486
|
),
|
|
6249
|
-
(0,
|
|
6250
|
-
sonar.enabled === true ? (0,
|
|
5487
|
+
(0, import_react3.createElement)("span", { style: label }, "\u590D\u7528 CI \u626B\u63CF\u7684 ceTaskId\uFF1B\u8D28\u91CF\u95E8\u7981\u6216\u65B0\u4EE3\u7801\u4E2D\u9AD8\u7B49\u7EA7\u95EE\u9898\u672A\u901A\u8FC7\u65F6\u963B\u6B62\u5BA1\u6838\u3002Token \u4EC5\u4ECE\u670D\u52A1\u8FDB\u7A0B\u73AF\u5883\u53D8\u91CF\u8BFB\u53D6\uFF0C\u4E0D\u5199\u5165\u4ED3\u5E93\u3002"),
|
|
5488
|
+
sonar.enabled === true ? (0, import_react3.createElement)(
|
|
6251
5489
|
"div",
|
|
6252
5490
|
{ style: grid },
|
|
6253
5491
|
...[
|
|
6254
5492
|
["host_url", "\u670D\u52A1\u5730\u5740", "https://sonar.example"],
|
|
6255
5493
|
["project_key", "\u9879\u76EE Key", "my-project"],
|
|
6256
5494
|
["token_env", "Token \u73AF\u5883\u53D8\u91CF\u540D", "SONAR_TOKEN"]
|
|
6257
|
-
].map(([key, title, placeholder]) => (0,
|
|
5495
|
+
].map(([key, title, placeholder]) => (0, import_react3.createElement)(
|
|
6258
5496
|
"label",
|
|
6259
5497
|
{ key, style: { display: "flex", flexDirection: "column", gap: 4 } },
|
|
6260
|
-
(0,
|
|
6261
|
-
(0,
|
|
5498
|
+
(0, import_react3.createElement)("span", { style: label }, title),
|
|
5499
|
+
(0, import_react3.createElement)("input", {
|
|
6262
5500
|
style: input,
|
|
6263
5501
|
value: sonar[key] ?? "",
|
|
6264
5502
|
placeholder,
|
|
6265
5503
|
onChange: (event) => updateSonar({ [key]: event.target.value })
|
|
6266
5504
|
})
|
|
6267
5505
|
)),
|
|
6268
|
-
(0,
|
|
5506
|
+
(0, import_react3.createElement)(
|
|
6269
5507
|
"label",
|
|
6270
5508
|
{ style: { display: "flex", flexDirection: "column", gap: 4 } },
|
|
6271
|
-
(0,
|
|
6272
|
-
(0,
|
|
5509
|
+
(0, import_react3.createElement)("span", { style: label }, "\u5206\u6790\u5BF9\u8C61"),
|
|
5510
|
+
(0, import_react3.createElement)(
|
|
6273
5511
|
"select",
|
|
6274
5512
|
{
|
|
6275
5513
|
style: input,
|
|
6276
5514
|
value: sonar.mode ?? "branch",
|
|
6277
5515
|
onChange: (event) => updateSonar({ mode: event.target.value })
|
|
6278
5516
|
},
|
|
6279
|
-
(0,
|
|
6280
|
-
(0,
|
|
5517
|
+
(0, import_react3.createElement)("option", { value: "branch" }, "\u5206\u652F"),
|
|
5518
|
+
(0, import_react3.createElement)("option", { value: "pull-request" }, "\u5408\u5E76\u8BF7\u6C42")
|
|
6281
5519
|
)
|
|
6282
5520
|
)
|
|
6283
5521
|
) : null
|
|
6284
5522
|
),
|
|
6285
|
-
(0,
|
|
5523
|
+
(0, import_react3.createElement)(
|
|
6286
5524
|
"div",
|
|
6287
5525
|
{ style: row },
|
|
6288
|
-
(0,
|
|
6289
|
-
(0,
|
|
6290
|
-
|
|
6291
|
-
{ variant: "primary", size: "sm", disabled: loading || saving || !dirty, onClick:
|
|
5526
|
+
(0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", disabled: loading || saving, onClick: refresh }, "\u5237\u65B0"),
|
|
5527
|
+
(0, import_react3.createElement)(
|
|
5528
|
+
import_dsh_client_ui_primitives2.Button,
|
|
5529
|
+
{ variant: "primary", size: "sm", disabled: loading || saving || !dirty, onClick: save },
|
|
6292
5530
|
saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u81EA\u9002\u5E94\u914D\u7F6E"
|
|
6293
5531
|
),
|
|
6294
|
-
(0,
|
|
5532
|
+
(0, import_react3.createElement)("span", { style: label }, "\u9879\u76EE Skill / Rule \u521D\u59CB\u5316\u5165\u53E3\u4F4D\u4E8E\u201C\u9879\u76EE\u521D\u59CB\u5316\u201D\u9875\u3002")
|
|
6295
5533
|
),
|
|
6296
|
-
message ? (0,
|
|
6297
|
-
view?.problems.length ? (0,
|
|
6298
|
-
selected ? (0,
|
|
5534
|
+
message ? (0, import_react3.createElement)("p", { role: "status", style: styles.status }, message) : null,
|
|
5535
|
+
view?.problems.length ? (0, import_react3.createElement)("p", { role: "alert", style: styles.status }, view.problems.join("\uFF1B")) : null,
|
|
5536
|
+
selected ? (0, import_react3.createElement)(SkillRuleDialog, {
|
|
6299
5537
|
key: `${selected.skill.source}:${selected.skill.name}`,
|
|
6300
5538
|
skill: selected.skill,
|
|
6301
5539
|
profile: selected.profile,
|
|
6302
5540
|
rules,
|
|
6303
|
-
description: "\u9879\u76EE Skill \u7684\u89C4\u5219\u6863\u6848\u4FDD\u5B58\u5728\u5176 profile.json\uFF0C\u5F71\u54CD\u4E4B\u540E\u521B\u5EFA\u7684\u81EA\u9002\u5E94\u4EFB\u52A1\u3002",
|
|
5541
|
+
description: selected.template ? `\u5F53\u524D\u6765\u81EA ${selected.templateSource}\u3002\u4FDD\u5B58\u65F6\u4F1A\u5148\u590D\u5236\u4E3A\u540C\u540D\u9879\u76EE Skill\uFF0C\u518D\u5199\u5165\u9879\u76EE Rule\uFF1B\u65B0\u4EFB\u52A1\u4F18\u5148\u4F7F\u7528\u9879\u76EE\u7248\u672C\u3002` : "\u9879\u76EE Skill \u7684\u89C4\u5219\u6863\u6848\u4FDD\u5B58\u5728\u5176 profile.json\uFF0C\u5F71\u54CD\u4E4B\u540E\u521B\u5EFA\u7684\u81EA\u9002\u5E94\u4EFB\u52A1\u3002",
|
|
5542
|
+
saveLabel: selected.template ? "\u521B\u5EFA\u9879\u76EE Skill \u5E76\u4FDD\u5B58\u89C4\u5219" : "\u4FDD\u5B58\u914D\u7F6E",
|
|
6304
5543
|
onSave: saveRules,
|
|
6305
5544
|
onClose: () => setSelected(null)
|
|
6306
5545
|
}) : null
|
|
@@ -6308,8 +5547,8 @@ function AdaptivePanel({ workspace, remote }) {
|
|
|
6308
5547
|
}
|
|
6309
5548
|
|
|
6310
5549
|
// src/client/InitPanel.tsx
|
|
6311
|
-
var
|
|
6312
|
-
var
|
|
5550
|
+
var import_react4 = require("react");
|
|
5551
|
+
var import_dsh_client_ui_primitives3 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
6313
5552
|
var MD_LABELS = { code: { copyLabel: "\u590D\u5236", copiedLabel: "\u5DF2\u590D\u5236" }, footnotes: "\u811A\u6CE8" };
|
|
6314
5553
|
var INIT_TIMEOUT_S = 150;
|
|
6315
5554
|
var card2 = {
|
|
@@ -6320,15 +5559,17 @@ var card2 = {
|
|
|
6320
5559
|
borderRadius: 8,
|
|
6321
5560
|
padding: "12px 14px"
|
|
6322
5561
|
};
|
|
5562
|
+
var projectInitPrompt = (workspace) => `\u8BF7\u5728\u5F53\u524D\u9879\u76EE\u6839\u5DE5\u4F5C\u533A ${workspace} \u4F7F\u7528\u5DE5\u7A0B\u5316\u5F00\u53D1\u5F15\u64CE\u521D\u59CB\u5316\u9879\u76EE Skill \u548C Rule\u3002\u5148\u8C03\u7528 dev_task init_project\uFF08phase=inspect\uFF09\uFF0C\u7ED3\u5408\u4EE3\u8868\u6027\u6E90\u7801\u3001\u6784\u5EFA\u6587\u4EF6\u3001\u6D4B\u8BD5\u548C\u5DF2\u6709\u89C4\u8303\u6838\u5B9E\u626B\u63CF\u7ED3\u679C\u3002\u6309\u9879\u76EE\u5B9E\u9645\u60C5\u51B5\u62DF\u5B9A\u9879\u76EE\u7ED3\u6784\u5730\u56FE\u3001\u6280\u672F\u6808\u3001\u7F16\u7801\u65B9\u6CD5\u7B49 Skill \u548C\u5FC5\u8981\u7684 Rule\uFF0C\u5E76\u6807\u660E\u9002\u7528\u7684\u5143\u6280\u80FD\u3002\u8C03\u7528 phase=propose \u5C55\u793A\u62DF\u521B\u5EFA\u7684\u6587\u4EF6\u3001\u5185\u5BB9\u548C\u6302\u8F7D\u5173\u7CFB\uFF1B\u7B49\u6211\u5BA1\u9605\u786E\u8BA4\u540E\u518D\u8C03\u7528 phase=apply\u3002\u4E0D\u8981\u8986\u76D6\u540C\u540D\u8D44\u6E90\uFF0C\u4E5F\u4E0D\u8981\u628A\u5076\u53D1\u4EE3\u7801\u5199\u6CD5\u5F53\u6210\u56E2\u961F\u89C4\u8303\u3002`;
|
|
6323
5563
|
function InitPanel({ workspace, remote }) {
|
|
6324
|
-
const [view, setView] = (0,
|
|
6325
|
-
const [generating, setGenerating] = (0,
|
|
6326
|
-
const [elapsed, setElapsed] = (0,
|
|
6327
|
-
const [draft, setDraft] = (0,
|
|
6328
|
-
const [editing, setEditing] = (0,
|
|
6329
|
-
const [body2, setBody] = (0,
|
|
6330
|
-
const [msg, setMsg] = (0,
|
|
6331
|
-
(0,
|
|
5564
|
+
const [view, setView] = (0, import_react4.useState)(null);
|
|
5565
|
+
const [generating, setGenerating] = (0, import_react4.useState)(false);
|
|
5566
|
+
const [elapsed, setElapsed] = (0, import_react4.useState)(0);
|
|
5567
|
+
const [draft, setDraft] = (0, import_react4.useState)(null);
|
|
5568
|
+
const [editing, setEditing] = (0, import_react4.useState)(false);
|
|
5569
|
+
const [body2, setBody] = (0, import_react4.useState)("");
|
|
5570
|
+
const [msg, setMsg] = (0, import_react4.useState)("");
|
|
5571
|
+
const [projectInitMsg, setProjectInitMsg] = (0, import_react4.useState)("");
|
|
5572
|
+
(0, import_react4.useEffect)(() => {
|
|
6332
5573
|
if (!generating) {
|
|
6333
5574
|
setElapsed(0);
|
|
6334
5575
|
return;
|
|
@@ -6342,13 +5583,13 @@ function InitPanel({ workspace, remote }) {
|
|
|
6342
5583
|
clearInterval(timer);
|
|
6343
5584
|
};
|
|
6344
5585
|
}, [generating]);
|
|
6345
|
-
const refresh = (0,
|
|
5586
|
+
const refresh = (0, import_react4.useCallback)(() => {
|
|
6346
5587
|
void remote.readInit(workspace).then((r) => {
|
|
6347
5588
|
if (r.ok) setView(r.value);
|
|
6348
5589
|
}, () => {
|
|
6349
5590
|
});
|
|
6350
5591
|
}, [remote, workspace]);
|
|
6351
|
-
(0,
|
|
5592
|
+
(0, import_react4.useEffect)(() => {
|
|
6352
5593
|
refresh();
|
|
6353
5594
|
}, [refresh]);
|
|
6354
5595
|
const generate = async () => {
|
|
@@ -6391,45 +5632,82 @@ function InitPanel({ workspace, remote }) {
|
|
|
6391
5632
|
setMsg("");
|
|
6392
5633
|
};
|
|
6393
5634
|
const exists = view?.exists === true;
|
|
6394
|
-
return (0,
|
|
5635
|
+
return (0, import_react4.createElement)(
|
|
6395
5636
|
"div",
|
|
6396
5637
|
{ style: styles.section },
|
|
6397
|
-
(0,
|
|
5638
|
+
(0, import_react4.createElement)(
|
|
6398
5639
|
"div",
|
|
6399
5640
|
{ style: card2 },
|
|
6400
|
-
(0,
|
|
5641
|
+
(0, import_react4.createElement)("h2", { style: { margin: 0, fontSize: 17 } }, "\u9879\u76EE Skill / Rule \u521D\u59CB\u5316"),
|
|
5642
|
+
(0, import_react4.createElement)(
|
|
5643
|
+
"p",
|
|
5644
|
+
{ style: styles.muted },
|
|
5645
|
+
"\u626B\u63CF\u4EE3\u7801\u5E93\u5E76\u62DF\u5B9A\u9879\u76EE\u5730\u56FE\u3001\u6280\u672F\u6808\u3001\u7F16\u7801 Skill \u548C Rule\u3002\u5148\u9884\u89C8\u751F\u6210\u5185\u5BB9\uFF0C\u786E\u8BA4\u540E\u624D\u5199\u5165\u9879\u76EE\uFF1B\u5DF2\u6709\u540C\u540D\u8D44\u6E90\u4E0D\u4F1A\u88AB\u8986\u76D6\u3002"
|
|
5646
|
+
),
|
|
5647
|
+
(0, import_react4.createElement)(
|
|
5648
|
+
"p",
|
|
5649
|
+
{ style: styles.muted },
|
|
5650
|
+
"\u4F7F\u7528\u65B9\u6CD5\uFF1A\u5173\u95ED\u6B64\u9762\u677F\uFF0C\u5728\u5F53\u524D\u9879\u76EE\u6839\u5DE5\u4F5C\u533A\u9009\u62E9\u201C\u5DE5\u7A0B\u5316\u5F00\u53D1\u5F15\u64CE\u201D\uFF0C\u628A\u4E0B\u9762\u7684\u8BF7\u6C42\u53D1\u7ED9\u65B0\u4F1A\u8BDD\u3002"
|
|
5651
|
+
),
|
|
5652
|
+
(0, import_react4.createElement)("textarea", {
|
|
5653
|
+
style: { ...styles.textarea, minHeight: 100 },
|
|
5654
|
+
readOnly: true,
|
|
5655
|
+
"aria-label": "\u9879\u76EE Skill \u548C Rule \u521D\u59CB\u5316\u8BF7\u6C42",
|
|
5656
|
+
value: projectInitPrompt(workspace)
|
|
5657
|
+
}),
|
|
5658
|
+
(0, import_react4.createElement)(
|
|
5659
|
+
"div",
|
|
5660
|
+
{ style: styles.row },
|
|
5661
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "primary", size: "md", onClick: () => {
|
|
5662
|
+
if (!navigator.clipboard?.writeText) {
|
|
5663
|
+
setProjectInitMsg("\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u4E00\u952E\u590D\u5236\u3002\u8BF7\u76F4\u63A5\u9009\u4E2D\u4E0A\u65B9\u8BF7\u6C42\u6587\u672C\u5E76\u590D\u5236\u3002");
|
|
5664
|
+
return;
|
|
5665
|
+
}
|
|
5666
|
+
void navigator.clipboard.writeText(projectInitPrompt(workspace)).then(
|
|
5667
|
+
() => setProjectInitMsg("\u5DF2\u590D\u5236\u521D\u59CB\u5316\u8BF7\u6C42\u3002\u8BF7\u5728\u5DE5\u7A0B\u5316\u5F00\u53D1\u5F15\u64CE\u4F1A\u8BDD\u4E2D\u7C98\u8D34\u53D1\u9001\u3002"),
|
|
5668
|
+
() => setProjectInitMsg("\u590D\u5236\u5931\u8D25\u3002\u8BF7\u76F4\u63A5\u9009\u4E2D\u4E0A\u65B9\u8BF7\u6C42\u6587\u672C\u5E76\u590D\u5236\u3002")
|
|
5669
|
+
);
|
|
5670
|
+
} }, "\u590D\u5236\u521D\u59CB\u5316\u8BF7\u6C42"),
|
|
5671
|
+
projectInitMsg ? (0, import_react4.createElement)("span", { role: "status", style: styles.status }, projectInitMsg) : null
|
|
5672
|
+
)
|
|
5673
|
+
),
|
|
5674
|
+
(0, import_react4.createElement)(
|
|
5675
|
+
"div",
|
|
5676
|
+
{ style: card2 },
|
|
5677
|
+
(0, import_react4.createElement)("h2", { style: { margin: 0, fontSize: 17 } }, "AGENTS.md \u521D\u59CB\u5316"),
|
|
5678
|
+
(0, import_react4.createElement)(
|
|
6401
5679
|
"div",
|
|
6402
5680
|
{ style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" } },
|
|
6403
|
-
(0,
|
|
6404
|
-
(0,
|
|
6405
|
-
view?.path !== void 0 ? (0,
|
|
5681
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives3.StateDot, { state: exists ? "done" : "ongoing" }),
|
|
5682
|
+
(0, import_react4.createElement)("span", { style: styles.bindingLabel }, exists ? `AGENTS.md \u5DF2\u5B58\u5728 \xB7 ${view.lines} \u884C\uFF08\u4E0A\u9650 200\uFF09` : "AGENTS.md \u672A\u521B\u5EFA"),
|
|
5683
|
+
view?.path !== void 0 ? (0, import_react4.createElement)("span", { style: styles.sourceBadge }, `\u5DF2\u5B9A\u4F4D\u5230 ${view.path}`) : null
|
|
6406
5684
|
),
|
|
6407
|
-
(0,
|
|
5685
|
+
(0, import_react4.createElement)(
|
|
6408
5686
|
"p",
|
|
6409
5687
|
{ style: styles.muted },
|
|
6410
5688
|
"\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"
|
|
6411
5689
|
),
|
|
6412
|
-
exists && !editing && draft === null ? (0,
|
|
5690
|
+
exists && !editing && draft === null ? (0, import_react4.createElement)(
|
|
6413
5691
|
"div",
|
|
6414
5692
|
{ style: styles.mdPreview },
|
|
6415
|
-
(0,
|
|
5693
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives3.MarkdownText, { text: view.content, labels: MD_LABELS })
|
|
6416
5694
|
) : null,
|
|
6417
|
-
draft !== null ? (0,
|
|
5695
|
+
draft !== null ? (0, import_react4.createElement)(
|
|
6418
5696
|
"div",
|
|
6419
5697
|
{ style: styles.section },
|
|
6420
|
-
(0,
|
|
5698
|
+
(0, import_react4.createElement)(
|
|
6421
5699
|
"div",
|
|
6422
5700
|
{ style: styles.sourceRow },
|
|
6423
|
-
(0,
|
|
6424
|
-
(0,
|
|
5701
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives3.StateDot, { state: "ongoing", size: 8 }),
|
|
5702
|
+
(0, import_react4.createElement)("span", { style: styles.sourceBadge }, `AI \u8349\u7A3F \xB7 ${draft.lines} \u884C \xB7 \u5C1A\u672A\u5199\u5165`)
|
|
6425
5703
|
),
|
|
6426
|
-
(0,
|
|
5704
|
+
(0, import_react4.createElement)(
|
|
6427
5705
|
"div",
|
|
6428
5706
|
{ style: styles.mdPreview },
|
|
6429
|
-
(0,
|
|
5707
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives3.MarkdownText, { text: draft.content, labels: MD_LABELS })
|
|
6430
5708
|
)
|
|
6431
5709
|
) : null,
|
|
6432
|
-
editing ? (0,
|
|
5710
|
+
editing ? (0, import_react4.createElement)("textarea", {
|
|
6433
5711
|
style: { ...styles.textarea, minHeight: 300 },
|
|
6434
5712
|
placeholder: "AGENTS.md \u6B63\u6587\uFF08Markdown\uFF0C\u2264200 \u884C\uFF09",
|
|
6435
5713
|
value: body2,
|
|
@@ -6437,16 +5715,16 @@ function InitPanel({ workspace, remote }) {
|
|
|
6437
5715
|
setBody(ev.target.value);
|
|
6438
5716
|
}
|
|
6439
5717
|
}) : null,
|
|
6440
|
-
generating ? (0,
|
|
5718
|
+
generating ? (0, import_react4.createElement)(
|
|
6441
5719
|
"p",
|
|
6442
5720
|
{ style: styles.status },
|
|
6443
5721
|
`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`
|
|
6444
5722
|
) : null,
|
|
6445
|
-
msg !== "" ? (0,
|
|
6446
|
-
draft !== null ? (0,
|
|
5723
|
+
msg !== "" ? (0, import_react4.createElement)("p", { style: styles.status }, msg) : null,
|
|
5724
|
+
draft !== null ? (0, import_react4.createElement)(
|
|
6447
5725
|
"div",
|
|
6448
5726
|
{ style: styles.row },
|
|
6449
|
-
(0,
|
|
5727
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
|
|
6450
5728
|
variant: "primary",
|
|
6451
5729
|
size: "md",
|
|
6452
5730
|
disabled: draft.lines > 200,
|
|
@@ -6455,14 +5733,14 @@ function InitPanel({ workspace, remote }) {
|
|
|
6455
5733
|
void write(draft.content, exists);
|
|
6456
5734
|
}
|
|
6457
5735
|
}, exists ? "\u4FDD\u5B58\u5E76\u8986\u76D6" : "\u4FDD\u5B58"),
|
|
6458
|
-
draft.lines > 200 ? (0,
|
|
6459
|
-
(0,
|
|
5736
|
+
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,
|
|
5737
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "ghost", size: "md", onClick: () => {
|
|
6460
5738
|
setDraft(null);
|
|
6461
5739
|
} }, "\u653E\u5F03")
|
|
6462
|
-
) : editing ? (0,
|
|
5740
|
+
) : editing ? (0, import_react4.createElement)(
|
|
6463
5741
|
"div",
|
|
6464
5742
|
{ style: styles.row },
|
|
6465
|
-
(0,
|
|
5743
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
|
|
6466
5744
|
variant: "primary",
|
|
6467
5745
|
size: "md",
|
|
6468
5746
|
disabled: body2.trim() === "",
|
|
@@ -6471,13 +5749,13 @@ function InitPanel({ workspace, remote }) {
|
|
|
6471
5749
|
void write(body2, exists);
|
|
6472
5750
|
}
|
|
6473
5751
|
}, exists ? "\u4FDD\u5B58\u5E76\u8986\u76D6" : "\u4FDD\u5B58"),
|
|
6474
|
-
(0,
|
|
5752
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "ghost", size: "md", onClick: () => {
|
|
6475
5753
|
setEditing(false);
|
|
6476
5754
|
} }, "\u53D6\u6D88")
|
|
6477
|
-
) : (0,
|
|
5755
|
+
) : (0, import_react4.createElement)(
|
|
6478
5756
|
"div",
|
|
6479
5757
|
{ style: styles.row },
|
|
6480
|
-
(0,
|
|
5758
|
+
(0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
|
|
6481
5759
|
variant: "primary",
|
|
6482
5760
|
size: "md",
|
|
6483
5761
|
disabled: generating,
|
|
@@ -6485,56 +5763,56 @@ function InitPanel({ workspace, remote }) {
|
|
|
6485
5763
|
onClick: () => {
|
|
6486
5764
|
void generate();
|
|
6487
5765
|
}
|
|
6488
|
-
}, exists ? "\u91CD\u65B0\
|
|
6489
|
-
exists ? (0,
|
|
5766
|
+
}, exists ? "\u91CD\u65B0\u751F\u6210 AGENTS.md" : "\u751F\u6210 AGENTS.md"),
|
|
5767
|
+
exists ? (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "outline", size: "md", onClick: startEdit }, "\u624B\u52A8\u7F16\u8F91") : null
|
|
6490
5768
|
)
|
|
6491
5769
|
)
|
|
6492
5770
|
);
|
|
6493
5771
|
}
|
|
6494
5772
|
|
|
6495
5773
|
// src/client/SkillManager.tsx
|
|
6496
|
-
var import_react7 = require("react");
|
|
6497
|
-
|
|
6498
|
-
// src/client/ResourceManager.tsx
|
|
6499
5774
|
var import_react6 = require("react");
|
|
6500
|
-
|
|
5775
|
+
|
|
5776
|
+
// src/client/ResourceManager.tsx
|
|
5777
|
+
var import_react5 = require("react");
|
|
5778
|
+
var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
6501
5779
|
var labels = { code: { copyLabel: "\u590D\u5236", copiedLabel: "\u5DF2\u590D\u5236" }, footnotes: "\u811A\u6CE8" };
|
|
6502
5780
|
var levelOf = (row2) => row2.source === "bundled" ? "bundled" : row2.source.startsWith("user") ? "user" : "project";
|
|
6503
|
-
var
|
|
5781
|
+
var sourceText = (source) => source === "bundled" ? "\u5185\u7F6E" : source === "codex-project" ? "\u9879\u76EE \xB7 Codex" : source.startsWith("user") ? "\u4E2A\u4EBA" : "\u9879\u76EE";
|
|
6504
5782
|
var sizeText = (bytes) => bytes < 1024 ? `${bytes} B` : bytes < 1024 * 1024 ? `${(bytes / 1024).toFixed(1)} KB` : `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
6505
5783
|
var fail = (r) => describeError(r.error ?? "\u64CD\u4F5C\u5931\u8D25");
|
|
6506
5784
|
function ResourceManager({ workspace, remote, kind, onConfigureSkill }) {
|
|
6507
5785
|
const noun = kind === "skill" ? "\u6280\u80FD" : "\u89C4\u5219";
|
|
6508
|
-
const [rows, setRows] = (0,
|
|
6509
|
-
const [query, setQuery] = (0,
|
|
6510
|
-
const [filter, setFilter] = (0,
|
|
6511
|
-
const [notice, setNotice] = (0,
|
|
6512
|
-
const [error, setError] = (0,
|
|
6513
|
-
const [loading, setLoading] = (0,
|
|
6514
|
-
const [revision, refresh] = (0,
|
|
6515
|
-
const [busy, setBusy] = (0,
|
|
6516
|
-
const [roots, setRoots] = (0,
|
|
6517
|
-
const [importing, setImporting] = (0,
|
|
6518
|
-
const [request, setRequest] = (0,
|
|
6519
|
-
const [preview, setPreview] = (0,
|
|
6520
|
-
const [level, setLevel] = (0,
|
|
6521
|
-
const [manual, setManual] = (0,
|
|
6522
|
-
const [sourceDir, setSourceDir] = (0,
|
|
6523
|
-
const [dirs, setDirs] = (0,
|
|
6524
|
-
const [browsePath, setBrowsePath] = (0,
|
|
6525
|
-
const [editing, setEditing] = (0,
|
|
6526
|
-
const [viewing, setViewing] = (0,
|
|
6527
|
-
const [name, setName] = (0,
|
|
6528
|
-
const [description, setDescription] = (0,
|
|
6529
|
-
const [whenToUse, setWhenToUse] = (0,
|
|
6530
|
-
const [body2, setBody] = (0,
|
|
6531
|
-
const [templateSource, setTemplateSource] = (0,
|
|
6532
|
-
const [deleting, setDeleting] = (0,
|
|
6533
|
-
const input2 = (0,
|
|
6534
|
-
const fileEpoch = (0,
|
|
6535
|
-
const browseEpoch = (0,
|
|
5786
|
+
const [rows, setRows] = (0, import_react5.useState)([]);
|
|
5787
|
+
const [query, setQuery] = (0, import_react5.useState)("");
|
|
5788
|
+
const [filter, setFilter] = (0, import_react5.useState)("all");
|
|
5789
|
+
const [notice, setNotice] = (0, import_react5.useState)("");
|
|
5790
|
+
const [error, setError] = (0, import_react5.useState)("");
|
|
5791
|
+
const [loading, setLoading] = (0, import_react5.useState)(true);
|
|
5792
|
+
const [revision, refresh] = (0, import_react5.useState)(0);
|
|
5793
|
+
const [busy, setBusy] = (0, import_react5.useState)(false);
|
|
5794
|
+
const [roots, setRoots] = (0, import_react5.useState)(null);
|
|
5795
|
+
const [importing, setImporting] = (0, import_react5.useState)(false);
|
|
5796
|
+
const [request, setRequest] = (0, import_react5.useState)(null);
|
|
5797
|
+
const [preview, setPreview] = (0, import_react5.useState)(null);
|
|
5798
|
+
const [level, setLevel] = (0, import_react5.useState)("project");
|
|
5799
|
+
const [manual, setManual] = (0, import_react5.useState)(false);
|
|
5800
|
+
const [sourceDir, setSourceDir] = (0, import_react5.useState)("");
|
|
5801
|
+
const [dirs, setDirs] = (0, import_react5.useState)([]);
|
|
5802
|
+
const [browsePath, setBrowsePath] = (0, import_react5.useState)("");
|
|
5803
|
+
const [editing, setEditing] = (0, import_react5.useState)(null);
|
|
5804
|
+
const [viewing, setViewing] = (0, import_react5.useState)(false);
|
|
5805
|
+
const [name, setName] = (0, import_react5.useState)("");
|
|
5806
|
+
const [description, setDescription] = (0, import_react5.useState)("");
|
|
5807
|
+
const [whenToUse, setWhenToUse] = (0, import_react5.useState)("");
|
|
5808
|
+
const [body2, setBody] = (0, import_react5.useState)("");
|
|
5809
|
+
const [templateSource, setTemplateSource] = (0, import_react5.useState)(null);
|
|
5810
|
+
const [deleting, setDeleting] = (0, import_react5.useState)(null);
|
|
5811
|
+
const input2 = (0, import_react5.useRef)(null);
|
|
5812
|
+
const fileEpoch = (0, import_react5.useRef)(0);
|
|
5813
|
+
const browseEpoch = (0, import_react5.useRef)(0);
|
|
6536
5814
|
const readonly = editing !== null && editing !== "new" && (levelOf(editing) === "bundled" || editing.source === "codex-project");
|
|
6537
|
-
(0,
|
|
5815
|
+
(0, import_react5.useEffect)(() => {
|
|
6538
5816
|
let active = true;
|
|
6539
5817
|
setLoading(true);
|
|
6540
5818
|
setRows([]);
|
|
@@ -6561,7 +5839,7 @@ function ResourceManager({ workspace, remote, kind, onConfigureSkill }) {
|
|
|
6561
5839
|
fileEpoch.current++;
|
|
6562
5840
|
};
|
|
6563
5841
|
}, [workspace, remote, kind, revision]);
|
|
6564
|
-
(0,
|
|
5842
|
+
(0, import_react5.useEffect)(() => {
|
|
6565
5843
|
let active = true;
|
|
6566
5844
|
setPreview(null);
|
|
6567
5845
|
if (!request) return;
|
|
@@ -6723,13 +6001,15 @@ function ResourceManager({ workspace, remote, kind, onConfigureSkill }) {
|
|
|
6723
6001
|
setBusy(false);
|
|
6724
6002
|
}
|
|
6725
6003
|
};
|
|
6726
|
-
const
|
|
6004
|
+
const save = async () => {
|
|
6727
6005
|
if (busy) return;
|
|
6728
6006
|
setBusy(true);
|
|
6729
6007
|
setError("");
|
|
6730
6008
|
try {
|
|
6731
|
-
if (editing === "new" && rows.some((r2) => r2.name === name && (levelOf(r2) === level || levelOf(r2) === "bundled")))
|
|
6732
|
-
|
|
6009
|
+
if (editing === "new" && rows.some((r2) => r2.name === name && (levelOf(r2) === level && r2.source !== "codex-project" || kind === "rule" && levelOf(r2) === "bundled"))) {
|
|
6010
|
+
throw new Error("\u540C\u540D\u8D44\u6E90\u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u540D\u6216\u7F16\u8F91\u73B0\u6709\u8D44\u6E90");
|
|
6011
|
+
}
|
|
6012
|
+
const r = kind === "skill" ? await remote.writeSkill({ name, description, whenToUse, content: body2, level, path: workspace, createOnly: editing === "new" }) : await remote.writeRule({ name, content: body2, level, path: workspace });
|
|
6733
6013
|
if (!r.ok) throw new Error(fail(r));
|
|
6734
6014
|
if (!r.value.ok) throw new Error(r.value.error ?? "\u4FDD\u5B58\u5931\u8D25");
|
|
6735
6015
|
const copied = templateSource !== null;
|
|
@@ -6763,104 +6043,329 @@ function ResourceManager({ workspace, remote, kind, onConfigureSkill }) {
|
|
|
6763
6043
|
setBusy(false);
|
|
6764
6044
|
}
|
|
6765
6045
|
};
|
|
6766
|
-
const status = () => error ? (0,
|
|
6767
|
-
const targets = () => (0,
|
|
6046
|
+
const status = () => error ? (0, import_react5.createElement)("div", { className: "te-alert", role: "alert" }, error) : null;
|
|
6047
|
+
const targets = () => (0, import_react5.createElement)(
|
|
6768
6048
|
"div",
|
|
6769
6049
|
{ className: "te-targets" },
|
|
6770
|
-
...["project", "user"].map((lvl) => (0,
|
|
6050
|
+
...["project", "user"].map((lvl) => (0, import_react5.createElement)(
|
|
6771
6051
|
"button",
|
|
6772
6052
|
{ type: "button", key: lvl, className: `te-target ${level === lvl ? "selected" : ""}`, "aria-pressed": level === lvl, disabled: busy || editing !== null && editing !== "new", onClick: () => {
|
|
6773
6053
|
setPreview(null);
|
|
6774
6054
|
setLevel(lvl);
|
|
6775
6055
|
} },
|
|
6776
|
-
(0,
|
|
6777
|
-
(0,
|
|
6056
|
+
(0, import_react5.createElement)("strong", null, lvl === "project" ? "\u9879\u76EE\u5171\u4EAB" : "\u4E2A\u4EBA\u5168\u5C40"),
|
|
6057
|
+
(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")
|
|
6778
6058
|
)),
|
|
6779
|
-
(0,
|
|
6059
|
+
(0, import_react5.createElement)("code", { className: "te-path" }, roots?.[level] ?? (level === "project" ? `${workspace}/.dsh/${kind}s` : `DSH_HOME/${kind}s`))
|
|
6780
6060
|
);
|
|
6781
6061
|
const visible = rows.filter((r) => `${r.name} ${r.description ?? ""}`.toLowerCase().includes(query.toLowerCase()) && (filter === "all" || levelOf(r) === filter));
|
|
6782
|
-
return (0,
|
|
6062
|
+
return (0, import_react5.createElement)(
|
|
6783
6063
|
"section",
|
|
6784
6064
|
{ className: "te-resource" },
|
|
6785
|
-
(0,
|
|
6065
|
+
(0, import_react5.createElement)("input", { type: "file", ref: input2, 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) => {
|
|
6786
6066
|
void selected(Array.from(e.target.files ?? []));
|
|
6787
6067
|
} }),
|
|
6788
|
-
(0,
|
|
6068
|
+
(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_primitives4.Button, { variant: "outline", onClick: () => {
|
|
6789
6069
|
void edit("new");
|
|
6790
|
-
} }, `\u65B0\u5EFA${noun}`), (0,
|
|
6791
|
-
(0,
|
|
6792
|
-
notice ? (0,
|
|
6070
|
+
} }, `\u65B0\u5EFA${noun}`), (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "primary", onClick: choose }, `\u5B89\u88C5${noun}`))),
|
|
6071
|
+
(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: "project" }, "\u9879\u76EE"), (0, import_react5.createElement)("option", { value: "user" }, "\u4E2A\u4EBA")), (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", onClick: () => refresh((n) => n + 1), disabled: loading }, "\u5237\u65B0")),
|
|
6072
|
+
notice ? (0, import_react5.createElement)("div", { className: "te-success", role: "status" }, notice) : null,
|
|
6793
6073
|
!importing && !editing && !deleting ? status() : null,
|
|
6794
|
-
loading ? (0,
|
|
6074
|
+
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((row2) => (0, import_react5.createElement)(
|
|
6795
6075
|
"article",
|
|
6796
6076
|
{ className: "te-resource-card", key: row2.source + "/" + row2.name },
|
|
6797
|
-
(0,
|
|
6798
|
-
(0,
|
|
6799
|
-
(0,
|
|
6800
|
-
(0,
|
|
6077
|
+
(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" }, sourceText(row2.source))),
|
|
6078
|
+
(0, import_react5.createElement)("h3", null, row2.name),
|
|
6079
|
+
(0, import_react5.createElement)("p", null, row2.description || "\u9879\u76EE\u7EA6\u5B9A\u4E0E\u6267\u884C\u89C4\u5219"),
|
|
6080
|
+
(0, import_react5.createElement)("div", { className: "te-actions" }, kind === "skill" && onConfigureSkill ? (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "primary", size: "sm", onClick: () => onConfigureSkill({ source: row2.source === "codex-project" ? "codex-project" : levelOf(row2), name: row2.name }) }, "\u914D\u7F6E\u89C4\u5219") : null, (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", size: "sm", onClick: () => {
|
|
6801
6081
|
void edit(row2, true);
|
|
6802
|
-
} }, "\u67E5\u770B"), levelOf(row2) === "bundled" ? (0,
|
|
6082
|
+
} }, "\u67E5\u770B"), levelOf(row2) === "bundled" ? (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "sm", disabled: busy, onClick: () => {
|
|
6803
6083
|
void copyTemplate(row2);
|
|
6804
|
-
} }, "\u4EE5\u6B64\u4E3A\u6A21\u677F\u65B0\u5EFA") : row2.source !== "codex-project" ? (0,
|
|
6084
|
+
} }, "\u4EE5\u6B64\u4E3A\u6A21\u677F\u65B0\u5EFA") : row2.source !== "codex-project" ? (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "sm", onClick: () => {
|
|
6805
6085
|
void edit(row2);
|
|
6806
|
-
} }, "\u7F16\u8F91") : null, levelOf(row2) !== "bundled" && row2.source !== "codex-project" ? (0,
|
|
6086
|
+
} }, "\u7F16\u8F91") : null, levelOf(row2) !== "bundled" && row2.source !== "codex-project" ? (0, import_react5.createElement)("button", { className: "te-delete", onClick: () => {
|
|
6807
6087
|
setDeleting(row2);
|
|
6808
6088
|
setError("");
|
|
6809
6089
|
} }, "\u5220\u9664") : null)
|
|
6810
6090
|
))),
|
|
6811
|
-
kind === "skill" ? (0,
|
|
6091
|
+
kind === "skill" ? (0, import_react5.createElement)("button", { className: "te-link", onClick: () => {
|
|
6812
6092
|
setImporting(true);
|
|
6813
6093
|
setManual(true);
|
|
6814
6094
|
setError("");
|
|
6815
6095
|
} }, "\u9AD8\u7EA7\uFF1A\u4ECE Harness \u4E3B\u673A\u8DEF\u5F84\u5B89\u88C5") : null,
|
|
6816
|
-
importing ? (0,
|
|
6096
|
+
importing ? (0, import_react5.createElement)(
|
|
6817
6097
|
ResourceModal,
|
|
6818
|
-
{ 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,
|
|
6098
|
+
{ 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_primitives4.Button, { variant: "ghost", disabled: busy, onClick: close }, "\u53D6\u6D88"), (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "primary", disabled: busy || !preview || preview.conflict, onClick: () => {
|
|
6819
6099
|
void install();
|
|
6820
6100
|
} }, busy ? "\u5904\u7406\u4E2D\u2026" : "\u786E\u8BA4\u5B89\u88C5")) },
|
|
6821
6101
|
targets(),
|
|
6822
|
-
(0,
|
|
6823
|
-
manual ? (0,
|
|
6102
|
+
(0, import_react5.createElement)("div", { className: "te-actions" }, (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", disabled: busy, onClick: choose }, "\u91CD\u65B0\u9009\u62E9"), kind === "skill" ? (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", disabled: busy, onClick: () => setManual(!manual) }, manual ? "\u6536\u8D77\u9AD8\u7EA7\u65B9\u5F0F" : "\u4E3B\u673A\u8DEF\u5F84") : null),
|
|
6103
|
+
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) => {
|
|
6824
6104
|
setSourceDir(e.target.value);
|
|
6825
6105
|
setRequest(null);
|
|
6826
|
-
} }), (0,
|
|
6106
|
+
} }), (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", onClick: () => {
|
|
6827
6107
|
void browse(sourceDir);
|
|
6828
|
-
} }, "\u6D4F\u89C8"), (0,
|
|
6108
|
+
} }, "\u6D4F\u89C8"), (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", disabled: busy || !sourceDir.trim(), onClick: () => setRequest({ kind, level, path: workspace, files: [], sourceDir }) }, "\u9884\u89C8\u76EE\u5F55")), (0, import_react5.createElement)("div", { className: "te-dir-list" }, browsePath ? (0, import_react5.createElement)("button", { onClick: () => {
|
|
6829
6109
|
void browse(browsePath.replace(/[\\/][^\\/]+[\\/]?$/u, "") || "/");
|
|
6830
|
-
} }, "\u2191 \u4E0A\u7EA7\u76EE\u5F55") : null, ...dirs.map((d) => (0,
|
|
6110
|
+
} }, "\u2191 \u4E0A\u7EA7\u76EE\u5F55") : null, ...dirs.map((d) => (0, import_react5.createElement)("button", { key: d.name, onClick: () => {
|
|
6831
6111
|
setRequest(null);
|
|
6832
6112
|
void browse(browsePath.replace(/[\\/]+$/u, "") + "/" + d.name);
|
|
6833
6113
|
} }, d.name + (d.hasSkill ? " \xB7 SKILL.md" : ""))))) : null,
|
|
6834
|
-
busy ? (0,
|
|
6114
|
+
busy ? (0, import_react5.createElement)("p", { role: "status" }, "\u6B63\u5728\u6821\u9A8C\u6587\u4EF6\uFF0C\u8BF7\u7A0D\u5019\u2026") : null,
|
|
6835
6115
|
status(),
|
|
6836
|
-
preview ? (0,
|
|
6116
|
+
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_primitives4.MarkdownText, { text: preview.content, labels }))) : null
|
|
6837
6117
|
) : null,
|
|
6838
|
-
editing ? (0,
|
|
6118
|
+
editing ? (0, import_react5.createElement)(
|
|
6839
6119
|
ResourceModal,
|
|
6840
|
-
{ title: editing === "new" ? `\u65B0\u5EFA${noun}` : `${viewing ? "\u67E5\u770B" : "\u7F16\u8F91"}${noun} \xB7 ${name}`, onClose: close, footer: (0,
|
|
6120
|
+
{ 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_primitives4.Button, { variant: "ghost", disabled: busy, onClick: close }, "\u5173\u95ED"), editing !== "new" && levelOf(editing) === "bundled" ? (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", disabled: busy, onClick: () => {
|
|
6841
6121
|
void copyTemplate(editing);
|
|
6842
|
-
} }, "\u4EE5\u6B64\u4E3A\u6A21\u677F\u65B0\u5EFA") : null, !readonly ? (0,
|
|
6843
|
-
void
|
|
6122
|
+
} }, "\u4EE5\u6B64\u4E3A\u6A21\u677F\u65B0\u5EFA") : null, !readonly ? (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", disabled: busy, onClick: () => setViewing(!viewing) }, viewing ? "\u7F16\u8F91\u5185\u5BB9" : "\u9884\u89C8") : null, !readonly ? (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "primary", disabled: busy || !name.trim() || !body2.trim() || kind === "skill" && !description.trim(), onClick: () => {
|
|
6123
|
+
void save();
|
|
6844
6124
|
} }, busy ? "\u5904\u7406\u4E2D\u2026" : "\u4FDD\u5B58") : null) },
|
|
6845
|
-
!readonly ? targets() : (0,
|
|
6846
|
-
templateSource ? (0,
|
|
6125
|
+
!readonly ? targets() : (0, import_react5.createElement)("p", { className: "te-badge" }, editing.source === "codex-project" ? "Codex \u9879\u76EE\u6280\u80FD \xB7 \u6B63\u6587\u8BF7\u5728\u539F\u76EE\u5F55\u7F16\u8F91" : "\u5185\u7F6E\u6837\u672C \xB7 \u53EA\u8BFB"),
|
|
6126
|
+
templateSource ? (0, import_react5.createElement)("p", null, `\u4EE5\u300C${templateSource.name}\u300D\u4E3A\u6A21\u677F\u590D\u5236\u6B63\u6587\u3002\u65B0\u8D44\u6E90\u7684\u5B8C\u6210\u51ED\u8BC1\u3001\u89C4\u5219\u548C\u9636\u6BB5\u7ED1\u5B9A\u9700\u5355\u72EC\u914D\u7F6E\uFF0C\u4FDD\u5B58\u672C\u8EAB\u4E0D\u4F1A\u542F\u7528\u5B83\u3002`) : null,
|
|
6847
6127
|
status(),
|
|
6848
|
-
viewing ? (0,
|
|
6128
|
+
viewing ? (0, import_react5.createElement)("div", { className: "te-markdown" }, (0, import_react5.createElement)(import_dsh_client_ui_primitives4.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) })))
|
|
6849
6129
|
) : null,
|
|
6850
|
-
deleting ? (0,
|
|
6130
|
+
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_primitives4.Button, { variant: "outline", disabled: busy, onClick: close }, "\u4FDD\u7559"), (0, import_react5.createElement)("button", { className: "te-danger-button", disabled: busy, onClick: () => {
|
|
6851
6131
|
void remove();
|
|
6852
|
-
} }, busy ? "\u5220\u9664\u4E2D\u2026" : "\u786E\u8BA4\u6C38\u4E45\u5220\u9664")) }, (0,
|
|
6132
|
+
} }, 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
|
|
6853
6133
|
);
|
|
6854
6134
|
}
|
|
6855
6135
|
|
|
6136
|
+
// src/workflows.ts
|
|
6137
|
+
var STANDARD = {
|
|
6138
|
+
stages: ["\u9700\u6C42\u8BC4\u5BA1", "\u8BBE\u8BA1", "\u5F00\u53D1", "\u4EA4\u4ED8", "\u4EE3\u7801\u5BA1\u6838", "\u5B8C\u6210"],
|
|
6139
|
+
start_stage: "\u9700\u6C42\u8BC4\u5BA1",
|
|
6140
|
+
transitions: [
|
|
6141
|
+
{ from: "\u9700\u6C42\u8BC4\u5BA1", to: "\u8BBE\u8BA1", requires: ["requirement_confirmation", "artifacts_present"] },
|
|
6142
|
+
{ from: "\u8BBE\u8BA1", to: "\u5F00\u53D1", requires: ["solution_confirmation", "artifacts_present"] },
|
|
6143
|
+
{ from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] },
|
|
6144
|
+
{ from: "\u4EA4\u4ED8", to: "\u4EE3\u7801\u5BA1\u6838", requires: ["verified"] },
|
|
6145
|
+
{ from: "\u4EE3\u7801\u5BA1\u6838", to: "\u5B8C\u6210", requires: ["review_passed", "artifacts_present"] }
|
|
6146
|
+
],
|
|
6147
|
+
// No artifacts, no commit policy, no skills: the skeleton carries none of them.
|
|
6148
|
+
artifacts: [],
|
|
6149
|
+
commit: { policy: "task", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EE3\u7801\u5BA1\u6838"], file_scope: true },
|
|
6150
|
+
high_risk_requires_verification: true
|
|
6151
|
+
};
|
|
6152
|
+
var STANDARD_RECOMMENDATION = {
|
|
6153
|
+
commit: {
|
|
6154
|
+
// Only the TEXT conventions. Policy, checkpoints and scope stay on the
|
|
6155
|
+
// skeleton: they decide when a gate fires, not how a message reads.
|
|
6156
|
+
message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
|
|
6157
|
+
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"
|
|
6158
|
+
},
|
|
6159
|
+
artifacts: [
|
|
6160
|
+
{ stage: "\u9700\u6C42\u8BC4\u5BA1", id: "requirement", name: "\u9700\u6C42\u8BF4\u660E", fields: ["scope", "acceptance_criteria"] },
|
|
6161
|
+
{ stage: "\u8BBE\u8BA1", id: "design", name: "\u8BBE\u8BA1\u6587\u6863", fields: ["approach", "risks", "impact"] },
|
|
6162
|
+
{ stage: "\u4EE3\u7801\u5BA1\u6838", id: "review", name: "\u8BC4\u5BA1\u8BB0\u5F55", fields: ["conclusion", "issues"] }
|
|
6163
|
+
]
|
|
6164
|
+
};
|
|
6165
|
+
var AGILE = {
|
|
6166
|
+
stages: ["\u9700\u6C42", "\u5F00\u53D1", "\u4EA4\u4ED8", "\u5BA1\u67E5"],
|
|
6167
|
+
start_stage: "\u9700\u6C42",
|
|
6168
|
+
transitions: [
|
|
6169
|
+
{ from: "\u9700\u6C42", to: "\u5F00\u53D1", requires: ["requirement_confirmation"] },
|
|
6170
|
+
{ from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] },
|
|
6171
|
+
// Entering 审查 is unconditional. A review guard on this edge would be
|
|
6172
|
+
// circular — it would demand the verdict BEFORE the stage that produces it —
|
|
6173
|
+
// and it would also block the commit at 交付, since a commit requires its
|
|
6174
|
+
// stage's outgoing guards. What 审查 requires is declared as completion_guards
|
|
6175
|
+
// instead, because a terminal stage has no outgoing edge to carry it.
|
|
6176
|
+
{ from: "\u4EA4\u4ED8", to: "\u5BA1\u67E5", requires: [] }
|
|
6177
|
+
],
|
|
6178
|
+
artifacts: [],
|
|
6179
|
+
commit: { policy: "item", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EA4\u4ED8"], file_scope: true },
|
|
6180
|
+
high_risk_requires_verification: false,
|
|
6181
|
+
// 审查 is terminal and IS the review, so there is no outgoing edge to carry
|
|
6182
|
+
// the guard. Declaring it here is what makes a blocked review prevent
|
|
6183
|
+
// completion; without it the stage could be reached and finished with the
|
|
6184
|
+
// review failing, which is what the assessment found.
|
|
6185
|
+
completion_guards: ["review_passed"]
|
|
6186
|
+
};
|
|
6187
|
+
var AGILE_RECOMMENDATION = {
|
|
6188
|
+
commit: {
|
|
6189
|
+
// `item` policy emits two label shapes: `T<n>` mid-flow and `TASK` at the
|
|
6190
|
+
// closing checkpoint. The pattern accepts BOTH, so the label the engine hands
|
|
6191
|
+
// the model always satisfies the rule that validates it.
|
|
6192
|
+
message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
|
|
6193
|
+
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"
|
|
6194
|
+
},
|
|
6195
|
+
artifacts: [
|
|
6196
|
+
{ stage: "\u9700\u6C42", id: "requirement", name: "\u9700\u6C42\u8BF4\u660E", fields: ["scope"] },
|
|
6197
|
+
// Optional review record; the flow's review gate itself does not require a skill.
|
|
6198
|
+
{ stage: "\u5BA1\u67E5", id: "review", name: "\u8BC4\u5BA1\u8BB0\u5F55", fields: ["conclusion", "issues"] }
|
|
6199
|
+
]
|
|
6200
|
+
};
|
|
6201
|
+
var MINIMAL = {
|
|
6202
|
+
stages: ["\u5F00\u53D1", "\u4EA4\u4ED8"],
|
|
6203
|
+
start_stage: "\u5F00\u53D1",
|
|
6204
|
+
transitions: [
|
|
6205
|
+
{ from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] }
|
|
6206
|
+
],
|
|
6207
|
+
artifacts: [],
|
|
6208
|
+
commit: { policy: "task", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EA4\u4ED8"], file_scope: false },
|
|
6209
|
+
high_risk_requires_verification: false
|
|
6210
|
+
};
|
|
6211
|
+
var MINIMAL_RECOMMENDATION = {
|
|
6212
|
+
// A fast-change flow checks each change once, not twice under two headings a
|
|
6213
|
+
// short change rarely distinguishes. The item still has to be reviewed — what
|
|
6214
|
+
// drops is the duplicated verdict, which is where the weight actually was.
|
|
6215
|
+
review_depth: "single"
|
|
6216
|
+
};
|
|
6217
|
+
function deriveCapabilities(config) {
|
|
6218
|
+
const caps = [];
|
|
6219
|
+
const guards = new Set(config.transitions.flatMap((t) => t.requires ?? []));
|
|
6220
|
+
if (guards.has("verified")) caps.push("verification_gate");
|
|
6221
|
+
if (guards.has("review_passed")) caps.push("review_gate");
|
|
6222
|
+
if (guards.has("artifacts_present")) caps.push("artifact_gate");
|
|
6223
|
+
if (config.commit.file_scope) caps.push("file_scope");
|
|
6224
|
+
return caps;
|
|
6225
|
+
}
|
|
6226
|
+
function preset(id, version, label3, description, config, recommendation) {
|
|
6227
|
+
return {
|
|
6228
|
+
id,
|
|
6229
|
+
version,
|
|
6230
|
+
label: label3,
|
|
6231
|
+
description,
|
|
6232
|
+
capabilities: deriveCapabilities(config),
|
|
6233
|
+
config,
|
|
6234
|
+
// exactOptionalPropertyTypes: omit rather than assign undefined.
|
|
6235
|
+
...recommendation !== void 0 ? { recommendation } : {}
|
|
6236
|
+
};
|
|
6237
|
+
}
|
|
6238
|
+
var FLOW_PRESETS = {
|
|
6239
|
+
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),
|
|
6240
|
+
// Version 4 for agile: 交付 → 审查 now requires review_passed, where it previously
|
|
6241
|
+
// required nothing. That is a gate-semantics change, so a task created before it
|
|
6242
|
+
// keeps its frozen version 3 config and behaves exactly as it did.
|
|
6243
|
+
//
|
|
6244
|
+
// Version 3 across all three: the preset is now a bare skeleton and its former
|
|
6245
|
+
// built-in bindings, commit rule and artifacts are a separate recommendation a
|
|
6246
|
+
// user adopts explicitly. Tasks created before this keep their frozen config and
|
|
6247
|
+
// are unaffected; a project's existing config is likewise left exactly as it is.
|
|
6248
|
+
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),
|
|
6249
|
+
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)
|
|
6250
|
+
};
|
|
6251
|
+
function dedupe(names) {
|
|
6252
|
+
return [...new Set(names)];
|
|
6253
|
+
}
|
|
6254
|
+
function applyProjectConfig(base, project) {
|
|
6255
|
+
if (project === void 0) return base;
|
|
6256
|
+
const next = { ...base };
|
|
6257
|
+
if (project.stage_bindings !== void 0) {
|
|
6258
|
+
const profiles = { ...project.skill_profiles ?? {} };
|
|
6259
|
+
const explicitProfiles = new Set(Object.keys(project.skill_profiles ?? {}));
|
|
6260
|
+
const problems = [];
|
|
6261
|
+
const bindings = {};
|
|
6262
|
+
for (const [stage, binding] of Object.entries(project.stage_bindings)) {
|
|
6263
|
+
const entry = {};
|
|
6264
|
+
if (binding === null || typeof binding !== "object") {
|
|
6265
|
+
problems.push(`stage_bindings "${stage}" must be an object`);
|
|
6266
|
+
bindings[stage] = entry;
|
|
6267
|
+
continue;
|
|
6268
|
+
}
|
|
6269
|
+
if (binding.skill_refs !== void 0 && binding.skills !== void 0) {
|
|
6270
|
+
problems.push(`stage_bindings "${stage}" has both skill_refs and legacy skills`);
|
|
6271
|
+
}
|
|
6272
|
+
if (binding.skill_refs !== void 0) {
|
|
6273
|
+
if (!Array.isArray(binding.skill_refs)) {
|
|
6274
|
+
problems.push(`stage_bindings "${stage}" skill_refs must be an array`);
|
|
6275
|
+
}
|
|
6276
|
+
entry.skills = (Array.isArray(binding.skill_refs) ? binding.skill_refs : []).flatMap((ref) => {
|
|
6277
|
+
if (ref === null || typeof ref !== "object") {
|
|
6278
|
+
problems.push(`stage_bindings "${stage}" has an invalid skill reference`);
|
|
6279
|
+
return [];
|
|
6280
|
+
}
|
|
6281
|
+
const key = formatResourceRef(ref);
|
|
6282
|
+
const profile = profiles[key];
|
|
6283
|
+
if (profile === void 0) {
|
|
6284
|
+
problems.push(`skill profile "${key}" is missing`);
|
|
6285
|
+
return [];
|
|
6286
|
+
}
|
|
6287
|
+
if (profile === null || !Array.isArray(profile.rules)) {
|
|
6288
|
+
problems.push(`skill profile "${key}" must declare a rules array`);
|
|
6289
|
+
return [];
|
|
6290
|
+
}
|
|
6291
|
+
return [{ skill: ref, rules: profile.rules, ...profile.evidence !== void 0 ? { evidence: profile.evidence } : {} }];
|
|
6292
|
+
});
|
|
6293
|
+
} else if (binding.skills !== void 0) {
|
|
6294
|
+
if (!Array.isArray(binding.skills)) {
|
|
6295
|
+
problems.push(`stage_bindings "${stage}" skills must be an array`);
|
|
6296
|
+
}
|
|
6297
|
+
entry.skills = (Array.isArray(binding.skills) ? binding.skills : []).flatMap((skill) => {
|
|
6298
|
+
if (skill === null || typeof skill !== "object" || skill.skill === null || typeof skill.skill !== "object") {
|
|
6299
|
+
problems.push(`stage_bindings "${stage}" has an invalid skill binding`);
|
|
6300
|
+
return [];
|
|
6301
|
+
}
|
|
6302
|
+
const key = formatResourceRef(skill.skill);
|
|
6303
|
+
if (explicitProfiles.has(key)) {
|
|
6304
|
+
const profile = profiles[key];
|
|
6305
|
+
if (profile === null || !Array.isArray(profile?.rules)) {
|
|
6306
|
+
problems.push(`skill profile "${key}" must declare a rules array`);
|
|
6307
|
+
return [];
|
|
6308
|
+
}
|
|
6309
|
+
return [{
|
|
6310
|
+
skill: skill.skill,
|
|
6311
|
+
rules: profile.rules,
|
|
6312
|
+
...profile.evidence !== void 0 ? { evidence: profile.evidence } : {}
|
|
6313
|
+
}];
|
|
6314
|
+
}
|
|
6315
|
+
const candidate = { rules: skill.rules ?? [], ...skill.evidence !== void 0 ? { evidence: skill.evidence } : {} };
|
|
6316
|
+
const existing = profiles[key];
|
|
6317
|
+
if (existing !== void 0 && JSON.stringify(existing) !== JSON.stringify(candidate)) {
|
|
6318
|
+
problems.push(`skill "${key}" has different rules or evidence in multiple stages; copy it as a distinct skill`);
|
|
6319
|
+
} else profiles[key] = candidate;
|
|
6320
|
+
return [skill];
|
|
6321
|
+
});
|
|
6322
|
+
}
|
|
6323
|
+
const legacy = dedupe(binding.legacy_rules ?? []);
|
|
6324
|
+
if (legacy.length > 0) entry.legacy_rules = legacy;
|
|
6325
|
+
bindings[stage] = entry;
|
|
6326
|
+
}
|
|
6327
|
+
next.stage_bindings = bindings;
|
|
6328
|
+
next.skill_profiles = profiles;
|
|
6329
|
+
if (problems.length > 0) next.configuration_errors = problems;
|
|
6330
|
+
} else if (project.skill_profiles !== void 0) {
|
|
6331
|
+
next.skill_profiles = project.skill_profiles;
|
|
6332
|
+
}
|
|
6333
|
+
if (project.commit !== void 0) next.commit = project.commit;
|
|
6334
|
+
if (project.artifacts !== void 0) next.artifacts = project.artifacts;
|
|
6335
|
+
if (project.review_depth !== void 0) next.review_depth = project.review_depth;
|
|
6336
|
+
if (project.commit_required !== void 0) next.commit_required = project.commit_required;
|
|
6337
|
+
return next;
|
|
6338
|
+
}
|
|
6339
|
+
function compactProjectConfig(project) {
|
|
6340
|
+
const resolved = resolveFlow(project.flow, project);
|
|
6341
|
+
if (!resolved.ok) return project;
|
|
6342
|
+
const profiles = resolved.config.skill_profiles ?? {};
|
|
6343
|
+
const bindings = {};
|
|
6344
|
+
for (const [stage, binding] of Object.entries(resolved.config.stage_bindings ?? {})) {
|
|
6345
|
+
bindings[stage] = {
|
|
6346
|
+
skill_refs: (binding.skills ?? []).map((entry) => entry.skill),
|
|
6347
|
+
...binding.legacy_rules?.length ? { legacy_rules: binding.legacy_rules } : {}
|
|
6348
|
+
};
|
|
6349
|
+
}
|
|
6350
|
+
return { ...project, stage_bindings: bindings, skill_profiles: profiles };
|
|
6351
|
+
}
|
|
6352
|
+
function resolveFlow(flow, project) {
|
|
6353
|
+
const preset2 = FLOW_PRESETS[flow];
|
|
6354
|
+
if (preset2 === void 0) {
|
|
6355
|
+
return { ok: false, code: "UNKNOWN_FLOW", flow, knownFlows: Object.keys(FLOW_PRESETS) };
|
|
6356
|
+
}
|
|
6357
|
+
const { flow: _ignored, ...rest } = project ?? { flow };
|
|
6358
|
+
return { ok: true, config: applyProjectConfig(preset2.config, { flow, ...rest }), preset: preset2 };
|
|
6359
|
+
}
|
|
6360
|
+
|
|
6856
6361
|
// src/client/SkillManager.tsx
|
|
6857
|
-
var
|
|
6362
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
6858
6363
|
function SkillManager({ workspace, remote }) {
|
|
6859
|
-
const [config, setConfig] = (0,
|
|
6860
|
-
const [rules, setRules] = (0,
|
|
6861
|
-
const [selected, setSelected] = (0,
|
|
6862
|
-
const [message, setMessage] = (0,
|
|
6863
|
-
(0,
|
|
6364
|
+
const [config, setConfig] = (0, import_react6.useState)(null);
|
|
6365
|
+
const [rules, setRules] = (0, import_react6.useState)([]);
|
|
6366
|
+
const [selected, setSelected] = (0, import_react6.useState)(null);
|
|
6367
|
+
const [message, setMessage] = (0, import_react6.useState)("");
|
|
6368
|
+
(0, import_react6.useEffect)(() => {
|
|
6864
6369
|
let active = true;
|
|
6865
6370
|
void Promise.all([remote.read(workspace), remote.listRules(workspace)]).then(([saved, availableRules]) => {
|
|
6866
6371
|
if (!active) return;
|
|
@@ -6901,15 +6406,15 @@ function SkillManager({ workspace, remote }) {
|
|
|
6901
6406
|
setMessage(`\u5DF2\u4FDD\u5B58 ${selected.name} \u7684\u89C4\u5219\u914D\u7F6E\u3002`);
|
|
6902
6407
|
setSelected(null);
|
|
6903
6408
|
};
|
|
6904
|
-
return /* @__PURE__ */ (0,
|
|
6905
|
-
/* @__PURE__ */ (0,
|
|
6906
|
-
/* @__PURE__ */ (0,
|
|
6409
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `te-config-layout${selected ? " is-open" : ""}`, children: [
|
|
6410
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-config-main", children: [
|
|
6411
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ResourceManager, { workspace, remote, kind: "skill", onConfigureSkill: config ? (ref) => {
|
|
6907
6412
|
setMessage("");
|
|
6908
6413
|
setSelected(ref);
|
|
6909
6414
|
} : void 0 }),
|
|
6910
|
-
selected === null && message ? /* @__PURE__ */ (0,
|
|
6415
|
+
selected === null && message ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", className: "te-success", children: message }) : null
|
|
6911
6416
|
] }),
|
|
6912
|
-
selected !== null ? /* @__PURE__ */ (0,
|
|
6417
|
+
selected !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
6913
6418
|
SkillRuleDialog,
|
|
6914
6419
|
{
|
|
6915
6420
|
skill: selected,
|
|
@@ -6925,14 +6430,14 @@ function SkillManager({ workspace, remote }) {
|
|
|
6925
6430
|
}
|
|
6926
6431
|
|
|
6927
6432
|
// src/client/RuleManager.tsx
|
|
6928
|
-
var
|
|
6433
|
+
var import_react7 = require("react");
|
|
6929
6434
|
function RuleManager(props) {
|
|
6930
|
-
return (0,
|
|
6435
|
+
return (0, import_react7.createElement)(ResourceManager, { ...props, key: props.workspace, kind: "rule" });
|
|
6931
6436
|
}
|
|
6932
6437
|
|
|
6933
6438
|
// src/client/TaskLedger.tsx
|
|
6934
|
-
var
|
|
6935
|
-
var
|
|
6439
|
+
var import_react8 = require("react");
|
|
6440
|
+
var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
6936
6441
|
var card3 = {
|
|
6937
6442
|
display: "flex",
|
|
6938
6443
|
flexDirection: "column",
|
|
@@ -6970,10 +6475,10 @@ var badge = {
|
|
|
6970
6475
|
color: "var(--dsw-alias-label-secondary)"
|
|
6971
6476
|
};
|
|
6972
6477
|
function verdictDot(outcome) {
|
|
6973
|
-
return (0,
|
|
6478
|
+
return (0, import_react8.createElement)(import_dsh_client_ui_primitives5.StateDot, { state: outcome === "pass" ? "done" : "error" });
|
|
6974
6479
|
}
|
|
6975
6480
|
function itemStatusDot(status) {
|
|
6976
|
-
return (0,
|
|
6481
|
+
return (0, import_react8.createElement)(import_dsh_client_ui_primitives5.StateDot, { state: status === "done" ? "done" : "ongoing" });
|
|
6977
6482
|
}
|
|
6978
6483
|
function timeText(at) {
|
|
6979
6484
|
return at.slice(0, 19).replace("T", " ");
|
|
@@ -6981,48 +6486,48 @@ function timeText(at) {
|
|
|
6981
6486
|
function itemAudit(item) {
|
|
6982
6487
|
const lines = [];
|
|
6983
6488
|
if (item.dispatch !== void 0) {
|
|
6984
|
-
lines.push((0,
|
|
6489
|
+
lines.push((0, import_react8.createElement)(
|
|
6985
6490
|
"div",
|
|
6986
6491
|
{ key: "dispatch", style: metaLine },
|
|
6987
|
-
(0,
|
|
6988
|
-
(0,
|
|
6989
|
-
(0,
|
|
6492
|
+
(0, import_react8.createElement)("span", { style: badge }, "\u5DF2\u6D3E\u53D1"),
|
|
6493
|
+
(0, import_react8.createElement)("span", null, item.dispatch.description === "" ? "\uFF08\u65E0\u63CF\u8FF0\uFF09" : item.dispatch.description),
|
|
6494
|
+
(0, import_react8.createElement)("span", { style: badge }, timeText(item.dispatch.at))
|
|
6990
6495
|
));
|
|
6991
6496
|
}
|
|
6992
6497
|
if (item.review !== void 0) {
|
|
6993
6498
|
const spec = item.review.spec;
|
|
6994
6499
|
const quality = item.review.quality;
|
|
6995
|
-
lines.push((0,
|
|
6500
|
+
lines.push((0, import_react8.createElement)(
|
|
6996
6501
|
"div",
|
|
6997
6502
|
{ key: "review", style: metaLine },
|
|
6998
6503
|
verdictDot(spec.outcome),
|
|
6999
|
-
(0,
|
|
7000
|
-
(0,
|
|
6504
|
+
(0, import_react8.createElement)("span", null, `\u89C4\u683C\u7B26\u5408 ${spec.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`),
|
|
6505
|
+
(0, import_react8.createElement)("span", null, "\xB7"),
|
|
7001
6506
|
verdictDot(quality.outcome),
|
|
7002
|
-
(0,
|
|
6507
|
+
(0, import_react8.createElement)("span", null, `\u4EE3\u7801\u8D28\u91CF ${quality.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`)
|
|
7003
6508
|
));
|
|
7004
6509
|
const failNotes = [spec, quality].flatMap((stage) => stage.outcome === "fail" ? stage.notes ?? [] : []);
|
|
7005
6510
|
if (failNotes.length > 0) {
|
|
7006
|
-
lines.push((0,
|
|
6511
|
+
lines.push((0, import_react8.createElement)(
|
|
7007
6512
|
"div",
|
|
7008
6513
|
{ key: "notes", style: metaLine },
|
|
7009
|
-
...failNotes.map((note) => (0,
|
|
6514
|
+
...failNotes.map((note) => (0, import_react8.createElement)("span", { key: note, style: badge }, note))
|
|
7010
6515
|
));
|
|
7011
6516
|
}
|
|
7012
6517
|
}
|
|
7013
6518
|
if (lines.length === 0) {
|
|
7014
|
-
lines.push((0,
|
|
6519
|
+
lines.push((0, import_react8.createElement)("div", { key: "none", style: metaLine }, (0, import_react8.createElement)("span", { style: badge }, "\u672A\u6D3E\u53D1 / \u672A\u5BA1\u67E5")));
|
|
7015
6520
|
}
|
|
7016
|
-
return (0,
|
|
6521
|
+
return (0, import_react8.createElement)("div", { style: { display: "flex", flexDirection: "column", gap: 4 } }, ...lines);
|
|
7017
6522
|
}
|
|
7018
6523
|
function TaskLedger({ workspace, remote }) {
|
|
7019
|
-
const [tasks, setTasks] = (0,
|
|
7020
|
-
const [error, setError] = (0,
|
|
7021
|
-
const [loading, setLoading] = (0,
|
|
7022
|
-
const [query, setQuery] = (0,
|
|
7023
|
-
const [risk, setRisk] = (0,
|
|
7024
|
-
const [stage, setStage] = (0,
|
|
7025
|
-
const refresh = (0,
|
|
6524
|
+
const [tasks, setTasks] = (0, import_react8.useState)([]);
|
|
6525
|
+
const [error, setError] = (0, import_react8.useState)("");
|
|
6526
|
+
const [loading, setLoading] = (0, import_react8.useState)(true);
|
|
6527
|
+
const [query, setQuery] = (0, import_react8.useState)("");
|
|
6528
|
+
const [risk, setRisk] = (0, import_react8.useState)("all");
|
|
6529
|
+
const [stage, setStage] = (0, import_react8.useState)("all");
|
|
6530
|
+
const refresh = (0, import_react8.useCallback)(() => {
|
|
7026
6531
|
if (workspace === "") return;
|
|
7027
6532
|
setError("");
|
|
7028
6533
|
setLoading(true);
|
|
@@ -7035,58 +6540,58 @@ function TaskLedger({ workspace, remote }) {
|
|
|
7035
6540
|
setError("\u8BFB\u53D6\u53F0\u8D26\u5931\u8D25\uFF1A" + describeError(reason));
|
|
7036
6541
|
});
|
|
7037
6542
|
}, [remote, workspace]);
|
|
7038
|
-
(0,
|
|
6543
|
+
(0, import_react8.useEffect)(() => {
|
|
7039
6544
|
refresh();
|
|
7040
6545
|
}, [refresh]);
|
|
7041
6546
|
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));
|
|
7042
|
-
return (0,
|
|
6547
|
+
return (0, import_react8.createElement)(
|
|
7043
6548
|
"div",
|
|
7044
6549
|
{ style: styles.section },
|
|
7045
|
-
(0,
|
|
6550
|
+
(0, import_react8.createElement)(
|
|
7046
6551
|
"div",
|
|
7047
6552
|
{ className: "te-toolbar" },
|
|
7048
|
-
(0,
|
|
7049
|
-
(0,
|
|
7050
|
-
(0,
|
|
6553
|
+
(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) }),
|
|
6554
|
+
(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")),
|
|
6555
|
+
(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)))
|
|
7051
6556
|
),
|
|
7052
|
-
(0,
|
|
6557
|
+
(0, import_react8.createElement)(
|
|
7053
6558
|
"div",
|
|
7054
6559
|
{ style: headerRow },
|
|
7055
|
-
(0,
|
|
7056
|
-
(0,
|
|
7057
|
-
(0,
|
|
6560
|
+
(0, import_react8.createElement)("span", { style: styles.bindingLabel }, "\u4EFB\u52A1\u53F0\u8D26"),
|
|
6561
|
+
(0, import_react8.createElement)("span", { style: styles.sourceBadge }, "\u53EA\u8BFB \xB7 \u6765\u81EA .dsh/task-*.json"),
|
|
6562
|
+
(0, import_react8.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", size: "sm", disabled: loading, onClick: refresh }, loading ? "\u8BFB\u53D6\u4E2D\u2026" : "\u5237\u65B0")
|
|
7058
6563
|
),
|
|
7059
|
-
loading ? (0,
|
|
6564
|
+
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)(
|
|
7060
6565
|
"div",
|
|
7061
6566
|
{ style: { display: "flex", flexDirection: "column", gap: 12 } },
|
|
7062
|
-
...visible.map((task) => (0,
|
|
6567
|
+
...visible.map((task) => (0, import_react8.createElement)(
|
|
7063
6568
|
"div",
|
|
7064
6569
|
{ key: task.task_id, style: card3 },
|
|
7065
|
-
(0,
|
|
6570
|
+
(0, import_react8.createElement)(
|
|
7066
6571
|
"div",
|
|
7067
6572
|
{ style: headerRow },
|
|
7068
|
-
(0,
|
|
7069
|
-
(0,
|
|
7070
|
-
(0,
|
|
7071
|
-
task.complexity ? (0,
|
|
7072
|
-
(0,
|
|
7073
|
-
(0,
|
|
7074
|
-
(0,
|
|
7075
|
-
(0,
|
|
7076
|
-
task.updated_at ? (0,
|
|
6573
|
+
(0, import_react8.createElement)("span", { style: { fontSize: 14, fontWeight: 600, color: "var(--dsw-alias-label-primary)" } }, task.task_id),
|
|
6574
|
+
(0, import_react8.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, task.title),
|
|
6575
|
+
(0, import_react8.createElement)("span", { style: badge }, task.stage),
|
|
6576
|
+
task.complexity ? (0, import_react8.createElement)("span", { style: badge }, `\u590D\u6742\u5EA6\uFF1A${{ low: "\u4F4E", medium: "\u4E2D", high: "\u9AD8", ultra: "\u8D85\u9AD8" }[task.complexity] ?? task.complexity}`) : null,
|
|
6577
|
+
(0, import_react8.createElement)("span", { style: badge }, task.branch),
|
|
6578
|
+
(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"),
|
|
6579
|
+
(0, import_react8.createElement)("span", { className: "te-badge" }, task.verification_passed ? "\u9A8C\u8BC1\u901A\u8FC7" : "\u5F85\u9A8C\u8BC1"),
|
|
6580
|
+
(0, import_react8.createElement)("span", { className: "te-badge" }, `\u5BA1\u6838\uFF1A${task.review_outcome ?? "pending"}`),
|
|
6581
|
+
task.updated_at ? (0, import_react8.createElement)("span", { style: metaLine }, "\u66F4\u65B0\u4E8E " + timeText(task.updated_at)) : null
|
|
7077
6582
|
),
|
|
7078
|
-
(0,
|
|
6583
|
+
(0, import_react8.createElement)(
|
|
7079
6584
|
"div",
|
|
7080
6585
|
{ style: { display: "flex", flexDirection: "column" } },
|
|
7081
|
-
...task.items.map((item) => (0,
|
|
6586
|
+
...task.items.map((item) => (0, import_react8.createElement)(
|
|
7082
6587
|
"div",
|
|
7083
6588
|
{ key: item.id, style: itemRow },
|
|
7084
|
-
(0,
|
|
6589
|
+
(0, import_react8.createElement)(
|
|
7085
6590
|
"div",
|
|
7086
6591
|
{ style: headerRow },
|
|
7087
6592
|
itemStatusDot(item.status),
|
|
7088
|
-
(0,
|
|
7089
|
-
(0,
|
|
6593
|
+
(0, import_react8.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, item.id),
|
|
6594
|
+
(0, import_react8.createElement)("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, item.title)
|
|
7090
6595
|
),
|
|
7091
6596
|
itemAudit(item)
|
|
7092
6597
|
))
|
|
@@ -7153,7 +6658,6 @@ var closeStyle = {
|
|
|
7153
6658
|
var TABS = [
|
|
7154
6659
|
{ id: "init", label: "\u9879\u76EE\u521D\u59CB\u5316" },
|
|
7155
6660
|
{ id: "adaptive", label: "\u81EA\u9002\u5E94\u6D41\u7A0B" },
|
|
7156
|
-
{ id: "flow", label: "\u65E7\u7248\u6D41\u7A0B" },
|
|
7157
6661
|
{ id: "tasks", label: "\u4EFB\u52A1\u53F0\u8D26" },
|
|
7158
6662
|
{ id: "skills", label: "\u6280\u80FD" },
|
|
7159
6663
|
{ id: "rules", label: "\u89C4\u5219" }
|
|
@@ -7161,29 +6665,29 @@ var TABS = [
|
|
|
7161
6665
|
function Workbench({ useStore, actions, useWorkspaces, remote }) {
|
|
7162
6666
|
const open = useStore((s) => s.open);
|
|
7163
6667
|
const workspaces = useWorkspaces((s) => s.items);
|
|
7164
|
-
const [tab, setTab] = (0,
|
|
7165
|
-
const [workspace, setWorkspace] = (0,
|
|
6668
|
+
const [tab, setTab] = (0, import_react9.useState)("adaptive");
|
|
6669
|
+
const [workspace, setWorkspace] = (0, import_react9.useState)("");
|
|
7166
6670
|
if (!open) return null;
|
|
7167
6671
|
const current = workspaces.some((w) => w.path === workspace) ? workspace : workspaces[0]?.path ?? "";
|
|
7168
|
-
return (0,
|
|
6672
|
+
return (0, import_react9.createElement)(
|
|
7169
6673
|
"div",
|
|
7170
6674
|
{ style: overlay, className: "te-workbench" },
|
|
7171
|
-
(0,
|
|
7172
|
-
(0,
|
|
6675
|
+
(0, import_react9.createElement)("style", null, workbenchTheme),
|
|
6676
|
+
(0, import_react9.createElement)(
|
|
7173
6677
|
"div",
|
|
7174
6678
|
{ style: header },
|
|
7175
|
-
(0,
|
|
6679
|
+
(0, import_react9.createElement)(
|
|
7176
6680
|
"div",
|
|
7177
6681
|
{ style: headerBrand },
|
|
7178
|
-
(0,
|
|
7179
|
-
(0,
|
|
6682
|
+
(0, import_react9.createElement)(IconSettings, { size: 18 }),
|
|
6683
|
+
(0, import_react9.createElement)(
|
|
7180
6684
|
"div",
|
|
7181
6685
|
{ style: headerText },
|
|
7182
|
-
(0,
|
|
7183
|
-
(0,
|
|
6686
|
+
(0, import_react9.createElement)("span", { style: headerTitle }, "\u5DE5\u7A0B\u4EFB\u52A1"),
|
|
6687
|
+
(0, import_react9.createElement)("p", { style: headerSub }, "\u6309\u9700\u6C42\u590D\u6742\u5EA6\u9009\u62E9\u4EFB\u52A1\u6D41\u7A0B \xB7 \u5143\u6280\u80FD\u6302\u8F7D\u9879\u76EE Skill \u4E0E Rule")
|
|
7184
6688
|
)
|
|
7185
6689
|
),
|
|
7186
|
-
(0,
|
|
6690
|
+
(0, import_react9.createElement)(
|
|
7187
6691
|
"button",
|
|
7188
6692
|
{
|
|
7189
6693
|
type: "button",
|
|
@@ -7199,43 +6703,43 @@ function Workbench({ useStore, actions, useWorkspaces, remote }) {
|
|
|
7199
6703
|
event.currentTarget.style.background = "transparent";
|
|
7200
6704
|
}
|
|
7201
6705
|
},
|
|
7202
|
-
(0,
|
|
6706
|
+
(0, import_react9.createElement)(IconClose, { size: 16 })
|
|
7203
6707
|
)
|
|
7204
6708
|
),
|
|
7205
|
-
(0,
|
|
6709
|
+
(0, import_react9.createElement)(
|
|
7206
6710
|
"div",
|
|
7207
6711
|
{ style: tabbar },
|
|
7208
|
-
...TABS.map((t) => (0,
|
|
6712
|
+
...TABS.map((t) => (0, import_react9.createElement)(import_dsh_client_ui_primitives6.Pill, { key: t.id, active: tab === t.id, onClick: () => {
|
|
7209
6713
|
setTab(t.id);
|
|
7210
6714
|
} }, t.label)),
|
|
7211
|
-
workspaces.length > 0 ? (0,
|
|
6715
|
+
workspaces.length > 0 ? (0, import_react9.createElement)("select", {
|
|
7212
6716
|
style: selectStyle,
|
|
7213
6717
|
"aria-label": "\u5F53\u524D\u5DE5\u4F5C\u533A",
|
|
7214
6718
|
value: current,
|
|
7215
6719
|
onChange: (ev) => {
|
|
7216
6720
|
setWorkspace(ev.target.value);
|
|
7217
6721
|
}
|
|
7218
|
-
}, ...workspaces.map((w) => (0,
|
|
6722
|
+
}, ...workspaces.map((w) => (0, import_react9.createElement)("option", { key: w.path, value: w.path }, w.title || w.path))) : null
|
|
7219
6723
|
),
|
|
7220
|
-
(0,
|
|
6724
|
+
(0, import_react9.createElement)(
|
|
7221
6725
|
"div",
|
|
7222
6726
|
{ style: body },
|
|
7223
|
-
(0,
|
|
6727
|
+
(0, import_react9.createElement)(
|
|
7224
6728
|
"div",
|
|
7225
6729
|
{ className: "te-content", key: current },
|
|
7226
|
-
(0,
|
|
7227
|
-
current === "" ? (0,
|
|
6730
|
+
(0, import_react9.createElement)("p", { style: { ...styles.hint, marginBottom: 10 }, title: current }, "\u5DE5\u4F5C\u533A \xB7 " + current),
|
|
6731
|
+
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\u3002") : tab === "init" ? (0, import_react9.createElement)(InitPanel, { workspace: current, remote }) : tab === "adaptive" ? (0, import_react9.createElement)(AdaptivePanel, { workspace: current, remote, onOpenInit: () => setTab("init") }) : 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 })
|
|
7228
6732
|
)
|
|
7229
6733
|
)
|
|
7230
6734
|
);
|
|
7231
6735
|
}
|
|
7232
6736
|
|
|
7233
6737
|
// src/client/TriggerButton.tsx
|
|
7234
|
-
var
|
|
6738
|
+
var import_react10 = require("react");
|
|
7235
6739
|
var hover = "var(--dsw-alias-bg-layer-2)";
|
|
7236
6740
|
var label2 = "var(--dsw-alias-label-primary)";
|
|
7237
6741
|
function TriggerButton({ wide, actions }) {
|
|
7238
|
-
return (0,
|
|
6742
|
+
return (0, import_react10.createElement)(
|
|
7239
6743
|
"button",
|
|
7240
6744
|
{
|
|
7241
6745
|
type: "button",
|
|
@@ -7275,8 +6779,8 @@ function TriggerButton({ wide, actions }) {
|
|
|
7275
6779
|
transition: "background 120ms ease"
|
|
7276
6780
|
}
|
|
7277
6781
|
},
|
|
7278
|
-
(0,
|
|
7279
|
-
wide ? (0,
|
|
6782
|
+
(0, import_react10.createElement)(IconSettings, { size: wide ? 16 : 18 }),
|
|
6783
|
+
wide ? (0, import_react10.createElement)("span", { style: { fontSize: 14, lineHeight: "22px" } }, "\u5DE5\u7A0B\u6D41\u7A0B") : null
|
|
7280
6784
|
);
|
|
7281
6785
|
}
|
|
7282
6786
|
|