@godv61/dsh-task-engine 0.26.1 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -4082,15 +4082,24 @@ var artifactSchema = external_exports.object({
4082
4082
  fields: external_exports.array(external_exports.string())
4083
4083
  });
4084
4084
  var commitSchema = external_exports.object({
4085
- policy: external_exports.string(),
4085
+ policy: external_exports.enum(["task", "item", "manual"]),
4086
4086
  message_pattern: external_exports.string(),
4087
4087
  message_hint: external_exports.string(),
4088
4088
  checkpoints: external_exports.array(external_exports.string()),
4089
4089
  file_scope: external_exports.boolean()
4090
4090
  });
4091
+ var resourceRefSchema = external_exports.object({ source: external_exports.enum(["bundled", "project", "user"]), name: external_exports.string() });
4092
+ var evidenceSchema = external_exports.enum(["command", "artifact", "review", "manual", "none"]);
4093
+ var skillProfileSchema = external_exports.object({ rules: external_exports.array(resourceRefSchema), evidence: evidenceSchema.optional() });
4094
+ var skillBindingSchema = external_exports.object({
4095
+ skill: resourceRefSchema,
4096
+ rules: external_exports.array(resourceRefSchema),
4097
+ evidence: evidenceSchema.optional()
4098
+ });
4091
4099
  var stageBindingSchema = external_exports.object({
4092
- skills: external_exports.array(external_exports.string()).optional(),
4093
- rules: external_exports.array(external_exports.string()).optional()
4100
+ skills: external_exports.array(skillBindingSchema).optional(),
4101
+ skill_refs: external_exports.array(resourceRefSchema).optional(),
4102
+ legacy_rules: external_exports.array(external_exports.string()).optional()
4094
4103
  });
