@godv61/dsh-task-engine 0.29.0 → 0.29.2

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(),
@@ -4290,10 +4291,91 @@ var resourceRequestSchema = external_exports.object({
4290
4291
  var resourcePreviewSchema = external_exports.object({ ok: external_exports.boolean(), name: external_exports.string(), description: external_exports.string(), content: external_exports.string(), target: external_exports.string(), files: external_exports.number(), bytes: external_exports.number(), hash: external_exports.string(), conflict: external_exports.boolean(), error: external_exports.string().optional() });
4291
4292
  var resourceRootsRequestSchema = external_exports.object({ kind: external_exports.enum(["skill", "rule"]), path: external_exports.string() });
4292
4293
  var resourceRootsSchema = external_exports.object({ project: external_exports.string(), user: external_exports.string() });
4294
+ var adaptiveConfigSchema = external_exports.object({
4295
+ meta_bindings: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())).optional(),
4296
+ sonar: external_exports.object({
4297
+ enabled: external_exports.boolean().optional(),
4298
+ host_url: external_exports.string().optional(),
4299
+ project_key: external_exports.string().optional(),
4300
+ mode: external_exports.enum(["branch", "pull-request"]).optional(),
4301
+ token_env: external_exports.string().optional()
4302
+ }).optional()
4303
+ });
4304
+ var adaptiveViewSchema = external_exports.object({
4305
+ ok: external_exports.boolean(),
4306
+ source: external_exports.enum(["default", "project", "invalid"]),
4307
+ config: adaptiveConfigSchema,
4308
+ hash: external_exports.string(),
4309
+ problems: external_exports.array(external_exports.string()),
4310
+ grades: external_exports.array(external_exports.object({ id: external_exports.string(), label: external_exports.string(), guidance: external_exports.string(), stages: external_exports.array(external_exports.string()) }))
4311
+ });
4312
+ var adaptiveWriteRequestSchema = external_exports.object({ path: external_exports.string(), config: adaptiveConfigSchema, expected_hash: external_exports.string() });
4313
+ var projectSkillProfileRequestSchema = external_exports.object({ path: external_exports.string(), name: external_exports.string() });
4314
+ var projectSkillProfileWriteRequestSchema = projectSkillProfileRequestSchema.extend({
4315
+ profile: skillProfileSchema,
4316
+ expected_hash: external_exports.string()
4317
+ });
4318
+ var projectSkillProfileViewSchema = external_exports.object({ profile: skillProfileSchema, hash: external_exports.string() });
4293
4319
  var PACKAGE = "@godv61/dsh-task-engine";
