@godv61/dsh-task-engine 0.30.1 → 0.30.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
@@ -38,7 +38,7 @@ __export(index_exports, {
38
38
  });
39
39
  module.exports = __toCommonJS(index_exports);
40
40
 
41
- // ../../dsharness/task-en/node_modules/zod/v3/external.js
41
+ // node_modules/zod/v3/external.js
42
42
  var external_exports = {};
43
43
  __export(external_exports, {
44
44
  BRAND: () => BRAND,
@@ -150,7 +150,7 @@ __export(external_exports, {
150
150
  void: () => voidType
151
151
  });
152
152
 
153
- // ../../dsharness/task-en/node_modules/zod/v3/helpers/util.js
153
+ // node_modules/zod/v3/helpers/util.js
154
154
  var util;
155
155
  (function(util2) {
156
156
  util2.assertEqual = (_) => {
@@ -284,7 +284,7 @@ var getParsedType = (data) => {
284
284
  }
285
285
  };
286
286
 
287
- // ../../dsharness/task-en/node_modules/zod/v3/ZodError.js
287
+ // node_modules/zod/v3/ZodError.js
288
288
  var ZodIssueCode = util.arrayToEnum([
289
289
  "invalid_type",
290
290
  "invalid_literal",
@@ -402,7 +402,7 @@ ZodError.create = (issues) => {
402
402
  return error;
403
403
  };
404
404
 
405
- // ../../dsharness/task-en/node_modules/zod/v3/locales/en.js
405
+ // node_modules/zod/v3/locales/en.js
406
406
  var errorMap = (issue, _ctx) => {
407
407
  let message;
408
408
  switch (issue.code) {
@@ -505,7 +505,7 @@ var errorMap = (issue, _ctx) => {
505
505
  };
506
506
  var en_default = errorMap;
507
507
 
508
- // ../../dsharness/task-en/node_modules/zod/v3/errors.js
508
+ // node_modules/zod/v3/errors.js
509
509
  var overrideErrorMap = en_default;
510
510
  function setErrorMap(map) {
511
511
  overrideErrorMap = map;
@@ -514,7 +514,7 @@ function getErrorMap() {
514
514
  return overrideErrorMap;
515
515
  }
516
516
 
517
- // ../../dsharness/task-en/node_modules/zod/v3/helpers/parseUtil.js
517
+ // node_modules/zod/v3/helpers/parseUtil.js
518
518
  var makeIssue = (params) => {
519
519
  const { data, path, errorMaps, issueData } = params;
520
520
  const fullPath = [...path, ...issueData.path || []];
@@ -624,14 +624,14 @@ var isDirty = (x) => x.status === "dirty";
624
624
  var isValid = (x) => x.status === "valid";
625
625
  var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
626
626
 
627
- // ../../dsharness/task-en/node_modules/zod/v3/helpers/errorUtil.js
627
+ // node_modules/zod/v3/helpers/errorUtil.js
628
628
  var errorUtil;
629
629
  (function(errorUtil2) {
630
630
  errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
631
631
  errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
632
632
  })(errorUtil || (errorUtil = {}));
633
633
 
634
- // ../../dsharness/task-en/node_modules/zod/v3/types.js
634
+ // node_modules/zod/v3/types.js
635
635
  var ParseInputLazyPath = class {
636
636
  constructor(parent, value, path, key) {
637
637
  this._cachedPath = [];
@@ -4267,6 +4267,7 @@ var taskLedgerViewSchema = external_exports.object({
4267
4267
  })).optional(),
4268
4268
  report_path: external_exports.string().optional(),
4269
4269
  scanned_files: external_exports.array(external_exports.string()).optional(),
4270
+ profile_coverage: external_exports.array(external_exports.object({ language: external_exports.string(), active_rules: external_exports.number(), analyzer: external_exports.string() })).optional(),
4270
4271
  findings: external_exports.array(external_exports.object({
4271
4272
  key: external_exports.string(),
4272
4273
  rule: external_exports.string(),
@@ -4374,6 +4375,11 @@ var adaptiveViewSchema = external_exports.object({
4374
4375
  var adaptiveWriteRequestSchema = external_exports.object({ path: external_exports.string(), config: adaptiveConfigSchema, expected_hash: external_exports.string() });
4375
4376
  var sonarTokenInfoSchema = external_exports.object({ configured: external_exports.boolean(), source: external_exports.string().optional(), writable: external_exports.boolean() });
4376
4377
  var sonarTokenWriteSchema = external_exports.object({ path: external_exports.string(), token: external_exports.string().min(1) });
4378
+ var sonarAnalyzerStatusSchema = external_exports.object({ profiles: external_exports.array(external_exports.object({
4379
+ language: external_exports.string(),
4380
+ active_rules: external_exports.number(),
4381
+ analyzer: external_exports.string()
4382
+ })) });
4377
4383
  var projectSkillProfileRequestSchema = external_exports.object({ path: external_exports.string(), name: external_exports.string() });
4378
4384
  var projectSkillProfileWriteRequestSchema = projectSkillProfileRequestSchema.extend({
4379
4385
  profile: skillProfileSchema,
@@ -4454,6 +4460,25 @@ var TYPERT_REMOTE = {
4454
4460
  }],
4455
4461
  result: { mode: "strict", typeSymbol: `${PACKAGE}/types#SonarTokenInfo`, create: () => sonarTokenInfoSchema, schema: sonarTokenInfoSchema }
4456
4462
  },
4463
+ {
4464
+ id: `${PACKAGE}#task-engine/prepareSonarAnalyzer`,
4465
+ service: "taskEngineController",
4466
+ namespace: "task-engine",
4467
+ method: "prepareSonarAnalyzer",
4468
+ invocation: { kind: "direct" },
4469
+ parameters: [{
4470
+ name: "path",
4471
+ wire: "path",
4472
+ source: "json",
4473
+ codec: { mode: "strict", typeSymbol: "string", create: () => external_exports.string(), schema: external_exports.string() }
4474
+ }],
4475
+ result: {
4476
+ mode: "strict",
4477
+ typeSymbol: `${PACKAGE}/types#SonarAnalyzerStatus`,
4478
+ create: () => sonarAnalyzerStatusSchema,
4479
+ schema: sonarAnalyzerStatusSchema
4480
+ }
4481
+ },
4457
4482
  {
4458
4483
  id: `${PACKAGE}#task-engine/readProjectSkillProfile`,
4459
4484
  service: "taskEngineController",
@@ -4834,7 +4859,6 @@ var workbenchTheme = `
4834
4859
  .te-workbench h2 { margin:0 0 6px; font-size:24px; letter-spacing:-.5px; }
4835
4860
  .te-workbench h3,.te-modal h3 { margin:0; font-size:16px; overflow-wrap:anywhere; }
4836
4861
  .te-config-layout { display:grid; grid-template-columns:minmax(0,1fr); gap:16px; align-items:start; width:100%; }
4837
- .te-config-layout.is-open { grid-template-columns:minmax(0,1fr) minmax(320px,420px); }
4838
4862
  .te-config-main { min-width:0; }
4839
4863
  .te-inline-panel { position:sticky !important; top:12px; min-width:0; }
4840
4864
  .te-flow-notice { margin:0; padding:10px 12px; border:1px solid var(--dsw-alias-state-warn-primary); border-radius:8px; font-size:13px; }
@@ -4890,10 +4914,28 @@ var workbenchTheme = `
4890
4914
  .te-skill-evidence { display:flex; align-items:center; justify-content:space-between; gap:12px; font-size:13px; font-weight:600; }
4891
4915
  .te-skill-evidence .te-input { min-width:210px; }
4892
4916
  .te-skill-rule-list { display:flex; flex:1; flex-direction:column; gap:4px; min-height:0; overflow:auto; padding:4px; }
4917
+ .te-rule-filters { display:flex; gap:6px; flex-wrap:wrap; }
4918
+ .te-rule-filter { border:1px solid var(--dsw-alias-border-l2); border-radius:999px; padding:5px 10px; background:var(--dsw-alias-bg-layer-1); color:var(--dsw-alias-label-secondary); cursor:pointer; font-size:12px; }
4919
+ .te-rule-filter[aria-pressed="true"] { border-color:var(--dsw-alias-state-business-primary); color:var(--dsw-alias-state-business-primary); }
4893
4920
  .te-skill-rule-row { display:flex; align-items:center; gap:10px; padding:9px 10px; border:1px solid var(--dsw-alias-border-l2); border-radius:8px; cursor:pointer; }
4921
+ .te-skill-rule-row:has(input:checked) { border-color:var(--dsw-alias-state-business-primary); background:var(--dsw-alias-bg-layer-1); }
4894
4922
  .te-skill-rule-row:hover { background:var(--dsw-alias-bg-layer-1); }
4895
4923
  .te-skill-rule-row span { flex:1; min-width:0; overflow-wrap:anywhere; }
4896
4924
  .te-skill-rule-row small { color:var(--dsw-alias-label-secondary); }
4925
+ .te-meta-layout { display:grid; grid-template-columns:minmax(170px,220px) minmax(0,1fr); gap:14px; align-items:start; }
4926
+ .te-meta-nav { display:flex; flex-direction:column; gap:6px; min-width:0; }
4927
+ .te-meta-nav button { width:100%; border:1px solid var(--dsw-alias-border-l2); border-radius:9px; background:var(--dsw-alias-bg-layer-1); color:var(--dsw-alias-label-primary); text-align:left; padding:10px 12px; cursor:pointer; }
4928
+ .te-meta-nav button[aria-current="true"] { border-color:var(--dsw-alias-state-business-primary); color:var(--dsw-alias-state-business-primary); }
4929
+ .te-meta-nav small { display:block; color:var(--dsw-alias-label-secondary); margin-top:3px; }
4930
+ .te-meta-detail { min-width:0; border:1px solid var(--dsw-alias-border-l2); border-radius:12px; padding:16px; display:flex; flex-direction:column; gap:14px; }
4931
+ .te-meta-skill-row { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:10px 12px; border:1px solid var(--dsw-alias-border-l2); border-radius:9px; }
4932
+ .te-meta-skill-row>span { min-width:0; overflow-wrap:anywhere; }
4933
+ .te-meta-skill-actions { display:flex; align-items:center; gap:6px; flex:none; }
4934
+ .te-meta-candidates { display:flex; flex-direction:column; gap:4px; max-height:230px; overflow:auto; }
4935
+ .te-meta-candidate { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:8px 10px; border:1px solid var(--dsw-alias-border-l2); border-radius:8px; }
4936
+ .te-meta-candidate span { min-width:0; overflow-wrap:anywhere; }
4937
+ .te-meta-candidate small { display:block; color:var(--dsw-alias-label-secondary); font-size:11px; }
4938
+ .te-adaptive-savebar { position:sticky; bottom:0; z-index:3; display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:12px 16px; border:1px solid var(--dsw-alias-border-l2); border-radius:10px; background:var(--dsw-alias-bg-layer-2); box-shadow:var(--dsw-elevation-prominent); }
4897
4939
  .te-workbench p,.te-modal p { color:var(--dsw-alias-label-secondary); line-height:1.65; }
4898
4940
  .te-content { max-width:1600px; margin:auto; width:100%; }
4899
4941
  .te-resource { display:flex; flex-direction:column; gap:20px; }
@@ -4934,8 +4976,8 @@ var workbenchTheme = `
4934
4976
  .te-form { display:flex; flex-direction:column; gap:16px; }
4935
4977
  .te-form label { display:flex; flex-direction:column; gap:8px; font-size:13px; }
4936
4978
  .te-editor { min-height:260px; resize:vertical; line-height:1.6; font-family:monospace; }
4937
- @media(max-width:760px) { .te-transfer {grid-template-columns:1fr;} .te-transfer-arrow {transform:rotate(90deg); height:20px;} .te-transfer-list {max-height:210px;} }
4938
- @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; } }
4979
+ @media(max-width:760px) { .te-transfer {grid-template-columns:1fr;} .te-transfer-arrow {transform:rotate(90deg); height:20px;} .te-transfer-list {max-height:210px;} .te-meta-layout {grid-template-columns:1fr;} .te-meta-nav {display:grid; grid-template-columns:repeat(2,minmax(0,1fr));} }
4980
+ @media(max-width:1000px) { .te-inline-panel { position:static !important; height:min(600px,calc(100vh - 32px)) !important; } }
4939
4981
  @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;} }
4940
4982
  `;
4941
4983
 
@@ -5276,6 +5318,7 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
5276
5318
  const [draftRules, setDraftRules] = (0, import_react2.useState)(profile?.rules ?? []);
5277
5319
  const [evidence, setEvidence] = (0, import_react2.useState)(profile?.evidence ?? "");
5278
5320
  const [query, setQuery] = (0, import_react2.useState)("");
5321
+ const [filter, setFilter] = (0, import_react2.useState)("all");
5279
5322
  const [dirty, setDirty] = (0, import_react2.useState)(false);
5280
5323
  const [busy, setBusy] = (0, import_react2.useState)(false);
5281
5324
  const [error, setError] = (0, import_react2.useState)("");
@@ -5302,17 +5345,20 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
5302
5345
  setBusy(false);
5303
5346
  }
5304
5347
  };
5348
+ const selectedKeys = new Set(draftRules.map(formatResourceRef));
5305
5349
  const filtered = rules.filter((rule) => {
5306
5350
  const key = formatResourceRef(rule.ref);
5307
- const chosen = draftRules.some((item) => formatResourceRef(item) === key);
5308
- return chosen || `${rule.name} ${rule.sourceLabel}`.toLowerCase().includes(query.trim().toLowerCase());
5309
- });
5351
+ const chosen = selectedKeys.has(key);
5352
+ const matches = `${rule.name} ${rule.sourceLabel} ${rule.source}`.toLowerCase().includes(query.trim().toLowerCase());
5353
+ return matches && (filter === "all" || filter === "selected" && chosen || filter === "project" && (rule.ref.source === "project" || rule.ref.source === "codex-project") || filter === "user" && rule.ref.source === "user" || filter === "bundled" && rule.ref.source === "bundled");
5354
+ }).sort((a, b) => Number(selectedKeys.has(formatResourceRef(b.ref))) - Number(selectedKeys.has(formatResourceRef(a.ref))) || a.name.localeCompare(b.name));
5310
5355
  const catalogKeys = new Set(rules.map((rule) => formatResourceRef(rule.ref)));
5311
5356
  const missingRules = draftRules.filter((rule) => !catalogKeys.has(formatResourceRef(rule)));
5357
+ const visibleMissing = missingRules.filter((rule) => (filter === "all" || filter === "selected") && rule.name.toLowerCase().includes(query.trim().toLowerCase()));
5312
5358
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
5313
5359
  ResourceModal,
5314
5360
  {
5315
- placement: "inline",
5361
+ placement: "right",
5316
5362
  title: `\u914D\u7F6E\u89C4\u5219 \xB7 ${skill.name}`,
5317
5363
  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",
5318
5364
  onClose: close,
@@ -5346,10 +5392,21 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
5346
5392
  ] })
5347
5393
  ] }),
5348
5394
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { className: "te-input", type: "search", "aria-label": "\u641C\u7D22\u89C4\u5219", placeholder: "\u641C\u7D22\u89C4\u5219\u540D\u79F0\u6216\u6765\u6E90", value: query, onChange: (event) => setQuery(event.target.value) }),
5395
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "te-rule-filters", role: "group", "aria-label": "\u7B5B\u9009\u89C4\u5219", children: [["all", "\u5168\u90E8"], ["selected", `\u5DF2\u9009 ${draftRules.length}`], ["project", "\u9879\u76EE"], ["user", "\u7528\u6237"], ["bundled", "\u5185\u7F6E"]].map(([value, label3]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
5396
+ "button",
5397
+ {
5398
+ type: "button",
5399
+ "aria-pressed": filter === value,
5400
+ className: "te-rule-filter",
5401
+ onClick: () => setFilter(value),
5402
+ children: label3
5403
+ },
5404
+ value
5405
+ )) }),
5349
5406
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "te-skill-rule-list", role: "group", "aria-label": "\u89C4\u5219\u5217\u8868", children: [
5350
5407
  rules.length === 0 && missingRules.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "te-binding-empty", children: "\u89C4\u5219\u5E93\u4E3A\u7A7A\uFF0C\u8BF7\u5148\u5230\u201C\u89C4\u5219\u201D\u9875\u521B\u5EFA\u6216\u5B89\u88C5\u3002" }) : null,
5351
- rules.length > 0 && filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "te-binding-empty", children: "\u6CA1\u6709\u5339\u914D\u7684\u89C4\u5219\u3002" }) : null,
5352
- missingRules.map((rule) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "te-skill-rule-row", children: [
5408
+ rules.length > 0 && filtered.length === 0 && visibleMissing.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "te-binding-empty", children: "\u6CA1\u6709\u5339\u914D\u7684\u89C4\u5219\u3002" }) : null,
5409
+ visibleMissing.map((rule) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "te-skill-rule-row", children: [
5353
5410
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked: true, onChange: () => toggle(rule) }),
5354
5411
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: rule.name }),
5355
5412
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { children: [
@@ -5359,7 +5416,7 @@ function SkillRuleDialog({ skill, profile, rules, description, saveLabel, onSave
5359
5416
  ] }, formatResourceRef(rule))),