4095
4104
  var configSchema = external_exports.object({
4096
4105
  stages: external_exports.array(external_exports.string()),
@@ -4099,31 +4108,47 @@ var configSchema = external_exports.object({
4099
4108
  artifacts: external_exports.array(artifactSchema),
4100
4109
  commit: commitSchema,
4101
4110
  high_risk_requires_verification: external_exports.boolean(),
4102
- stage_bindings: external_exports.record(external_exports.string(), stageBindingSchema).optional()
4111
+ stage_bindings: external_exports.record(external_exports.string(), stageBindingSchema).optional(),
4112
+ skill_profiles: external_exports.record(external_exports.string(), skillProfileSchema).optional(),
4113
+ configuration_errors: external_exports.array(external_exports.string()).optional(),
4114
+ review_depth: external_exports.enum(["two-stage", "single"]).optional(),
4115
+ commit_required: external_exports.boolean().optional(),
4116
+ completion_guards: external_exports.array(external_exports.string()).optional()
4103
4117
  });
4104
4118
  var viewSchema = external_exports.object({
4105
4119
  ok: external_exports.boolean(),
4106
4120
  source: external_exports.enum(["default", "project", "invalid"]),
4107
4121
  flow: external_exports.string(),
4108
4122
  config: configSchema,
4109
- problems: external_exports.array(external_exports.string())
4123
+ problems: external_exports.array(external_exports.string()),
4124
+ adoption: external_exports.object({ created: external_exports.array(external_exports.string()), reused: external_exports.array(external_exports.string()) }).optional()
4110
4125
  });
4111
4126
  var writeRequestSchema = external_exports.object({
4112
4127
  path: external_exports.string(),
4113
4128
  flow: external_exports.string(),
4114
- stage_bindings: external_exports.record(external_exports.string(), stageBindingSchema).optional()
4129
+ stage_bindings: external_exports.record(external_exports.string(), stageBindingSchema).optional(),
4130
+ skill_profiles: external_exports.record(external_exports.string(), skillProfileSchema).optional(),
4131
+ commit: commitSchema.optional(),
4132
+ artifacts: external_exports.array(artifactSchema).optional(),
4133
+ review_depth: external_exports.enum(["two-stage", "single"]).optional(),
4134
+ commit_required: external_exports.boolean().optional(),
4135
+ materialize_bundled: external_exports.enum(["project", "user"]).optional()
4115
4136
  });
4116
4137
  var skillCatalogSchema = external_exports.object({
4117
4138
  skills: external_exports.array(external_exports.object({
4118
4139
  name: external_exports.string(),
4119
4140
  description: external_exports.string(),
4120
- source: external_exports.string()
4141
+ source: external_exports.string(),
4142
+ ref: resourceRefSchema,
4143
+ sourceLabel: external_exports.string()
4121
4144
  }))
4122
4145
  });
4123
4146
  var ruleCatalogSchema = external_exports.object({
4124
4147
  rules: external_exports.array(external_exports.object({
4125
4148
  name: external_exports.string(),
4126
- source: external_exports.string()
4149
+ source: external_exports.string(),
4150
+ ref: resourceRefSchema,
4151
+ sourceLabel: external_exports.string()
4127
4152
  }))
4128
4153
  });
4129
4154
  var writeSkillRequestSchema = external_exports.object({
@@ -4154,6 +4179,8 @@ var writeRuleRequestSchema = external_exports.object({
4154
4179
  level: external_exports.enum(["project", "user"]),
4155
4180
  path: external_exports.string().optional()
4156
4181
  });
4182
+ var writeUserSkillProfileRequestSchema = external_exports.object({ name: external_exports.string(), profile: skillProfileSchema });
4183
+ var writeUserSkillProfileResultSchema = external_exports.object({ ok: external_exports.boolean(), error: external_exports.string().optional() });
4157
4184
  var writeResourceResultSchema = external_exports.object({
4158
4185
  ok: external_exports.boolean(),
4159
4186
  name: external_exports.string(),
@@ -4403,6 +4430,20 @@ var TYPERT_REMOTE = {
4403
4430
  ],
4404
4431
  result: { mode: "strict", typeSymbol: `${PACKAGE}/types#WriteResourceResult`, create: () => writeResourceResultSchema, schema: writeResourceResultSchema }
4405
4432
  },
4433
+ {
4434
+ id: `${PACKAGE}#task-engine/writeUserSkillProfile`,
4435
+ service: "taskEngineController",
4436
+ namespace: "task-engine",
4437
+ method: "writeUserSkillProfile",
4438
+ invocation: { kind: "direct" },
4439
+ parameters: [{
4440
+ name: "request",
4441
+ wire: "request",
4442
+ source: "json",
4443
+ codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#WriteUserSkillProfileRequest`, create: () => writeUserSkillProfileRequestSchema, schema: writeUserSkillProfileRequestSchema }
4444
+ }],
4445
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#WriteUserSkillProfileResult`, create: () => writeUserSkillProfileResultSchema, schema: writeUserSkillProfileResultSchema }
4446
+ },
4406
4447
  {
4407
4448
  id: `${PACKAGE}#task-engine/readSkill`,
4408
4449
  service: "taskEngineController",
@@ -4547,6 +4588,11 @@ var workbenchTheme = `
4547
4588
  .te-workbench button:focus-visible,.te-modal button:focus-visible,.te-input:focus-visible { outline:2px solid var(--dsw-alias-state-business-primary); outline-offset:3px; }
4548
4589
  .te-workbench h2 { margin:0 0 6px; font-size:24px; letter-spacing:-.5px; }
4549
4590
  .te-workbench h3,.te-modal h3 { margin:0; font-size:16px; overflow-wrap:anywhere; }
4591
+ .te-config-layout { display:grid; grid-template-columns:minmax(0,1fr); gap:16px; align-items:start; width:100%; }
4592
+ .te-config-layout.is-open { grid-template-columns:minmax(0,1fr) minmax(320px,420px); }
4593
+ .te-config-main { min-width:0; }
4594
+ .te-inline-panel { position:sticky !important; top:12px; min-width:0; }
4595
+ .te-flow-notice { margin:0; padding:10px 12px; border:1px solid var(--dsw-alias-state-warn-primary); border-radius:8px; font-size:13px; }
4550
4596
  .te-workbench .te-disclosure-title { font-size:16px; font-weight:700; color:var(--dsw-alias-label-primary); }
4551
4597
  .te-binding-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr)); gap:14px; align-items:start; }
4552
4598
  .te-binding-picker { min-width:0; display:flex; flex-direction:column; gap:10px; border:1px solid var(--dsw-alias-border-l2); border-radius:12px; padding:14px; background:var(--dsw-alias-bg-layer-1); }
@@ -4644,6 +4690,7 @@ var workbenchTheme = `
4644
4690
  .te-form label { display:flex; flex-direction:column; gap:8px; font-size:13px; }
4645
4691
  .te-editor { min-height:260px; resize:vertical; line-height:1.6; font-family:monospace; }
4646
4692
  @media(max-width:760px) { .te-transfer {grid-template-columns:1fr;} .te-transfer-arrow {transform:rotate(90deg); height:20px;} .te-transfer-list {max-height:210px;} }
4693
+ @media(max-width:1000px) { .te-config-layout.is-open { grid-template-columns:minmax(0,1fr); } .te-inline-panel { position:static !important; height:min(600px,calc(100vh - 32px)) !important; } }
4647
4694
  @media(max-width:640px) { .te-targets {grid-template-columns:1fr;} .te-resource {gap:14px;} .te-section-heading h2 {font-size:21px;} .te-modal:not(.te-drawer) {padding:10px !important;} .te-drawer [role=dialog] {border-radius:0 !important;} .te-skill-evidence {align-items:stretch; flex-direction:column;} .te-skill-evidence .te-input {min-width:0;} }
4648
4695
  `;
4649
4696
 
@@ -5054,6 +5101,16 @@ var FLOW_PRESETS = {
5054
5101
  agile: preset("agile", 4, "\u65E5\u5E38\u8FED\u4EE3", "\u76EE\u6807\u660E\u786E\u7684\u5E38\u89C4\u529F\u80FD\u4E0E\u7F3A\u9677\u4FEE\u590D\uFF1A\u76EE\u6807\u4E0E\u9A8C\u6536 \u2192 \u5B9E\u73B0 \u2192 \u9A8C\u6536\u4E0E\u5BA1\u67E5 \u2192 \u63D0\u4EA4", AGILE, AGILE_RECOMMENDATION),
5055
5102
  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)
5056
5103
  };
5104
+ function retainStageBindings(flow, bindings) {
5105
+ const stages = new Set(FLOW_PRESETS[flow]?.config.stages ?? []);
5106
+ const kept = {};
5107
+ const dropped = [];
5108
+ for (const [stage, binding] of Object.entries(bindings)) {
5109
+ if (stages.has(stage)) kept[stage] = binding;
5110
+ else dropped.push(stage);
5111
+ }
5112
+ return { bindings: kept, dropped };
5113
+ }
5057
5114
  function dedupe(names) {
5058
5115
  return [...new Set(names)];
5059
5116
  }
@@ -5234,6 +5291,15 @@ var drawerStyle = {
5234
5291
  maxHeight: "100%",
5235
5292
  borderRadius: "16px 0 0 16px"
5236
5293
  };
5294
+ var inlineStyle = {
5295
+ ...dialogStyle,
5296
+ width: "100%",
5297
+ height: "min(720px, calc(100vh - 32px))",
5298
+ maxHeight: "calc(100vh - 32px)",
5299
+ borderRadius: 12,
5300
+ border: "1px solid var(--dsw-alias-border-l2)",
5301
+ boxShadow: "none"
5302
+ };
5237
5303
  var headerStyle = {
5238
5304
  display: "flex",
5239
5305
  alignItems: "center",
@@ -5293,7 +5359,7 @@ function ResourceModal({ title, description, onClose, footer, children, placemen
5293
5359
  closer.current = onClose;
5294
5360
  (0, import_react.useEffect)(() => {
5295
5361
  const previous = document.activeElement;
5296
- dialog.current?.focus();
5362
+ if (placement !== "inline") dialog.current?.focus();
5297
5363
  const onKey = (e) => {
5298
5364
  if (!dialog.current?.contains(document.activeElement)) return;
5299
5365
  if (e.key === "Escape") {
@@ -5302,6 +5368,7 @@ function ResourceModal({ title, description, onClose, footer, children, placemen
5302
5368
  closer.current();
5303
5369
  return;
5304
5370
  }
5371
+ if (placement === "inline") return;
5305
5372
  if (e.key !== "Tab") return;
5306
5373
  const nodes = Array.from(dialog.current.querySelectorAll('button:not(:disabled),input:not(:disabled):not([hidden]),select:not(:disabled),textarea:not(:disabled),[tabindex="0"]')).filter((el) => el.getClientRects().length);
5307
5374
  const first = nodes[0], last = nodes[nodes.length - 1];
@@ -5322,29 +5389,39 @@ function ResourceModal({ title, description, onClose, footer, children, placemen
5322
5389
  document.removeEventListener("keydown", onKey);
5323
5390
  if (previous?.isConnected) previous.focus();
5324
5391
  };
5325
- }, []);
5392
+ }, [placement]);
5393
+ const panel = (0, import_react.createElement)(
5394
+ "div",
5395
+ {
5396
+ style: placement === "inline" ? inlineStyle : placement === "right" ? drawerStyle : dialogStyle,
5397
+ className: placement === "inline" ? "te-inline-panel" : void 0,
5398
+ ref: dialog,
5399
+ tabIndex: -1,
5400
+ role: placement === "inline" ? "complementary" : "dialog",
5401
+ ...placement === "inline" ? {} : { "aria-modal": true },
5402
+ "aria-label": title
5403
+ },
5404
+ (0, import_react.createElement)(
5405
+ "div",
5406
+ { style: headerStyle },
5407
+ (0, import_react.createElement)("h2", { style: titleStyle }, title),
5408
+ (0, import_react.createElement)(
5409
+ "button",
5410
+ { type: "button", style: closeBtnStyle, "aria-label": "\u5173\u95ED", onClick: onClose },
5411
+ (0, import_react.createElement)(import_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 })
5412
+ )
5413
+ ),
5414
+ description !== void 0 && description !== "" ? (0, import_react.createElement)("p", { style: descStyle }, description) : null,
5415
+ (0, import_react.createElement)("div", { style: bodyStyle }, children),
5416
+ footer !== void 0 ? (0, import_react.createElement)("div", { style: footerStyle }, footer) : null
5417
+ );
5418
+ if (placement === "inline") return panel;
5326
5419
  return (0, import_react_dom.createPortal)(
5327
5420
  (0, import_react.createElement)(
5328
5421
  "div",
5329
5422
  { style: placement === "right" ? { ...rootStyle, justifyContent: "flex-end", padding: 0 } : rootStyle, className: `te-modal${placement === "right" ? " te-drawer" : ""}`, role: "presentation" },
5330
5423
  (0, import_react.createElement)("div", { style: placement === "right" ? { ...maskStyle, background: "rgba(0, 0, 0, 0.18)" } : maskStyle, "aria-hidden": true, onClick: onClose }),
5331
- (0, import_react.createElement)(
5332
- "div",
5333
- { style: placement === "right" ? drawerStyle : dialogStyle, ref: dialog, tabIndex: -1, role: "dialog", "aria-modal": true, "aria-label": title },
5334
- (0, import_react.createElement)(
5335
- "div",
5336
- { style: headerStyle },
5337
- (0, import_react.createElement)("h2", { style: titleStyle }, title),
5338
- (0, import_react.createElement)(
5339
- "button",
5340
- { type: "button", style: closeBtnStyle, "aria-label": "\u5173\u95ED", onClick: onClose },
5341
- (0, import_react.createElement)(import_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 })
5342
- )
5343
- ),
5344
- description !== void 0 && description !== "" ? (0, import_react.createElement)("p", { style: descStyle }, description) : null,
5345
- (0, import_react.createElement)("div", { style: bodyStyle }, children),
5346
- footer !== void 0 ? (0, import_react.createElement)("div", { style: footerStyle }, footer) : null
5347
- )
5424
+ panel
5348
5425
  ),
5349
5426
  document.body
5350
5427
  );
@@ -5392,7 +5469,7 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
5392
5469
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
5393
5470
  ResourceModal,
5394
5471
  {
5395
- placement: "right",
5472
+ placement: "inline",
5396
5473
  title: `\u914D\u7F6E\u89C4\u5219 \xB7 ${skill.name}`,
5397
5474
  description: description ?? "\u89C4\u5219\u5C5E\u4E8E\u6280\u80FD\uFF1B\u6B64\u5904\u7684\u914D\u7F6E\u4F1A\u7528\u4E8E\u6240\u6709\u7ED1\u5B9A\u8BE5\u6280\u80FD\u7684\u8282\u70B9\u3002",
5398
5475
  onClose: close,
@@ -5478,6 +5555,8 @@ function TaskEngineSection(props) {
5478
5555
  const [loading, setLoading] = (0, import_react3.useState)(true);
5479
5556
  const [loadAttempt, setLoadAttempt] = (0, import_react3.useState)(0);
5480
5557
  const [configProblems, setConfigProblems] = (0, import_react3.useState)([]);
5558
+ const [flowNotice, setFlowNotice] = (0, import_react3.useState)("");
5559
+ const [pendingAdoption, setPendingAdoption] = (0, import_react3.useState)(false);
5481
5560
  const [skills, setSkills] = (0, import_react3.useState)([]);
5482
5561
  const [rules, setRules] = (0, import_react3.useState)([]);
5483
5562
  const [configuringSkill, setConfiguringSkill] = (0, import_react3.useState)(null);
@@ -5499,6 +5578,8 @@ function TaskEngineSection(props) {
5499
5578
  setCommitRequired(result.value.config.commit_required);
5500
5579
  setSource(result.value.source);
5501
5580
  setConfigProblems(result.value.problems);
5581
+ setFlowNotice("");
5582
+ setPendingAdoption(false);
5502
5583
  setSavedAt("");
5503
5584
  } else {
5504
5585
  setLoadError("\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25\uFF1A" + describeError(result.error));
@@ -5532,10 +5613,18 @@ function TaskEngineSection(props) {
5532
5613
  () => validateWorkflow(resolvedConfig(flow, stageBindings, skillProfiles)),
5533
5614
  [flow, stageBindings, skillProfiles]
5534
5615
  );
5616
+ const hasBundledReferences = (0, import_react3.useMemo)(
5617
+ () => 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")),
5618
+ [stageBindings, skillProfiles]
5619
+ );
5535
5620
  const selectFlow = (id) => {
5536
5621
  if (id === flow) return;
5537
- if (dirty && !window.confirm("\u5F53\u524D\u6D41\u7A0B\u914D\u7F6E\u6709\u672A\u4FDD\u5B58\u7684\u4FEE\u6539\uFF0C\u5207\u6362\u6D41\u7A0B\u4F1A\u4E22\u5F03\u5B83\u4EEC\u3002\u7EE7\u7EED\u5207\u6362\uFF1F")) return;
5622
+ const { bindings, dropped } = retainStageBindings(id, stageBindings);
5623
+ 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;
5624
+ setStageBindings(bindings);
5625
+ 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` : "");
5538
5626
  setFlow(id);
5627
+ setPendingAdoption(false);
5539
5628
  setDirty(true);
5540
5629
  setSavedAt("");
5541
5630
  };
@@ -5544,6 +5633,8 @@ function TaskEngineSection(props) {
5544
5633
  if (adopted === void 0) return;
5545
5634
  if (dirty && !window.confirm("\u91C7\u7528\u63A8\u8350\u914D\u7F6E\u4F1A\u66FF\u6362\u5F53\u524D\u7684\u6280\u80FD\u4E0E\u89C4\u5219\u8BBE\u7F6E\u3002\u7EE7\u7EED\uFF1F")) return;
5546
5635
  setStageBindings({ ...adopted.stage_bindings ?? {} });
5636
+ setPendingAdoption(true);
5637
+ setFlowNotice("");
5547
5638
  const adoptedFlow = resolveFlow(flow, adopted);
5548
5639
  setSkillProfiles(adoptedFlow.ok ? adoptedFlow.config.skill_profiles ?? {} : {});
5549
5640
  setCommitRule(adopted.commit);
@@ -5554,6 +5645,10 @@ function TaskEngineSection(props) {
5554
5645
  };
5555
5646
  const updateSkillProfile = async (profile) => {
5556
5647
  if (!configuringSkill) return;
5648
+ if (configuringSkill.source === "user") {
5649
+ const result = await remote.writeUserSkillProfile({ name: configuringSkill.name, profile });
5650
+ 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");
5651
+ }
5557
5652
  const key = formatResourceRef(configuringSkill);
5558
5653
  const bindings = {};
5559
5654
  for (const [name, binding] of Object.entries(stageBindings)) {
@@ -5579,107 +5674,123 @@ function TaskEngineSection(props) {
5579
5674
  ] });
5580
5675
  }
5581
5676
  if (loading) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", children: "\u6B63\u5728\u8BFB\u53D6\u6D41\u7A0B\u914D\u7F6E\u2026" });
5582
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.wrap, children: [
5583
- configProblems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { role: "alert", style: styles.problems, children: [
5584
- "\u539F\u914D\u7F6E\u6709\u95EE\u9898\uFF1A",
5585
- configProblems.join("\uFF1B"),
5586
- "\u3002\u8BF7\u9009\u62E9\u6709\u6548\u9884\u8BBE\u5E76\u4FDD\u5B58\u4FEE\u590D\u3002"
5587
- ] }),
5588
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.head, children: [
5589
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { style: styles.title, children: "\u5DE5\u7A0B\u6D41\u7A0B\u914D\u7F6E" }),
5590
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: "\u6D41\u7A0B\u51B3\u5B9A\u5DE5\u4F5C\u600E\u4E48\u6D41\u8F6C\uFF08\u9636\u6BB5\u4E0E\u95E8\u7981\uFF09\uFF1B\u6280\u80FD\u3001\u89C4\u5219\u3001\u63D0\u4EA4\u683C\u5F0F\u548C\u4EA7\u7269\u5B57\u6BB5\u7531\u4F60\u81EA\u5DF1\u914D\u7F6E\u3002 \u9700\u8981\u4E00\u4EFD\u73B0\u6210\u7684\u8D77\u70B9\u65F6\uFF0C\u53EF\u4EE5\u300C\u91C7\u7528\u63A8\u8350\u914D\u7F6E\u300D\u2014\u2014\u91C7\u7528\u540E\u8FD9\u4E9B\u5C31\u5B8C\u5168\u5C5E\u4E8E\u4F60\uFF0C\u53EF\u968F\u610F\u4FEE\u6539\u6216\u5220\u9664\u3002" })
5591
- ] }),
5592
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.adoptRow, children: [
5593
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dsh_client_ui_primitives3.Button, { size: "sm", onClick: adopt, children: [
5594
- "\u91C7\u7528\u300C",
5595
- FLOW_PRESETS[flow]?.label ?? flow,
5596
- "\u300D\u7684\u63A8\u8350\u914D\u7F6E"
5677
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `te-config-layout${configuringSkill ? " is-open" : ""}`, children: [
5678
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-config-main", style: styles.wrap, children: [
5679
+ configProblems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { role: "alert", style: styles.problems, children: [
5680
+ "\u539F\u914D\u7F6E\u6709\u95EE\u9898\uFF1A",
5681
+ configProblems.join("\uFF1B"),
5682
+ "\u3002\u8BF7\u9009\u62E9\u6709\u6548\u9884\u8BBE\u5E76\u4FDD\u5B58\u4FEE\u590D\u3002"
5597
5683
  ] }),
5598
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.muted, children: "\u5199\u5165\u63A8\u8350\u6280\u80FD\u3001\u63D0\u4EA4\u4FE1\u606F\u683C\u5F0F\u4E0E\u4EA7\u7269\u5B57\u6BB5\u3002\u4EC5\u5728\u4F60\u70B9\u51FB\u65F6\u53D1\u751F\u4E00\u6B21\uFF1B\u5220\u9664\u540E\u4E0D\u4F1A\u81EA\u52A8\u8865\u56DE\u3002" })
5599
- ] }),
5600
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.sourceRow, children: [
5601
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: source === "project" ? "done" : source === "invalid" ? "warning" : "ongoing" }),
5602
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.sourceText, children: sourceText(source) })
5603
- ] }),
5604
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.field, children: [
5605
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u6D41\u7A0B\u9884\u8BBE" }),
5606
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.flowGrid, children: FLOW_OPTIONS.map((option) => {
5607
- const active = flow === option.id;
5608
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
5609
- "button",
5684
+ flowNotice && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { role: "status", className: "te-flow-notice", children: flowNotice }),
5685
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.head, children: [
5686
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { style: styles.title, children: "\u5DE5\u7A0B\u6D41\u7A0B\u914D\u7F6E" }),
5687
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.muted, children: "\u6D41\u7A0B\u51B3\u5B9A\u5DE5\u4F5C\u600E\u4E48\u6D41\u8F6C\uFF08\u9636\u6BB5\u4E0E\u95E8\u7981\uFF09\uFF1B\u6280\u80FD\u3001\u89C4\u5219\u3001\u63D0\u4EA4\u683C\u5F0F\u548C\u4EA7\u7269\u5B57\u6BB5\u7531\u4F60\u81EA\u5DF1\u914D\u7F6E\u3002 \u9700\u8981\u4E00\u4EFD\u73B0\u6210\u7684\u8D77\u70B9\u65F6\uFF0C\u53EF\u4EE5\u300C\u91C7\u7528\u63A8\u8350\u914D\u7F6E\u300D\uFF1B\u4FDD\u5B58\u65F6\u4F1A\u628A\u5185\u7F6E\u6837\u672C\u590D\u5236\u5230\u5F53\u524D\u9879\u76EE\uFF0C\u518D\u7531\u4F60\u7684\u9879\u76EE\u8D44\u6E90\u627F\u8F7D\u8FD9\u4E9B\u89C4\u5219\u3002" })
5688
+ ] }),
5689
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.adoptRow, children: [
5690
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dsh_client_ui_primitives3.Button, { size: "sm", onClick: adopt, children: [
5691
+ "\u91C7\u7528\u300C",
5692
+ FLOW_PRESETS[flow]?.label ?? flow,
5693
+ "\u300D\u7684\u63A8\u8350\u914D\u7F6E"
5694
+ ] }),
5695
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.muted, children: "\u4FDD\u5B58\u540E\u590D\u5236\u63A8\u8350\u6280\u80FD\u4E0E\u5171\u4EAB\u89C4\u5219\u5404\u4E00\u4EFD\u5230\u9879\u76EE\uFF1B\u5DF2\u6709\u9879\u76EE\u526F\u672C\u4E0D\u4F1A\u88AB\u8986\u76D6\uFF0C\u4E4B\u540E\u63D2\u4EF6\u5347\u7EA7\u4E5F\u4E0D\u4F1A\u6539\u5199\u5B83\u4EEC\u3002" })
5696
+ ] }),
5697
+ hasBundledReferences && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.adoptRow, children: [
5698
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.Button, { size: "sm", onClick: () => {
5699
+ setPendingAdoption(true);
5700
+ setDirty(true);
5701
+ setSavedAt("");
5702
+ 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");
5703
+ }, children: "\u628A\u5F53\u524D\u5185\u7F6E\u5F15\u7528\u8FC1\u79FB\u5230\u9879\u76EE" }),
5704
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.muted, children: "\u65E7\u9879\u76EE\u53EF\u5355\u72EC\u8FC1\u79FB\uFF0C\u4E0D\u5FC5\u91CD\u65B0\u91C7\u7528\u63A8\u8350\u914D\u7F6E\u3002" })
5705
+ ] }),
5706
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.sourceRow, children: [
5707
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: source === "project" ? "done" : source === "invalid" ? "warning" : "ongoing" }),
5708
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: styles.sourceText, children: sourceText(source) })
5709
+ ] }),
5710
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.field, children: [
5711
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { children: "\u6D41\u7A0B\u9884\u8BBE" }),
5712
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles.flowGrid, children: FLOW_OPTIONS.map((option) => {
5713
+ const active = flow === option.id;
5714
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
5715
+ "button",
5716
+ {
5717
+ type: "button",
5718
+ "aria-pressed": active,
5719
+ onClick: () => {
5720
+ selectFlow(option.id);
5721
+ },
5722
+ style: { ...styles.flowOption, ...active ? styles.flowOptionActive : {} },
5723
+ children: [
5724
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.flowOptionTitle, children: [
5725
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: active ? "done" : "ongoing", size: 8 }),
5726
+ option.label
5727
+ ] }),
5728
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.flowOptionDesc, children: option.description })
5729
+ ]
5730
+ },
5731
+ option.id
5732
+ );
5733
+ }) })
5734
+ ] }),
5735
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.IconSettingsOutline16, { size: 16 }), title: "\u9636\u6BB5\u6280\u80FD", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BindingEditor, { stages, stageBindings, setStageBindings: (next) => {
5736
+ setStageBindings(next);
5737
+ setDirty(true);
5738
+ setSavedAt("");
5739
+ }, skillProfiles, setSkillProfiles: (next) => {
5740
+ setSkillProfiles(next);
5741
+ setDirty(true);
5742
+ setSavedAt("");
5743
+ }, skills, onConfigureSkill: setConfiguringSkill }) }),
5744
+ problems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.problems, children: [
5745
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.problemsTitle, children: [
5746
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: "error" }),
5747
+ "\u6709 ",
5748
+ problems.length,
5749
+ " \u4E2A\u95EE\u9898\uFF08\u4FDD\u5B58\u4F1A\u88AB\u62D2\u7EDD\uFF09"
5750
+ ] }),
5751
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { style: styles.problemsList, children: problems.map((p) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: p }, p)) })
5752
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.okText, children: [
5753
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: "done" }),
5754
+ source === "project" ? "\u914D\u7F6E\u6709\u6548" : "\u4F7F\u7528\u7A7A\u767D\u6D41\u7A0B\u914D\u7F6E\uFF08\u5C1A\u672A\u4FDD\u5B58\uFF09"
5755
+ ] }),
5756
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.actions, children: [
5757
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5758
+ import_dsh_client_ui_primitives3.Button,
5610
5759
  {
5611
- type: "button",
5612
- "aria-pressed": active,
5760
+ variant: "primary",
5761
+ size: "md",
5762
+ icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.IconCheckOutline16, { size: 16 }),
5763
+ disabled: problems.length > 0 || saving,
5613
5764
  onClick: () => {
5614
- selectFlow(option.id);
5765
+ setSaving(true);
5766
+ 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) => {
5767
+ if (view) {
5768
+ setConfigProblems([]);
5769
+ setDirty(false);
5770
+ setPendingAdoption(false);
5771
+ setStageBindings(view.config.stage_bindings ?? {});
5772
+ setSkillProfiles(view.config.skill_profiles ?? {});
5773
+ refreshCatalogs();
5774
+ }
5775
+ }).finally(() => setSaving(false));
5615
5776
  },