4294
4320
  var TYPERT_REMOTE = {
4295
4321
  package: PACKAGE,
4296
4322
  descriptors: [
4323
+ {
4324
+ id: `${PACKAGE}#task-engine/readAdaptive`,
4325
+ service: "taskEngineController",
4326
+ namespace: "task-engine",
4327
+ method: "readAdaptive",
4328
+ invocation: { kind: "direct" },
4329
+ parameters: [{
4330
+ name: "path",
4331
+ wire: "path",
4332
+ source: "json",
4333
+ codec: { mode: "strict", typeSymbol: "string", create: () => external_exports.string(), schema: external_exports.string() }
4334
+ }],
4335
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#AdaptiveConfigView`, create: () => adaptiveViewSchema, schema: adaptiveViewSchema }
4336
+ },
4337
+ {
4338
+ id: `${PACKAGE}#task-engine/writeAdaptive`,
4339
+ service: "taskEngineController",
4340
+ namespace: "task-engine",
4341
+ method: "writeAdaptive",
4342
+ invocation: { kind: "direct" },
4343
+ parameters: [{
4344
+ name: "request",
4345
+ wire: "request",
4346
+ source: "json",
4347
+ codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#AdaptiveWriteRequest`, create: () => adaptiveWriteRequestSchema, schema: adaptiveWriteRequestSchema }
4348
+ }],
4349
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#AdaptiveConfigView`, create: () => adaptiveViewSchema, schema: adaptiveViewSchema }
4350
+ },
4351
+ {
4352
+ id: `${PACKAGE}#task-engine/readProjectSkillProfile`,
4353
+ service: "taskEngineController",
4354
+ namespace: "task-engine",
4355
+ method: "readProjectSkillProfile",
4356
+ invocation: { kind: "direct" },
4357
+ parameters: [{
4358
+ name: "request",
4359
+ wire: "request",
4360
+ source: "json",
4361
+ codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#ProjectSkillProfileRequest`, create: () => projectSkillProfileRequestSchema, schema: projectSkillProfileRequestSchema }
4362
+ }],
4363
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#ProjectSkillProfileView`, create: () => projectSkillProfileViewSchema, schema: projectSkillProfileViewSchema }
4364
+ },
4365
+ {
4366
+ id: `${PACKAGE}#task-engine/writeProjectSkillProfile`,
4367
+ service: "taskEngineController",
4368
+ namespace: "task-engine",
4369
+ method: "writeProjectSkillProfile",
4370
+ invocation: { kind: "direct" },
4371
+ parameters: [{
4372
+ name: "request",
4373
+ wire: "request",
4374
+ source: "json",
4375
+ codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#ProjectSkillProfileWriteRequest`, create: () => projectSkillProfileWriteRequestSchema, schema: projectSkillProfileWriteRequestSchema }
4376
+ }],
4377
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#ProjectSkillProfileView`, create: () => projectSkillProfileViewSchema, schema: projectSkillProfileViewSchema }
4378
+ },
4297
4379
  ...["previewResource", "importResource"].map((method) => ({
4298
4380
  id: `${PACKAGE}#task-engine/${method}`,
4299
4381
  service: "taskEngineController",
@@ -4587,14 +4669,13 @@ var TYPERT_REMOTE = {
4587
4669
  var remote_default = TYPERT_REMOTE;
4588
4670
 
4589
4671
  // src/client/Workbench.tsx
4590
- var import_react10 = require("react");
4591
- 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");
4592
4674
 
4593
4675
  // src/client/icons.ts
4594
4676
  var primitives = __toESM(require("@deepseek-ai/dsh-client-ui-primitives"), 1);
4595
4677
  var IconSettings = primitives.IconSettingsOutlineRegular ?? primitives.IconSettingsOutline16;
4596
4678
  var IconClose = primitives.IconCloseOutlineRegular ?? primitives.IconCloseOutline16;
4597
- var IconCheck = primitives.IconCheckOutlineRegular ?? primitives.IconCheckOutline16;
4598
4679
 
4599
4680
  // src/client/workbench-theme.ts
4600
4681
  var workbenchTheme = `
@@ -4838,461 +4919,84 @@ var styles = {
4838
4919
  }
4839
4920
  };
4840
4921
 
4841
- // src/client/TaskEngineSection.tsx
4922
+ // src/client/AdaptivePanel.tsx
4842
4923
  var import_react3 = require("react");
4843
4924
  var import_dsh_client_ui_primitives2 = require("@deepseek-ai/dsh-client-ui-primitives");
4844
4925
 
4845
- // src/engine.ts
4846
- function formatResourceRef(ref) {
4847
- return `${ref.source}:${ref.name}`;
4848
- }
4849
- function parseResourceRef(text2) {
4850
- const match = /^(bundled|project|codex-project|user):(.+)$/u.exec(text2);
4851
- if (match === null) return void 0;
4852
- return { source: match[1], name: match[2] };
4853
- }
4854
- var GUARD_NAMES = [
4855
- "requirement_confirmation",
4856
- "solution_confirmation",
4857
- "todos_done",
4858
- "verified",
4859
- "review_passed",
4860
- "artifacts_present"
4861
- ];
4862
- function validateWorkflow(config) {
4863
- const problems = [...config.configuration_errors ?? []];
4864
- if (config.stages.length === 0) problems.push("stages must not be empty");
4865
- const seen = /* @__PURE__ */ new Set();
4866
- for (const stage of config.stages) {
4867
- if (seen.has(stage)) problems.push(`duplicate stage "${stage}"`);
4868
- seen.add(stage);
4869
- }
4870
- if (!config.stages.includes(config.start_stage)) {
4871
- problems.push(`start_stage "${config.start_stage}" is not in stages`);
4872
- }
4873
- const edges = /* @__PURE__ */ new Set();
4874
- config.transitions.forEach((transition, index) => {
4875
- if (!config.stages.includes(transition.from)) {
4876
- problems.push(`transition ${index + 1}: from "${transition.from}" is not a stage`);
4877
- }
4878
- if (!config.stages.includes(transition.to)) {
4879
- problems.push(`transition ${index + 1}: to "${transition.to}" is not a stage`);
4880
- }
4881
- const edge = `${transition.from}->${transition.to}`;
4882
- if (edges.has(edge)) problems.push(`duplicate transition "${edge}"`);
4883
- edges.add(edge);
4884
- for (const guard of transition.requires ?? []) {
4885
- if (!GUARD_NAMES.includes(guard)) {
4886
- problems.push(`transition ${index + 1}: unknown guard "${String(guard)}"`);
4887
- }
4888
- }
4889
- });
4890
- const artifactKeys = /* @__PURE__ */ new Set();
4891
- config.artifacts.forEach((artifact, index) => {
4892
- if (!config.stages.includes(artifact.stage)) {
4893
- problems.push(`artifact ${index + 1}: stage "${artifact.stage}" is not a stage`);
4894
- }
4895
- const key = artifact.id;
4896
- if (artifactKeys.has(key)) problems.push(`duplicate artifact id "${key}" (ids are unique across all stages)`);
4897
- artifactKeys.add(key);
4898
- if (artifact.fields.length === 0) {
4899
- problems.push(`artifact ${index + 1} ("${artifact.id}"): fields must not be empty`);
4900
- }
4901
- const fieldSet = /* @__PURE__ */ new Set();
4902
- for (const field of artifact.fields) {
4903
- if (fieldSet.has(field)) {
4904
- problems.push(`artifact ${index + 1} ("${artifact.id}"): duplicate field "${field}"`);
4905
- }
4906
- fieldSet.add(field);
4907
- }
4908
- });
4909
- const bindings = config.stage_bindings ?? {};
4910
- const skillMethods = /* @__PURE__ */ new Map();
4911
- for (const [stage, binding] of Object.entries(bindings)) {
4912
- if (!config.stages.includes(stage)) {
4913
- problems.push(`stage_bindings: stage "${stage}" is not a stage`);
4914
- }
4915
- for (const [index, entry] of (binding.skills ?? []).entries()) {
4916
- if (typeof entry?.skill?.name !== "string" || entry.skill.name.trim() === "") {
4917
- problems.push(`stage_bindings "${stage}": skill ${index + 1} has no name`);
4918
- continue;
4919
- }
4920
- if (!["bundled", "project", "codex-project", "user"].includes(entry.skill.source)) {
4921
- problems.push(`stage_bindings "${stage}": skill "${entry.skill.name}" has unknown source "${String(entry.skill.source)}"`);
4922
- }
4923
- const skillKey = formatResourceRef(entry.skill);
4924
- const method = JSON.stringify({ rules: entry.rules ?? [], evidence: entry.evidence });
4925
- const existing = skillMethods.get(skillKey);
4926
- if (existing !== void 0 && existing !== method) {
4927
- problems.push(`skill "${skillKey}" has different rules or evidence in multiple stages; copy it as a distinct skill`);
4928
- }
4929
- skillMethods.set(skillKey, method);
4930
- if (entry.evidence === "artifact" && !config.artifacts.some((artifact) => artifact.stage === stage)) {
4931
- problems.push(`skill "${skillKey}" requires artifact evidence, but stage "${stage}" declares no artifact`);
4932
- }
4933
- if (entry.evidence !== void 0 && !["command", "artifact", "review", "manual", "none"].includes(entry.evidence)) {
4934
- problems.push(`skill "${skillKey}" has unknown evidence type "${String(entry.evidence)}"`);
4935
- }
4936
- for (const rule of entry.rules ?? []) {
4937
- if (typeof rule?.name !== "string" || rule.name.trim() === "") {
4938
- problems.push(`stage_bindings "${stage}": skill "${entry.skill.name}" has a rule with no name`);
4939
- continue;
4940
- }
4941
- if (!["bundled", "project", "user"].includes(rule.source)) {
4942
- problems.push(`stage_bindings "${stage}": skill "${entry.skill.name}" rule "${rule.name}" has unknown source "${String(rule.source)}"`);
4943
- }
4944
- }
4945
- }
4946
- if ((binding.legacy_rules ?? []).length > 0) {
4947
- 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`);
4948
- }
4949
- }
4950
- if (!["task", "item", "manual"].includes(config.commit.policy)) {
4951
- problems.push(`commit.policy "${config.commit.policy}" is not task|item|manual`);
4952
- }
4953
- for (const checkpoint of config.commit.checkpoints) {
4954
- if (!config.stages.includes(checkpoint)) {
4955
- problems.push(`commit.checkpoint "${checkpoint}" is not a stage`);
4956
- }
4957
- }
4958
- if (config.commit.message_pattern !== "") {
4959
- try {
4960
- new RegExp(config.commit.message_pattern);
4961
- } catch {
4962
- problems.push("commit.message_pattern is not a valid regular expression");
4963
- }
4964
- }
4965
- if (config.review_depth !== void 0 && config.review_depth !== "two-stage" && config.review_depth !== "single") {
4966
- problems.push(`review_depth "${String(config.review_depth)}" is not one of: two-stage, single`);
4967
- }
4968
- 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";
4969
4941
  }
4970
4942
 
4971
- // src/workflows.ts
4972
- var FLOW_OPTIONS = [
4973
- { 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" },
4974
- { 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" },
4975
- { 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" }
4976
- ];
4977
- var STANDARD = {
4978
- stages: ["\u9700\u6C42\u8BC4\u5BA1", "\u8BBE\u8BA1", "\u5F00\u53D1", "\u4EA4\u4ED8", "\u4EE3\u7801\u5BA1\u6838", "\u5B8C\u6210"],
4979
- start_stage: "\u9700\u6C42\u8BC4\u5BA1",
4980
- transitions: [
4981
- { from: "\u9700\u6C42\u8BC4\u5BA1", to: "\u8BBE\u8BA1", requires: ["requirement_confirmation", "artifacts_present"] },
4982
- { from: "\u8BBE\u8BA1", to: "\u5F00\u53D1", requires: ["solution_confirmation", "artifacts_present"] },
4983
- { from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] },
4984
- { from: "\u4EA4\u4ED8", to: "\u4EE3\u7801\u5BA1\u6838", requires: ["verified"] },
4985
- { from: "\u4EE3\u7801\u5BA1\u6838", to: "\u5B8C\u6210", requires: ["review_passed", "artifacts_present"] }
4986
- ],
4987
- // No artifacts, no commit policy, no skills: the skeleton carries none of them.
4988
- artifacts: [],
4989
- commit: { policy: "task", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EE3\u7801\u5BA1\u6838"], file_scope: true },
4990
- 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
4991
4958
  };
4992
- var STANDARD_RECOMMENDATION = {
4993
- commit: {
4994
- // Only the TEXT conventions. Policy, checkpoints and scope stay on the
4995
- // skeleton: they decide when a gate fires, not how a message reads.
4996
- message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
4997
- 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"
4998
- },
4999
- artifacts: [
5000
- { stage: "\u9700\u6C42\u8BC4\u5BA1", id: "requirement", name: "\u9700\u6C42\u8BF4\u660E", fields: ["scope", "acceptance_criteria"] },
5001
- { stage: "\u8BBE\u8BA1", id: "design", name: "\u8BBE\u8BA1\u6587\u6863", fields: ["approach", "risks", "impact"] },
5002
- { stage: "\u4EE3\u7801\u5BA1\u6838", id: "review", name: "\u8BC4\u5BA1\u8BB0\u5F55", fields: ["conclusion", "issues"] }
5003
- ]
4959
+ var maskStyle = {
4960
+ position: "absolute",
4961
+ inset: 0,
4962
+ background: "var(--dsw-alias-bg-mask-1)",
4963
+ backdropFilter: "var(--dsw-mask-blur)"
5004
4964
  };
5005
- var AGILE = {
5006
- stages: ["\u9700\u6C42", "\u5F00\u53D1", "\u4EA4\u4ED8", "\u5BA1\u67E5"],
5007
- start_stage: "\u9700\u6C42",
5008
- transitions: [
5009
- { from: "\u9700\u6C42", to: "\u5F00\u53D1", requires: ["requirement_confirmation"] },
5010
- { from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] },
5011
- // Entering 审查 is unconditional. A review guard on this edge would be
5012
- // circular — it would demand the verdict BEFORE the stage that produces it —
5013
- // and it would also block the commit at 交付, since a commit requires its
5014
- // stage's outgoing guards. What 审查 requires is declared as completion_guards
5015
- // instead, because a terminal stage has no outgoing edge to carry it.
5016
- { from: "\u4EA4\u4ED8", to: "\u5BA1\u67E5", requires: [] }
5017
- ],
5018
- artifacts: [],
5019
- commit: { policy: "item", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EA4\u4ED8"], file_scope: true },
5020
- high_risk_requires_verification: false,
5021
- // 审查 is terminal and IS the review, so there is no outgoing edge to carry
5022
- // the guard. Declaring it here is what makes a blocked review prevent
5023
- // completion; without it the stage could be reached and finished with the
5024
- // review failing, which is what the assessment found.
5025
- 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"
5026
4976
  };
5027
- var AGILE_RECOMMENDATION = {
5028
- commit: {
5029
- // `item` policy emits two label shapes: `T<n>` mid-flow and `TASK` at the
5030
- // closing checkpoint. The pattern accepts BOTH, so the label the engine hands
5031
- // the model always satisfies the rule that validates it.
5032
- message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
5033
- 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"
5034
- },
5035
- artifacts: [
5036
- { stage: "\u9700\u6C42", id: "requirement", name: "\u9700\u6C42\u8BF4\u660E", fields: ["scope"] },
5037
- // Optional review record; the flow's review gate itself does not require a skill.
5038
- { stage: "\u5BA1\u67E5", id: "review", name: "\u8BC4\u5BA1\u8BB0\u5F55", fields: ["conclusion", "issues"] }
5039
- ]
4977
+ var drawerStyle = {
4978
+ ...dialogStyle,
4979
+ width: "min(560px, 100%)",
4980
+ height: "100%",
4981
+ maxHeight: "100%",
4982
+ borderRadius: "16px 0 0 16px"
5040
4983
  };
5041
- var MINIMAL = {
5042
- stages: ["\u5F00\u53D1", "\u4EA4\u4ED8"],
5043
- start_stage: "\u5F00\u53D1",
5044
- transitions: [
5045
- { from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] }
5046
- ],
5047
- artifacts: [],
5048
- commit: { policy: "task", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EA4\u4ED8"], file_scope: false },
5049
- 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"
5050
4992
  };
5051
- var MINIMAL_RECOMMENDATION = {
5052
- // A fast-change flow checks each change once, not twice under two headings a
5053
- // short change rarely distinguishes. The item still has to be reviewed — what
5054
- // drops is the duplicated verdict, which is where the weight actually was.
5055
- review_depth: "single"
5056
- };
5057
- function deriveCapabilities(config) {
5058
- const caps = [];
5059
- const guards = new Set(config.transitions.flatMap((t) => t.requires ?? []));
5060
- if (guards.has("verified")) caps.push("verification_gate");
5061
- if (guards.has("review_passed")) caps.push("review_gate");
5062
- if (guards.has("artifacts_present")) caps.push("artifact_gate");
5063
- if (config.commit.file_scope) caps.push("file_scope");
5064
- return caps;
5065
- }
5066
- function preset(id, version, label3, description, config, recommendation) {
5067
- return {
5068
- id,
5069
- version,
5070
- label: label3,
5071
- description,
5072
- capabilities: deriveCapabilities(config),
5073
- config,
5074
- // exactOptionalPropertyTypes: omit rather than assign undefined.
5075
- ...recommendation !== void 0 ? { recommendation } : {}
5076
- };
5077
- }
5078
- var FLOW_PRESETS = {
5079
- 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),
5080
- // Version 4 for agile: 交付 → 审查 now requires review_passed, where it previously
5081
- // required nothing. That is a gate-semantics change, so a task created before it
5082
- // keeps its frozen version 3 config and behaves exactly as it did.
5083
- //
5084
- // Version 3 across all three: the preset is now a bare skeleton and its former
5085
- // built-in bindings, commit rule and artifacts are a separate recommendation a
5086
- // user adopts explicitly. Tasks created before this keep their frozen config and
5087
- // are unaffected; a project's existing config is likewise left exactly as it is.
5088
- 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),
5089
- 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)
5090
- };
5091
- function retainStageBindings(flow, bindings) {
5092
- const stages = new Set(FLOW_PRESETS[flow]?.config.stages ?? []);
5093
- const kept = {};
5094
- const dropped = [];
5095
- for (const [stage, binding] of Object.entries(bindings)) {
5096
- if (stages.has(stage)) kept[stage] = binding;
5097
- else dropped.push(stage);
5098
- }
5099
- return { bindings: kept, dropped };
5100
- }
5101
- function dedupe(names) {
5102
- return [...new Set(names)];
5103
- }
5104
- function applyProjectConfig(base, project) {
5105
- if (project === void 0) return base;
5106
- const next = { ...base };
5107
- if (project.stage_bindings !== void 0) {
5108
- const profiles = { ...project.skill_profiles ?? {} };
5109
- const explicitProfiles = new Set(Object.keys(project.skill_profiles ?? {}));
5110
- const problems = [];
5111
- const bindings = {};
5112
- for (const [stage, binding] of Object.entries(project.stage_bindings)) {
5113
- const entry = {};
5114
- if (binding === null || typeof binding !== "object") {
5115
- problems.push(`stage_bindings "${stage}" must be an object`);
5116
- bindings[stage] = entry;
5117
- continue;
5118
- }
5119
- if (binding.skill_refs !== void 0 && binding.skills !== void 0) {
5120
- problems.push(`stage_bindings "${stage}" has both skill_refs and legacy skills`);
5121
- }
5122
- if (binding.skill_refs !== void 0) {
5123
- if (!Array.isArray(binding.skill_refs)) {
5124
- problems.push(`stage_bindings "${stage}" skill_refs must be an array`);
5125
- }
5126
- entry.skills = (Array.isArray(binding.skill_refs) ? binding.skill_refs : []).flatMap((ref) => {
5127
- if (ref === null || typeof ref !== "object") {
5128
- problems.push(`stage_bindings "${stage}" has an invalid skill reference`);
5129
- return [];
5130
- }
5131
- const key = formatResourceRef(ref);
5132
- const profile = profiles[key];
5133
- if (profile === void 0) {
5134
- problems.push(`skill profile "${key}" is missing`);
5135
- return [];
5136
- }
5137
- if (profile === null || !Array.isArray(profile.rules)) {
5138
- problems.push(`skill profile "${key}" must declare a rules array`);
5139
- return [];
5140
- }
5141
- return [{ skill: ref, rules: profile.rules, ...profile.evidence !== void 0 ? { evidence: profile.evidence } : {} }];
5142
- });
5143
- } else if (binding.skills !== void 0) {
5144
- if (!Array.isArray(binding.skills)) {
5145
- problems.push(`stage_bindings "${stage}" skills must be an array`);
5146
- }
5147
- entry.skills = (Array.isArray(binding.skills) ? binding.skills : []).flatMap((skill) => {
5148
- if (skill === null || typeof skill !== "object" || skill.skill === null || typeof skill.skill !== "object") {
5149
- problems.push(`stage_bindings "${stage}" has an invalid skill binding`);
5150
- return [];
5151
- }
5152
- const key = formatResourceRef(skill.skill);
5153
- if (explicitProfiles.has(key)) {
5154
- const profile = profiles[key];
5155
- if (profile === null || !Array.isArray(profile?.rules)) {
5156
- problems.push(`skill profile "${key}" must declare a rules array`);
5157
- return [];
5158
- }
5159
- return [{
5160
- skill: skill.skill,
5161
- rules: profile.rules,
5162
- ...profile.evidence !== void 0 ? { evidence: profile.evidence } : {}
5163
- }];
5164
- }
5165
- const candidate = { rules: skill.rules ?? [], ...skill.evidence !== void 0 ? { evidence: skill.evidence } : {} };
5166
- const existing = profiles[key];
5167
- if (existing !== void 0 && JSON.stringify(existing) !== JSON.stringify(candidate)) {
5168
- problems.push(`skill "${key}" has different rules or evidence in multiple stages; copy it as a distinct skill`);
5169
- } else profiles[key] = candidate;
5170
- return [skill];
5171
- });
5172
- }
5173
- const legacy = dedupe(binding.legacy_rules ?? []);
5174
- if (legacy.length > 0) entry.legacy_rules = legacy;
5175
- bindings[stage] = entry;
5176
- }
5177
- next.stage_bindings = bindings;
5178
- next.skill_profiles = profiles;
5179
- if (problems.length > 0) next.configuration_errors = problems;
5180
- } else if (project.skill_profiles !== void 0) {
5181
- next.skill_profiles = project.skill_profiles;
5182
- }
5183
- if (project.commit !== void 0) next.commit = project.commit;
5184
- if (project.artifacts !== void 0) next.artifacts = project.artifacts;
5185
- if (project.review_depth !== void 0) next.review_depth = project.review_depth;
5186
- if (project.commit_required !== void 0) next.commit_required = project.commit_required;
5187
- return next;
5188
- }
5189
- function adoptRecommendation(presetId, current) {
5190
- const preset2 = FLOW_PRESETS[presetId];
5191
- if (preset2 === void 0) return void 0;
5192
- const rec = preset2.recommendation;
5193
- if (rec === void 0) return { flow: presetId, ...current };
5194
- const commit = {
5195
- ...preset2.config.commit,
5196
- ...rec.commit ?? {},
5197
- ...current?.commit ?? {}
5198
- };
5199
- const config = {
5200
- flow: presetId,
5201
- stage_bindings: current?.stage_bindings ?? rec.stage_bindings ?? {},
5202
- ...current?.skill_profiles !== void 0 ? { skill_profiles: current.skill_profiles } : {},
5203
- commit,
5204
- artifacts: current?.artifacts ?? rec.artifacts ?? preset2.config.artifacts,
5205
- ...current?.review_depth !== void 0 ? { review_depth: current.review_depth } : rec.review_depth !== void 0 ? { review_depth: rec.review_depth } : {},
5206
- ...current?.commit_required !== void 0 ? { commit_required: current.commit_required } : {}
5207
- };
5208
- return config;
5209
- }
5210
- function compactProjectConfig(project) {
5211
- const resolved = resolveFlow(project.flow, project);
5212
- if (!resolved.ok) return project;
5213
- const profiles = resolved.config.skill_profiles ?? {};
5214
- const bindings = {};
5215
- for (const [stage, binding] of Object.entries(resolved.config.stage_bindings ?? {})) {
5216
- bindings[stage] = {
5217
- skill_refs: (binding.skills ?? []).map((entry) => entry.skill),
5218
- ...binding.legacy_rules?.length ? { legacy_rules: binding.legacy_rules } : {}
5219
- };
5220
- }
5221
- return { ...project, stage_bindings: bindings, skill_profiles: profiles };
5222
- }
5223
- function resolveFlow(flow, project) {
5224
- const preset2 = FLOW_PRESETS[flow];
5225
- if (preset2 === void 0) {
5226
- return { ok: false, code: "UNKNOWN_FLOW", flow, knownFlows: Object.keys(FLOW_PRESETS) };
5227
- }
5228
- const { flow: _ignored, ...rest } = project ?? { flow };
5229
- return { ok: true, config: applyProjectConfig(preset2.config, { flow, ...rest }), preset: preset2 };
5230
- }
5231
-
5232
- // src/client/shared.ts
5233
- function describeError(error) {
5234
- if (error instanceof Error) return error.message;
5235
- if (typeof error === "string") return error;
5236
- return "\u672A\u77E5\u9519\u8BEF";
5237
- }
5238
-
5239
- // src/client/SkillRuleDialog.tsx
5240
- var import_react2 = require("react");
5241
- var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
5242
-
5243
- // src/client/ResourceModal.tsx
5244
- var import_react = require("react");
5245
- var import_react_dom = require("react-dom");
5246
- var rootStyle = {
5247
- position: "fixed",
5248
- inset: 0,
5249
- zIndex: 1e3,
5250
- display: "flex",
5251
- alignItems: "center",
5252
- justifyContent: "center",
5253
- padding: 24
5254
- };
5255
- var maskStyle = {
5256
- position: "absolute",
5257
- inset: 0,
5258
- background: "var(--dsw-alias-bg-mask-1)",
5259
- backdropFilter: "var(--dsw-mask-blur)"
5260
- };
5261
- var dialogStyle = {
5262
- position: "relative",
5263
- zIndex: 1,
5264
- display: "flex",
5265
- flexDirection: "column",
5266
- width: "min(760px, 100%)",
5267
- maxHeight: "85vh",
5268
- borderRadius: 24,
5269
- background: "var(--dsw-alias-bg-layer-2)",
5270
- boxShadow: "var(--dsw-elevation-prominent)",
5271
- overflow: "hidden"
5272
- };
5273
- var drawerStyle = {
5274
- ...dialogStyle,
5275
- width: "min(560px, 100%)",
5276
- height: "100%",
5277
- maxHeight: "100%",
5278
- borderRadius: "16px 0 0 16px"
5279
- };
5280
- var inlineStyle = {
5281
- ...dialogStyle,
5282
- width: "100%",
5283
- height: "min(720px, calc(100vh - 32px))",
5284
- maxHeight: "calc(100vh - 32px)",
5285
- borderRadius: 12,
5286
- border: "1px solid var(--dsw-alias-border-l2)",
5287
- boxShadow: "none"
5288
- };
5289
- var headerStyle = {
5290
- display: "flex",
5291
- alignItems: "center",
5292
- justifyContent: "space-between",
5293
- gap: 8,
5294
- padding: "18px 18px 10px 24px",
5295
- flex: "none"
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"
5296
5000
  };
5297
5001
  var titleStyle = {
5298
5002
  margin: 0,
@@ -5413,6 +5117,11 @@ function ResourceModal({ title, description, onClose, footer, children, placemen
5413
5117
  );
5414
5118
  }
5415
5119
 
5120
+ // src/engine.ts
5121
+ function formatResourceRef(ref) {
5122
+ return `${ref.source}:${ref.name}`;
5123
+ }
5124
+
5416
5125
  // src/client/SkillRuleDialog.tsx
5417
5126
  var import_jsx_runtime = require("react/jsx-runtime");
5418
5127
  function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave, onClose }) {
@@ -5433,7 +5142,7 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
5433
5142
  setDirty(true);
5434
5143
  setError("");
5435
5144
  };
5436
- const save2 = async () => {
5145
+ const save = async () => {
5437
5146
  if (busy || !dirty) return;
5438
5147
  setBusy(true);
5439
5148
  setError("");
@@ -5463,7 +5172,7 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
5463
5172
  error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { role: "alert", className: "te-dialog-error", children: error }) : null,
5464
5173
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "ghost", disabled: busy, onClick: close, children: "\u53D6\u6D88" }),
5465
5174
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", disabled: busy || !dirty, onClick: () => {
5466
- void save2();
5175
+ void save();
5467
5176
  }, children: busy ? "\u5904\u7406\u4E2D\u2026" : saveLabel ?? "\u4FDD\u5B58\u914D\u7F6E" })
5468
5177
  ] }),
5469
5178
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "te-skill-config", children: [
@@ -5515,447 +5224,6 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
5515
5224
  );
5516
5225
  }
5517
5226
 