5360
5417
  filtered.map((rule) => {
5361
5418
  const key = formatResourceRef(rule.ref);
5362
- const checked = draftRules.some((item) => formatResourceRef(item) === key);
5419
+ const checked = selectedKeys.has(key);
5363
5420
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "te-skill-rule-row", children: [
5364
5421
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked, onChange: () => toggle(rule.ref) }),
5365
5422
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: rule.name }),
@@ -5394,7 +5451,7 @@ var input = {
5394
5451
  };
5395
5452
  var SOURCE_ORDER = ["project", "codex-project", "user", "bundled"];
5396
5453
  function effectiveSource(entries, name) {
5397
- return entries.filter((entry) => entry.name === name).sort((a, b) => SOURCE_ORDER.indexOf(a.source) - SOURCE_ORDER.indexOf(b.source))[0]?.source ?? "\u7F3A\u5931";
5454
+ return entries.filter((entry) => entry.name === name).sort((a, b) => SOURCE_ORDER.indexOf(a.source) - SOURCE_ORDER.indexOf(b.source))[0]?.sourceLabel ?? "\u7F3A\u5931";
5398
5455
  }
5399
5456
  function AdaptivePanel({ workspace, remote, onOpenInit }) {
5400
5457
  const [view, setView] = (0, import_react3.useState)(null);
@@ -5402,6 +5459,9 @@ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5402
5459
  const [skills, setSkills] = (0, import_react3.useState)([]);
5403
5460
  const [rules, setRules] = (0, import_react3.useState)([]);
5404
5461
  const [selected, setSelected] = (0, import_react3.useState)(null);
5462
+ const [activeMeta, setActiveMeta] = (0, import_react3.useState)("requirements-analysis");
5463
+ const [metaQuery, setMetaQuery] = (0, import_react3.useState)("");
5464
+ const [skillQuery, setSkillQuery] = (0, import_react3.useState)("");
5405
5465
  const [loading, setLoading] = (0, import_react3.useState)(true);
5406
5466
  const [saving, setSaving] = (0, import_react3.useState)(false);
5407
5467
  const [dirty, setDirty] = (0, import_react3.useState)(false);
@@ -5409,11 +5469,14 @@ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5409
5469
  const [sonarToken, setSonarToken] = (0, import_react3.useState)("");
5410
5470
  const [tokenInfo, setTokenInfo] = (0, import_react3.useState)(null);
5411
5471
  const [tokenBusy, setTokenBusy] = (0, import_react3.useState)(false);
5472
+ const [analyzerBusy, setAnalyzerBusy] = (0, import_react3.useState)(false);
5473
+ const [analyzerProfiles, setAnalyzerProfiles] = (0, import_react3.useState)(null);
5412
5474
  const refresh = (0, import_react3.useCallback)(() => {
5413
5475
  setLoading(true);
5414
5476
  setMessage("");
5415
5477
  setSonarToken("");
5416
5478
  setTokenInfo(null);
5479
+ setAnalyzerProfiles(null);
5417
5480
  void remote.describeSonarToken(workspace).then((result) => {
5418
5481
  if (result.ok) setTokenInfo(result.value);
5419
5482
  }, () => {
@@ -5460,7 +5523,15 @@ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5460
5523
  update({ ...draft, meta_bindings });
5461
5524
  };
5462
5525
  const updateSonar = (patch) => {
5463
- update({ ...draft, sonar: { mode: "branch", token_env: "SONAR_TOKEN", ...draft.sonar, ...patch } });
5526
+ update({ ...draft, sonar: {
5527
+ ...draft.sonar,
5528
+ ...patch,
5529
+ source: "ide-local",
5530
+ mode: "branch",
5531
+ token_env: draft.sonar?.token_env ?? "SONAR_TOKEN",
5532
+ reference_branch: patch.reference_branch ?? draft.sonar?.reference_branch ?? "HEAD",
5533
+ scan_command: void 0
5534
+ } });
5464
5535
  };
5465
5536
  const openRules = (name) => {
5466
5537
  setMessage("");
@@ -5535,7 +5606,14 @@ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5535
5606
  const save = () => {
5536
5607
  if (!view) return;
5537
5608
  setSaving(true);
5538
- void remote.writeAdaptive({ path: workspace, config: draft, expected_hash: view.hash }).then((result) => {
5609
+ const config = { ...draft, ...draft.sonar?.enabled ? { sonar: {
5610
+ ...draft.sonar,
5611
+ source: "ide-local",
5612
+ mode: "branch",
5613
+ reference_branch: draft.sonar.reference_branch?.trim() || "HEAD",
5614
+ scan_command: void 0
5615
+ } } : {} };
5616
+ void remote.writeAdaptive({ path: workspace, config, expected_hash: view.hash }).then((result) => {
5539
5617
  setSaving(false);
5540
5618
  if (!result.ok) {
5541
5619
  setMessage("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(result.error));
@@ -5587,7 +5665,34 @@ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5587
5665
  setMessage("\u79FB\u9664 SonarQube Token \u5931\u8D25\uFF1A" + describeError(error));
5588
5666
  });
5589
5667
  };
5668
+ const prepareAnalyzer = () => {
5669
+ if (dirty) {
5670
+ setMessage("\u8BF7\u5148\u4FDD\u5B58 SonarQube \u5BA1\u6838\u914D\u7F6E\uFF0C\u518D\u68C0\u67E5\u672C\u5730\u5206\u6790\u5668\u3002");
5671
+ return;
5672
+ }
5673
+ setAnalyzerBusy(true);
5674
+ setAnalyzerProfiles(null);
5675
+ setMessage("\u6B63\u5728\u5B89\u88C5\u6216\u68C0\u67E5\u672C\u5730\u5206\u6790\u5668\uFF0C\u5E76\u8FDE\u63A5\u5F53\u524D\u9879\u76EE\u7684 SonarQube\uFF1B\u9996\u6B21\u4E0B\u8F7D\u53EF\u80FD\u9700\u8981\u8F83\u957F\u65F6\u95F4\u3002");
5676
+ void remote.prepareSonarAnalyzer(workspace).then((result) => {
5677
+ setAnalyzerBusy(false);
5678
+ if (!result.ok) {
5679
+ setMessage("\u672C\u5730\u5206\u6790\u5668\u68C0\u67E5\u5931\u8D25\uFF1A" + describeError(result.error));
5680
+ return;
5681
+ }
5682
+ setAnalyzerProfiles(result.value.profiles);
5683
+ setMessage("\u5DF2\u8FDE\u63A5 SonarQube\uFF1B\u8BF7\u67E5\u770B\u4E0B\u65B9\u5404\u8BED\u8A00\u7684\u672C\u5730\u5206\u6790\u5668\u72B6\u6001\u3002");
5684
+ }, (error) => {
5685
+ setAnalyzerBusy(false);
5686
+ setMessage("\u672C\u5730\u5206\u6790\u5668\u68C0\u67E5\u5931\u8D25\uFF1A" + describeError(error));
5687
+ });
5688
+ };
5590
5689
  const candidates = [...new Set(skills.map((skill) => skill.name))].filter((name) => name !== "eng-delivery" && !(name in META_STAGES)).sort();
5690
+ const stageQuery = metaQuery.trim().toLowerCase();
5691
+ const visibleStages = Object.entries(META_STAGES).filter(([id, stage]) => !stageQuery || `${id} ${stage} ${(draft.meta_bindings?.[id] ?? []).join(" ")}`.toLowerCase().includes(stageQuery));
5692
+ const visibleMeta = visibleStages.find(([id]) => id === activeMeta)?.[0] ?? visibleStages[0]?.[0];
5693
+ const mounted = visibleMeta ? draft.meta_bindings?.[visibleMeta] ?? [] : [];
5694
+ const candidateQuery = skillQuery.trim().toLowerCase();
5695
+ const matchingCandidates = candidates.filter((name) => !mounted.includes(name) && (!candidateQuery || name.toLowerCase().includes(candidateQuery) || skills.some((skill) => skill.name === name && `${skill.description} ${skill.sourceLabel}`.toLowerCase().includes(candidateQuery))));
5591
5696
  const sonar = draft.sonar ?? {};
5592
5697
  return (0, import_react3.createElement)(
5593
5698
  "div",
@@ -5599,10 +5704,10 @@ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5599
5704
  (0, import_react3.createElement)("span", { style: label }, "\u626B\u63CF\u9879\u76EE\u540E\u5148\u9884\u89C8\uFF0C\u786E\u8BA4\u540E\u5199\u5165\u3002")
5600
5705
  ),
5601
5706
  (0, import_react3.createElement)(
5602
- "div",
5707
+ "details",
5603
5708
  { style: card },
5604
- (0, import_react3.createElement)("strong", null, "\u6309\u9700\u6C42\u9009\u62E9\u6D41\u7A0B"),
5605
- (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"),
5709
+ (0, import_react3.createElement)("summary", { style: { cursor: "pointer", fontWeight: 600 } }, "\u6309\u9700\u6C42\u9009\u62E9\u6D41\u7A0B \xB7 \u67E5\u770B\u56DB\u6863\u9636\u6BB5"),
5710
+ (0, import_react3.createElement)("span", { style: label }, "\u6BCF\u4E2A\u4EFB\u52A1\u5355\u72EC\u9009\u62E9\u590D\u6742\u5EA6\u5E76\u51BB\u7ED3\u9636\u6BB5\u548C\u6280\u80FD\uFF1B\u4E0D\u540C\u4F1A\u8BDD\u53EF\u8D70\u4E0D\u540C\u6D41\u7A0B\u3002"),
5606
5711
  (0, import_react3.createElement)("div", { style: grid }, ...(view?.grades ?? []).map((grade) => (0, import_react3.createElement)(
5607
5712
  "div",
5608
5713
  { key: grade.id, style: { ...card, gap: 5 } },
@@ -5616,45 +5721,111 @@ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5616
5721
  { style: card },
5617
5722
  (0, import_react3.createElement)("strong", null, "\u5143\u6280\u80FD\u4E0E\u9879\u76EE\u6280\u80FD"),
5618
5723
  (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"),
5619
- ...Object.entries(META_STAGES).map(([id, stage]) => {
5620
- const meta = id;
5621
- const selected2 = draft.meta_bindings?.[meta] ?? [];
5622
- return (0, import_react3.createElement)(
5724
+ (0, import_react3.createElement)("input", {
5725
+ className: "te-input",
5726
+ type: "search",
5727
+ "aria-label": "\u641C\u7D22\u5143\u6280\u80FD\u6216\u5DF2\u6302\u8F7D\u6280\u80FD",
5728
+ placeholder: "\u641C\u7D22\u9636\u6BB5\u6216\u5DF2\u6302\u8F7D\u7684 Skill",
5729
+ value: metaQuery,
5730
+ onChange: (event) => setMetaQuery(event.target.value)
5731
+ }),
5732
+ (0, import_react3.createElement)(
5733
+ "div",
5734
+ { className: "te-meta-layout" },
5735
+ (0, import_react3.createElement)(
5736
+ "nav",
5737
+ { className: "te-meta-nav", "aria-label": "\u5143\u6280\u80FD\u9636\u6BB5" },
5738
+ ...visibleStages.map(([id, stage]) => (0, import_react3.createElement)(
5739
+ "button",
5740
+ {
5741
+ key: id,
5742
+ type: "button",
5743
+ "aria-current": visibleMeta === id ? "true" : void 0,
5744
+ onClick: () => {
5745
+ setActiveMeta(id);
5746
+ setSkillQuery("");
5747
+ }
5748
+ },
5749
+ stage,
5750
+ (0, import_react3.createElement)("small", null, `\u5DF2\u6302\u8F7D ${(draft.meta_bindings?.[id] ?? []).length} \u4E2A Skill`)
5751
+ )),
5752
+ visibleStages.length === 0 ? (0, import_react3.createElement)("span", { style: label }, "\u6CA1\u6709\u5339\u914D\u7684\u9636\u6BB5\u3002") : null
5753
+ ),
5754
+ visibleMeta ? (0, import_react3.createElement)(
5623
5755
  "div",
5624
- { key: id, style: { ...card, gap: 6 } },
5625
- (0, import_react3.createElement)("strong", null, stage),
5626
- (0, import_react3.createElement)("span", { style: label }, `\u6838\u5FC3\uFF1A${id} \xB7 \u751F\u6548\u6765\u6E90\uFF1A${effectiveSource(skills, id)}`),
5627
- (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", onClick: () => openRules(id) }, "\u914D\u7F6E\u6838\u5FC3 Skill \u7684 Rule"),
5756
+ { className: "te-meta-detail" },
5628
5757
  (0, import_react3.createElement)(
5629
5758
  "div",
5630
- { style: row },
5631
- ...selected2.map((name) => (0, import_react3.createElement)("button", {
5632
- key: name,
5633
- type: "button",
5634
- title: "\u79FB\u9664\u6302\u8F7D",
5635
- style: { ...input, minWidth: 0, cursor: "pointer" },
5636
- onClick: () => removeSkill(meta, name)
5637
- }, `${name} \xB7 ${effectiveSource(skills, name)} \xD7`)),
5638
- ...selected2.map((name) => (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, {
5639
- key: `rules-${name}`,
5640
- variant: "outline",
5641
- size: "sm",
5642
- onClick: () => openRules(name)
5643
- }, `\u914D\u7F6E ${name} \u7684 Rule`))
5759
+ null,
5760
+ (0, import_react3.createElement)("strong", null, META_STAGES[visibleMeta]),
5761
+ (0, import_react3.createElement)("div", { style: label }, "\u6838\u5FC3 Skill \u4E0E\u9644\u52A0 Skill \u7684 Rule \u5206\u522B\u4FDD\u5B58\u5728\u5404\u81EA\u7684\u914D\u7F6E\u4E2D\u3002")
5644
5762
  ),
5645
5763
  (0, import_react3.createElement)(
5646
- "select",
5647
- {
5648
- style: input,
5649
- "aria-label": `\u7ED9${stage}\u6302\u8F7D\u9879\u76EE\u6280\u80FD`,
5650
- value: "",
5651
- onChange: (event) => addSkill(meta, event.target.value)
5652
- },
5653
- (0, import_react3.createElement)("option", { value: "" }, "\u6302\u8F7D\u9644\u52A0\u6280\u80FD\u2026"),
5654
- ...candidates.filter((name) => !selected2.includes(name)).map((name) => (0, import_react3.createElement)("option", { key: name, value: name }, `${name} \xB7 ${effectiveSource(skills, name)}`))
5764
+ "div",
5765
+ { className: "te-meta-skill-row" },
5766
+ (0, import_react3.createElement)(
5767
+ "span",
5768
+ null,
5769
+ (0, import_react3.createElement)("strong", null, visibleMeta),
5770
+ (0, import_react3.createElement)("small", { style: { ...label, display: "block" } }, `\u6838\u5FC3 \xB7 ${effectiveSource(skills, visibleMeta)}`)
5771
+ ),
5772
+ (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", onClick: () => openRules(visibleMeta) }, "\u914D\u7F6E Rule")
5773
+ ),
5774
+ (0, import_react3.createElement)("strong", { style: { fontSize: 13 } }, `\u9644\u52A0 Skill \xB7 ${mounted.length}`),
5775
+ ...mounted.map((name) => (0, import_react3.createElement)(
5776
+ "div",
5777
+ { key: name, className: "te-meta-skill-row" },
5778
+ (0, import_react3.createElement)(
5779
+ "span",
5780
+ null,
5781
+ (0, import_react3.createElement)("strong", null, name),
5782
+ (0, import_react3.createElement)("small", { style: { ...label, display: "block" } }, effectiveSource(skills, name))
5783
+ ),
5784
+ (0, import_react3.createElement)(
5785
+ "div",
5786
+ { className: "te-meta-skill-actions" },
5787
+ (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", onClick: () => openRules(name) }, "\u914D\u7F6E Rule"),
5788
+ (0, import_react3.createElement)("button", {
5789
+ type: "button",
5790
+ className: "te-transfer-remove",
5791
+ "aria-label": `\u4ECE${META_STAGES[visibleMeta]}\u79FB\u9664 ${name}`,
5792
+ onClick: () => removeSkill(visibleMeta, name)
5793
+ }, "\xD7")
5794
+ )
5795
+ )),
5796
+ mounted.length === 0 ? (0, import_react3.createElement)("span", { style: label }, "\u5C1A\u672A\u6302\u8F7D\u9644\u52A0 Skill\u3002") : null,
5797
+ (0, import_react3.createElement)(
5798
+ "div",
5799
+ { style: { display: "flex", flexDirection: "column", gap: 7 } },
5800
+ (0, import_react3.createElement)("strong", { style: { fontSize: 13 } }, "\u6302\u8F7D\u9644\u52A0 Skill"),
5801
+ (0, import_react3.createElement)("input", {
5802
+ className: "te-input",
5803
+ type: "search",
5804
+ "aria-label": "\u641C\u7D22\u53EF\u6302\u8F7D\u6280\u80FD",
5805
+ placeholder: "\u641C\u7D22 Skill \u540D\u79F0\u3001\u8BF4\u660E\u6216\u6765\u6E90",
5806
+ value: skillQuery,
5807
+ onChange: (event) => setSkillQuery(event.target.value)
5808
+ }),
5809
+ (0, import_react3.createElement)("span", { style: label }, `\u53EF\u9009 ${matchingCandidates.length} \u4E2A${matchingCandidates.length > 12 ? "\uFF0C\u5148\u663E\u793A\u524D 12 \u4E2A\uFF1B\u53EF\u7EE7\u7EED\u8F93\u5165\u7F29\u5C0F\u8303\u56F4" : ""}`),
5810
+ (0, import_react3.createElement)(
5811
+ "div",
5812
+ { className: "te-meta-candidates" },
5813
+ ...matchingCandidates.slice(0, 12).map((name) => (0, import_react3.createElement)(
5814
+ "div",
5815
+ { key: name, className: "te-meta-candidate" },
5816
+ (0, import_react3.createElement)(
5817
+ "span",
5818
+ null,
5819
+ (0, import_react3.createElement)("strong", null, name),
5820
+ (0, import_react3.createElement)("small", null, effectiveSource(skills, name))
5821
+ ),
5822
+ (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", onClick: () => addSkill(visibleMeta, name) }, "\u6302\u8F7D")
5823
+ )),
5824
+ matchingCandidates.length === 0 ? (0, import_react3.createElement)("span", { style: label }, "\u6CA1\u6709\u5339\u914D\u7684 Skill\u3002") : null
5825
+ )
5655
5826
  )
5656
- );
5657
- })
5827
+ ) : null
5828
+ )
5658
5829
  ),
5659
5830
  (0, import_react3.createElement)(
5660
5831
  "div",
@@ -5674,35 +5845,16 @@ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5674
5845
  "\u542F\u7528\uFF08\u4EC5\u4EE3\u7801\u5BA1\u6838\u9636\u6BB5\uFF09"
5675
5846
  )
5676
5847
  ),
5677
- (0, import_react3.createElement)("span", { style: label }, "\u53EF\u590D\u7528 CI \u626B\u63CF\uFF0C\u6216\u5728\u672C\u673A\u6309\u670D\u52A1\u7AEF\u89C4\u5219\u5BA1\u6838\u65B0\u4EE3\u7801\u3002Token \u6309\u5F53\u524D\u9879\u76EE\u4FDD\u5B58\u5728\u672C\u673A DSH \u51ED\u636E\u5B58\u50A8\uFF0C\u4E0D\u5199\u5165\u4EE3\u7801\u4ED3\u5E93\uFF1B\u4ECD\u517C\u5BB9\u5DF2\u6709\u7684\u73AF\u5883\u53D8\u91CF\u3002"),
5848
+ (0, import_react3.createElement)("span", { style: label }, "\u6D4B\u8BD5\u901A\u8FC7\u540E\uFF0C\u4EE3\u7801\u5BA1\u6838\u5143\u6280\u80FD\u4F1A\u68C0\u67E5\u63D0\u4EA4\u524D\u7684\u65B0\u589E\u4EE3\u7801\u3002\u9996\u6B21\u5BA1\u6838\u81EA\u52A8\u51C6\u5907\u672C\u5730\u5206\u6790\u7EC4\u4EF6\uFF0C\u5E76\u4ECE SonarQube \u540C\u6B65\u5F53\u524D\u9879\u76EE\u7684\u89C4\u5219\u3002Token \u6309\u9879\u76EE\u4FDD\u5B58\u5728\u672C\u673A DSH \u51ED\u636E\u5B58\u50A8\u3002"),
5849
+ sonar.enabled === true && sonar.source && sonar.source !== "ide-local" ? (0, import_react3.createElement)(
5850
+ "span",
5851
+ { style: label },
5852
+ "\u6B64\u9879\u76EE\u4ECD\u662F\u65E7\u5BA1\u6838\u6A21\u5F0F\uFF1B\u4FDD\u5B58\u914D\u7F6E\u540E\uFF0C\u65B0\u4EFB\u52A1\u5C06\u4F7F\u7528\u63D0\u4EA4\u524D\u672C\u5730\u5BA1\u6838\u3002\u5DF2\u6709\u4EFB\u52A1\u6309\u521B\u5EFA\u65F6\u7684\u914D\u7F6E\u7EE7\u7EED\u3002"
5853
+ ) : null,
5678
5854
  sonar.enabled === true ? (0, import_react3.createElement)(
5679
5855
  "div",
5680
5856
  { style: grid },
5681
- (0, import_react3.createElement)(
5682
- "label",
5683
- { style: { display: "flex", flexDirection: "column", gap: 4 } },
5684
- (0, import_react3.createElement)("span", { style: label }, "\u626B\u63CF\u6765\u6E90"),
5685
- (0, import_react3.createElement)(
5686
- "select",
5687
- {
5688
- style: input,
5689
- value: sonar.source ?? "ci",
5690
- onChange: (event) => updateSonar({
5691
- source: event.target.value,
5692
- ...event.target.value !== "ci" ? { mode: "branch" } : {},
5693
- ...event.target.value !== "ide-local" ? { include_paths: [] } : {}
5694
- })
5695
- },
5696
- (0, import_react3.createElement)("option", { value: "ci" }, "CI \u5DF2\u6709\u7ED3\u679C"),
5697
- (0, import_react3.createElement)("option", { value: "ide-local" }, "\u672C\u5730\u89C4\u5219\u5BA1\u6838\uFF08\u65E0\u9700\u63D0\u4EA4\u6216\u63A8\u9001\uFF09"),
5698
- (0, import_react3.createElement)("option", { value: "local" }, "\u672C\u673A\u626B\u63CF\u5E76\u4E0A\u4F20\uFF08\u9700 Developer Edition\uFF09")
5699
- )
5700
- ),
5701
- ...[
5702
- ["host_url", "\u670D\u52A1\u5730\u5740", "https://sonar.example"],
5703
- ["project_key", "\u9879\u76EE Key", "my-project"],
5704
- ["token_env", "Token \u73AF\u5883\u53D8\u91CF\u540D\uFF08\u53EF\u9009\u540E\u5907\uFF09", "SONAR_TOKEN"]
5705
- ].map(([key, title, placeholder]) => (0, import_react3.createElement)(
5857
+ ...[["host_url", "\u670D\u52A1\u5730\u5740", "https://sonar.example"], ["project_key", "\u9879\u76EE Key", "my-project"]].map(([key, title, placeholder]) => (0, import_react3.createElement)(
5706
5858
  "label",
5707
5859
  { key, style: { display: "flex", flexDirection: "column", gap: 4 } },
5708
5860
  (0, import_react3.createElement)("span", { style: label }, title),
@@ -5714,65 +5866,62 @@ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5714
5866
  })
5715
5867
  )),
5716
5868
  (0, import_react3.createElement)(
5717
- "label",
5718
- { style: { display: "flex", flexDirection: "column", gap: 4 } },
5719
- (0, import_react3.createElement)("span", { style: label }, "\u5206\u6790\u5BF9\u8C61"),
5869
+ "details",
5870
+ { style: { gridColumn: "1 / -1" } },
5871
+ (0, import_react3.createElement)("summary", null, "\u9AD8\u7EA7\u8BBE\u7F6E\uFF1A\u65B0\u589E\u4EE3\u7801\u53C2\u8003\u7248\u672C\u4E0E\u5BA1\u6838\u8303\u56F4"),
5720
5872
  (0, import_react3.createElement)(
5721
- "select",
5722
- {
5723
- style: input,
5724
- value: sonar.mode ?? "branch",
5725
- disabled: sonar.source === "local" || sonar.source === "ide-local",
5726
- onChange: (event) => updateSonar({ mode: event.target.value })
5727
- },
5728
- (0, import_react3.createElement)("option", { value: "branch" }, "\u5206\u652F"),
5729
- (0, import_react3.createElement)("option", { value: "pull-request" }, "\u5408\u5E76\u8BF7\u6C42")
5873
+ "div",
5874
+ { style: { ...grid, marginTop: 8 } },
5875
+ (0, import_react3.createElement)(
5876
+ "label",
5877
+ { style: { display: "flex", flexDirection: "column", gap: 4 } },
5878
+ (0, import_react3.createElement)("span", { style: label }, "Git \u53C2\u8003\u7248\u672C\uFF08\u9ED8\u8BA4 HEAD\uFF0C\u5373\u672A\u63D0\u4EA4\u53D8\u66F4\uFF09"),
5879
+ (0, import_react3.createElement)("input", {
5880
+ style: input,
5881
+ value: sonar.reference_branch ?? "HEAD",
5882
+ placeholder: "HEAD",
5883
+ onChange: (event) => updateSonar({ reference_branch: event.target.value })
5884
+ })
5885
+ ),
5886
+ (0, import_react3.createElement)(
5887
+ "label",
5888
+ { style: { display: "flex", flexDirection: "column", gap: 4 } },
5889
+ (0, import_react3.createElement)("span", { style: label }, "\u5BA1\u6838\u8DEF\u5F84\uFF08\u6BCF\u884C\u4E00\u4E2A\uFF1B\u7559\u7A7A\u4E3A\u672C\u6B21\u4EFB\u52A1\u7684\u5168\u90E8\u4EE3\u7801\uFF09"),
5890
+ (0, import_react3.createElement)("textarea", {
5891
+ style: { ...input, minHeight: 76 },
5892
+ value: (sonar.include_paths ?? []).join("\n"),
5893
+ onChange: (event) => updateSonar({
5894
+ include_paths: event.target.value.split(/\r?\n|,/u).map((path) => path.trim()).filter(Boolean)
5895
+ })
5896
+ })
5897
+ )
5730
5898
  )
5731
5899
  ),
5732
- sonar.source === "local" || sonar.source === "ide-local" ? (0, import_react3.createElement)(
5733
- "label",
5734
- { style: { display: "flex", flexDirection: "column", gap: 4 } },
5735
- (0, import_react3.createElement)("span", { style: label }, sonar.source === "local" ? "\u65B0\u4EE3\u7801\u53C2\u8003\u5206\u652F\uFF08\u987B\u5DF2\u6709 Sonar \u5206\u6790\uFF09" : "\u65B0\u4EE3\u7801\u53C2\u8003\u5206\u652F\uFF08\u672C\u673A Git \u5206\u652F\uFF09"),
5736
- (0, import_react3.createElement)("input", {
5737
- style: input,
5738
- value: sonar.reference_branch ?? "",
5739
- placeholder: "\u4F8B\u5982 qdm_sit",
5740
- onChange: (event) => updateSonar({ reference_branch: event.target.value })
5741
- })
5742
- ) : null,
5743
- sonar.source === "local" ? (0, import_react3.createElement)(
5744
- "label",
5745
- { style: { display: "flex", flexDirection: "column", gap: 4 } },
5746
- (0, import_react3.createElement)("span", { style: label }, "\u672C\u673A\u626B\u63CF\u547D\u4EE4\uFF08\u53EF\u9009\uFF1B\u4E0D\u586B\u5219\u81EA\u52A8\u9009\u62E9 Maven / sonar-scanner\uFF09"),
5747
- (0, import_react3.createElement)("input", {
5748
- style: input,
5749
- value: sonar.scan_command ?? "",
5750
- placeholder: "mvn org.sonarsource.scanner.maven:sonar-maven-plugin:5.5.0.6356:sonar",
5751
- onChange: (event) => updateSonar({ scan_command: event.target.value })
5752
- })
5753
- ) : null,
5754
- sonar.source === "local" ? (0, import_react3.createElement)(
5755
- "span",
5756
- { style: label },
5757
- "\u672C\u673A\u5206\u652F\u626B\u63CF\u9700\u8981 SonarQube Developer Edition \u6216\u66F4\u9AD8\u7248\u672C\u3001\u5DF2\u6709\u5206\u6790\u7684\u53C2\u8003\u5206\u652F\u53CA\u672C\u673A\u626B\u63CF\u5668/JDK\uFF1BCommunity Build \u4F1A\u5728\u4E0A\u4F20\u524D\u62D2\u7EDD\u3002"
5758
- ) : null,
5759
- sonar.source === "ide-local" ? (0, import_react3.createElement)(
5760
- "label",
5761
- { style: { display: "flex", flexDirection: "column", gap: 4 } },
5762
- (0, import_react3.createElement)("span", { style: label }, "\u672C\u5730\u5BA1\u6838\u8303\u56F4\uFF08\u6BCF\u884C\u4E00\u4E2A\u9879\u76EE\u76F8\u5BF9\u76EE\u5F55\u6216\u6587\u4EF6\uFF1B\u7559\u7A7A\u4E3A\u4EFB\u52A1\u5168\u90E8\u4EE3\u7801\uFF09"),
5763
- (0, import_react3.createElement)("textarea", {
5764
- style: { ...input, minHeight: 76 },
5765
- value: (sonar.include_paths ?? []).join("\n"),
5766
- placeholder: "\u4F8B\u5982 fp-bussiness\nfp-ruoyi\nfp-ruoyi-spring-boot\npom.xml",
5767
- onChange: (event) => updateSonar({
5768
- include_paths: event.target.value.split(/\r?\n|,/u).map((path) => path.trim()).filter(Boolean)
5769
- })
5770
- })
5771
- ) : null,
5772
- sonar.source === "ide-local" ? (0, import_react3.createElement)(
5900
+ (0, import_react3.createElement)(
5773
5901
  "span",
5774
- { style: label },
5775
- "\u672C\u5730\u89C4\u5219\u5BA1\u6838\u4ECE SonarQube \u540C\u6B65\u9879\u76EE\u89C4\u5219\uFF0C\u6309\u4E0A\u65B9\u8303\u56F4\u7B5B\u9009\u4EFB\u52A1\u65B0\u589E\u4EE3\u7801\uFF0C\u4E0D\u4E0A\u4F20\u7ED3\u679C\u3002\u626B\u63CF\u8303\u56F4\u7531 CI \u6784\u5EFA\u4E0E\u9879\u76EE\u914D\u7F6E\u51B3\u5B9A\uFF0CQuality Profile \u672C\u8EAB\u4E0D\u51B3\u5B9A\u626B\u63CF\u54EA\u4E9B\u76EE\u5F55\u3002\u5176\u4ED6\u8BED\u8A00\u4EC5\u5728\u8BE5\u9879\u76EE\u5B58\u5728\u751F\u6548\u89C4\u5219\u800C\u672C\u5730\u65E0\u6CD5\u5206\u6790\u65F6\u5217\u4E3A\u672A\u8986\u76D6\u3002\u9700\u5B89\u88C5 SonarLint \u540E\u53F0\u7EC4\u4EF6\u5E76\u914D\u7F6E DSH_SONARLINT_JAVA\u3001DSH_SONARLINT_LIB\u3001DSH_SONARLINT_PLUGINS\u3002"
5902
+ { style: { ...label, gridColumn: "1 / -1" } },
5903
+ "\u65E0\u9700\u5B89\u88C5 IDEA\u3001Maven \u6216 SonarScanner\u3002\u9996\u6B21\u5BA1\u6838\u4F1A\u4E0B\u8F7D\u5B98\u65B9\u672C\u5730\u5206\u6790\u540E\u53F0\uFF1B\u8BED\u8A00\u5206\u6790\u5668\u7531\u540E\u53F0\u4ECE SonarQube \u540C\u6B65\u3002\u90E8\u5206\u670D\u52A1\u7AEF\u89C4\u5219\u65E0\u6CD5\u5728\u672C\u5730\u6267\u884C\uFF0C\u672C\u5730\u901A\u8FC7\u4E0D\u7B49\u4E8E\u670D\u52A1\u7AEF\u8D28\u91CF\u95E8\u7981\u901A\u8FC7\u3002"
5904
+ ),
5905
+ (0, import_react3.createElement)(
5906
+ "div",
5907
+ { style: { ...row, gridColumn: "1 / -1" } },
5908
+ (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, {
5909
+ variant: "outline",
5910
+ size: "sm",
5911
+ disabled: analyzerBusy || saving || dirty,
5912
+ onClick: prepareAnalyzer
5913
+ }, analyzerBusy ? "\u5B89\u88C5\u4E0E\u68C0\u67E5\u4E2D\u2026" : "\u5B89\u88C5\u6216\u68C0\u67E5\u672C\u5730\u5206\u6790\u5668"),
5914
+ (0, import_react3.createElement)("span", { style: label }, "\u5148\u4FDD\u5B58\u670D\u52A1\u5730\u5740\u3001\u9879\u76EE Key \u548C Token\uFF1B\u68C0\u67E5\u4E0D\u4F1A\u5BA1\u6838\u6216\u4E0A\u4F20\u9879\u76EE\u4EE3\u7801\u3002")
5915
+ ),
5916
+ analyzerProfiles ? (0, import_react3.createElement)(
5917
+ "div",
5918
+ { style: { ...label, gridColumn: "1 / -1" } },
5919
+ analyzerProfiles.length ? analyzerProfiles.map((profile) => (0, import_react3.createElement)(
5920
+ "div",
5921
+ { key: profile.language },
5922
+ `${profile.language}\uFF1A\u670D\u52A1\u7AEF ${profile.active_rules} \u6761\u89C4\u5219\uFF1B\u672C\u5730\u5206\u6790\u5668 ${profile.analyzer}`
5923
+ )) : "\u9879\u76EE\u6CA1\u6709\u8FD4\u56DE\u5DF2\u542F\u7528\u89C4\u5219\u7684\u8BED\u8A00\u3002",
5924
+ (0, import_react3.createElement)("div", null, "\u5DF2\u540C\u6B65\u8868\u793A\u8BE5\u8BED\u8A00\u5206\u6790\u5668\u53EF\u7528\uFF0C\u4E0D\u4EE3\u8868\u670D\u52A1\u7AEF\u5168\u90E8\u89C4\u5219\u90FD\u80FD\u5728\u672C\u5730\u6267\u884C\u3002")
5776
5925
  ) : null,
5777
5926
  (0, import_react3.createElement)(
5778
5927
  "div",
@@ -5807,16 +5956,16 @@ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5807
5956
  ),
5808
5957
  (0, import_react3.createElement)(
5809
5958
  "div",
5810
- { style: row },
5959
+ { className: "te-adaptive-savebar" },
5811
5960
  (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", disabled: loading || saving, onClick: refresh }, "\u5237\u65B0"),
5812
5961
  (0, import_react3.createElement)(
5813
5962
  import_dsh_client_ui_primitives2.Button,
5814
5963
  { variant: "primary", size: "sm", disabled: loading || saving || !dirty, onClick: save },
5815
5964
  saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u81EA\u9002\u5E94\u914D\u7F6E"
5816
5965
  ),
5817
- (0, import_react3.createElement)("span", { style: label }, "\u9879\u76EE Skill / Rule \u521D\u59CB\u5316\u5165\u53E3\u4F4D\u4E8E\u201C\u9879\u76EE\u521D\u59CB\u5316\u201D\u9875\u3002")
5966
+ (0, import_react3.createElement)("span", { style: label }, dirty ? "\u6709\u672A\u4FDD\u5B58\u7684\u9879\u76EE\u914D\u7F6E" : "\u9879\u76EE\u914D\u7F6E\u5DF2\u4FDD\u5B58"),
5967
+ message ? (0, import_react3.createElement)("span", { role: "status", style: { ...label, flexBasis: "100%" } }, message) : null
5818
5968
  ),
5819
- message ? (0, import_react3.createElement)("p", { role: "status", style: styles.status }, message) : null,
5820
5969
  view?.problems.length ? (0, import_react3.createElement)("p", { role: "alert", style: styles.status }, view.problems.join("\uFF1B")) : null,
5821
5970
  selected ? (0, import_react3.createElement)(SkillRuleDialog, {
5822
5971
  key: `${selected.skill.source}:${selected.skill.name}`,
@@ -6833,7 +6982,7 @@ function SkillManager({ workspace, remote }) {
6833
6982
  setMessage(`\u5DF2\u4FDD\u5B58 ${selected.name} \u7684\u89C4\u5219\u914D\u7F6E\u3002`);
6834
6983
  setSelected(null);
6835
6984
  };
6836
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `te-config-layout${selected ? " is-open" : ""}`, children: [
6985
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-config-layout", children: [
6837
6986
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "te-config-main", children: [
6838
6987
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ResourceManager, { workspace, remote, kind: "skill", onConfigureSkill: config ? (ref) => {
6839
6988
  setMessage("");
@@ -6976,6 +7125,17 @@ function sonarAudit(task) {
6976
7125
  (0, import_react8.createElement)("summary", { style: { cursor: "pointer", fontSize: 12 } }, `\u672C\u6B21\u5206\u6790\u6587\u4EF6\uFF08${audit.scanned_files.length}\uFF09`),
6977
7126
  ...audit.scanned_files.map((file) => (0, import_react8.createElement)("div", { key: file, style: metaLine }, file))
6978
7127
  ) : null,
7128
+ audit.profile_coverage?.length ? (0, import_react8.createElement)(
7129
+ "details",
7130
+ null,
7131
+ (0, import_react8.createElement)("summary", { style: { cursor: "pointer", fontSize: 12 } }, "\u9879\u76EE\u89C4\u5219\u4E0E\u672C\u5730\u5206\u6790\u5668"),
7132
+ ...audit.profile_coverage.map((profile) => (0, import_react8.createElement)(
7133
+ "div",
7134
+ { key: profile.language, style: metaLine },
7135
+ `${profile.language}\uFF1A\u670D\u52A1\u7AEF\u542F\u7528 ${profile.active_rules} \u6761\u89C4\u5219\uFF1B\u672C\u5730\u5206\u6790\u5668 ${profile.analyzer}`
7136
+ )),
7137
+ (0, import_react8.createElement)("div", { style: metaLine }, "\u6B64\u5904\u663E\u793A\u8BED\u8A00\u5206\u6790\u5668\u72B6\u6001\uFF0C\u4E0D\u80FD\u8BC1\u660E\u6BCF\u6761\u670D\u52A1\u7AEF\u89C4\u5219\u90FD\u53EF\u5728\u672C\u5730\u6267\u884C\u3002")
7138
+ ) : null,
6979
7139
  ...audit.uncovered_files.map((file) => (0, import_react8.createElement)(
6980
7140
  "div",
6981
7141
  { key: `uncovered-${file}`, style: metaLine },