5616
- style: { ...styles.flowOption, ...active ? styles.flowOptionActive : {} },
5617
- children: [
5618
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.flowOptionTitle, children: [
5619
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: active ? "done" : "ongoing", size: 8 }),
5620
- option.label
5621
- ] }),
5622
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: styles.flowOptionDesc, children: option.description })
5623
- ]
5624
- },
5625
- option.id
5626
- );
5627
- }) })
5628
- ] }),
5629
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.IconSettingsOutline16, { size: 16 }), title: "\u9636\u6BB5\u6280\u80FD", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BindingEditor, { stages, stageBindings, setStageBindings: (next) => {
5630
- setStageBindings(next);
5631
- setDirty(true);
5632
- setSavedAt("");
5633
- }, skillProfiles, setSkillProfiles: (next) => {
5634
- setSkillProfiles(next);
5635
- setDirty(true);
5636
- setSavedAt("");
5637
- }, skills, onConfigureSkill: setConfiguringSkill }) }),
5638
- problems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.problems, children: [
5639
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.problemsTitle, children: [
5640
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: "error" }),
5641
- "\u6709 ",
5642
- problems.length,
5643
- " \u4E2A\u95EE\u9898\uFF08\u4FDD\u5B58\u4F1A\u88AB\u62D2\u7EDD\uFF09"
5644
- ] }),
5645
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { style: styles.problemsList, children: problems.map((p) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { children: p }, p)) })
5646
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.okText, children: [
5647
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: "done" }),
5648
- source === "project" ? "\u914D\u7F6E\u6709\u6548" : "\u4F7F\u7528\u7A7A\u767D\u6D41\u7A0B\u914D\u7F6E\uFF08\u5C1A\u672A\u4FDD\u5B58\uFF09"
5649
- ] }),
5650
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles.actions, children: [
5651
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5652
- import_dsh_client_ui_primitives3.Button,
5653
- {
5654
- variant: "primary",
5655
- size: "md",
5656
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.IconCheckOutline16, { size: 16 }),
5657
- disabled: problems.length > 0 || saving,
5658
- onClick: () => {
5659
- setSaving(true);
5660
- void save(remote, { flow, stage_bindings: stageBindings, skill_profiles: skillProfiles, ...commitRule !== void 0 ? { commit: commitRule } : {}, ...artifacts !== void 0 ? { artifacts } : {}, ...reviewDepth !== void 0 ? { review_depth: reviewDepth } : {}, ...commitRequired !== void 0 ? { commit_required: commitRequired } : {} }, workspace, setSavedAt, setSource).then((ok) => {
5661
- if (ok) {
5662
- setConfigProblems([]);
5663
- setDirty(false);
5664
- }
5665
- }).finally(() => setSaving(false));
5666
- },
5667
- children: saving ? "\u6B63\u5728\u4FDD\u5B58\u2026" : dirty ? "\u4FDD\u5B58\u5230 .dsh/eng.json" : "\u5DF2\u4FDD\u5B58 \xB7 \u65E0\u9700\u4FDD\u5B58"
5668
- }
5669
- ),
5670
- savedAt !== "" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.okText, children: [
5671
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: savedAt.startsWith("\u5DF2") ? "done" : "error" }),
5672
- savedAt
5673
- ] }) : null
5777
+ children: saving ? "\u6B63\u5728\u4FDD\u5B58\u2026" : dirty ? "\u4FDD\u5B58\u5230 .dsh/eng.json" : "\u5DF2\u4FDD\u5B58 \xB7 \u65E0\u9700\u4FDD\u5B58"
5778
+ }
5779
+ ),
5780
+ savedAt !== "" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles.okText, children: [
5781
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives3.StateDot, { state: savedAt.startsWith("\u5DF2") ? "done" : "error" }),
5782
+ savedAt
5783
+ ] }) : null
5784
+ ] })
5674
5785
  ] }),