5518
- // src/client/TaskEngineSection.tsx
5519
- var import_jsx_runtime2 = require("react/jsx-runtime");
5520
- function refFromText(text2) {
5521
- return parseResourceRef(text2) ?? { source: "bundled", name: text2 };
5522
- }
5523
- function resolvedConfig(flow, stageBindings, skillProfiles) {
5524
- const resolved = resolveFlow(flow, { flow, stage_bindings: stageBindings, skill_profiles: skillProfiles });
5525
- return resolved.ok ? resolved.config : FLOW_PRESETS.standard.config;
5526
- }
5527
- function TaskEngineSection(props) {
5528
- const { remote, workspace } = props;
5529
- const [flow, setFlow] = (0, import_react3.useState)("standard");
5530
- const [stageBindings, setStageBindings] = (0, import_react3.useState)({});
5531
- const [skillProfiles, setSkillProfiles] = (0, import_react3.useState)({});
5532
- const [commitRule, setCommitRule] = (0, import_react3.useState)(void 0);
5533
- const [artifacts, setArtifacts] = (0, import_react3.useState)(void 0);
5534
- const [reviewDepth, setReviewDepth] = (0, import_react3.useState)(void 0);
5535
- const [commitRequired, setCommitRequired] = (0, import_react3.useState)(void 0);
5536
- const [source, setSource] = (0, import_react3.useState)("default");
5537
- const [savedAt, setSavedAt] = (0, import_react3.useState)("");
5538
- const [dirty, setDirty] = (0, import_react3.useState)(false);
5539
- const [loadError, setLoadError] = (0, import_react3.useState)("");
5540
- const [saving, setSaving] = (0, import_react3.useState)(false);
5541
- const [loading, setLoading] = (0, import_react3.useState)(true);
5542
- const [loadAttempt, setLoadAttempt] = (0, import_react3.useState)(0);
5543
- const [configProblems, setConfigProblems] = (0, import_react3.useState)([]);
5544
- const [flowNotice, setFlowNotice] = (0, import_react3.useState)("");
5545
- const [pendingAdoption, setPendingAdoption] = (0, import_react3.useState)(false);
5546
- const [skills, setSkills] = (0, import_react3.useState)([]);
5547
- const [rules, setRules] = (0, import_react3.useState)([]);
5548
- const [configuringSkill, setConfiguringSkill] = (0, import_react3.useState)(null);
5549
- (0, import_react3.useEffect)(() => {
5550
- if (workspace === "") return;
5551
- let alive = true;
5552
- setLoadError("");
5553
- setLoading(true);
5554
- void remote.read(workspace).then((result) => {
5555
- if (!alive) return;
5556
- setLoading(false);
5557
- if (result.ok) {
5558
- setFlow(result.value.flow);
5559
- setStageBindings(result.value.config.stage_bindings ?? {});
5560
- setSkillProfiles(result.value.config.skill_profiles ?? {});
5561
- setCommitRule(result.value.config.commit);
5562
- setArtifacts(result.value.config.artifacts);
5563
- setReviewDepth(result.value.config.review_depth);
5564
- setCommitRequired(result.value.config.commit_required);
5565
- setSource(result.value.source);
5566
- setConfigProblems(result.value.problems);
5567
- setFlowNotice("");
5568
- setPendingAdoption(false);
5569
- setSavedAt("");
5570
- } else {
5571
- setLoadError("\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25\uFF1A" + describeError(result.error));
5572
- }
5573
- }, (error) => {
5574
- if (alive) {
5575
- setLoading(false);
5576
- setLoadError("\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25\uFF1A" + describeError(error));
5577
- }
5578
- });
5579
- return () => {
5580
- alive = false;
5581
- };
5582
- }, [remote, workspace, loadAttempt]);
5583
- const refreshCatalogs = (0, import_react3.useCallback)(() => {
5584
- if (workspace === "") return;
5585
- void remote.listSkills(workspace).then((result) => {
5586
- if (result.ok) setSkills(result.value.skills);
5587
- }, () => {
5588
- });
5589
- void remote.listRules(workspace).then((result) => {
5590
- if (result.ok) setRules(result.value.rules);
5591
- }, () => {
5592
- });
5593
- }, [remote, workspace]);
5594
- (0, import_react3.useEffect)(() => {
5595
- refreshCatalogs();
5596
- }, [refreshCatalogs]);
5597
- const stages = (0, import_react3.useMemo)(() => (FLOW_PRESETS[flow] ?? FLOW_PRESETS.standard).config.stages, [flow]);
5598
- const problems = (0, import_react3.useMemo)(
5599
- () => validateWorkflow(resolvedConfig(flow, stageBindings, skillProfiles)),
5600
- [flow, stageBindings, skillProfiles]
5601
- );
5602
- const hasBundledReferences = (0, import_react3.useMemo)(
5603
- () => 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")),
5604
- [stageBindings, skillProfiles]
5605
- );
5606
- const selectFlow = (id) => {
5607
- if (id === flow) return;
5608
- const { bindings, dropped } = retainStageBindings(id, stageBindings);
5609
- 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;
5610
- setStageBindings(bindings);
5611
- 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` : "");
5612
- setFlow(id);
5613
- setPendingAdoption(false);
5614
- setDirty(true);
5615
- setSavedAt("");
5616
- };
5617
- const adopt = () => {
5618
- const adopted = adoptRecommendation(flow, {
5619
- flow,
5620
- stage_bindings: stageBindings,
5621
- skill_profiles: skillProfiles,
5622
- ...commitRequired !== void 0 ? { commit_required: commitRequired } : {}
5623
- });
5624
- if (adopted === void 0) return;
5625
- 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;
5626
- setFlowNotice("");
5627
- setCommitRule(adopted.commit);
5628
- setArtifacts(adopted.artifacts);
5629
- setReviewDepth(adopted.review_depth);
5630
- setDirty(true);
5631
- setSavedAt("");
5632
- };
5633
- const updateSkillProfile = async (profile) => {
5634
- if (!configuringSkill) return;
5635
- if (configuringSkill.source === "user") {
5636
- const result = await remote.writeUserSkillProfile({ name: configuringSkill.name, profile });
5637
- 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");
5638
- }
5639
- const key = formatResourceRef(configuringSkill);
5640
- const bindings = {};
5641
- for (const [name, binding] of Object.entries(stageBindings)) {
5642
- bindings[name] = { ...binding, skills: binding.skills?.map((entry) => formatResourceRef(entry.skill) === key ? { skill: entry.skill, rules: profile.rules, ...profile.evidence ? { evidence: profile.evidence } : {} } : entry) };
5643
- }
5644
- setStageBindings(bindings);
5645
- setSkillProfiles({ ...skillProfiles, [key]: profile });
5646
- setDirty(true);
5647
- setSavedAt("");
5648
- setConfiguringSkill(null);
5649
- };
5650
- if (loadError !== "") {
5651
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.wrap, children: [
5652
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { style: styles.title, children: "\u5DE5\u7A0B\u6D41\u7A0B\u914D\u7F6E" }),
5653
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.problems, children: [
5654
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.problemsTitle, children: [
5655
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: "error" }),
5656
- "\u8BFB\u53D6\u5931\u8D25"
5657
- ] }),
5658
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: loadError }),
5659
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.Button, { onClick: () => setLoadAttempt((n) => n + 1), children: "\u91CD\u8BD5" })
5660
- ] })
5661
- ] });
5662
- }
5663
- if (loading) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", children: "\u6B63\u5728\u8BFB\u53D6\u6D41\u7A0B\u914D\u7F6E\u2026" });
5664
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `te-config-layout${configuringSkill ? " is-open" : ""}`, children: [
5665
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-config-main", style: styles.wrap, children: [
5666
- configProblems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { role: "alert", style: styles.problems, children: [
5667
- "\u539F\u914D\u7F6E\u6709\u95EE\u9898\uFF1A",
5668
- configProblems.join("\uFF1B"),
5669
- "\u3002\u8BF7\u9009\u62E9\u6709\u6548\u9884\u8BBE\u5E76\u4FDD\u5B58\u4FEE\u590D\u3002"
5670
- ] }),
5671
- flowNotice && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", className: "te-flow-notice", children: flowNotice }),
5672
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.head, children: [
5673
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { style: styles.title, children: "\u5DE5\u7A0B\u6D41\u7A0B\u914D\u7F6E" }),
5674
- /* @__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" })
5675
- ] }),
5676
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.adoptRow, children: [
5677
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dsh_client_ui_primitives2.Button, { size: "sm", onClick: adopt, children: [
5678
- "\u91C7\u7528\u300C",
5679
- FLOW_PRESETS[flow]?.label ?? flow,
5680
- "\u300D\u7684\u63A8\u8350\u914D\u7F6E"
5681
- ] }),
5682
- /* @__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" })
5683
- ] }),
5684
- hasBundledReferences && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.adoptRow, children: [
5685
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.Button, { size: "sm", onClick: () => {
5686
- setPendingAdoption(true);
5687
- setDirty(true);
5688
- setSavedAt("");
5689
- 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");
5690
- }, children: "\u628A\u5F53\u524D\u5185\u7F6E\u5F15\u7528\u8FC1\u79FB\u5230\u9879\u76EE" }),
5691
- /* @__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" })
5692
- ] }),
5693
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.sourceRow, children: [
5694
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: source === "project" ? "done" : source === "invalid" ? "warning" : "ongoing" }),
5695
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.sourceText, children: sourceText(source) })
5696
- ] }),
5697
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.field, children: [
5698
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u6D41\u7A0B\u9884\u8BBE" }),
5699
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.flowGrid, children: FLOW_OPTIONS.map((option) => {
5700
- const active = flow === option.id;
5701
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
5702
- "button",
5703
- {
5704
- type: "button",
5705
- "aria-pressed": active,
5706
- onClick: () => {
5707
- selectFlow(option.id);
5708
- },
5709
- style: { ...styles.flowOption, ...active ? styles.flowOptionActive : {} },
5710
- children: [
5711
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.flowOptionTitle, children: [
5712
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: active ? "done" : "ongoing", size: 8 }),
5713
- option.label
5714
- ] }),
5715
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.flowOptionDesc, children: option.description })
5716
- ]
5717
- },
5718
- option.id
5719
- );
5720
- }) })
5721
- ] }),
5722
- /* @__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) => {
5723
- setStageBindings(next);
5724
- setDirty(true);
5725
- setSavedAt("");
5726
- }, skillProfiles, setSkillProfiles: (next) => {
5727
- setSkillProfiles(next);
5728
- setDirty(true);
5729
- setSavedAt("");
5730
- }, skills, onConfigureSkill: setConfiguringSkill }) }),
5731
- problems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.problems, children: [
5732
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.problemsTitle, children: [
5733
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: "error" }),
5734
- "\u6709 ",
5735
- problems.length,
5736
- " \u4E2A\u95EE\u9898\uFF08\u4FDD\u5B58\u4F1A\u88AB\u62D2\u7EDD\uFF09"
5737
- ] }),
5738
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { style: styles.problemsList, children: problems.map((p) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: p }, p)) })
5739
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.okText, children: [
5740
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: "done" }),
5741
- source === "project" ? "\u914D\u7F6E\u6709\u6548" : "\u4F7F\u7528\u7A7A\u767D\u6D41\u7A0B\u914D\u7F6E\uFF08\u5C1A\u672A\u4FDD\u5B58\uFF09"
5742
- ] }),
5743
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.actions, children: [
5744
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5745
- import_dsh_client_ui_primitives2.Button,
5746
- {
5747
- variant: "primary",
5748
- size: "md",
5749
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(IconCheck, { size: 16 }),
5750
- disabled: problems.length > 0 || saving,
5751
- onClick: () => {
5752
- setSaving(true);
5753
- 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) => {
5754
- if (view) {
5755
- setConfigProblems([]);
5756
- setDirty(false);
5757
- setPendingAdoption(false);
5758
- setStageBindings(view.config.stage_bindings ?? {});
5759
- setSkillProfiles(view.config.skill_profiles ?? {});
5760
- refreshCatalogs();
5761
- }
5762
- }).finally(() => setSaving(false));
5763
- },
5764
- children: saving ? "\u6B63\u5728\u4FDD\u5B58\u2026" : dirty ? "\u4FDD\u5B58\u5230 .dsh/eng.json" : "\u5DF2\u4FDD\u5B58 \xB7 \u65E0\u9700\u4FDD\u5B58"
5765
- }
5766
- ),
5767
- savedAt !== "" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.okText, children: [
5768
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.StateDot, { state: savedAt.startsWith("\u5DF2") ? "done" : "error" }),
5769
- savedAt
5770
- ] }) : null
5771
- ] })
5772
- ] }),
5773
- configuringSkill ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5774
- SkillRuleDialog,
5775
- {
5776
- skill: configuringSkill,
5777
- profile: skillProfiles[formatResourceRef(configuringSkill)],
5778
- rules: configuringSkill.source === "user" ? rules.filter((rule) => rule.ref.source !== "project") : rules,
5779
- 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",
5780
- saveLabel: configuringSkill.source === "user" ? "\u4FDD\u5B58\u7528\u6237\u7EA7\u89C4\u5219" : "\u5E94\u7528\u5230\u5F53\u524D\u914D\u7F6E",
5781
- onSave: updateSkillProfile,
5782
- onClose: () => setConfiguringSkill(null)
5783
- },
5784
- formatResourceRef(configuringSkill)
5785
- ) : null
5786
- ] });
5787
- }
5788
- function sourceText(source) {
5789
- switch (source) {
5790
- case "project":
5791
- return "\u9879\u76EE\u914D\u7F6E\uFF08.dsh/eng.json\uFF09";
5792
- case "invalid":
5793
- return "\u539F\u6587\u4EF6\u65E0\u6CD5\u89E3\u6790\uFF0C\u663E\u793A\u6807\u51C6\u9884\u8BBE";
5794
- default:
5795
- return "\u6807\u51C6\u9884\u8BBE\uFF08\u5DE5\u4F5C\u533A\u5C1A\u65E0 .dsh/eng.json\uFF09";
5796
- }
5797
- }
5798
- function SectionCard({ icon, title, hint, children }) {
5799
- const [open, setOpen] = (0, import_react3.useState)(true);
5800
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.section, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5801
- import_dsh_client_ui_primitives2.DisclosureRow,
5802
- {
5803
- icon,
5804
- title,
5805
- titleClassName: "te-disclosure-title",
5806
- open,
5807
- expandable: true,
5808
- expandOnRowClick: true,
5809
- onToggle: () => {
5810
- setOpen(!open);
5811
- },
5812
- keepContentWhenOpen: true,
5813
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.cardBody, children: [
5814
- hint !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: hint }) : null,
5815
- children
5816
- ] })
5817
- }
5818
- ) });
5819
- }
5820
- function BindingEditor({ stages, stageBindings, setStageBindings, skillProfiles, setSkillProfiles, skills, onConfigureSkill }) {
5821
- const [stage, setStage] = (0, import_react3.useState)(stages[0] ?? "");
5822
- const [query, setQuery] = (0, import_react3.useState)("");
5823
- const currentStage = stages.includes(stage) ? stage : stages[0] ?? "";
5824
- const bindingFor = (name) => stageBindings[name] ?? {};
5825
- const setSkills = (name, next) => {
5826
- setStageBindings({ ...stageBindings, [name]: { ...bindingFor(name), skills: next } });
5827
- };
5828
- const toggleSkill = (raw) => {
5829
- if (currentStage === "") return;
5830
- const current = bindingFor(currentStage).skills ?? [];
5831
- const profile = skillProfiles[raw];
5832
- const alreadyBound = current.some((entry) => formatResourceRef(entry.skill) === raw);
5833
- 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)));
5834
- if (!alreadyBound && profile === void 0) setSkillProfiles({ ...skillProfiles, [raw]: { rules: [] } });
5835
- setSkills(currentStage, next);
5836
- };
5837
- if (currentStage === "") {
5838
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: "\u5F53\u524D\u6D41\u7A0B\u6CA1\u6709\u8282\u70B9\u3002" });
5839
- }
5840
- const boundSkills = bindingFor(currentStage).skills ?? [];
5841
- const unassigned = bindingFor(currentStage).legacy_rules ?? [];
5842
- const boundKeys = new Set(boundSkills.map((entry) => formatResourceRef(entry.skill)));
5843
- const needle = query.trim().toLowerCase();
5844
- const available = skills.filter((entry) => !boundKeys.has(formatResourceRef(entry.ref)) && `${entry.name} ${entry.description} ${entry.sourceLabel}`.toLowerCase().includes(needle));
5845
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.section, children: [
5846
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.field, children: [
5847
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.bindingLabel, children: "\u9009\u62E9\u8282\u70B9" }),
5848
- /* @__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: () => {
5849
- setStage(s);
5850
- }, children: s }, s)) })
5851
- ] }),
5852
- unassigned.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-alert", children: [
5853
- "\u4EE5\u4E0B\u89C4\u5219\u5C5E\u4E8E",
5854
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "\u8282\u70B9" }),
5855
- "\u800C\u4E0D\u662F\u4EFB\u4F55\u6280\u80FD\uFF08\u65E7\u914D\u7F6E\uFF09\uFF1A",
5856
- unassigned.join("\u3001"),
5857
- "\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"
5858
- ] }) : null,
5859
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer", children: [
5860
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "te-transfer-pane", "aria-label": "\u53EF\u7528\u6280\u80FD", children: [
5861
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-binding-heading", children: [
5862
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h4", { children: "\u53EF\u7528\u6280\u80FD" }),
5863
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-binding-count", children: [
5864
- skills.filter((entry) => !boundKeys.has(formatResourceRef(entry.ref))).length,
5865
- " \u9879"
5866
- ] })
5867
- ] }),
5868
- /* @__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) }),
5869
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer-list", role: "group", "aria-label": "\u53EF\u7528\u6280\u80FD\u5217\u8868", children: [
5870
- 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,
5871
- 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,
5872
- 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: [
5873
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-transfer-row-main", children: [
5874
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: entry.name }),
5875
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("small", { children: [
5876
- entry.sourceLabel,
5877
- entry.description ? ` \xB7 ${entry.description}` : ""
5878
- ] })
5879
- ] }),
5880
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "te-transfer-action", "aria-hidden": "true", children: "\uFF0B" })
5881
- ] }, formatResourceRef(entry.ref)))
5882
- ] })
5883
- ] }),
5884
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "te-transfer-arrow", "aria-hidden": "true", children: "\u2192" }),
5885
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "te-transfer-pane", "aria-label": "\u5F53\u524D\u8282\u70B9\u6280\u80FD", children: [
5886
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-binding-heading", children: [
5887
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h4", { children: [
5888
- currentStage,
5889
- " \xB7 \u5DF2\u7ED1\u5B9A"
5890
- ] }),
5891
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-binding-count", children: [
5892
- boundSkills.length,
5893
- " \u9879"
5894
- ] })
5895
- ] }),
5896
- /* @__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" }),
5897
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer-list", role: "group", "aria-label": "\u5DF2\u7ED1\u5B9A\u6280\u80FD\u5217\u8868", children: [
5898
- 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,
5899
- boundSkills.map((entry) => {
5900
- const raw = formatResourceRef(entry.skill);
5901
- const catalog = skills.find((skill) => formatResourceRef(skill.ref) === raw);
5902
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-transfer-row is-bound", children: [
5903
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-transfer-row-main", children: [
5904
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: entry.skill.name }),
5905
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("small", { children: [
5906
- catalog?.sourceLabel ?? entry.skill.source,
5907
- " \xB7 ",
5908
- entry.rules.length,
5909
- " \u6761\u89C4\u5219",
5910
- catalog ? "" : " \xB7 \u8D44\u6E90\u672A\u627E\u5230"
5911
- ] })
5912
- ] }),
5913
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "te-transfer-actions", children: [
5914
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "te-transfer-config", onClick: () => onConfigureSkill(entry.skill), children: "\u914D\u7F6E\u89C4\u5219" }),
5915
- /* @__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" })
5916
- ] })
5917
- ] }, raw);
5918
- })
5919
- ] })
5920
- ] })
5921
- ] }, currentStage)
5922
- ] });
5923
- }
5924
- async function save(remote, config, workspace, setSavedAt, setSource) {
5925
- try {
5926
- const result = await remote.write({ path: workspace, ...config });
5927
- if (!result.ok) {
5928
- setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(result.error));
5929
- return void 0;
5930
- }
5931
- if (!result.value.ok) {
5932
- setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + result.value.problems.join("\uFF1B"));
5933
- return void 0;
5934
- }
5935
- setSource(result.value.source);
5936
- const reused = result.value.adoption?.reused.length ?? 0;
5937
- setSavedAt(reused > 0 ? `\u5DF2\u4FDD\u5B58\uFF1B\u4FDD\u7559\u4E86 ${reused} \u4EFD\u5DF2\u6709\u9879\u76EE\u8D44\u6E90` : "\u5DF2\u4FDD\u5B58");
5938
- return result.value;
5939
- } catch (error) {
5940
- setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(error));
5941
- return void 0;
5942
- }
5943
- }
5944
-
5945
- // src/client/AdaptivePanel.tsx
5946
- var import_react4 = require("react");
5947
- var import_dsh_client_ui_primitives3 = require("@deepseek-ai/dsh-client-ui-primitives");
5948
-
5949
- // src/adaptive.ts
5950
- var META_STAGES = {
5951
- "requirements-analysis": "\u9700\u6C42\u5206\u6790",
5952
- "architecture-design": "\u67B6\u6784\u8BBE\u8BA1",
5953
- "task-orchestration": "\u4EFB\u52A1\u7F16\u6392",
5954
- "code-development": "\u4EE3\u7801\u5F00\u53D1",
5955
- "test-validation": "\u6D4B\u8BD5",
5956
- "code-review": "\u4EE3\u7801\u5BA1\u6838"
5957
- };
5958
-
5959
5227
  // src/client/AdaptivePanel.tsx
5960
5228
  var card = {
5961
5229
  border: "1px solid var(--dsw-alias-border-l2)",
@@ -5981,16 +5249,16 @@ function effectiveSource(entries, name) {
5981
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";
5982
5250
  }
5983
5251
  function AdaptivePanel({ workspace, remote }) {
5984
- const [view, setView] = (0, import_react4.useState)(null);
5985
- const [draft, setDraft] = (0, import_react4.useState)({});
5986
- const [skills, setSkills] = (0, import_react4.useState)([]);
5987
- const [rules, setRules] = (0, import_react4.useState)([]);
5988
- const [selected, setSelected] = (0, import_react4.useState)(null);
5989
- const [loading, setLoading] = (0, import_react4.useState)(true);
5990
- const [saving, setSaving] = (0, import_react4.useState)(false);
5991
- const [dirty, setDirty] = (0, import_react4.useState)(false);
5992
- const [message, setMessage] = (0, import_react4.useState)("");
5993
- const refresh = (0, import_react4.useCallback)(() => {
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)(() => {
5994
5262
  setLoading(true);
5995
5263
  setMessage("");
5996
5264
  void Promise.all([remote.readAdaptive(workspace), remote.listSkills(workspace), remote.listRules(workspace)]).then(([config, catalog, ruleCatalog]) => {
@@ -6017,7 +5285,7 @@ function AdaptivePanel({ workspace, remote }) {
6017
5285
  setMessage("\u8BFB\u53D6\u5931\u8D25\uFF1A" + describeError(error));
6018
5286
  });
6019
5287
  }, [remote, workspace]);
6020
- (0, import_react4.useEffect)(() => {
5288
+ (0, import_react3.useEffect)(() => {
6021
5289
  refresh();
6022
5290
  }, [refresh]);
6023
5291
  const update = (config) => {
@@ -6038,31 +5306,76 @@ function AdaptivePanel({ workspace, remote }) {
6038
5306
  update({ ...draft, sonar: { mode: "branch", token_env: "SONAR_TOKEN", ...draft.sonar, ...patch } });
6039
5307
  };
6040
5308
  const openRules = (name) => {
6041
- if (effectiveSource(skills, name) !== "project") {
6042
- 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`);
6043
5313
  return;
6044
5314
  }
