@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/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 import_react10 = require("react");
4672
- var import_dsh_client_ui_primitives7 = require("@deepseek-ai/dsh-client-ui-primitives");
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/TaskEngineSection.tsx
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/engine.ts
4927
- function formatResourceRef(ref) {
4928
- return `${ref.source}:${ref.name}`;
4929
- }
4930
- function parseResourceRef(text2) {
4931
- const match = /^(bundled|project|codex-project|user):(.+)$/u.exec(text2);
4932
- if (match === null) return void 0;
4933
- return { source: match[1], name: match[2] };
4934
- }
4935
- var GUARD_NAMES = [
4936
- "requirement_confirmation",
4937
- "solution_confirmation",
4938
- "todos_done",
4939
- "verified",
4940
- "review_passed",
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/workflows.ts
5053
- var FLOW_OPTIONS = [
5054
- { id: "standard", label: "\u5B8C\u6574\u7814\u53D1", description: "\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" },
5055
- { id: "agile", label: "\u65E5\u5E38\u8FED\u4EE3", description: "\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" },
5056
- { id: "minimal", label: "\u5FEB\u901F\u4FEE\u6539", description: "\u5C40\u90E8\u3001\u4F4E\u98CE\u9669\u3001\u65B9\u6848\u660E\u786E\u7684\u6539\u52A8\uFF1A\u4FEE\u6539 \u2192 \u68C0\u67E5\u4E0E\u63D0\u4EA4" }
5057
- ];
5058
- var STANDARD = {
5059
- stages: ["\u9700\u6C42\u8BC4\u5BA1", "\u8BBE\u8BA1", "\u5F00\u53D1", "\u4EA4\u4ED8", "\u4EE3\u7801\u5BA1\u6838", "\u5B8C\u6210"],
5060
- start_stage: "\u9700\u6C42\u8BC4\u5BA1",
5061
- transitions: [
5062
- { from: "\u9700\u6C42\u8BC4\u5BA1", to: "\u8BBE\u8BA1", requires: ["requirement_confirmation", "artifacts_present"] },
5063
- { from: "\u8BBE\u8BA1", to: "\u5F00\u53D1", requires: ["solution_confirmation", "artifacts_present"] },
5064
- { from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] },
5065
- { from: "\u4EA4\u4ED8", to: "\u4EE3\u7801\u5BA1\u6838", requires: ["verified"] },
5066
- { from: "\u4EE3\u7801\u5BA1\u6838", to: "\u5B8C\u6210", requires: ["review_passed", "artifacts_present"] }
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 STANDARD_RECOMMENDATION = {
5074
- commit: {
5075
- // Only the TEXT conventions. Policy, checkpoints and scope stay on the
5076
- // skeleton: they decide when a gate fires, not how a message reads.
5077
- message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
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 AGILE = {
5087
- stages: ["\u9700\u6C42", "\u5F00\u53D1", "\u4EA4\u4ED8", "\u5BA1\u67E5"],
5088
- start_stage: "\u9700\u6C42",
5089
- transitions: [
5090
- { from: "\u9700\u6C42", to: "\u5F00\u53D1", requires: ["requirement_confirmation"] },
5091
- { from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] },
5092
- // Entering 审查 is unconditional. A review guard on this edge would be
5093
- // circular — it would demand the verdict BEFORE the stage that produces it —
5094
- // and it would also block the commit at 交付, since a commit requires its
5095
- // stage's outgoing guards. What 审查 requires is declared as completion_guards
5096
- // instead, because a terminal stage has no outgoing edge to carry it.
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 AGILE_RECOMMENDATION = {
5109
- commit: {
5110
- // `item` policy emits two label shapes: `T<n>` mid-flow and `TASK` at the
5111
- // closing checkpoint. The pattern accepts BOTH, so the label the engine hands
5112
- // the model always satisfies the rule that validates it.
5113
- message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
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 MINIMAL = {
5123
- stages: ["\u5F00\u53D1", "\u4EA4\u4ED8"],
5124
- start_stage: "\u5F00\u53D1",
5125
- transitions: [
5126
- { from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] }
5127
- ],
5128
- artifacts: [],
5129
- commit: { policy: "task", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EA4\u4ED8"], file_scope: false },
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 MINIMAL_RECOMMENDATION = {
5133
- // A fast-change flow checks each change once, not twice under two headings a
5134
- // short change rarely distinguishes. The item still has to be reviewed — what
5135
- // drops is the duplicated verdict, which is where the weight actually was.
5136
- review_depth: "single"
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
- function deriveCapabilities(config) {
5139
- const caps = [];
5140
- const guards = new Set(config.transitions.flatMap((t) => t.requires ?? []));
5141
- if (guards.has("verified")) caps.push("verification_gate");
5142
- if (guards.has("review_passed")) caps.push("review_gate");
5143
- if (guards.has("artifacts_present")) caps.push("artifact_gate");
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 save2 = async () => {
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 save2();
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, import_react4.useState)(null);
6066
- const [draft, setDraft] = (0, import_react4.useState)({});
6067
- const [skills, setSkills] = (0, import_react4.useState)([]);
6068
- const [rules, setRules] = (0, import_react4.useState)([]);
6069
- const [selected, setSelected] = (0, import_react4.useState)(null);
6070
- const [loading, setLoading] = (0, import_react4.useState)(true);
6071
- const [saving, setSaving] = (0, import_react4.useState)(false);
6072
- const [dirty, setDirty] = (0, import_react4.useState)(false);
6073
- const [message, setMessage] = (0, import_react4.useState)("");
6074
- const refresh = (0, import_react4.useCallback)(() => {
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, import_react4.useEffect)(() => {
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
- if (effectiveSource(skills, name) !== "project") {
6123
- setMessage(`\u5F53\u524D ${name} \u6765\u81EA\u975E\u9879\u76EE\u7EA7\uFF1B\u8BF7\u5148\u5728\u201C\u6280\u80FD\u201D\u9875\u521B\u5EFA\u540C\u540D\u9879\u76EE Skill\uFF0C\u518D\u7F16\u8F91\u5B83\u7684 Rule\u3002`);
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.readProjectSkillProfile({ path: workspace, name }).then((result) => {
5325
+ void remote.readSkill({ path: workspace, name, level: source }).then((result) => {
6127
5326
  if (!result.ok) {
6128
- setMessage("\u8BFB\u53D6\u6280\u80FD\u89C4\u5219\u5931\u8D25\uFF1A" + describeError(result.error));
5327
+ setMessage("\u8BFB\u53D6\u6280\u80FD\u5931\u8D25\uFF1A" + describeError(result.error));
6129
5328
  return;
6130
5329
  }
6131
- setSelected({ skill: { source: "project", name }, profile: result.value.profile, hash: result.value.hash });
6132
- }, (error) => setMessage("\u8BFB\u53D6\u6280\u80FD\u89C4\u5219\u5931\u8D25\uFF1A" + describeError(error)));
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: selected.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 save2 = () => {
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, import_react4.createElement)(
5402
+ return (0, import_react3.createElement)(
6171
5403
  "div",
6172
5404
  { style: { ...styles.section, display: "flex", flexDirection: "column", gap: 16 } },
6173
- (0, import_react4.createElement)(
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, import_react4.createElement)("strong", null, "\u6309\u9700\u6C42\u9009\u62E9\u6D41\u7A0B"),
6177
- (0, import_react4.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"),
6178
- (0, import_react4.createElement)("div", { style: grid }, ...(view?.grades ?? []).map((grade) => (0, import_react4.createElement)(
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, import_react4.createElement)("strong", null, `${grade.label} \xB7 ${grade.id}`),
6182
- (0, import_react4.createElement)("span", { style: label }, grade.guidance),
6183
- (0, import_react4.createElement)("span", { style: { fontSize: 12 } }, grade.stages.join(" \u2192 "))
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, import_react4.createElement)(
5424
+ (0, import_react3.createElement)(
6187
5425
  "div",
6188
5426
  { style: card },
6189
- (0, import_react4.createElement)("strong", null, "\u5143\u6280\u80FD\u4E0E\u9879\u76EE\u6280\u80FD"),
6190
- (0, import_react4.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"),
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, import_react4.createElement)(
5432
+ return (0, import_react3.createElement)(
6195
5433
  "div",
6196
5434
  { key: id, style: { ...card, gap: 6 } },
6197
- (0, import_react4.createElement)("strong", null, stage),
6198
- (0, import_react4.createElement)("span", { style: label }, `\u6838\u5FC3\uFF1A${id} \xB7 \u751F\u6548\u6765\u6E90\uFF1A${effectiveSource(skills, id)}`),
6199
- (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "outline", size: "sm", onClick: () => openRules(id) }, "\u914D\u7F6E\u6838\u5FC3 Skill \u7684 Rule"),
6200
- (0, import_react4.createElement)(
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, import_react4.createElement)("button", {
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, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
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, import_react4.createElement)(
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, import_react4.createElement)("option", { value: "" }, "\u6302\u8F7D\u9644\u52A0\u6280\u80FD\u2026"),
6226
- ...candidates.filter((name) => !selected2.includes(name)).map((name) => (0, import_react4.createElement)("option", { key: name, value: name }, `${name} \xB7 ${effectiveSource(skills, name)}`))
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, import_react4.createElement)(
5469
+ (0, import_react3.createElement)(
6232
5470
  "div",
6233
5471
  { style: card },
6234
- (0, import_react4.createElement)(
5472
+ (0, import_react3.createElement)(
6235
5473
  "div",
6236
5474
  { style: row },
6237
- (0, import_react4.createElement)("strong", null, "SonarQube \u5BA1\u6838"),
6238
- (0, import_react4.createElement)(
5475
+ (0, import_react3.createElement)("strong", null, "SonarQube \u5BA1\u6838"),
5476
+ (0, import_react3.createElement)(
6239
5477
  "label",
6240
5478
  { style: row },
6241
- (0, import_react4.createElement)("input", {
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, import_react4.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"),
6250
- sonar.enabled === true ? (0, import_react4.createElement)(
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, import_react4.createElement)(
5495
+ ].map(([key, title, placeholder]) => (0, import_react3.createElement)(
6258
5496
  "label",
6259
5497
  { key, style: { display: "flex", flexDirection: "column", gap: 4 } },
6260
- (0, import_react4.createElement)("span", { style: label }, title),
6261
- (0, import_react4.createElement)("input", {
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, import_react4.createElement)(
5506
+ (0, import_react3.createElement)(
6269
5507
  "label",
6270
5508
  { style: { display: "flex", flexDirection: "column", gap: 4 } },
6271
- (0, import_react4.createElement)("span", { style: label }, "\u5206\u6790\u5BF9\u8C61"),
6272
- (0, import_react4.createElement)(
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, import_react4.createElement)("option", { value: "branch" }, "\u5206\u652F"),
6280
- (0, import_react4.createElement)("option", { value: "pull-request" }, "\u5408\u5E76\u8BF7\u6C42")
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, import_react4.createElement)(
5523
+ (0, import_react3.createElement)(
6286
5524
  "div",
6287
5525
  { style: row },
6288
- (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "outline", size: "sm", disabled: loading || saving, onClick: refresh }, "\u5237\u65B0"),
6289
- (0, import_react4.createElement)(
6290
- import_dsh_client_ui_primitives3.Button,
6291
- { variant: "primary", size: "sm", disabled: loading || saving || !dirty, onClick: save2 },
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, import_react4.createElement)("span", { style: label }, "\u65B0\u9879\u76EE\u53EF\u5728\u5DE5\u7A0B\u4F1A\u8BDD\u4E2D\u8C03\u7528 dev_task init_project\uFF1A\u626B\u63CF \u2192 \u9884\u89C8 \u2192 \u5199\u5165\u9879\u76EE\u6280\u80FD\u4E0E\u89C4\u5219\u3002")
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, import_react4.createElement)("p", { role: "status", style: styles.status }, message) : null,
6297
- view?.problems.length ? (0, import_react4.createElement)("p", { role: "alert", style: styles.status }, view.problems.join("\uFF1B")) : null,
6298
- selected ? (0, import_react4.createElement)(SkillRuleDialog, {
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 import_react5 = require("react");
6312
- var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
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, import_react5.useState)(null);
6325
- const [generating, setGenerating] = (0, import_react5.useState)(false);
6326
- const [elapsed, setElapsed] = (0, import_react5.useState)(0);
6327
- const [draft, setDraft] = (0, import_react5.useState)(null);
6328
- const [editing, setEditing] = (0, import_react5.useState)(false);
6329
- const [body2, setBody] = (0, import_react5.useState)("");
6330
- const [msg, setMsg] = (0, import_react5.useState)("");
6331
- (0, import_react5.useEffect)(() => {
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, import_react5.useCallback)(() => {
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, import_react5.useEffect)(() => {
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, import_react5.createElement)(
5635
+ return (0, import_react4.createElement)(
6395
5636
  "div",
6396
5637
  { style: styles.section },
6397
- (0, import_react5.createElement)(
5638
+ (0, import_react4.createElement)(
6398
5639
  "div",
6399
5640
  { style: card2 },
6400
- (0, import_react5.createElement)(
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, import_react5.createElement)(import_dsh_client_ui_primitives4.StateDot, { state: exists ? "done" : "ongoing" }),
6404
- (0, import_react5.createElement)("span", { style: styles.bindingLabel }, exists ? `\u5DF2\u521D\u59CB\u5316 \xB7 ${view.lines} \u884C\uFF08\u4E0A\u9650 200\uFF09` : "\u672A\u521D\u59CB\u5316"),
6405
- view?.path !== void 0 ? (0, import_react5.createElement)("span", { style: styles.sourceBadge }, `\u5DF2\u5B9A\u4F4D\u5230 ${view.path}`) : null
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, import_react5.createElement)(
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, import_react5.createElement)(
5690
+ exists && !editing && draft === null ? (0, import_react4.createElement)(
6413
5691
  "div",
6414
5692
  { style: styles.mdPreview },
6415
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.MarkdownText, { text: view.content, labels: MD_LABELS })
5693
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.MarkdownText, { text: view.content, labels: MD_LABELS })
6416
5694
  ) : null,
6417
- draft !== null ? (0, import_react5.createElement)(
5695
+ draft !== null ? (0, import_react4.createElement)(
6418
5696
  "div",
6419
5697
  { style: styles.section },
6420
- (0, import_react5.createElement)(
5698
+ (0, import_react4.createElement)(
6421
5699
  "div",
6422
5700
  { style: styles.sourceRow },
6423
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.StateDot, { state: "ongoing", size: 8 }),
6424
- (0, import_react5.createElement)("span", { style: styles.sourceBadge }, `AI \u8349\u7A3F \xB7 ${draft.lines} \u884C \xB7 \u5C1A\u672A\u5199\u5165`)
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, import_react5.createElement)(
5704
+ (0, import_react4.createElement)(
6427
5705
  "div",
6428
5706
  { style: styles.mdPreview },
6429
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.MarkdownText, { text: draft.content, labels: MD_LABELS })
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, import_react5.createElement)("textarea", {
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, import_react5.createElement)(
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, import_react5.createElement)("p", { style: styles.status }, msg) : null,
6446
- draft !== null ? (0, import_react5.createElement)(
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, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, {
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, import_react5.createElement)("span", { style: styles.sourceBadge }, `\u8349\u7A3F ${draft.lines} \u884C\u8D85\u9650\uFF0C\u8BF7\u70B9\u300C\u653E\u5F03\u300D\u540E\u91CD\u8BD5`) : null,
6459
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "md", onClick: () => {
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, import_react5.createElement)(
5740
+ ) : editing ? (0, import_react4.createElement)(
6463
5741
  "div",
6464
5742
  { style: styles.row },
6465
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, {
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, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "md", onClick: () => {
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, import_react5.createElement)(
5755
+ ) : (0, import_react4.createElement)(
6478
5756
  "div",
6479
5757
  { style: styles.row },
6480
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, {
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\u521D\u59CB\u5316\uFF08AI \u626B\u63CF\u8986\u76D6\uFF09" : "\u8BA9 AI \u521D\u59CB\u5316"),
6489
- exists ? (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", size: "md", onClick: startEdit }, "\u624B\u52A8\u7F16\u8F91") : null
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
- var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
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 sourceText2 = (source) => source === "bundled" ? "\u5185\u7F6E" : source === "codex-project" ? "\u9879\u76EE \xB7 Codex" : source.startsWith("user") ? "\u4E2A\u4EBA" : "\u9879\u76EE";
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, import_react6.useState)([]);
6509
- const [query, setQuery] = (0, import_react6.useState)("");
6510
- const [filter, setFilter] = (0, import_react6.useState)("all");
6511
- const [notice, setNotice] = (0, import_react6.useState)("");
6512
- const [error, setError] = (0, import_react6.useState)("");
6513
- const [loading, setLoading] = (0, import_react6.useState)(true);
6514
- const [revision, refresh] = (0, import_react6.useState)(0);
6515
- const [busy, setBusy] = (0, import_react6.useState)(false);
6516
- const [roots, setRoots] = (0, import_react6.useState)(null);
6517
- const [importing, setImporting] = (0, import_react6.useState)(false);
6518
- const [request, setRequest] = (0, import_react6.useState)(null);
6519
- const [preview, setPreview] = (0, import_react6.useState)(null);
6520
- const [level, setLevel] = (0, import_react6.useState)("project");
6521
- const [manual, setManual] = (0, import_react6.useState)(false);
6522
- const [sourceDir, setSourceDir] = (0, import_react6.useState)("");
6523
- const [dirs, setDirs] = (0, import_react6.useState)([]);
6524
- const [browsePath, setBrowsePath] = (0, import_react6.useState)("");
6525
- const [editing, setEditing] = (0, import_react6.useState)(null);
6526
- const [viewing, setViewing] = (0, import_react6.useState)(false);
6527
- const [name, setName] = (0, import_react6.useState)("");
6528
- const [description, setDescription] = (0, import_react6.useState)("");
6529
- const [whenToUse, setWhenToUse] = (0, import_react6.useState)("");
6530
- const [body2, setBody] = (0, import_react6.useState)("");
6531
- const [templateSource, setTemplateSource] = (0, import_react6.useState)(null);
6532
- const [deleting, setDeleting] = (0, import_react6.useState)(null);
6533
- const input2 = (0, import_react6.useRef)(null);
6534
- const fileEpoch = (0, import_react6.useRef)(0);
6535
- const browseEpoch = (0, import_react6.useRef)(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, import_react6.useEffect)(() => {
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, import_react6.useEffect)(() => {
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 save2 = async () => {
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"))) throw new Error("\u540C\u540D\u8D44\u6E90\u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u540D\u6216\u7F16\u8F91\u73B0\u6709\u8D44\u6E90");
6732
- const r = kind === "skill" ? await remote.writeSkill({ name, description, whenToUse, content: body2, level, path: workspace }) : await remote.writeRule({ name, content: body2, level, path: workspace });
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, import_react6.createElement)("div", { className: "te-alert", role: "alert" }, error) : null;
6767
- const targets = () => (0, import_react6.createElement)(
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, import_react6.createElement)(
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, import_react6.createElement)("strong", null, lvl === "project" ? "\u9879\u76EE\u5171\u4EAB" : "\u4E2A\u4EBA\u5168\u5C40"),
6777
- (0, import_react6.createElement)("small", null, lvl === "project" ? "\u4EC5\u5F53\u524D\u5DE5\u4F5C\u533A\u4F7F\u7528" : "\u6B64\u4E3B\u673A\u4E0A\u7684\u6240\u6709\u9879\u76EE\u53EF\u7528")
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, import_react6.createElement)("code", { className: "te-path" }, roots?.[level] ?? (level === "project" ? `${workspace}/.dsh/${kind}s` : `DSH_HOME/${kind}s`))
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, import_react6.createElement)(
6062
+ return (0, import_react5.createElement)(
6783
6063
  "section",
6784
6064
  { className: "te-resource" },
6785
- (0, import_react6.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) => {
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, import_react6.createElement)("div", { className: "te-section-heading" }, (0, import_react6.createElement)("div", null, (0, import_react6.createElement)("h2", null, `${noun}\u5E93`), (0, import_react6.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_react6.createElement)("div", { className: "te-actions" }, (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", onClick: () => {
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, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "primary", onClick: choose }, `\u5B89\u88C5${noun}`))),
6791
- (0, import_react6.createElement)("div", { className: "te-toolbar" }, (0, import_react6.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_react6.createElement)("select", { className: "te-input", "aria-label": "\u7B5B\u9009\u6765\u6E90", value: filter, onChange: (e) => setFilter(e.target.value) }, (0, import_react6.createElement)("option", { value: "all" }, `\u5168\u90E8\u6765\u6E90 \xB7 ${rows.length}`), (0, import_react6.createElement)("option", { value: "project" }, "\u9879\u76EE"), (0, import_react6.createElement)("option", { value: "user" }, "\u4E2A\u4EBA")), (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", onClick: () => refresh((n) => n + 1), disabled: loading }, "\u5237\u65B0")),
6792
- notice ? (0, import_react6.createElement)("div", { className: "te-success", role: "status" }, notice) : null,
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, import_react6.createElement)("div", { className: "te-empty", role: "status" }, "\u6B63\u5728\u52A0\u8F7D\u2026") : visible.length === 0 ? (0, import_react6.createElement)("div", { className: "te-empty" }, (0, import_react6.createElement)("h3", null, query || filter !== "all" ? "\u6CA1\u6709\u5339\u914D\u7684\u7ED3\u679C" : `\u8FD8\u6CA1\u6709${noun}`), (0, import_react6.createElement)("p", null, "\u8C03\u6574\u7B5B\u9009\uFF0C\u6216\u4F7F\u7528\u53F3\u4E0A\u89D2\u6309\u94AE\u6DFB\u52A0\u3002")) : (0, import_react6.createElement)("div", { className: "te-resource-grid" }, ...visible.map((row2) => (0, import_react6.createElement)(
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, import_react6.createElement)("div", { className: "te-card-top" }, (0, import_react6.createElement)("span", { className: "te-resource-icon", "aria-hidden": true }, kind === "skill" ? "\u25C7" : "\u2261"), (0, import_react6.createElement)("span", { className: "te-badge" }, sourceText2(row2.source))),
6798
- (0, import_react6.createElement)("h3", null, row2.name),
6799
- (0, import_react6.createElement)("p", null, row2.description || "\u9879\u76EE\u7EA6\u5B9A\u4E0E\u6267\u884C\u89C4\u5219"),
6800
- (0, import_react6.createElement)("div", { className: "te-actions" }, kind === "skill" && onConfigureSkill ? (0, import_react6.createElement)(import_dsh_client_ui_primitives5.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_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", size: "sm", onClick: () => {
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, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", size: "sm", disabled: busy, onClick: () => {
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, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", size: "sm", onClick: () => {
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, import_react6.createElement)("button", { className: "te-delete", onClick: () => {
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, import_react6.createElement)("button", { className: "te-link", onClick: () => {
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, import_react6.createElement)(
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, import_react6.createElement)("div", { className: "te-actions" }, (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: busy, onClick: close }, "\u53D6\u6D88"), (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "primary", disabled: busy || !preview || preview.conflict, onClick: () => {
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, import_react6.createElement)("div", { className: "te-actions" }, (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", disabled: busy, onClick: choose }, "\u91CD\u65B0\u9009\u62E9"), kind === "skill" ? (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: busy, onClick: () => setManual(!manual) }, manual ? "\u6536\u8D77\u9AD8\u7EA7\u65B9\u5F0F" : "\u4E3B\u673A\u8DEF\u5F84") : null),
6823
- manual ? (0, import_react6.createElement)("div", { className: "te-advanced" }, (0, import_react6.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_react6.createElement)("div", { className: "te-toolbar" }, (0, import_react6.createElement)("input", { className: "te-input", "aria-label": "\u4E3B\u673A\u6280\u80FD\u76EE\u5F55", value: sourceDir, onChange: (e) => {
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, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", onClick: () => {
6106
+ } }), (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", onClick: () => {
6827
6107
  void browse(sourceDir);
6828
- } }, "\u6D4F\u89C8"), (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", disabled: busy || !sourceDir.trim(), onClick: () => setRequest({ kind, level, path: workspace, files: [], sourceDir }) }, "\u9884\u89C8\u76EE\u5F55")), (0, import_react6.createElement)("div", { className: "te-dir-list" }, browsePath ? (0, import_react6.createElement)("button", { onClick: () => {
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, import_react6.createElement)("button", { key: d.name, onClick: () => {
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, import_react6.createElement)("p", { role: "status" }, "\u6B63\u5728\u6821\u9A8C\u6587\u4EF6\uFF0C\u8BF7\u7A0D\u5019\u2026") : null,
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, import_react6.createElement)("div", { className: "te-preview" }, (0, import_react6.createElement)("h3", null, preview.name), (0, import_react6.createElement)("p", null, preview.description), (0, import_react6.createElement)("div", { className: "te-actions" }, (0, import_react6.createElement)("span", { className: "te-badge" }, `${preview.files} \u4E2A\u6587\u4EF6`), (0, import_react6.createElement)("span", { className: "te-badge" }, sizeText(preview.bytes))), (0, import_react6.createElement)("code", { className: "te-path" }, preview.target), preview.conflict ? (0, import_react6.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_react6.createElement)("div", { className: "te-markdown" }, (0, import_react6.createElement)(import_dsh_client_ui_primitives5.MarkdownText, { text: preview.content, labels }))) : null
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, import_react6.createElement)(
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, import_react6.createElement)("div", { className: "te-actions" }, (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: busy, onClick: close }, "\u5173\u95ED"), editing !== "new" && levelOf(editing) === "bundled" ? (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", disabled: busy, onClick: () => {
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, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", disabled: busy, onClick: () => setViewing(!viewing) }, viewing ? "\u7F16\u8F91\u5185\u5BB9" : "\u9884\u89C8") : null, !readonly ? (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "primary", disabled: busy || !name.trim() || !body2.trim() || kind === "skill" && !description.trim(), onClick: () => {
6843
- void save2();
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, import_react6.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"),
6846
- templateSource ? (0, import_react6.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,
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, import_react6.createElement)("div", { className: "te-markdown" }, (0, import_react6.createElement)(import_dsh_client_ui_primitives5.MarkdownText, { text: body2, labels })) : (0, import_react6.createElement)("div", { className: "te-form" }, (0, import_react6.createElement)("label", null, "\u540D\u79F0", (0, import_react6.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_react6.createElement)("label", null, "\u63CF\u8FF0", (0, import_react6.createElement)("input", { className: "te-input", value: description, disabled: busy, onChange: (e) => setDescription(e.target.value) })) : null, kind === "skill" ? (0, import_react6.createElement)("label", null, "\u4F7F\u7528\u65F6\u673A\uFF08\u53EF\u9009\uFF09", (0, import_react6.createElement)("input", { className: "te-input", value: whenToUse, disabled: busy, onChange: (e) => setWhenToUse(e.target.value) })) : null, (0, import_react6.createElement)("label", null, "Markdown \u6B63\u6587", (0, import_react6.createElement)("textarea", { className: "te-input te-editor", value: body2, disabled: busy, onChange: (e) => setBody(e.target.value) })))
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, import_react6.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_react6.createElement)("div", { className: "te-actions" }, (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", disabled: busy, onClick: close }, "\u4FDD\u7559"), (0, import_react6.createElement)("button", { className: "te-danger-button", disabled: busy, onClick: () => {
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, import_react6.createElement)("code", { className: "te-path" }, `${roots?.[levelOf(deleting) === "user" ? "user" : "project"] ?? "\u8D44\u6E90\u76EE\u5F55"}/${deleting.name}${kind === "rule" ? ".md" : ""}`), (0, import_react6.createElement)("p", null, "\u6B64\u64CD\u4F5C\u4E0D\u4F1A\u8FDB\u5165\u56DE\u6536\u7AD9\uFF0C\u8BF7\u786E\u8BA4\u5DF2\u6709\u5907\u4EFD\u3002"), status()) : null
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 import_jsx_runtime3 = require("react/jsx-runtime");
6362
+ var import_jsx_runtime2 = require("react/jsx-runtime");
6858
6363
  function SkillManager({ workspace, remote }) {
6859
- const [config, setConfig] = (0, import_react7.useState)(null);
6860
- const [rules, setRules] = (0, import_react7.useState)([]);
6861
- const [selected, setSelected] = (0, import_react7.useState)(null);
6862
- const [message, setMessage] = (0, import_react7.useState)("");
6863
- (0, import_react7.useEffect)(() => {
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, import_jsx_runtime3.jsxs)("div", { className: `te-config-layout${selected ? " is-open" : ""}`, children: [
6905
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "te-config-main", children: [
6906
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ResourceManager, { workspace, remote, kind: "skill", onConfigureSkill: config ? (ref) => {
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, import_jsx_runtime3.jsx)("p", { role: "status", className: "te-success", children: message }) : null
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, import_jsx_runtime3.jsx)(
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 import_react8 = require("react");
6433
+ var import_react7 = require("react");
6929
6434
  function RuleManager(props) {
6930
- return (0, import_react8.createElement)(ResourceManager, { ...props, key: props.workspace, kind: "rule" });
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 import_react9 = require("react");
6935
- var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
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, import_react9.createElement)(import_dsh_client_ui_primitives6.StateDot, { state: outcome === "pass" ? "done" : "error" });
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, import_react9.createElement)(import_dsh_client_ui_primitives6.StateDot, { state: status === "done" ? "done" : "ongoing" });
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, import_react9.createElement)(
6489
+ lines.push((0, import_react8.createElement)(
6985
6490
  "div",
6986
6491
  { key: "dispatch", style: metaLine },
6987
- (0, import_react9.createElement)("span", { style: badge }, "\u5DF2\u6D3E\u53D1"),
6988
- (0, import_react9.createElement)("span", null, item.dispatch.description === "" ? "\uFF08\u65E0\u63CF\u8FF0\uFF09" : item.dispatch.description),
6989
- (0, import_react9.createElement)("span", { style: badge }, timeText(item.dispatch.at))
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, import_react9.createElement)(
6500
+ lines.push((0, import_react8.createElement)(
6996
6501
  "div",
6997
6502
  { key: "review", style: metaLine },
6998
6503
  verdictDot(spec.outcome),
6999
- (0, import_react9.createElement)("span", null, `\u89C4\u683C\u7B26\u5408 ${spec.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`),
7000
- (0, import_react9.createElement)("span", null, "\xB7"),
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, import_react9.createElement)("span", null, `\u4EE3\u7801\u8D28\u91CF ${quality.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`)
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, import_react9.createElement)(
6511
+ lines.push((0, import_react8.createElement)(
7007
6512
  "div",
7008
6513
  { key: "notes", style: metaLine },
7009
- ...failNotes.map((note) => (0, import_react9.createElement)("span", { key: note, style: badge }, note))
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, import_react9.createElement)("div", { key: "none", style: metaLine }, (0, import_react9.createElement)("span", { style: badge }, "\u672A\u6D3E\u53D1 / \u672A\u5BA1\u67E5")));
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, import_react9.createElement)("div", { style: { display: "flex", flexDirection: "column", gap: 4 } }, ...lines);
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, import_react9.useState)([]);
7020
- const [error, setError] = (0, import_react9.useState)("");
7021
- const [loading, setLoading] = (0, import_react9.useState)(true);
7022
- const [query, setQuery] = (0, import_react9.useState)("");
7023
- const [risk, setRisk] = (0, import_react9.useState)("all");
7024
- const [stage, setStage] = (0, import_react9.useState)("all");
7025
- const refresh = (0, import_react9.useCallback)(() => {
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, import_react9.useEffect)(() => {
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, import_react9.createElement)(
6547
+ return (0, import_react8.createElement)(
7043
6548
  "div",
7044
6549
  { style: styles.section },
7045
- (0, import_react9.createElement)(
6550
+ (0, import_react8.createElement)(
7046
6551
  "div",
7047
6552
  { className: "te-toolbar" },
7048
- (0, import_react9.createElement)("input", { className: "te-input", placeholder: "\u641C\u7D22\u4EFB\u52A1\u3001\u6807\u9898\u6216\u5206\u652F", value: query, onChange: (e) => setQuery(e.target.value) }),
7049
- (0, import_react9.createElement)("select", { className: "te-input", "aria-label": "\u98CE\u9669\u7B5B\u9009", value: risk, onChange: (e) => setRisk(e.target.value) }, (0, import_react9.createElement)("option", { value: "all" }, "\u5168\u90E8\u98CE\u9669"), (0, import_react9.createElement)("option", { value: "standard" }, "\u6807\u51C6"), (0, import_react9.createElement)("option", { value: "high_risk" }, "\u9AD8\u98CE\u9669")),
7050
- (0, import_react9.createElement)("select", { className: "te-input", "aria-label": "\u9636\u6BB5\u7B5B\u9009", value: stage, onChange: (e) => setStage(e.target.value) }, (0, import_react9.createElement)("option", { value: "all" }, "\u5168\u90E8\u9636\u6BB5"), ...Array.from(new Set(tasks.map((t) => t.stage))).map((value) => (0, import_react9.createElement)("option", { key: value, value }, value)))
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, import_react9.createElement)(
6557
+ (0, import_react8.createElement)(
7053
6558
  "div",
7054
6559
  { style: headerRow },
7055
- (0, import_react9.createElement)("span", { style: styles.bindingLabel }, "\u4EFB\u52A1\u53F0\u8D26"),
7056
- (0, import_react9.createElement)("span", { style: styles.sourceBadge }, "\u53EA\u8BFB \xB7 \u6765\u81EA .dsh/task-*.json"),
7057
- (0, import_react9.createElement)(import_dsh_client_ui_primitives6.Button, { variant: "outline", size: "sm", disabled: loading, onClick: refresh }, loading ? "\u8BFB\u53D6\u4E2D\u2026" : "\u5237\u65B0")
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, import_react9.createElement)("p", { role: "status" }, "\u6B63\u5728\u8BFB\u53D6\u4EFB\u52A1\u2026") : error !== "" ? (0, import_react9.createElement)("p", { style: styles.status }, error) : tasks.length === 0 ? (0, import_react9.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_react9.createElement)("div", { className: "te-empty" }, "\u6CA1\u6709\u5339\u914D\u7684\u4EFB\u52A1\uFF0C\u8BF7\u8C03\u6574\u7B5B\u9009\u3002") : (0, import_react9.createElement)(
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, import_react9.createElement)(
6567
+ ...visible.map((task) => (0, import_react8.createElement)(
7063
6568
  "div",
7064
6569
  { key: task.task_id, style: card3 },
7065
- (0, import_react9.createElement)(
6570
+ (0, import_react8.createElement)(
7066
6571
  "div",
7067
6572
  { style: headerRow },
7068
- (0, import_react9.createElement)("span", { style: { fontSize: 14, fontWeight: 600, color: "var(--dsw-alias-label-primary)" } }, task.task_id),
7069
- (0, import_react9.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, task.title),
7070
- (0, import_react9.createElement)("span", { style: badge }, task.stage),
7071
- task.complexity ? (0, import_react9.createElement)("span", { style: badge }, `\u590D\u6742\u5EA6\uFF1A${{ low: "\u4F4E", medium: "\u4E2D", high: "\u9AD8", ultra: "\u8D85\u9AD8" }[task.complexity] ?? task.complexity}`) : null,
7072
- (0, import_react9.createElement)("span", { style: badge }, task.branch),
7073
- (0, import_react9.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"),
7074
- (0, import_react9.createElement)("span", { className: "te-badge" }, task.verification_passed ? "\u9A8C\u8BC1\u901A\u8FC7" : "\u5F85\u9A8C\u8BC1"),
7075
- (0, import_react9.createElement)("span", { className: "te-badge" }, `\u5BA1\u6838\uFF1A${task.review_outcome ?? "pending"}`),
7076
- task.updated_at ? (0, import_react9.createElement)("span", { style: metaLine }, "\u66F4\u65B0\u4E8E " + timeText(task.updated_at)) : null
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, import_react9.createElement)(
6583
+ (0, import_react8.createElement)(
7079
6584
  "div",
7080
6585
  { style: { display: "flex", flexDirection: "column" } },
7081
- ...task.items.map((item) => (0, import_react9.createElement)(
6586
+ ...task.items.map((item) => (0, import_react8.createElement)(
7082
6587
  "div",
7083
6588
  { key: item.id, style: itemRow },
7084
- (0, import_react9.createElement)(
6589
+ (0, import_react8.createElement)(
7085
6590
  "div",
7086
6591
  { style: headerRow },
7087
6592
  itemStatusDot(item.status),
7088
- (0, import_react9.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, item.id),
7089
- (0, import_react9.createElement)("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, item.title)
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, import_react10.useState)("adaptive");
7165
- const [workspace, setWorkspace] = (0, import_react10.useState)("");
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, import_react10.createElement)(
6672
+ return (0, import_react9.createElement)(
7169
6673
  "div",
7170
6674
  { style: overlay, className: "te-workbench" },
7171
- (0, import_react10.createElement)("style", null, workbenchTheme),
7172
- (0, import_react10.createElement)(
6675
+ (0, import_react9.createElement)("style", null, workbenchTheme),
6676
+ (0, import_react9.createElement)(
7173
6677
  "div",
7174
6678
  { style: header },
7175
- (0, import_react10.createElement)(
6679
+ (0, import_react9.createElement)(
7176
6680
  "div",
7177
6681
  { style: headerBrand },
7178
- (0, import_react10.createElement)(IconSettings, { size: 18 }),
7179
- (0, import_react10.createElement)(
6682
+ (0, import_react9.createElement)(IconSettings, { size: 18 }),
6683
+ (0, import_react9.createElement)(
7180
6684
  "div",
7181
6685
  { style: headerText },
7182
- (0, import_react10.createElement)("span", { style: headerTitle }, "\u5DE5\u7A0B\u4EFB\u52A1"),
7183
- (0, import_react10.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")
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, import_react10.createElement)(
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, import_react10.createElement)(IconClose, { size: 16 })
6706
+ (0, import_react9.createElement)(IconClose, { size: 16 })
7203
6707
  )
7204
6708
  ),
7205
- (0, import_react10.createElement)(
6709
+ (0, import_react9.createElement)(
7206
6710
  "div",
7207
6711
  { style: tabbar },
7208
- ...TABS.map((t) => (0, import_react10.createElement)(import_dsh_client_ui_primitives7.Pill, { key: t.id, active: tab === t.id, onClick: () => {
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, import_react10.createElement)("select", {
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, import_react10.createElement)("option", { key: w.path, value: w.path }, w.title || w.path))) : null
6722
+ }, ...workspaces.map((w) => (0, import_react9.createElement)("option", { key: w.path, value: w.path }, w.title || w.path))) : null
7219
6723
  ),
7220
- (0, import_react10.createElement)(
6724
+ (0, import_react9.createElement)(
7221
6725
  "div",
7222
6726
  { style: body },
7223
- (0, import_react10.createElement)(
6727
+ (0, import_react9.createElement)(
7224
6728
  "div",
7225
6729
  { className: "te-content", key: current },
7226
- (0, import_react10.createElement)("p", { style: { ...styles.hint, marginBottom: 10 }, title: current }, "\u5DE5\u4F5C\u533A \xB7 " + current),
7227
- current === "" ? (0, import_react10.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_react10.createElement)(InitPanel, { workspace: current, remote }) : tab === "adaptive" ? (0, import_react10.createElement)(AdaptivePanel, { workspace: current, remote }) : tab === "flow" ? (0, import_react10.createElement)(TaskEngineSection, { workspace: current, remote }) : tab === "tasks" ? (0, import_react10.createElement)(TaskLedger, { workspace: current, remote }) : tab === "skills" ? (0, import_react10.createElement)(SkillManager, { workspace: current, remote }) : (0, import_react10.createElement)(RuleManager, { workspace: current, remote })
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 import_react11 = require("react");
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, import_react11.createElement)(
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, import_react11.createElement)(IconSettings, { size: wide ? 16 : 18 }),
7279
- wide ? (0, import_react11.createElement)("span", { style: { fontSize: 14, lineHeight: "22px" } }, "\u5DE5\u7A0B\u6D41\u7A0B") : null
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