5675
5786
  configuringSkill ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5676
5787
  SkillRuleDialog,
5677
5788
  {
5678
5789
  skill: configuringSkill,
5679
5790
  profile: skillProfiles[formatResourceRef(configuringSkill)],
5680
- rules,
5681
- description: "\u89C4\u5219\u5C5E\u4E8E\u6280\u80FD\uFF0C\u6240\u6709\u5F15\u7528\u6B64\u6280\u80FD\u7684\u8282\u70B9\u90FD\u4F1A\u540C\u6B65\u3002\u5E94\u7528\u540E\u8BF7\u70B9\u51FB\u9875\u9762\u5E95\u90E8\u4FDD\u5B58\u3002",
5682
- saveLabel: "\u5E94\u7528\u5230\u5F53\u524D\u914D\u7F6E",
5791
+ rules: configuringSkill.source === "user" ? rules.filter((rule) => rule.ref.source !== "project") : rules,
5792
+ 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",
5793
+ saveLabel: configuringSkill.source === "user" ? "\u4FDD\u5B58\u7528\u6237\u7EA7\u89C4\u5219" : "\u5E94\u7528\u5230\u5F53\u524D\u914D\u7F6E",
5683
5794
  onSave: updateSkillProfile,
5684
5795
  onClose: () => setConfiguringSkill(null)
5685
5796
  },