6045
- void remote.readProjectSkillProfile({ path: workspace, name }).then((result) => {
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)));
5323
+ return;
5324
+ }
5325
+ void remote.readSkill({ path: workspace, name, level: source }).then((result) => {
6046
5326
  if (!result.ok) {
6047
- 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));
5328
+ return;
5329
+ }
5330
+ if (!result.value.ok) {
5331
+ setMessage("\u8BFB\u53D6\u6280\u80FD\u5931\u8D25\uFF1A" + describeError(result.value.error));
6048
5332
  return;
6049
5333
  }
6050
- setSelected({ skill: { source: "project", name }, profile: result.value.profile, hash: result.value.hash });
6051
- }, (error) => setMessage("\u8BFB\u53D6\u6280\u80FD\u89C4\u5219\u5931\u8D25\uFF1A" + describeError(error)));
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)));
6052
5342
  };
6053
5343
  const saveRules = async (profile) => {
6054
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
+ }
6055
5364
  const result = await remote.writeProjectSkillProfile({
6056
5365
  path: workspace,
6057
5366
  name: selected.skill.name,
6058
5367
  profile,
6059
- expected_hash: selected.hash
5368
+ expected_hash: hash
6060
5369
  });
6061
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
+ });
6062
5375
  setSelected(null);
6063
5376
  setMessage(`\u5DF2\u4FDD\u5B58 ${selected.skill.name} \u7684\u9879\u76EE Rule\uFF1B\u65B0\u4EFB\u52A1\u5C06\u8BFB\u53D6\u6B64\u914D\u7F6E\u3002`);
6064
5377
  };