@@ -5828,18 +5939,19 @@ async function save(remote, config, workspace, setSavedAt, setSource) {
5828
5939
  const result = await remote.write({ path: workspace, ...config });
5829
5940
  if (!result.ok) {
5830
5941
  setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(result.error));
5831
- return false;
5942
+ return void 0;
5832
5943
  }
5833
5944
  if (!result.value.ok) {
5834
5945
  setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + result.value.problems.join("\uFF1B"));
5835
- return false;
5946
+ return void 0;
5836
5947
  }
5837
5948
  setSource(result.value.source);
5838
- setSavedAt("\u5DF2\u4FDD\u5B58");
5839
- return true;
5949
+ const reused = result.value.adoption?.reused.length ?? 0;
5950
+ setSavedAt(reused > 0 ? `\u5DF2\u4FDD\u5B58\uFF1B\u4FDD\u7559\u4E86 ${reused} \u4EFD\u5DF2\u6709\u9879\u76EE\u8D44\u6E90` : "\u5DF2\u4FDD\u5B58");
5951
+ return result.value;
5840
5952
  } catch (error) {
5841
5953
  setSavedAt("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(error));
5842
- return false;
5954
+ return void 0;
5843
5955
  }
5844
5956
  }
5845
5957
 
@@ -6426,24 +6538,32 @@ function SkillManager({ workspace, remote }) {
6426
6538
  if (!config || !selected) throw new Error("\u914D\u7F6E\u5C1A\u672A\u52A0\u8F7D\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
6427
6539
  const key = formatResourceRef(selected);
6428
6540
  const next = { ...config, skill_profiles: { ...config.skill_profiles, [key]: profile } };
6429
- const result = await remote.write({ path: workspace, ...next });
6430
- if (!result.ok || !result.value.ok) throw new Error(result.ok ? result.value.problems.join("\uFF1B") : "\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
6541
+ if (selected.source === "user") {
6542
+ const result = await remote.writeUserSkillProfile({ name: selected.name, profile });
6543
+ if (!result.ok || !result.value.ok) throw new Error(result.ok ? result.value.error : "\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
6544
+ } else {
6545
+ const result = await remote.write({ path: workspace, ...next });
6546
+ if (!result.ok || !result.value.ok) throw new Error(result.ok ? result.value.problems.join("\uFF1B") : "\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
6547
+ }
6431
6548
  setConfig(next);
6432
6549
  setMessage(`\u5DF2\u4FDD\u5B58 ${selected.name} \u7684\u89C4\u5219\u914D\u7F6E\u3002`);
6433
6550
  setSelected(null);
6434
6551
  };
6435
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
6436
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ResourceManager, { workspace, remote, kind: "skill", onConfigureSkill: config ? (ref) => {
6437
- setMessage("");
6438
- setSelected(ref);
6439
- } : void 0 }),
6440
- selected === null && message ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { role: "status", className: "te-success", children: message }) : null,
6552
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `te-config-layout${selected ? " is-open" : ""}`, children: [
6553
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "te-config-main", children: [
6554
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ResourceManager, { workspace, remote, kind: "skill", onConfigureSkill: config ? (ref) => {
6555
+ setMessage("");
6556
+ setSelected(ref);
6557
+ } : void 0 }),
6558
+ selected === null && message ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { role: "status", className: "te-success", children: message }) : null
6559
+ ] }),
6441
6560
  selected !== null ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6442