6065
- const save2 = () => {
5378
+ const save = () => {
6066
5379
  if (!view) return;
6067
5380
  setSaving(true);
6068
5381
  void remote.writeAdaptive({ path: workspace, config: draft, expected_hash: view.hash }).then((result) => {
@@ -6086,54 +5399,54 @@ function AdaptivePanel({ workspace, remote }) {
6086
5399
  };
6087
5400
  const candidates = [...new Set(skills.map((skill) => skill.name))].filter((name) => name !== "eng-delivery" && !(name in META_STAGES)).sort();
6088
5401
  const sonar = draft.sonar ?? {};
6089
- return (0, import_react4.createElement)(
5402
+ return (0, import_react3.createElement)(
6090
5403
  "div",
6091
5404
  { style: { ...styles.section, display: "flex", flexDirection: "column", gap: 16 } },
6092
- (0, import_react4.createElement)(
5405
+ (0, import_react3.createElement)(
6093
5406
  "div",
6094
5407
  { style: card },
6095
- (0, import_react4.createElement)("strong", null, "\u6309\u9700\u6C42\u9009\u62E9\u6D41\u7A0B"),
6096
- (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"),
6097
- (0, import_react4.createElement)("div", { style: grid }, ...(view?.grades ?? []).map((grade) => (0, import_react4.createElement)(
5408
+ (0, import_react3.createElement)("strong", null, "\u6309\u9700\u6C42\u9009\u62E9\u6D41\u7A0B"),
5409
+ (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"),
5410
+ (0, import_react3.createElement)("div", { style: grid }, ...(view?.grades ?? []).map((grade) => (0, import_react3.createElement)(
6098
5411
  "div",
6099
5412
  { key: grade.id, style: { ...card, gap: 5 } },
6100
- (0, import_react4.createElement)("strong", null, `${grade.label} \xB7 ${grade.id}`),
6101
- (0, import_react4.createElement)("span", { style: label }, grade.guidance),
6102
- (0, import_react4.createElement)("span", { style: { fontSize: 12 } }, grade.stages.join(" \u2192 "))
5413
+ (0, import_react3.createElement)("strong", null, `${grade.label} \xB7 ${grade.id}`),
5414
+ (0, import_react3.createElement)("span", { style: label }, grade.guidance),
5415
+ (0, import_react3.createElement)("span", { style: { fontSize: 12 } }, grade.stages.join(" \u2192 "))
6103
5416
  )))
6104
5417
  ),
6105
- (0, import_react4.createElement)(
5418
+ (0, import_react3.createElement)(
6106
5419
  "div",
6107
5420
  { style: card },
6108
- (0, import_react4.createElement)("strong", null, "\u5143\u6280\u80FD\u4E0E\u9879\u76EE\u6280\u80FD"),
6109
- (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"),
5421
+ (0, import_react3.createElement)("strong", null, "\u5143\u6280\u80FD\u4E0E\u9879\u76EE\u6280\u80FD"),
5422
+ (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"),
6110
5423
  ...Object.entries(META_STAGES).map(([id, stage]) => {
6111
5424
  const meta = id;
6112
5425
  const selected2 = draft.meta_bindings?.[meta] ?? [];
6113
- return (0, import_react4.createElement)(
5426
+ return (0, import_react3.createElement)(
6114
5427
  "div",
6115
5428
  { key: id, style: { ...card, gap: 6 } },
6116
- (0, import_react4.createElement)("strong", null, stage),
6117
- (0, import_react4.createElement)("span", { style: label }, `\u6838\u5FC3\uFF1A${id} \xB7 \u751F\u6548\u6765\u6E90\uFF1A${effectiveSource(skills, id)}`),
6118
- (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "outline", size: "sm", onClick: () => openRules(id) }, "\u914D\u7F6E\u6838\u5FC3 Skill \u7684 Rule"),
6119
- (0, import_react4.createElement)(
5429
+ (0, import_react3.createElement)("strong", null, stage),
5430
+ (0, import_react3.createElement)("span", { style: label }, `\u6838\u5FC3\uFF1A${id} \xB7 \u751F\u6548\u6765\u6E90\uFF1A${effectiveSource(skills, id)}`),
5431
+ (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", onClick: () => openRules(id) }, "\u914D\u7F6E\u6838\u5FC3 Skill \u7684 Rule"),
5432
+ (0, import_react3.createElement)(
6120
5433
  "div",
6121
5434
  { style: row },
6122
- ...selected2.map((name) => (0, import_react4.createElement)("button", {
5435
+ ...selected2.map((name) => (0, import_react3.createElement)("button", {
6123
5436
  key: name,
6124
5437
  type: "button",
6125
5438
  title: "\u79FB\u9664\u6302\u8F7D",
6126
5439
  style: { ...input, minWidth: 0, cursor: "pointer" },
6127
5440
  onClick: () => removeSkill(meta, name)
6128
5441
  }, `${name} \xB7 ${effectiveSource(skills, name)} \xD7`)),
6129
- ...selected2.map((name) => (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
5442
+ ...selected2.map((name) => (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, {
6130
5443
  key: `rules-${name}`,
6131
5444
  variant: "outline",
6132
5445
  size: "sm",
6133
5446
  onClick: () => openRules(name)
6134
5447
  }, `\u914D\u7F6E ${name} \u7684 Rule`))
6135
5448
  ),
6136
- (0, import_react4.createElement)(
5449
+ (0, import_react3.createElement)(
6137
5450
  "select",
6138
5451
  {
6139
5452
  style: input,
@@ -6141,23 +5454,23 @@ function AdaptivePanel({ workspace, remote }) {
6141
5454
  value: "",
6142
5455
  onChange: (event) => addSkill(meta, event.target.value)
6143
5456
  },
6144
- (0, import_react4.createElement)("option", { value: "" }, "\u6302\u8F7D\u9644\u52A0\u6280\u80FD\u2026"),
6145
- ...candidates.filter((name) => !selected2.includes(name)).map((name) => (0, import_react4.createElement)("option", { key: name, value: name }, `${name} \xB7 ${effectiveSource(skills, name)}`))
5457
+ (0, import_react3.createElement)("option", { value: "" }, "\u6302\u8F7D\u9644\u52A0\u6280\u80FD\u2026"),
5458
+ ...candidates.filter((name) => !selected2.includes(name)).map((name) => (0, import_react3.createElement)("option", { key: name, value: name }, `${name} \xB7 ${effectiveSource(skills, name)}`))
6146
5459
  )
6147
5460
  );
6148
5461
  })
6149
5462
  ),
6150
- (0, import_react4.createElement)(
5463
+ (0, import_react3.createElement)(
6151
5464
  "div",
6152
5465
  { style: card },
6153
- (0, import_react4.createElement)(
5466
+ (0, import_react3.createElement)(
6154
5467
  "div",
6155
5468
  { style: row },
6156
- (0, import_react4.createElement)("strong", null, "SonarQube \u5BA1\u6838"),
6157
- (0, import_react4.createElement)(
5469
+ (0, import_react3.createElement)("strong", null, "SonarQube \u5BA1\u6838"),
5470
+ (0, import_react3.createElement)(
6158
5471
  "label",
6159
5472
  { style: row },
6160
- (0, import_react4.createElement)("input", {
5473
+ (0, import_react3.createElement)("input", {
6161
5474
  type: "checkbox",
6162
5475
  checked: sonar.enabled === true,
6163
5476
  onChange: (event) => updateSonar({ enabled: event.target.checked })
@@ -6165,61 +5478,62 @@ function AdaptivePanel({ workspace, remote }) {
6165
5478
  "\u542F\u7528\uFF08\u4EC5\u4EE3\u7801\u5BA1\u6838\u9636\u6BB5\uFF09"
6166
5479
  )
6167
5480
  ),
6168
- (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"),
6169
- sonar.enabled === true ? (0, import_react4.createElement)(
5481
+ (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"),
5482
+ sonar.enabled === true ? (0, import_react3.createElement)(
6170
5483
  "div",
6171
5484
  { style: grid },
6172
5485
  ...[
6173
5486
  ["host_url", "\u670D\u52A1\u5730\u5740", "https://sonar.example"],
6174
5487
  ["project_key", "\u9879\u76EE Key", "my-project"],
6175
5488
  ["token_env", "Token \u73AF\u5883\u53D8\u91CF\u540D", "SONAR_TOKEN"]
6176
- ].map(([key, title, placeholder]) => (0, import_react4.createElement)(
5489
+ ].map(([key, title, placeholder]) => (0, import_react3.createElement)(
6177
5490
  "label",
6178
5491
  { key, style: { display: "flex", flexDirection: "column", gap: 4 } },
6179
- (0, import_react4.createElement)("span", { style: label }, title),
6180
- (0, import_react4.createElement)("input", {
5492
+ (0, import_react3.createElement)("span", { style: label }, title),
5493
+ (0, import_react3.createElement)("input", {
6181
5494
  style: input,
6182
5495
  value: sonar[key] ?? "",
6183
5496
  placeholder,
6184
5497
  onChange: (event) => updateSonar({ [key]: event.target.value })
6185
5498
  })
6186
5499
  )),
6187
- (0, import_react4.createElement)(
5500
+ (0, import_react3.createElement)(
6188
5501
  "label",
6189
5502
  { style: { display: "flex", flexDirection: "column", gap: 4 } },
6190
- (0, import_react4.createElement)("span", { style: label }, "\u5206\u6790\u5BF9\u8C61"),
6191
- (0, import_react4.createElement)(
5503
+ (0, import_react3.createElement)("span", { style: label }, "\u5206\u6790\u5BF9\u8C61"),
5504
+ (0, import_react3.createElement)(
6192
5505
  "select",
6193
5506
  {
6194
5507
  style: input,
6195
5508
  value: sonar.mode ?? "branch",
6196
5509
  onChange: (event) => updateSonar({ mode: event.target.value })
6197
5510
  },
6198
- (0, import_react4.createElement)("option", { value: "branch" }, "\u5206\u652F"),
6199
- (0, import_react4.createElement)("option", { value: "pull-request" }, "\u5408\u5E76\u8BF7\u6C42")
5511
+ (0, import_react3.createElement)("option", { value: "branch" }, "\u5206\u652F"),
5512
+ (0, import_react3.createElement)("option", { value: "pull-request" }, "\u5408\u5E76\u8BF7\u6C42")
6200
5513
  )
6201
5514
  )
6202
5515
  ) : null
6203
5516
  ),
6204
- (0, import_react4.createElement)(
5517
+ (0, import_react3.createElement)(
6205
5518
  "div",
6206
5519
  { style: row },
6207
- (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "outline", size: "sm", disabled: loading || saving, onClick: refresh }, "\u5237\u65B0"),
6208
- (0, import_react4.createElement)(
6209
- import_dsh_client_ui_primitives3.Button,
6210
- { variant: "primary", size: "sm", disabled: loading || saving || !dirty, onClick: save2 },
5520
+ (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", disabled: loading || saving, onClick: refresh }, "\u5237\u65B0"),
5521
+ (0, import_react3.createElement)(
5522
+ import_dsh_client_ui_primitives2.Button,
5523
+ { variant: "primary", size: "sm", disabled: loading || saving || !dirty, onClick: save },
6211
5524
  saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u81EA\u9002\u5E94\u914D\u7F6E"
6212
5525
  ),
6213
- (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")
5526
+ (0, import_react3.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")
6214
5527
  ),
6215
- message ? (0, import_react4.createElement)("p", { role: "status", style: styles.status }, message) : null,
6216
- view?.problems.length ? (0, import_react4.createElement)("p", { role: "alert", style: styles.status }, view.problems.join("\uFF1B")) : null,
6217
- selected ? (0, import_react4.createElement)(SkillRuleDialog, {
5528
+ message ? (0, import_react3.createElement)("p", { role: "status", style: styles.status }, message) : null,
5529
+ view?.problems.length ? (0, import_react3.createElement)("p", { role: "alert", style: styles.status }, view.problems.join("\uFF1B")) : null,
5530
+ selected ? (0, import_react3.createElement)(SkillRuleDialog, {
6218
5531
  key: `${selected.skill.source}:${selected.skill.name}`,
6219
5532
  skill: selected.skill,
6220
5533
  profile: selected.profile,
6221
5534
  rules,
6222
- 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",
5535
+ 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",
5536
+ saveLabel: selected.template ? "\u521B\u5EFA\u9879\u76EE Skill \u5E76\u4FDD\u5B58\u89C4\u5219" : "\u4FDD\u5B58\u914D\u7F6E",
6223
5537
  onSave: saveRules,
6224
5538
  onClose: () => setSelected(null)
6225
5539
  }) : null
@@ -6227,8 +5541,8 @@ function AdaptivePanel({ workspace, remote }) {
6227
5541
  }
6228
5542
 
6229
5543
  // src/client/InitPanel.tsx
6230
- var import_react5 = require("react");
6231
- var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
5544
+ var import_react4 = require("react");
5545
+ var import_dsh_client_ui_primitives3 = require("@deepseek-ai/dsh-client-ui-primitives");
6232
5546
  var MD_LABELS = { code: { copyLabel: "\u590D\u5236", copiedLabel: "\u5DF2\u590D\u5236" }, footnotes: "\u811A\u6CE8" };
6233
5547
  var INIT_TIMEOUT_S = 150;
6234
5548
  var card2 = {
@@ -6240,14 +5554,14 @@ var card2 = {
6240
5554
  padding: "12px 14px"
6241
5555
  };
6242
5556
  function InitPanel({ workspace, remote }) {
6243
- const [view, setView] = (0, import_react5.useState)(null);
6244
- const [generating, setGenerating] = (0, import_react5.useState)(false);
6245
- const [elapsed, setElapsed] = (0, import_react5.useState)(0);
6246
- const [draft, setDraft] = (0, import_react5.useState)(null);
6247
- const [editing, setEditing] = (0, import_react5.useState)(false);
6248
- const [body2, setBody] = (0, import_react5.useState)("");
6249
- const [msg, setMsg] = (0, import_react5.useState)("");
6250
- (0, import_react5.useEffect)(() => {
5557
+ const [view, setView] = (0, import_react4.useState)(null);
5558
+ const [generating, setGenerating] = (0, import_react4.useState)(false);
5559
+ const [elapsed, setElapsed] = (0, import_react4.useState)(0);
5560
+ const [draft, setDraft] = (0, import_react4.useState)(null);
5561
+ const [editing, setEditing] = (0, import_react4.useState)(false);
5562
+ const [body2, setBody] = (0, import_react4.useState)("");
5563
+ const [msg, setMsg] = (0, import_react4.useState)("");
5564
+ (0, import_react4.useEffect)(() => {
6251
5565
  if (!generating) {
6252
5566
  setElapsed(0);
6253
5567
  return;
@@ -6261,13 +5575,13 @@ function InitPanel({ workspace, remote }) {
6261
5575
  clearInterval(timer);
6262
5576
  };
6263
5577
  }, [generating]);
6264
- const refresh = (0, import_react5.useCallback)(() => {
5578
+ const refresh = (0, import_react4.useCallback)(() => {
6265
5579
  void remote.readInit(workspace).then((r) => {
6266
5580
  if (r.ok) setView(r.value);
6267
5581
  }, () => {
6268
5582
  });
6269
5583
  }, [remote, workspace]);
6270
- (0, import_react5.useEffect)(() => {
5584
+ (0, import_react4.useEffect)(() => {
6271
5585
  refresh();
6272
5586
  }, [refresh]);
6273
5587
  const generate = async () => {
@@ -6310,45 +5624,45 @@ function InitPanel({ workspace, remote }) {
6310
5624
  setMsg("");
6311
5625
  };
6312
5626
  const exists = view?.exists === true;
6313
- return (0, import_react5.createElement)(
5627
+ return (0, import_react4.createElement)(
6314
5628
  "div",
6315
5629
  { style: styles.section },
6316
- (0, import_react5.createElement)(
5630
+ (0, import_react4.createElement)(
6317
5631
  "div",
6318
5632
  { style: card2 },
6319
- (0, import_react5.createElement)(
5633
+ (0, import_react4.createElement)(
6320
5634
  "div",
6321
5635
  { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" } },
6322
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.StateDot, { state: exists ? "done" : "ongoing" }),
6323
- (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"),
6324
- view?.path !== void 0 ? (0, import_react5.createElement)("span", { style: styles.sourceBadge }, `\u5DF2\u5B9A\u4F4D\u5230 ${view.path}`) : null
5636
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.StateDot, { state: exists ? "done" : "ongoing" }),
5637
+ (0, import_react4.createElement)("span", { style: styles.bindingLabel }, exists ? `\u5DF2\u521D\u59CB\u5316 \xB7 ${view.lines} \u884C\uFF08\u4E0A\u9650 200\uFF09` : "\u672A\u521D\u59CB\u5316"),
5638
+ view?.path !== void 0 ? (0, import_react4.createElement)("span", { style: styles.sourceBadge }, `\u5DF2\u5B9A\u4F4D\u5230 ${view.path}`) : null
6325
5639
  ),
6326
- (0, import_react5.createElement)(
5640
+ (0, import_react4.createElement)(
6327
5641
  "p",
6328
5642
  { style: styles.muted },
6329
5643
  "\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"
6330
5644
  ),
6331
- exists && !editing && draft === null ? (0, import_react5.createElement)(
5645
+ exists && !editing && draft === null ? (0, import_react4.createElement)(
6332
5646
  "div",
6333
5647
  { style: styles.mdPreview },
6334
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.MarkdownText, { text: view.content, labels: MD_LABELS })
5648
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.MarkdownText, { text: view.content, labels: MD_LABELS })
6335
5649
  ) : null,
6336
- draft !== null ? (0, import_react5.createElement)(
5650
+ draft !== null ? (0, import_react4.createElement)(
6337
5651
  "div",
6338
5652
  { style: styles.section },
6339
- (0, import_react5.createElement)(
5653
+ (0, import_react4.createElement)(
6340
5654
  "div",
6341
5655
  { style: styles.sourceRow },
6342
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.StateDot, { state: "ongoing", size: 8 }),
6343
- (0, import_react5.createElement)("span", { style: styles.sourceBadge }, `AI \u8349\u7A3F \xB7 ${draft.lines} \u884C \xB7 \u5C1A\u672A\u5199\u5165`)
5656
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.StateDot, { state: "ongoing", size: 8 }),
5657
+ (0, import_react4.createElement)("span", { style: styles.sourceBadge }, `AI \u8349\u7A3F \xB7 ${draft.lines} \u884C \xB7 \u5C1A\u672A\u5199\u5165`)
6344
5658
  ),
6345
- (0, import_react5.createElement)(
5659
+ (0, import_react4.createElement)(
6346
5660
  "div",
6347
5661
  { style: styles.mdPreview },
6348
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.MarkdownText, { text: draft.content, labels: MD_LABELS })
5662
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.MarkdownText, { text: draft.content, labels: MD_LABELS })
6349
5663
  )
6350
5664
  ) : null,
6351
- editing ? (0, import_react5.createElement)("textarea", {
5665
+ editing ? (0, import_react4.createElement)("textarea", {
6352
5666
  style: { ...styles.textarea, minHeight: 300 },
6353
5667
  placeholder: "AGENTS.md \u6B63\u6587\uFF08Markdown\uFF0C\u2264200 \u884C\uFF09",
6354
5668
  value: body2,
@@ -6356,16 +5670,16 @@ function InitPanel({ workspace, remote }) {
6356
5670
  setBody(ev.target.value);
6357
5671
  }
6358
5672
  }) : null,
6359
- generating ? (0, import_react5.createElement)(
5673
+ generating ? (0, import_react4.createElement)(
6360
5674
  "p",
6361
5675
  { style: styles.status },
6362
5676
  `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`
6363
5677
  ) : null,
6364
- msg !== "" ? (0, import_react5.createElement)("p", { style: styles.status }, msg) : null,
6365
- draft !== null ? (0, import_react5.createElement)(
5678
+ msg !== "" ? (0, import_react4.createElement)("p", { style: styles.status }, msg) : null,
5679
+ draft !== null ? (0, import_react4.createElement)(
6366
5680
  "div",
6367
5681
  { style: styles.row },
6368
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, {
5682
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
6369
5683
  variant: "primary",
6370
5684
  size: "md",
6371
5685
  disabled: draft.lines > 200,
@@ -6374,14 +5688,14 @@ function InitPanel({ workspace, remote }) {
6374
5688
  void write(draft.content, exists);
6375
5689
  }
6376
5690
  }, exists ? "\u4FDD\u5B58\u5E76\u8986\u76D6" : "\u4FDD\u5B58"),
6377
- 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,
6378
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "md", onClick: () => {
5691
+ 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,
5692
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "ghost", size: "md", onClick: () => {
6379
5693
  setDraft(null);
6380
5694
  } }, "\u653E\u5F03")
6381
- ) : editing ? (0, import_react5.createElement)(
5695
+ ) : editing ? (0, import_react4.createElement)(
6382
5696
  "div",
6383
5697
  { style: styles.row },
6384
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, {
5698
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
6385
5699
  variant: "primary",
6386
5700
  size: "md",
6387
5701
  disabled: body2.trim() === "",
@@ -6390,13 +5704,13 @@ function InitPanel({ workspace, remote }) {
6390
5704
  void write(body2, exists);
6391
5705
  }
6392
5706
  }, exists ? "\u4FDD\u5B58\u5E76\u8986\u76D6" : "\u4FDD\u5B58"),
6393
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "md", onClick: () => {
5707
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "ghost", size: "md", onClick: () => {
6394
5708
  setEditing(false);
6395
5709
  } }, "\u53D6\u6D88")
6396
- ) : (0, import_react5.createElement)(
5710
+ ) : (0, import_react4.createElement)(
6397
5711
  "div",
6398
5712
  { style: styles.row },
6399
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, {
5713
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
6400
5714
  variant: "primary",
6401
5715
  size: "md",
6402
5716
  disabled: generating,
@@ -6405,55 +5719,55 @@ function InitPanel({ workspace, remote }) {
6405
5719
  void generate();
6406
5720
  }
6407
5721
  }, exists ? "\u91CD\u65B0\u521D\u59CB\u5316\uFF08AI \u626B\u63CF\u8986\u76D6\uFF09" : "\u8BA9 AI \u521D\u59CB\u5316"),
6408
- exists ? (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", size: "md", onClick: startEdit }, "\u624B\u52A8\u7F16\u8F91") : null
5722
+ exists ? (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "outline", size: "md", onClick: startEdit }, "\u624B\u52A8\u7F16\u8F91") : null
6409
5723
  )
6410
5724
  )
6411
5725
  );
6412
5726
  }
6413
5727
 
6414
5728
  // src/client/SkillManager.tsx
6415
- var import_react7 = require("react");
6416
-
6417
- // src/client/ResourceManager.tsx
6418
5729
  var import_react6 = require("react");
6419
- var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
5730
+
5731
+ // src/client/ResourceManager.tsx
5732
+ var import_react5 = require("react");
5733
+ var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
6420
5734
  var labels = { code: { copyLabel: "\u590D\u5236", copiedLabel: "\u5DF2\u590D\u5236" }, footnotes: "\u811A\u6CE8" };
6421
5735
  var levelOf = (row2) => row2.source === "bundled" ? "bundled" : row2.source.startsWith("user") ? "user" : "project";
6422
- var sourceText2 = (source) => source === "bundled" ? "\u5185\u7F6E" : source === "codex-project" ? "\u9879\u76EE \xB7 Codex" : source.startsWith("user") ? "\u4E2A\u4EBA" : "\u9879\u76EE";
5736
+ var sourceText = (source) => source === "bundled" ? "\u5185\u7F6E" : source === "codex-project" ? "\u9879\u76EE \xB7 Codex" : source.startsWith("user") ? "\u4E2A\u4EBA" : "\u9879\u76EE";
6423
5737
  var sizeText = (bytes) => bytes < 1024 ? `${bytes} B` : bytes < 1024 * 1024 ? `${(bytes / 1024).toFixed(1)} KB` : `${(bytes / 1024 / 1024).toFixed(1)} MB`;
6424
5738
  var fail = (r) => describeError(r.error ?? "\u64CD\u4F5C\u5931\u8D25");
6425
5739
  function ResourceManager({ workspace, remote, kind, onConfigureSkill }) {
6426
5740
  const noun = kind === "skill" ? "\u6280\u80FD" : "\u89C4\u5219";
6427
- const [rows, setRows] = (0, import_react6.useState)([]);
6428
- const [query, setQuery] = (0, import_react6.useState)("");
6429
- const [filter, setFilter] = (0, import_react6.useState)("all");
6430
- const [notice, setNotice] = (0, import_react6.useState)("");
6431
- const [error, setError] = (0, import_react6.useState)("");
6432
- const [loading, setLoading] = (0, import_react6.useState)(true);
6433
- const [revision, refresh] = (0, import_react6.useState)(0);
6434
- const [busy, setBusy] = (0, import_react6.useState)(false);
6435
- const [roots, setRoots] = (0, import_react6.useState)(null);
6436
- const [importing, setImporting] = (0, import_react6.useState)(false);
6437
- const [request, setRequest] = (0, import_react6.useState)(null);
6438
- const [preview, setPreview] = (0, import_react6.useState)(null);
6439
- const [level, setLevel] = (0, import_react6.useState)("project");
6440
- const [manual, setManual] = (0, import_react6.useState)(false);
6441
- const [sourceDir, setSourceDir] = (0, import_react6.useState)("");
6442
- const [dirs, setDirs] = (0, import_react6.useState)([]);
6443
- const [browsePath, setBrowsePath] = (0, import_react6.useState)("");
6444
- const [editing, setEditing] = (0, import_react6.useState)(null);
6445
- const [viewing, setViewing] = (0, import_react6.useState)(false);
6446
- const [name, setName] = (0, import_react6.useState)("");
6447
- const [description, setDescription] = (0, import_react6.useState)("");
6448
- const [whenToUse, setWhenToUse] = (0, import_react6.useState)("");
6449
- const [body2, setBody] = (0, import_react6.useState)("");
6450
- const [templateSource, setTemplateSource] = (0, import_react6.useState)(null);
6451
- const [deleting, setDeleting] = (0, import_react6.useState)(null);
6452
- const input2 = (0, import_react6.useRef)(null);
6453
- const fileEpoch = (0, import_react6.useRef)(0);
6454
- const browseEpoch = (0, import_react6.useRef)(0);
5741
+ const [rows, setRows] = (0, import_react5.useState)([]);
5742
+ const [query, setQuery] = (0, import_react5.useState)("");
5743
+ const [filter, setFilter] = (0, import_react5.useState)("all");
5744
+ const [notice, setNotice] = (0, import_react5.useState)("");
5745
+ const [error, setError] = (0, import_react5.useState)("");
5746
+ const [loading, setLoading] = (0, import_react5.useState)(true);
5747
+ const [revision, refresh] = (0, import_react5.useState)(0);
5748
+ const [busy, setBusy] = (0, import_react5.useState)(false);
5749
+ const [roots, setRoots] = (0, import_react5.useState)(null);
5750
+ const [importing, setImporting] = (0, import_react5.useState)(false);
5751
+ const [request, setRequest] = (0, import_react5.useState)(null);
5752
+ const [preview, setPreview] = (0, import_react5.useState)(null);
5753
+ const [level, setLevel] = (0, import_react5.useState)("project");
5754
+ const [manual, setManual] = (0, import_react5.useState)(false);
5755
+ const [sourceDir, setSourceDir] = (0, import_react5.useState)("");
5756
+ const [dirs, setDirs] = (0, import_react5.useState)([]);
5757
+ const [browsePath, setBrowsePath] = (0, import_react5.useState)("");
5758
+ const [editing, setEditing] = (0, import_react5.useState)(null);
5759
+ const [viewing, setViewing] = (0, import_react5.useState)(false);
5760
+ const [name, setName] = (0, import_react5.useState)("");
5761
+ const [description, setDescription] = (0, import_react5.useState)("");
5762
+ const [whenToUse, setWhenToUse] = (0, import_react5.useState)("");
5763
+ const [body2, setBody] = (0, import_react5.useState)("");
5764
+ const [templateSource, setTemplateSource] = (0, import_react5.useState)(null);
5765
+ const [deleting, setDeleting] = (0, import_react5.useState)(null);
5766
+ const input2 = (0, import_react5.useRef)(null);
5767
+ const fileEpoch = (0, import_react5.useRef)(0);
5768
+ const browseEpoch = (0, import_react5.useRef)(0);
6455
5769
  const readonly = editing !== null && editing !== "new" && (levelOf(editing) === "bundled" || editing.source === "codex-project");
6456
- (0, import_react6.useEffect)(() => {
5770
+ (0, import_react5.useEffect)(() => {
6457
5771
  let active = true;
6458
5772
  setLoading(true);
6459
5773
  setRows([]);
@@ -6480,7 +5794,7 @@ function ResourceManager({ workspace, remote, kind, onConfigureSkill }) {
6480
5794
  fileEpoch.current++;
6481
5795
  };
6482
5796
  }, [workspace, remote, kind, revision]);
6483
- (0, import_react6.useEffect)(() => {
5797
+ (0, import_react5.useEffect)(() => {
6484
5798
  let active = true;
6485
5799
  setPreview(null);
6486
5800
  if (!request) return;
@@ -6642,13 +5956,15 @@ function ResourceManager({ workspace, remote, kind, onConfigureSkill }) {
6642
5956
  setBusy(false);
6643
5957
  }
6644
5958
  };
6645
- const save2 = async () => {
5959
+ const save = async () => {
6646
5960
  if (busy) return;
6647
5961
  setBusy(true);
6648
5962
  setError("");
6649
5963
  try {
6650
- 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");
6651
- const r = kind === "skill" ? await remote.writeSkill({ name, description, whenToUse, content: body2, level, path: workspace }) : await remote.writeRule({ name, content: body2, level, path: workspace });
5964
+ if (editing === "new" && rows.some((r2) => r2.name === name && (levelOf(r2) === level && r2.source !== "codex-project" || kind === "rule" && levelOf(r2) === "bundled"))) {
5965
+ throw new Error("\u540C\u540D\u8D44\u6E90\u5DF2\u5B58\u5728\uFF0C\u8BF7\u6362\u540D\u6216\u7F16\u8F91\u73B0\u6709\u8D44\u6E90");
5966
+ }
5967
+ 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 });
6652
5968
  if (!r.ok) throw new Error(fail(r));
6653
5969
  if (!r.value.ok) throw new Error(r.value.error ?? "\u4FDD\u5B58\u5931\u8D25");
6654
5970
  const copied = templateSource !== null;
@@ -6682,104 +5998,329 @@ function ResourceManager({ workspace, remote, kind, onConfigureSkill }) {
6682
5998
  setBusy(false);
6683
5999
  }
6684
6000
  };
6685
- const status = () => error ? (0, import_react6.createElement)("div", { className: "te-alert", role: "alert" }, error) : null;
6686
- const targets = () => (0, import_react6.createElement)(
6001
+ const status = () => error ? (0, import_react5.createElement)("div", { className: "te-alert", role: "alert" }, error) : null;
6002
+ const targets = () => (0, import_react5.createElement)(
6687
6003
  "div",
6688
6004
  { className: "te-targets" },
6689
- ...["project", "user"].map((lvl) => (0, import_react6.createElement)(
6005
+ ...["project", "user"].map((lvl) => (0, import_react5.createElement)(
6690
6006
  "button",
6691
6007
  { type: "button", key: lvl, className: `te-target ${level === lvl ? "selected" : ""}`, "aria-pressed": level === lvl, disabled: busy || editing !== null && editing !== "new", onClick: () => {
6692
6008
  setPreview(null);
6693
6009
  setLevel(lvl);
6694
6010
  } },
6695
- (0, import_react6.createElement)("strong", null, lvl === "project" ? "\u9879\u76EE\u5171\u4EAB" : "\u4E2A\u4EBA\u5168\u5C40"),
6696
- (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")
6011
+ (0, import_react5.createElement)("strong", null, lvl === "project" ? "\u9879\u76EE\u5171\u4EAB" : "\u4E2A\u4EBA\u5168\u5C40"),
6012
+ (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")
6697
6013
  )),
6698
- (0, import_react6.createElement)("code", { className: "te-path" }, roots?.[level] ?? (level === "project" ? `${workspace}/.dsh/${kind}s` : `DSH_HOME/${kind}s`))
6014
+ (0, import_react5.createElement)("code", { className: "te-path" }, roots?.[level] ?? (level === "project" ? `${workspace}/.dsh/${kind}s` : `DSH_HOME/${kind}s`))
6699
6015
  );
6700
6016
  const visible = rows.filter((r) => `${r.name} ${r.description ?? ""}`.toLowerCase().includes(query.toLowerCase()) && (filter === "all" || levelOf(r) === filter));
6701
- return (0, import_react6.createElement)(
6017
+ return (0, import_react5.createElement)(
6702
6018
  "section",
6703
6019
  { className: "te-resource" },
6704
- (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) => {
6020
+ (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) => {
6705
6021
  void selected(Array.from(e.target.files ?? []));
6706
6022
  } }),
6707
- (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: () => {
6023
+ (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: () => {
6708
6024
  void edit("new");
6709
- } }, `\u65B0\u5EFA${noun}`), (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "primary", onClick: choose }, `\u5B89\u88C5${noun}`))),
6710
- (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")),
6711
- notice ? (0, import_react6.createElement)("div", { className: "te-success", role: "status" }, notice) : null,
6025
+ } }, `\u65B0\u5EFA${noun}`), (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "primary", onClick: choose }, `\u5B89\u88C5${noun}`))),
6026
+ (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")),
6027
+ notice ? (0, import_react5.createElement)("div", { className: "te-success", role: "status" }, notice) : null,
6712
6028
  !importing && !editing && !deleting ? status() : null,
6713
- 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)(
6029
+ 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)(
6714
6030
  "article",
6715
6031
  { className: "te-resource-card", key: row2.source + "/" + row2.name },
6716
- (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))),
6717
- (0, import_react6.createElement)("h3", null, row2.name),
6718
- (0, import_react6.createElement)("p", null, row2.description || "\u9879\u76EE\u7EA6\u5B9A\u4E0E\u6267\u884C\u89C4\u5219"),
6719
- (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: () => {
6032
+ (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))),
6033
+ (0, import_react5.createElement)("h3", null, row2.name),
6034
+ (0, import_react5.createElement)("p", null, row2.description || "\u9879\u76EE\u7EA6\u5B9A\u4E0E\u6267\u884C\u89C4\u5219"),
6035
+ (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: () => {
6720
6036
  void edit(row2, true);
6721
- } }, "\u67E5\u770B"), levelOf(row2) === "bundled" ? (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", size: "sm", disabled: busy, onClick: () => {
6037
+ } }, "\u67E5\u770B"), levelOf(row2) === "bundled" ? (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "ghost", size: "sm", disabled: busy, onClick: () => {
6722
6038
  void copyTemplate(row2);
6723
- } }, "\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: () => {
6039
+ } }, "\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: () => {
6724
6040
  void edit(row2);
6725
- } }, "\u7F16\u8F91") : null, levelOf(row2) !== "bundled" && row2.source !== "codex-project" ? (0, import_react6.createElement)("button", { className: "te-delete", onClick: () => {
6041
+ } }, "\u7F16\u8F91") : null, levelOf(row2) !== "bundled" && row2.source !== "codex-project" ? (0, import_react5.createElement)("button", { className: "te-delete", onClick: () => {
6726
6042
  setDeleting(row2);
6727
6043
  setError("");
6728
6044
  } }, "\u5220\u9664") : null)
6729
6045
  ))),
6730
- kind === "skill" ? (0, import_react6.createElement)("button", { className: "te-link", onClick: () => {
6046
+ kind === "skill" ? (0, import_react5.createElement)("button", { className: "te-link", onClick: () => {
6731
6047
  setImporting(true);
6732
6048
  setManual(true);
6733
6049
  setError("");
6734
6050
  } }, "\u9AD8\u7EA7\uFF1A\u4ECE Harness \u4E3B\u673A\u8DEF\u5F84\u5B89\u88C5") : null,
6735
- importing ? (0, import_react6.createElement)(
6051
+ importing ? (0, import_react5.createElement)(
6736
6052
  ResourceModal,
6737
- { 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: () => {
6053
+ { 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: () => {
6738
6054
  void install();
6739
6055
  } }, busy ? "\u5904\u7406\u4E2D\u2026" : "\u786E\u8BA4\u5B89\u88C5")) },
6740
6056
  targets(),
6741
- (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),
6742
- 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) => {
6057
+ (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),
6058
+ 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) => {
6743
6059
  setSourceDir(e.target.value);
6744
6060
  setRequest(null);
6745
- } }), (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", onClick: () => {
6061
+ } }), (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", onClick: () => {
6746
6062
  void browse(sourceDir);
6747
- } }, "\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: () => {
6063
+ } }, "\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: () => {
6748
6064
  void browse(browsePath.replace(/[\\/][^\\/]+[\\/]?$/u, "") || "/");
6749
- } }, "\u2191 \u4E0A\u7EA7\u76EE\u5F55") : null, ...dirs.map((d) => (0, import_react6.createElement)("button", { key: d.name, onClick: () => {
6065
+ } }, "\u2191 \u4E0A\u7EA7\u76EE\u5F55") : null, ...dirs.map((d) => (0, import_react5.createElement)("button", { key: d.name, onClick: () => {
6750
6066
  setRequest(null);
6751
6067
  void browse(browsePath.replace(/[\\/]+$/u, "") + "/" + d.name);
6752
6068
  } }, d.name + (d.hasSkill ? " \xB7 SKILL.md" : ""))))) : null,
6753
- busy ? (0, import_react6.createElement)("p", { role: "status" }, "\u6B63\u5728\u6821\u9A8C\u6587\u4EF6\uFF0C\u8BF7\u7A0D\u5019\u2026") : null,
6069
+ busy ? (0, import_react5.createElement)("p", { role: "status" }, "\u6B63\u5728\u6821\u9A8C\u6587\u4EF6\uFF0C\u8BF7\u7A0D\u5019\u2026") : null,
6754
6070
  status(),
6755
- 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
6071
+ 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
6756
6072
  ) : null,
6757
- editing ? (0, import_react6.createElement)(
6073
+ editing ? (0, import_react5.createElement)(
6758
6074
  ResourceModal,
6759
- { 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: () => {
6075
+ { 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: () => {
6760
6076
  void copyTemplate(editing);
6761
- } }, "\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: () => {
6762
- void save2();
6077
+ } }, "\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: () => {
6078
+ void save();
6763
6079
  } }, busy ? "\u5904\u7406\u4E2D\u2026" : "\u4FDD\u5B58") : null) },
6764
- !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"),
6765
- 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,
6080
+ !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"),
6081
+ 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,
6766
6082
  status(),
6767
- 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) })))
6083
+ 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) })))
6768
6084
  ) : null,
6769
- 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: () => {
6085
+ 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: () => {
6770
6086
  void remove();
6771
- } }, 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
6087
+ } }, 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
6772
6088
  );
6773
6089
  }
6774
6090
 
6091
+ // src/workflows.ts
6092
+ var STANDARD = {
6093
+ stages: ["\u9700\u6C42\u8BC4\u5BA1", "\u8BBE\u8BA1", "\u5F00\u53D1", "\u4EA4\u4ED8", "\u4EE3\u7801\u5BA1\u6838", "\u5B8C\u6210"],
6094
+ start_stage: "\u9700\u6C42\u8BC4\u5BA1",
6095
+ transitions: [
6096
+ { from: "\u9700\u6C42\u8BC4\u5BA1", to: "\u8BBE\u8BA1", requires: ["requirement_confirmation", "artifacts_present"] },
6097
+ { from: "\u8BBE\u8BA1", to: "\u5F00\u53D1", requires: ["solution_confirmation", "artifacts_present"] },
6098
+ { from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] },
6099
+ { from: "\u4EA4\u4ED8", to: "\u4EE3\u7801\u5BA1\u6838", requires: ["verified"] },
6100
+ { from: "\u4EE3\u7801\u5BA1\u6838", to: "\u5B8C\u6210", requires: ["review_passed", "artifacts_present"] }
6101
+ ],
6102
+ // No artifacts, no commit policy, no skills: the skeleton carries none of them.
6103
+ artifacts: [],
6104
+ commit: { policy: "task", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EE3\u7801\u5BA1\u6838"], file_scope: true },
6105
+ high_risk_requires_verification: true
6106
+ };
6107
+ var STANDARD_RECOMMENDATION = {
6108
+ commit: {
6109
+ // Only the TEXT conventions. Policy, checkpoints and scope stay on the
6110
+ // skeleton: they decide when a gate fires, not how a message reads.
6111
+ message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
6112
+ 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"
6113
+ },
6114
+ artifacts: [
6115
+ { stage: "\u9700\u6C42\u8BC4\u5BA1", id: "requirement", name: "\u9700\u6C42\u8BF4\u660E", fields: ["scope", "acceptance_criteria"] },
6116
+ { stage: "\u8BBE\u8BA1", id: "design", name: "\u8BBE\u8BA1\u6587\u6863", fields: ["approach", "risks", "impact"] },
6117
+ { stage: "\u4EE3\u7801\u5BA1\u6838", id: "review", name: "\u8BC4\u5BA1\u8BB0\u5F55", fields: ["conclusion", "issues"] }
6118
+ ]
6119
+ };
6120
+ var AGILE = {
6121
+ stages: ["\u9700\u6C42", "\u5F00\u53D1", "\u4EA4\u4ED8", "\u5BA1\u67E5"],
6122
+ start_stage: "\u9700\u6C42",
6123
+ transitions: [
6124
+ { from: "\u9700\u6C42", to: "\u5F00\u53D1", requires: ["requirement_confirmation"] },
6125
+ { from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] },
6126
+ // Entering 审查 is unconditional. A review guard on this edge would be
6127
+ // circular — it would demand the verdict BEFORE the stage that produces it —
6128
+ // and it would also block the commit at 交付, since a commit requires its
6129
+ // stage's outgoing guards. What 审查 requires is declared as completion_guards
6130
+ // instead, because a terminal stage has no outgoing edge to carry it.
6131
+ { from: "\u4EA4\u4ED8", to: "\u5BA1\u67E5", requires: [] }
6132
+ ],
6133
+ artifacts: [],
6134
+ commit: { policy: "item", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EA4\u4ED8"], file_scope: true },
6135
+ high_risk_requires_verification: false,
6136
+ // 审查 is terminal and IS the review, so there is no outgoing edge to carry
6137
+ // the guard. Declaring it here is what makes a blocked review prevent
6138
+ // completion; without it the stage could be reached and finished with the
6139
+ // review failing, which is what the assessment found.
6140
+ completion_guards: ["review_passed"]
6141
+ };
6142
+ var AGILE_RECOMMENDATION = {
6143
+ commit: {
6144
+ // `item` policy emits two label shapes: `T<n>` mid-flow and `TASK` at the
6145
+ // closing checkpoint. The pattern accepts BOTH, so the label the engine hands
6146
+ // the model always satisfies the rule that validates it.
6147
+ message_pattern: "^\u3010(\\S+)\u3011\u3010(?:TASK|T\\d+)\u3011.+",
6148
+ 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"
6149
+ },
6150
+ artifacts: [
6151
+ { stage: "\u9700\u6C42", id: "requirement", name: "\u9700\u6C42\u8BF4\u660E", fields: ["scope"] },
6152
+ // Optional review record; the flow's review gate itself does not require a skill.
6153
+ { stage: "\u5BA1\u67E5", id: "review", name: "\u8BC4\u5BA1\u8BB0\u5F55", fields: ["conclusion", "issues"] }
6154
+ ]
6155
+ };
6156
+ var MINIMAL = {
6157
+ stages: ["\u5F00\u53D1", "\u4EA4\u4ED8"],
6158
+ start_stage: "\u5F00\u53D1",
6159
+ transitions: [
6160
+ { from: "\u5F00\u53D1", to: "\u4EA4\u4ED8", requires: ["todos_done"] }
6161
+ ],
6162
+ artifacts: [],
6163
+ commit: { policy: "task", message_pattern: "", message_hint: "\u65E0\u683C\u5F0F\u8981\u6C42", checkpoints: ["\u4EA4\u4ED8"], file_scope: false },
6164
+ high_risk_requires_verification: false
6165
+ };
6166
+ var MINIMAL_RECOMMENDATION = {
6167
+ // A fast-change flow checks each change once, not twice under two headings a
6168
+ // short change rarely distinguishes. The item still has to be reviewed — what
6169
+ // drops is the duplicated verdict, which is where the weight actually was.
6170
+ review_depth: "single"
6171
+ };
6172
+ function deriveCapabilities(config) {
6173
+ const caps = [];
6174
+ const guards = new Set(config.transitions.flatMap((t) => t.requires ?? []));
6175
+ if (guards.has("verified")) caps.push("verification_gate");
6176
+ if (guards.has("review_passed")) caps.push("review_gate");
6177
+ if (guards.has("artifacts_present")) caps.push("artifact_gate");
6178
+ if (config.commit.file_scope) caps.push("file_scope");
6179
+ return caps;
6180
+ }
6181
+ function preset(id, version, label3, description, config, recommendation) {
6182
+ return {
6183
+ id,
6184
+ version,
6185
+ label: label3,
6186
+ description,
6187
+ capabilities: deriveCapabilities(config),
6188
+ config,
6189
+ // exactOptionalPropertyTypes: omit rather than assign undefined.
6190
+ ...recommendation !== void 0 ? { recommendation } : {}
6191
+ };
6192
+ }
6193
+ var FLOW_PRESETS = {
6194
+ 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),
6195
+ // Version 4 for agile: 交付 → 审查 now requires review_passed, where it previously
6196
+ // required nothing. That is a gate-semantics change, so a task created before it
6197
+ // keeps its frozen version 3 config and behaves exactly as it did.
6198
+ //
6199
+ // Version 3 across all three: the preset is now a bare skeleton and its former
6200
+ // built-in bindings, commit rule and artifacts are a separate recommendation a
6201
+ // user adopts explicitly. Tasks created before this keep their frozen config and
6202
+ // are unaffected; a project's existing config is likewise left exactly as it is.
6203
+ 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),
6204
+ 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)
6205
+ };
6206
+ function dedupe(names) {
6207
+ return [...new Set(names)];
6208
+ }
6209
+ function applyProjectConfig(base, project) {
6210
+ if (project === void 0) return base;
6211
+ const next = { ...base };
6212
+ if (project.stage_bindings !== void 0) {
6213
+ const profiles = { ...project.skill_profiles ?? {} };
6214
+ const explicitProfiles = new Set(Object.keys(project.skill_profiles ?? {}));
6215
+ const problems = [];
6216
+ const bindings = {};
6217
+ for (const [stage, binding] of Object.entries(project.stage_bindings)) {
6218
+ const entry = {};
6219
+ if (binding === null || typeof binding !== "object") {
6220
+ problems.push(`stage_bindings "${stage}" must be an object`);
6221
+ bindings[stage] = entry;
6222
+ continue;
6223
+ }
6224
+ if (binding.skill_refs !== void 0 && binding.skills !== void 0) {
6225
+ problems.push(`stage_bindings "${stage}" has both skill_refs and legacy skills`);
6226
+ }
6227
+ if (binding.skill_refs !== void 0) {
6228
+ if (!Array.isArray(binding.skill_refs)) {
6229
+ problems.push(`stage_bindings "${stage}" skill_refs must be an array`);
6230
+ }
6231
+ entry.skills = (Array.isArray(binding.skill_refs) ? binding.skill_refs : []).flatMap((ref) => {
6232
+ if (ref === null || typeof ref !== "object") {
6233
+ problems.push(`stage_bindings "${stage}" has an invalid skill reference`);
6234
+ return [];
6235
+ }
6236
+ const key = formatResourceRef(ref);
6237
+ const profile = profiles[key];
6238
+ if (profile === void 0) {
6239
+ problems.push(`skill profile "${key}" is missing`);
6240
+ return [];
6241
+ }
6242
+ if (profile === null || !Array.isArray(profile.rules)) {
6243
+ problems.push(`skill profile "${key}" must declare a rules array`);
6244
+ return [];
6245
+ }
6246
+ return [{ skill: ref, rules: profile.rules, ...profile.evidence !== void 0 ? { evidence: profile.evidence } : {} }];
6247
+ });
6248
+ } else if (binding.skills !== void 0) {
6249
+ if (!Array.isArray(binding.skills)) {
6250
+ problems.push(`stage_bindings "${stage}" skills must be an array`);
6251
+ }
6252
+ entry.skills = (Array.isArray(binding.skills) ? binding.skills : []).flatMap((skill) => {
6253
+ if (skill === null || typeof skill !== "object" || skill.skill === null || typeof skill.skill !== "object") {
6254
+ problems.push(`stage_bindings "${stage}" has an invalid skill binding`);
6255
+ return [];
6256
+ }
6257
+ const key = formatResourceRef(skill.skill);
6258
+ if (explicitProfiles.has(key)) {
6259
+ const profile = profiles[key];
6260
+ if (profile === null || !Array.isArray(profile?.rules)) {
6261
+ problems.push(`skill profile "${key}" must declare a rules array`);
6262
+ return [];
6263
+ }
6264
+ return [{
6265
+ skill: skill.skill,
6266
+ rules: profile.rules,
6267
+ ...profile.evidence !== void 0 ? { evidence: profile.evidence } : {}
6268
+ }];
6269
+ }
6270
+ const candidate = { rules: skill.rules ?? [], ...skill.evidence !== void 0 ? { evidence: skill.evidence } : {} };
6271
+ const existing = profiles[key];
6272
+ if (existing !== void 0 && JSON.stringify(existing) !== JSON.stringify(candidate)) {
6273
+ problems.push(`skill "${key}" has different rules or evidence in multiple stages; copy it as a distinct skill`);
6274
+ } else profiles[key] = candidate;
6275
+ return [skill];
6276
+ });
6277
+ }
6278
+ const legacy = dedupe(binding.legacy_rules ?? []);
6279
+ if (legacy.length > 0) entry.legacy_rules = legacy;
6280
+ bindings[stage] = entry;
6281
+ }
6282
+ next.stage_bindings = bindings;
6283
+ next.skill_profiles = profiles;
6284
+ if (problems.length > 0) next.configuration_errors = problems;
6285
+ } else if (project.skill_profiles !== void 0) {
6286
+ next.skill_profiles = project.skill_profiles;
6287
+ }
6288
+ if (project.commit !== void 0) next.commit = project.commit;
6289
+ if (project.artifacts !== void 0) next.artifacts = project.artifacts;
6290
+ if (project.review_depth !== void 0) next.review_depth = project.review_depth;
6291
+ if (project.commit_required !== void 0) next.commit_required = project.commit_required;
6292
+ return next;
6293
+ }
6294
+ function compactProjectConfig(project) {
6295
+ const resolved = resolveFlow(project.flow, project);
6296
+ if (!resolved.ok) return project;
6297
+ const profiles = resolved.config.skill_profiles ?? {};
6298
+ const bindings = {};
6299
+ for (const [stage, binding] of Object.entries(resolved.config.stage_bindings ?? {})) {
6300
+ bindings[stage] = {
6301
+ skill_refs: (binding.skills ?? []).map((entry) => entry.skill),
6302
+ ...binding.legacy_rules?.length ? { legacy_rules: binding.legacy_rules } : {}
6303
+ };
6304
+ }
6305
+ return { ...project, stage_bindings: bindings, skill_profiles: profiles };
6306
+ }
6307
+ function resolveFlow(flow, project) {
6308
+ const preset2 = FLOW_PRESETS[flow];
6309
+ if (preset2 === void 0) {
6310
+ return { ok: false, code: "UNKNOWN_FLOW", flow, knownFlows: Object.keys(FLOW_PRESETS) };
6311
+ }
6312
+ const { flow: _ignored, ...rest } = project ?? { flow };
6313
+ return { ok: true, config: applyProjectConfig(preset2.config, { flow, ...rest }), preset: preset2 };
6314
+ }
6315
+
6775
6316
  // src/client/SkillManager.tsx
6776
- var import_jsx_runtime3 = require("react/jsx-runtime");
6317
+ var import_jsx_runtime2 = require("react/jsx-runtime");
6777
6318
  function SkillManager({ workspace, remote }) {
6778
- const [config, setConfig] = (0, import_react7.useState)(null);
6779
- const [rules, setRules] = (0, import_react7.useState)([]);
6780
- const [selected, setSelected] = (0, import_react7.useState)(null);
6781
- const [message, setMessage] = (0, import_react7.useState)("");
6782
- (0, import_react7.useEffect)(() => {
6319
+ const [config, setConfig] = (0, import_react6.useState)(null);
6320
+ const [rules, setRules] = (0, import_react6.useState)([]);
6321
+ const [selected, setSelected] = (0, import_react6.useState)(null);
6322
+ const [message, setMessage] = (0, import_react6.useState)("");
6323
+ (0, import_react6.useEffect)(() => {
6783
6324
  let active = true;
6784
6325
  void Promise.all([remote.read(workspace), remote.listRules(workspace)]).then(([saved, availableRules]) => {
6785
6326
  if (!active) return;
@@ -6820,15 +6361,15 @@ function SkillManager({ workspace, remote }) {
6820
6361
  setMessage(`\u5DF2\u4FDD\u5B58 ${selected.name} \u7684\u89C4\u5219\u914D\u7F6E\u3002`);
6821
6362
  setSelected(null);
6822
6363
  };
6823
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `te-config-layout${selected ? " is-open" : ""}`, children: [
6824
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "te-config-main", children: [
6825
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ResourceManager, { workspace, remote, kind: "skill", onConfigureSkill: config ? (ref) => {
6364
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `te-config-layout${selected ? " is-open" : ""}`, children: [
6365
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-config-main", children: [
6366
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ResourceManager, { workspace, remote, kind: "skill", onConfigureSkill: config ? (ref) => {
6826
6367
  setMessage("");
6827
6368
  setSelected(ref);
6828
6369
  } : void 0 }),
6829
- selected === null && message ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { role: "status", className: "te-success", children: message }) : null
6370
+ selected === null && message ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", className: "te-success", children: message }) : null
6830
6371
  ] }),
6831
- selected !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6372
+ selected !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
6832
6373
  SkillRuleDialog,
6833
6374
  {
6834
6375
  skill: selected,
@@ -6844,14 +6385,14 @@ function SkillManager({ workspace, remote }) {
6844
6385
  }
6845
6386
 
6846
6387
  // src/client/RuleManager.tsx
6847
- var import_react8 = require("react");
6388
+ var import_react7 = require("react");
6848
6389
  function RuleManager(props) {
6849
- return (0, import_react8.createElement)(ResourceManager, { ...props, key: props.workspace, kind: "rule" });
6390
+ return (0, import_react7.createElement)(ResourceManager, { ...props, key: props.workspace, kind: "rule" });
6850
6391
  }
6851
6392
 
6852
6393
  // src/client/TaskLedger.tsx
6853
- var import_react9 = require("react");
6854
- var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
6394
+ var import_react8 = require("react");
6395
+ var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
6855
6396
  var card3 = {
6856
6397
  display: "flex",
6857
6398
  flexDirection: "column",
@@ -6889,10 +6430,10 @@ var badge = {
6889
6430
  color: "var(--dsw-alias-label-secondary)"
6890
6431
  };
6891
6432
  function verdictDot(outcome) {
6892
- return (0, import_react9.createElement)(import_dsh_client_ui_primitives6.StateDot, { state: outcome === "pass" ? "done" : "error" });
6433
+ return (0, import_react8.createElement)(import_dsh_client_ui_primitives5.StateDot, { state: outcome === "pass" ? "done" : "error" });
6893
6434
  }
6894
6435
  function itemStatusDot(status) {
6895
- return (0, import_react9.createElement)(import_dsh_client_ui_primitives6.StateDot, { state: status === "done" ? "done" : "ongoing" });
6436
+ return (0, import_react8.createElement)(import_dsh_client_ui_primitives5.StateDot, { state: status === "done" ? "done" : "ongoing" });
6896
6437
  }
6897
6438
  function timeText(at) {
6898
6439
  return at.slice(0, 19).replace("T", " ");
@@ -6900,48 +6441,48 @@ function timeText(at) {
6900
6441
  function itemAudit(item) {
6901
6442
  const lines = [];
6902
6443
  if (item.dispatch !== void 0) {
6903
- lines.push((0, import_react9.createElement)(
6444
+ lines.push((0, import_react8.createElement)(
6904
6445
  "div",
6905
6446
  { key: "dispatch", style: metaLine },
6906
- (0, import_react9.createElement)("span", { style: badge }, "\u5DF2\u6D3E\u53D1"),
6907
- (0, import_react9.createElement)("span", null, item.dispatch.description === "" ? "\uFF08\u65E0\u63CF\u8FF0\uFF09" : item.dispatch.description),
6908
- (0, import_react9.createElement)("span", { style: badge }, timeText(item.dispatch.at))
6447
+ (0, import_react8.createElement)("span", { style: badge }, "\u5DF2\u6D3E\u53D1"),
6448
+ (0, import_react8.createElement)("span", null, item.dispatch.description === "" ? "\uFF08\u65E0\u63CF\u8FF0\uFF09" : item.dispatch.description),
6449
+ (0, import_react8.createElement)("span", { style: badge }, timeText(item.dispatch.at))
6909
6450
  ));
6910
6451
  }
6911
6452
  if (item.review !== void 0) {
6912
6453
  const spec = item.review.spec;
6913
6454
  const quality = item.review.quality;
6914
- lines.push((0, import_react9.createElement)(
6455
+ lines.push((0, import_react8.createElement)(
6915
6456
  "div",
6916
6457
  { key: "review", style: metaLine },
6917
6458
  verdictDot(spec.outcome),
6918
- (0, import_react9.createElement)("span", null, `\u89C4\u683C\u7B26\u5408 ${spec.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`),
6919
- (0, import_react9.createElement)("span", null, "\xB7"),
6459
+ (0, import_react8.createElement)("span", null, `\u89C4\u683C\u7B26\u5408 ${spec.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`),
6460
+ (0, import_react8.createElement)("span", null, "\xB7"),
6920
6461
  verdictDot(quality.outcome),
6921
- (0, import_react9.createElement)("span", null, `\u4EE3\u7801\u8D28\u91CF ${quality.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`)
6462
+ (0, import_react8.createElement)("span", null, `\u4EE3\u7801\u8D28\u91CF ${quality.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`)
6922
6463
  ));
6923
6464
  const failNotes = [spec, quality].flatMap((stage) => stage.outcome === "fail" ? stage.notes ?? [] : []);
6924
6465
  if (failNotes.length > 0) {
6925
- lines.push((0, import_react9.createElement)(
6466
+ lines.push((0, import_react8.createElement)(
6926
6467
  "div",
6927
6468
  { key: "notes", style: metaLine },
6928
- ...failNotes.map((note) => (0, import_react9.createElement)("span", { key: note, style: badge }, note))
6469
+ ...failNotes.map((note) => (0, import_react8.createElement)("span", { key: note, style: badge }, note))
6929
6470
  ));
6930
6471
  }
6931
6472
  }
6932
6473
  if (lines.length === 0) {
6933
- lines.push((0, import_react9.createElement)("div", { key: "none", style: metaLine }, (0, import_react9.createElement)("span", { style: badge }, "\u672A\u6D3E\u53D1 / \u672A\u5BA1\u67E5")));
6474
+ lines.push((0, import_react8.createElement)("div", { key: "none", style: metaLine }, (0, import_react8.createElement)("span", { style: badge }, "\u672A\u6D3E\u53D1 / \u672A\u5BA1\u67E5")));
6934
6475
  }
6935
- return (0, import_react9.createElement)("div", { style: { display: "flex", flexDirection: "column", gap: 4 } }, ...lines);
6476
+ return (0, import_react8.createElement)("div", { style: { display: "flex", flexDirection: "column", gap: 4 } }, ...lines);
6936
6477
  }
6937
6478
  function TaskLedger({ workspace, remote }) {
6938
- const [tasks, setTasks] = (0, import_react9.useState)([]);
6939
- const [error, setError] = (0, import_react9.useState)("");
6940
- const [loading, setLoading] = (0, import_react9.useState)(true);
6941
- const [query, setQuery] = (0, import_react9.useState)("");
6942
- const [risk, setRisk] = (0, import_react9.useState)("all");
6943
- const [stage, setStage] = (0, import_react9.useState)("all");
6944
- const refresh = (0, import_react9.useCallback)(() => {
6479
+ const [tasks, setTasks] = (0, import_react8.useState)([]);
6480
+ const [error, setError] = (0, import_react8.useState)("");
6481
+ const [loading, setLoading] = (0, import_react8.useState)(true);
6482
+ const [query, setQuery] = (0, import_react8.useState)("");
6483
+ const [risk, setRisk] = (0, import_react8.useState)("all");
6484
+ const [stage, setStage] = (0, import_react8.useState)("all");
6485
+ const refresh = (0, import_react8.useCallback)(() => {
6945
6486
  if (workspace === "") return;
6946
6487
  setError("");
6947
6488
  setLoading(true);
@@ -6954,58 +6495,58 @@ function TaskLedger({ workspace, remote }) {
6954
6495
  setError("\u8BFB\u53D6\u53F0\u8D26\u5931\u8D25\uFF1A" + describeError(reason));
6955
6496
  });
6956
6497
  }, [remote, workspace]);
6957
- (0, import_react9.useEffect)(() => {
6498
+ (0, import_react8.useEffect)(() => {
6958
6499
  refresh();
6959
6500
  }, [refresh]);
6960
6501
  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));
6961
- return (0, import_react9.createElement)(
6502
+ return (0, import_react8.createElement)(
6962
6503
  "div",
6963
6504
  { style: styles.section },
6964
- (0, import_react9.createElement)(
6505
+ (0, import_react8.createElement)(
6965
6506
  "div",
6966
6507
  { className: "te-toolbar" },
6967
- (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) }),
6968
- (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")),
6969
- (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)))
6508
+ (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) }),
6509
+ (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")),
6510
+ (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)))
6970
6511
  ),
6971
- (0, import_react9.createElement)(
6512
+ (0, import_react8.createElement)(
6972
6513
  "div",
6973
6514
  { style: headerRow },
6974
- (0, import_react9.createElement)("span", { style: styles.bindingLabel }, "\u4EFB\u52A1\u53F0\u8D26"),
6975
- (0, import_react9.createElement)("span", { style: styles.sourceBadge }, "\u53EA\u8BFB \xB7 \u6765\u81EA .dsh/task-*.json"),
6976
- (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")
6515
+ (0, import_react8.createElement)("span", { style: styles.bindingLabel }, "\u4EFB\u52A1\u53F0\u8D26"),
6516
+ (0, import_react8.createElement)("span", { style: styles.sourceBadge }, "\u53EA\u8BFB \xB7 \u6765\u81EA .dsh/task-*.json"),
6517
+ (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")
6977
6518
  ),
6978
- 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)(
6519
+ 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)(
6979
6520
  "div",
6980
6521
  { style: { display: "flex", flexDirection: "column", gap: 12 } },
6981
- ...visible.map((task) => (0, import_react9.createElement)(
6522
+ ...visible.map((task) => (0, import_react8.createElement)(
6982
6523
  "div",
6983
6524
  { key: task.task_id, style: card3 },
6984
- (0, import_react9.createElement)(
6525
+ (0, import_react8.createElement)(
6985
6526
  "div",
6986
6527
  { style: headerRow },
6987
- (0, import_react9.createElement)("span", { style: { fontSize: 14, fontWeight: 600, color: "var(--dsw-alias-label-primary)" } }, task.task_id),
6988
- (0, import_react9.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, task.title),
6989
- (0, import_react9.createElement)("span", { style: badge }, task.stage),
6990
- 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,
6991
- (0, import_react9.createElement)("span", { style: badge }, task.branch),
6992
- (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"),
6993
- (0, import_react9.createElement)("span", { className: "te-badge" }, task.verification_passed ? "\u9A8C\u8BC1\u901A\u8FC7" : "\u5F85\u9A8C\u8BC1"),
6994
- (0, import_react9.createElement)("span", { className: "te-badge" }, `\u5BA1\u6838\uFF1A${task.review_outcome ?? "pending"}`),
6995
- task.updated_at ? (0, import_react9.createElement)("span", { style: metaLine }, "\u66F4\u65B0\u4E8E " + timeText(task.updated_at)) : null
6528
+ (0, import_react8.createElement)("span", { style: { fontSize: 14, fontWeight: 600, color: "var(--dsw-alias-label-primary)" } }, task.task_id),
6529
+ (0, import_react8.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, task.title),
6530
+ (0, import_react8.createElement)("span", { style: badge }, task.stage),
6531
+ 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,
6532
+ (0, import_react8.createElement)("span", { style: badge }, task.branch),
6533
+ (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"),
6534
+ (0, import_react8.createElement)("span", { className: "te-badge" }, task.verification_passed ? "\u9A8C\u8BC1\u901A\u8FC7" : "\u5F85\u9A8C\u8BC1"),
6535
+ (0, import_react8.createElement)("span", { className: "te-badge" }, `\u5BA1\u6838\uFF1A${task.review_outcome ?? "pending"}`),
6536
+ task.updated_at ? (0, import_react8.createElement)("span", { style: metaLine }, "\u66F4\u65B0\u4E8E " + timeText(task.updated_at)) : null
6996
6537
  ),
6997
- (0, import_react9.createElement)(
6538
+ (0, import_react8.createElement)(
6998
6539
  "div",
6999
6540
  { style: { display: "flex", flexDirection: "column" } },
7000
- ...task.items.map((item) => (0, import_react9.createElement)(
6541
+ ...task.items.map((item) => (0, import_react8.createElement)(
7001
6542
  "div",
7002
6543
  { key: item.id, style: itemRow },
7003
- (0, import_react9.createElement)(
6544
+ (0, import_react8.createElement)(
7004
6545
  "div",
7005
6546
  { style: headerRow },
7006
6547
  itemStatusDot(item.status),
7007
- (0, import_react9.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, item.id),
7008
- (0, import_react9.createElement)("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, item.title)
6548
+ (0, import_react8.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, item.id),
6549
+ (0, import_react8.createElement)("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, item.title)
7009
6550
  ),
7010
6551
  itemAudit(item)
7011
6552
  ))
@@ -7072,7 +6613,6 @@ var closeStyle = {
7072
6613
  var TABS = [
7073
6614
  { id: "init", label: "\u9879\u76EE\u521D\u59CB\u5316" },
7074
6615
  { id: "adaptive", label: "\u81EA\u9002\u5E94\u6D41\u7A0B" },
7075
- { id: "flow", label: "\u65E7\u7248\u6D41\u7A0B" },
7076
6616
  { id: "tasks", label: "\u4EFB\u52A1\u53F0\u8D26" },
7077
6617
  { id: "skills", label: "\u6280\u80FD" },
7078
6618
  { id: "rules", label: "\u89C4\u5219" }
@@ -7080,29 +6620,29 @@ var TABS = [
7080
6620
  function Workbench({ useStore, actions, useWorkspaces, remote }) {
7081
6621
  const open = useStore((s) => s.open);
7082
6622
  const workspaces = useWorkspaces((s) => s.items);
7083
- const [tab, setTab] = (0, import_react10.useState)("adaptive");
7084
- const [workspace, setWorkspace] = (0, import_react10.useState)("");
6623
+ const [tab, setTab] = (0, import_react9.useState)("adaptive");
6624
+ const [workspace, setWorkspace] = (0, import_react9.useState)("");
7085
6625
  if (!open) return null;
7086
6626
  const current = workspaces.some((w) => w.path === workspace) ? workspace : workspaces[0]?.path ?? "";
7087
- return (0, import_react10.createElement)(
6627
+ return (0, import_react9.createElement)(
7088
6628
  "div",
7089
6629
  { style: overlay, className: "te-workbench" },
7090
- (0, import_react10.createElement)("style", null, workbenchTheme),
7091
- (0, import_react10.createElement)(
6630
+ (0, import_react9.createElement)("style", null, workbenchTheme),
6631
+ (0, import_react9.createElement)(
7092
6632
  "div",
7093
6633
  { style: header },
7094
- (0, import_react10.createElement)(
6634
+ (0, import_react9.createElement)(
7095
6635
  "div",
7096
6636
  { style: headerBrand },
7097
- (0, import_react10.createElement)(IconSettings, { size: 18 }),
7098
- (0, import_react10.createElement)(
6637
+ (0, import_react9.createElement)(IconSettings, { size: 18 }),
6638
+ (0, import_react9.createElement)(
7099
6639
  "div",
7100
6640
  { style: headerText },
7101
- (0, import_react10.createElement)("span", { style: headerTitle }, "\u5DE5\u7A0B\u4EFB\u52A1"),
7102
- (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")
6641
+ (0, import_react9.createElement)("span", { style: headerTitle }, "\u5DE5\u7A0B\u4EFB\u52A1"),
6642
+ (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")
7103
6643
  )
7104
6644
  ),
7105
- (0, import_react10.createElement)(
6645
+ (0, import_react9.createElement)(
7106
6646
  "button",
7107
6647
  {
7108
6648
  type: "button",
@@ -7118,43 +6658,43 @@ function Workbench({ useStore, actions, useWorkspaces, remote }) {
7118
6658
  event.currentTarget.style.background = "transparent";
7119
6659
  }
7120
6660
  },
7121
- (0, import_react10.createElement)(IconClose, { size: 16 })
6661
+ (0, import_react9.createElement)(IconClose, { size: 16 })
7122
6662
  )
7123
6663
  ),
7124
- (0, import_react10.createElement)(
6664
+ (0, import_react9.createElement)(
7125
6665
  "div",
7126
6666
  { style: tabbar },
7127
- ...TABS.map((t) => (0, import_react10.createElement)(import_dsh_client_ui_primitives7.Pill, { key: t.id, active: tab === t.id, onClick: () => {
6667
+ ...TABS.map((t) => (0, import_react9.createElement)(import_dsh_client_ui_primitives6.Pill, { key: t.id, active: tab === t.id, onClick: () => {
7128
6668
  setTab(t.id);
7129
6669
  } }, t.label)),
7130
- workspaces.length > 0 ? (0, import_react10.createElement)("select", {
6670
+ workspaces.length > 0 ? (0, import_react9.createElement)("select", {
7131
6671
  style: selectStyle,
7132
6672
  "aria-label": "\u5F53\u524D\u5DE5\u4F5C\u533A",
7133
6673
  value: current,
7134
6674
  onChange: (ev) => {
7135
6675
  setWorkspace(ev.target.value);
7136
6676
  }
7137
- }, ...workspaces.map((w) => (0, import_react10.createElement)("option", { key: w.path, value: w.path }, w.title || w.path))) : null
6677
+ }, ...workspaces.map((w) => (0, import_react9.createElement)("option", { key: w.path, value: w.path }, w.title || w.path))) : null
7138
6678
  ),
7139
- (0, import_react10.createElement)(
6679
+ (0, import_react9.createElement)(
7140
6680
  "div",
7141
6681
  { style: body },
7142
- (0, import_react10.createElement)(
6682
+ (0, import_react9.createElement)(
7143
6683
  "div",
7144
6684
  { className: "te-content", key: current },
7145
- (0, import_react10.createElement)("p", { style: { ...styles.hint, marginBottom: 10 }, title: current }, "\u5DE5\u4F5C\u533A \xB7 " + current),
7146
- 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 })
6685
+ (0, import_react9.createElement)("p", { style: { ...styles.hint, marginBottom: 10 }, title: current }, "\u5DE5\u4F5C\u533A \xB7 " + current),
6686
+ 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 }) : 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 })
7147
6687
  )
7148
6688
  )
7149
6689
  );
7150
6690
  }
7151
6691
 
7152
6692
  // src/client/TriggerButton.tsx
7153
- var import_react11 = require("react");
6693
+ var import_react10 = require("react");
7154
6694
  var hover = "var(--dsw-alias-bg-layer-2)";
7155
6695
  var label2 = "var(--dsw-alias-label-primary)";
7156
6696
  function TriggerButton({ wide, actions }) {
7157
- return (0, import_react11.createElement)(
6697
+ return (0, import_react10.createElement)(
7158
6698
  "button",
7159
6699
  {
7160
6700
  type: "button",
@@ -7194,8 +6734,8 @@ function TriggerButton({ wide, actions }) {
7194
6734
  transition: "background 120ms ease"
7195
6735
  }
7196
6736
  },
7197
- (0, import_react11.createElement)(IconSettings, { size: wide ? 16 : 18 }),
7198
- wide ? (0, import_react11.createElement)("span", { style: { fontSize: 14, lineHeight: "22px" } }, "\u5DE5\u7A0B\u6D41\u7A0B") : null
6737
+ (0, import_react10.createElement)(IconSettings, { size: wide ? 16 : 18 }),
6738
+ wide ? (0, import_react10.createElement)("span", { style: { fontSize: 14, lineHeight: "22px" } }, "\u5DE5\u7A0B\u6D41\u7A0B") : null
7199
6739
  );
7200
6740
  }
7201
6741