6561
  SkillRuleDialog,
6443
6562
  {
6444
6563
  skill: selected,
6445
6564
  profile: config?.skill_profiles?.[formatResourceRef(selected)],
6446
- rules,
6565
+ rules: selected.source === "user" ? rules.filter((rule) => rule.ref.source !== "project") : rules,
6566
+ description: selected.source === "user" ? "\u7528\u6237\u7EA7\u6280\u80FD\u7684\u89C4\u5219\u914D\u7F6E\u4FDD\u5B58\u5728\u7528\u6237\u76EE\u5F55\uFF0C\u6240\u6709\u9879\u76EE\u4E0E\u4F1A\u8BDD\u5171\u7528\uFF1B\u53EA\u80FD\u9009\u62E9\u7528\u6237\u7EA7\u6216\u5185\u7F6E\u89C4\u5219\u3002" : "\u89C4\u5219\u5C5E\u4E8E\u6280\u80FD\uFF1B\u6B64\u5904\u7684\u914D\u7F6E\u4F1A\u7528\u4E8E\u6240\u6709\u7ED1\u5B9A\u8BE5\u6280\u80FD\u7684\u8282\u70B9\u3002",
6447
6567
  onSave: saveProfile,
6448
6568
  onClose: () => setSelected(null)
6449
6569
  },