@godv61/dsh-task-engine 0.29.8 → 0.30.1

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.
Files changed (67) hide show
  1. package/.adaptive-test.mjs +257 -178
  2. package/.evidence-test.mjs +16 -16
  3. package/.resource-test.mjs +19 -19
  4. package/.roundtrip-test.mjs +5 -5
  5. package/.sonar-credential-test.mjs +38 -38
  6. package/.sonarlint-local-test.mjs +67 -61
  7. package/.workflow-test.mjs +51 -21
  8. package/README.md +216 -114
  9. package/docs/development.md +45 -53
  10. package/docs/manual.html +176 -127
  11. package/hooks/commit-msg +18 -0
  12. package/lib/client.js +261 -37
  13. package/lib/client.js.map +2 -2
  14. package/lib/controller.d.ts +42 -0
  15. package/lib/controller.js +234 -1
  16. package/lib/controller.js.map +1 -1
  17. package/lib/dev-task.js +93 -50
  18. package/lib/dev-task.js.map +1 -1
  19. package/lib/engine.d.ts +4 -0
  20. package/lib/engine.js +6 -0
  21. package/lib/engine.js.map +1 -1
  22. package/lib/project-init.d.ts +11 -0
  23. package/lib/project-init.js +32 -1
  24. package/lib/project-init.js.map +1 -1
  25. package/lib/sonar-report.d.ts +1 -1
  26. package/lib/sonar-report.js +13 -0
  27. package/lib/sonar-report.js.map +1 -1
  28. package/lib/sonar.d.ts +12 -0
  29. package/lib/sonar.js +8 -0
  30. package/lib/sonar.js.map +1 -1
  31. package/lib/sonarlint-local.d.ts +2 -0
  32. package/lib/sonarlint-local.js +11 -1
  33. package/lib/sonarlint-local.js.map +1 -1
  34. package/lib/verification-tests.d.ts +10 -0
  35. package/lib/verification-tests.js +15 -0
  36. package/lib/verification-tests.js.map +1 -0
  37. package/package.json +10 -10
  38. package/scripts/verify-package.mjs +3 -1
  39. package/skills/code-review/SKILL.md +3 -1
  40. package/skills/eng-delivery/SKILL.md +5 -4
  41. package/skills/task-orchestration/SKILL.md +1 -1
  42. package/skills/test-validation/SKILL.md +3 -1
  43. package/docs/BRIEF-FOR-REVIEW.md +0 -163
  44. package/docs/CHANGELOG.md +0 -421
  45. package/docs/README.md +0 -42
  46. package/docs/adaptive-workflows.md +0 -88
  47. package/docs/assets/workflow-banner.svg +0 -29
  48. package/docs/configuration.md +0 -80
  49. package/docs/faq.md +0 -65
  50. package/docs/getting-started.md +0 -55
  51. package/docs/listing/godv61__dsh-task-engine.yml +0 -6
  52. package/docs/listing/submission.md +0 -84
  53. package/docs/manual-legacy.html +0 -380
  54. package/docs/releases/0.23.0.md +0 -32
  55. package/docs/releases/0.23.1.md +0 -58
  56. package/docs/releases/0.23.2.md +0 -21
  57. package/docs/resource-install.md +0 -64
  58. package/docs/roadmap.md +0 -33
  59. package/docs/testing/0.23.0//346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225.md +0 -189
  60. package/docs/testing/0.23.0//346/265/213/350/257/225/346/212/245/345/221/212.md +0 -42
  61. package/docs/testing/0.23.1//346/265/213/350/257/225/346/212/245/345/221/212.md +0 -34
  62. package/docs/testing/0.23.1//350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/346/230/216/347/273/206.md +0 -41
  63. package/docs/testing/0.23.2/R02/344/270/232/345/212/241/346/265/213/350/257/225/346/230/216/347/273/206.md +0 -56
  64. package/docs/testing/0.23.2/R03/344/270/232/345/212/241/346/265/213/350/257/225/346/230/216/347/273/206.md +0 -38
  65. package/docs/testing/0.23.2//346/265/213/350/257/225/346/212/245/345/221/212.md +0 -65
  66. package/docs/testing/0.23.2//350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/346/230/216/347/273/206.md +0 -43
  67. package/docs/workflow-regression.md +0 -36
package/lib/client.js CHANGED
@@ -38,7 +38,7 @@ __export(index_exports, {
38
38
  });
39
39
  module.exports = __toCommonJS(index_exports);
40
40
 
41
- // node_modules/zod/v3/external.js
41
+ // ../../dsharness/task-en/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
- // node_modules/zod/v3/helpers/util.js
153
+ // ../../dsharness/task-en/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
- // node_modules/zod/v3/ZodError.js
287
+ // ../../dsharness/task-en/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
- // node_modules/zod/v3/locales/en.js
405
+ // ../../dsharness/task-en/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
- // node_modules/zod/v3/errors.js
508
+ // ../../dsharness/task-en/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
- // node_modules/zod/v3/helpers/parseUtil.js
517
+ // ../../dsharness/task-en/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
- // node_modules/zod/v3/helpers/errorUtil.js
627
+ // ../../dsharness/task-en/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
- // node_modules/zod/v3/types.js
634
+ // ../../dsharness/task-en/node_modules/zod/v3/types.js
635
635
  var ParseInputLazyPath = class {
636
636
  constructor(parent, value, path, key) {
637
637
  this._cachedPath = [];
@@ -4252,10 +4252,19 @@ var taskLedgerViewSchema = external_exports.object({
4252
4252
  source: external_exports.string(),
4253
4253
  audit: external_exports.object({
4254
4254
  gate: external_exports.string(),
4255
+ review_gate: external_exports.string().optional(),
4255
4256
  checked_at: external_exports.string(),
4256
4257
  target: external_exports.string(),
4257
4258
  blocking_count: external_exports.number(),
4259
+ unresolved_count: external_exports.number().optional(),
4258
4260
  uncovered_files: external_exports.array(external_exports.string()),
4261
+ dispositions: external_exports.array(external_exports.object({
4262
+ issue_key: external_exports.string(),
4263
+ kind: external_exports.string(),
4264
+ reason: external_exports.string(),
4265
+ evidence: external_exports.array(external_exports.string()),
4266
+ approved_at: external_exports.string()
4267
+ })).optional(),
4259
4268
  report_path: external_exports.string().optional(),
4260
4269
  scanned_files: external_exports.array(external_exports.string()).optional(),
4261
4270
  findings: external_exports.array(external_exports.object({
@@ -4300,6 +4309,35 @@ var initDraftSchema = external_exports.object({
4300
4309
  lines: external_exports.number(),
4301
4310
  error: external_exports.string().optional()
4302
4311
  });
4312
+ var projectInitResourceSchema = external_exports.object({
4313
+ kind: external_exports.enum(["skill", "rule"]),
4314
+ name: external_exports.string(),
4315
+ description: external_exports.string().optional(),
4316
+ content: external_exports.string(),
4317
+ meta_skills: external_exports.array(external_exports.string()).optional(),
4318
+ rules: external_exports.array(external_exports.string()).optional()
4319
+ });
4320
+ var projectInitInventorySchema = external_exports.object({
4321
+ project_name: external_exports.string(),
4322
+ root_entries: external_exports.array(external_exports.string()),
4323
+ modules: external_exports.array(external_exports.object({ path: external_exports.string(), entries: external_exports.array(external_exports.string()) })),
4324
+ manifests: external_exports.array(external_exports.object({ path: external_exports.string(), facts: external_exports.array(external_exports.string()) })),
4325
+ suggestions: external_exports.array(external_exports.object({ name: external_exports.string(), kind: external_exports.enum(["skill", "rule"]), meta_skills: external_exports.array(external_exports.string()), why: external_exports.string() })),
4326
+ caution: external_exports.string()
4327
+ });
4328
+ var projectInitPreviewRequestSchema = external_exports.object({ path: external_exports.string(), resources: external_exports.array(projectInitResourceSchema) });
4329
+ var projectInitPreviewSchema = external_exports.object({
4330
+ ok: external_exports.boolean(),
4331
+ inventory: projectInitInventorySchema,
4332
+ resources: external_exports.array(projectInitResourceSchema),
4333
+ files_to_create: external_exports.array(external_exports.string()),
4334
+ project_map_coverage: external_exports.array(external_exports.string()),
4335
+ existing_hash: external_exports.string(),
4336
+ expected_hash: external_exports.string(),
4337
+ error: external_exports.string().optional()
4338
+ });
4339
+ var projectInitApplyRequestSchema = projectInitPreviewRequestSchema.extend({ expected_hash: external_exports.string(), existing_hash: external_exports.string() });
4340
+ var projectInitApplyResultSchema = external_exports.object({ ok: external_exports.boolean(), created: external_exports.array(external_exports.string()), error: external_exports.string().optional() });
4303
4341
  var resourceRequestSchema = external_exports.object({
4304
4342
  kind: external_exports.enum(["skill", "rule"]),
4305
4343
  level: external_exports.enum(["project", "user"]),
@@ -4731,6 +4769,48 @@ var TYPERT_REMOTE = {
4731
4769
  }
4732
4770
  ],
4733
4771
  result: { mode: "strict", typeSymbol: `${PACKAGE}/types#InitDraft`, create: () => initDraftSchema, schema: initDraftSchema }
4772
+ },
4773
+ {
4774
+ id: `${PACKAGE}#task-engine/generateProjectInit`,
4775
+ service: "taskEngineController",
4776
+ namespace: "task-engine",
4777
+ method: "generateProjectInit",
4778
+ invocation: { kind: "direct" },
4779
+ parameters: [{
4780
+ name: "request",
4781
+ wire: "request",
4782
+ source: "json",
4783
+ codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#InitGenerateRequest`, create: () => initGenerateRequestSchema, schema: initGenerateRequestSchema }
4784
+ }],
4785
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#ProjectInitPreview`, create: () => projectInitPreviewSchema, schema: projectInitPreviewSchema }
4786
+ },
4787
+ {
4788
+ id: `${PACKAGE}#task-engine/previewProjectInit`,
4789
+ service: "taskEngineController",
4790
+ namespace: "task-engine",
4791
+ method: "previewProjectInit",
4792
+ invocation: { kind: "direct" },
4793
+ parameters: [{
4794
+ name: "request",
4795
+ wire: "request",
4796
+ source: "json",
4797
+ codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#ProjectInitPreviewRequest`, create: () => projectInitPreviewRequestSchema, schema: projectInitPreviewRequestSchema }
4798
+ }],
4799
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#ProjectInitPreview`, create: () => projectInitPreviewSchema, schema: projectInitPreviewSchema }
4800
+ },
4801
+ {
4802
+ id: `${PACKAGE}#task-engine/applyProjectInit`,
4803
+ service: "taskEngineController",
4804
+ namespace: "task-engine",
4805
+ method: "applyProjectInit",
4806
+ invocation: { kind: "direct" },
4807
+ parameters: [{
4808
+ name: "request",
4809
+ wire: "request",
4810
+ source: "json",
4811
+ codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#ProjectInitApplyRequest`, create: () => projectInitApplyRequestSchema, schema: projectInitApplyRequestSchema }
4812
+ }],
4813
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#ProjectInitApplyResult`, create: () => projectInitApplyResultSchema, schema: projectInitApplyResultSchema }
4734
4814
  }
4735
4815
  ]
4736
4816
  };
@@ -5764,7 +5844,6 @@ var card2 = {
5764
5844
  borderRadius: 8,
5765
5845
  padding: "12px 14px"
5766
5846
  };
5767
- var projectInitPrompt = (workspace) => `\u8BF7\u5728\u5F53\u524D\u9879\u76EE\u6839\u5DE5\u4F5C\u533A ${workspace} \u4F7F\u7528\u5DE5\u7A0B\u5316\u5F00\u53D1\u5F15\u64CE\u521D\u59CB\u5316\u9879\u76EE Skill \u548C Rule\u3002\u5148\u8C03\u7528 dev_task init_project\uFF08phase=inspect\uFF09\uFF0C\u7ED3\u5408\u4EE3\u8868\u6027\u6E90\u7801\u3001\u6784\u5EFA\u6587\u4EF6\u3001\u6D4B\u8BD5\u548C\u5DF2\u6709\u89C4\u8303\u6838\u5B9E\u626B\u63CF\u7ED3\u679C\u3002\u6309\u9879\u76EE\u5B9E\u9645\u60C5\u51B5\u62DF\u5B9A\u9879\u76EE\u7ED3\u6784\u5730\u56FE\u3001\u6280\u672F\u6808\u3001\u7F16\u7801\u65B9\u6CD5\u7B49 Skill \u548C\u5FC5\u8981\u7684 Rule\uFF0C\u5E76\u6807\u660E\u9002\u7528\u7684\u5143\u6280\u80FD\u3002\u9879\u76EE\u5730\u56FE\u5FC5\u987B\u603B\u7ED3\u6574\u4E2A\u4ED3\u5E93\u7684\u6A21\u5757\u804C\u8D23\u3001\u4F9D\u8D56\u548C\u901A\u7528\u4EE3\u7801\u5165\u53E3\uFF0C\u80FD\u591F\u4F9B\u4E0D\u540C\u9700\u6C42\u590D\u7528\uFF1B\u4E0D\u8981\u628A\u5F53\u524D\u4F1A\u8BDD\u7684\u9700\u6C42\u3001\u4E13\u5C5E\u8C03\u7528\u94FE\u6216\u5B9E\u73B0\u65B9\u6848\u5199\u6210\u9879\u76EE\u5730\u56FE\uFF0C\u76F8\u5173\u5185\u5BB9\u5E94\u8FDB\u5165\u8BE5\u4EFB\u52A1\u4EA7\u7269\u6216\u5355\u72EC\u7684\u9886\u57DF Skill\u3002\u8C03\u7528 phase=propose \u5C55\u793A\u62DF\u521B\u5EFA\u7684\u6587\u4EF6\u3001\u5185\u5BB9\u548C\u6302\u8F7D\u5173\u7CFB\uFF1B\u7B49\u6211\u5BA1\u9605\u786E\u8BA4\u540E\u518D\u8C03\u7528 phase=apply\u3002\u4E0D\u8981\u8986\u76D6\u540C\u540D\u8D44\u6E90\uFF0C\u4E5F\u4E0D\u8981\u628A\u5076\u53D1\u4EE3\u7801\u5199\u6CD5\u5F53\u6210\u56E2\u961F\u89C4\u8303\u3002`;
5768
5847
  function InitPanel({ workspace, remote }) {
5769
5848
  const [view, setView] = (0, import_react4.useState)(null);
5770
5849
  const [generating, setGenerating] = (0, import_react4.useState)(false);
@@ -5774,8 +5853,11 @@ function InitPanel({ workspace, remote }) {
5774
5853
  const [body2, setBody] = (0, import_react4.useState)("");
5775
5854
  const [msg, setMsg] = (0, import_react4.useState)("");
5776
5855
  const [projectInitMsg, setProjectInitMsg] = (0, import_react4.useState)("");
5856
+ const [projectBusy, setProjectBusy] = (0, import_react4.useState)(false);
5857
+ const [projectDraft, setProjectDraft] = (0, import_react4.useState)(null);
5858
+ const [projectResources, setProjectResources] = (0, import_react4.useState)([]);
5777
5859
  (0, import_react4.useEffect)(() => {
5778
- if (!generating) {
5860
+ if (!generating && !projectBusy) {
5779
5861
  setElapsed(0);
5780
5862
  return;
5781
5863
  }
@@ -5787,7 +5869,73 @@ function InitPanel({ workspace, remote }) {
5787
5869
  return () => {
5788
5870
  clearInterval(timer);
5789
5871
  };
5790
- }, [generating]);
5872
+ }, [generating, projectBusy]);
5873
+ (0, import_react4.useEffect)(() => {
5874
+ setProjectDraft(null);
5875
+ setProjectResources([]);
5876
+ setProjectInitMsg("");
5877
+ }, [workspace]);
5878
+ const generateProject = async () => {
5879
+ setProjectBusy(true);
5880
+ setProjectDraft(null);
5881
+ setProjectResources([]);
5882
+ setProjectInitMsg("");
5883
+ try {
5884
+ const result = await remote.generateProjectInit({ path: workspace });
5885
+ if (!result.ok) throw new Error(describeError(result.error));
5886
+ if (!result.value.ok) throw new Error(result.value.error ?? "\u9879\u76EE\u521D\u59CB\u5316\u63D0\u6848\u65E0\u6548");
5887
+ setProjectDraft(result.value);
5888
+ setProjectResources(result.value.resources);
5889
+ setProjectInitMsg("\u63D0\u6848\u5DF2\u751F\u6210\u5E76\u6821\u9A8C\u3002\u8BF7\u9010\u9879\u5BA1\u9605\u5185\u5BB9\u4E0E\u6302\u8F7D\u5173\u7CFB\uFF0C\u786E\u8BA4\u540E\u518D\u5199\u5165\u3002");
5890
+ } catch (error) {
5891
+ setProjectInitMsg(`\u751F\u6210\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}`);
5892
+ } finally {
5893
+ setProjectBusy(false);
5894
+ }
5895
+ };
5896
+ const updateProjectResource = (index, change) => {
5897
+ setProjectResources((current) => current.map((resource, at) => at === index ? { ...resource, ...change } : resource));
5898
+ setProjectDraft(null);
5899
+ setProjectInitMsg("\u63D0\u6848\u5DF2\u4FEE\u6539\u3002\u8BF7\u5148\u70B9\u51FB\u201C\u68C0\u67E5\u4FEE\u6539\u201D\uFF0C\u901A\u8FC7\u540E\u624D\u80FD\u5199\u5165\u3002");
5900
+ };
5901
+ const checkProject = async () => {
5902
+ setProjectBusy(true);
5903
+ setProjectInitMsg("");
5904
+ try {
5905
+ const result = await remote.previewProjectInit({ path: workspace, resources: projectResources });
5906
+ if (!result.ok) throw new Error(describeError(result.error));
5907
+ if (!result.value.ok) throw new Error(result.value.error ?? "\u63D0\u6848\u6821\u9A8C\u5931\u8D25");
5908
+ setProjectDraft(result.value);
5909
+ setProjectInitMsg("\u63D0\u6848\u68C0\u67E5\u901A\u8FC7\uFF0C\u53EF\u4EE5\u786E\u8BA4\u5199\u5165\u3002");
5910
+ } catch (error) {
5911
+ setProjectDraft(null);
5912
+ setProjectInitMsg(`\u68C0\u67E5\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}`);
5913
+ } finally {
5914
+ setProjectBusy(false);
5915
+ }
5916
+ };
5917
+ const applyProject = async () => {
5918
+ if (projectDraft === null || !window.confirm(`\u786E\u8BA4\u5728 ${workspace} \u521B\u5EFA ${projectDraft.files_to_create.length} \u4E2A Skill / Rule \u6587\u4EF6\u5E76\u66F4\u65B0 .dsh/meta.json\uFF1F`)) return;
5919
+ setProjectBusy(true);
5920
+ setProjectInitMsg("");
5921
+ try {
5922
+ const result = await remote.applyProjectInit({
5923
+ path: workspace,
5924
+ resources: projectDraft.resources,
5925
+ expected_hash: projectDraft.expected_hash,
5926
+ existing_hash: projectDraft.existing_hash
5927
+ });
5928
+ if (!result.ok) throw new Error(describeError(result.error));
5929
+ if (!result.value.ok) throw new Error(result.value.error ?? "\u5199\u5165\u5931\u8D25");
5930
+ setProjectInitMsg(`\u5DF2\u521B\u5EFA ${result.value.created.length} \u4E2A\u9879\u76EE\u914D\u7F6E\u6587\u4EF6\uFF1A${result.value.created.join("\u3001")}`);
5931
+ setProjectDraft(null);
5932
+ setProjectResources([]);
5933
+ } catch (error) {
5934
+ setProjectInitMsg(`\u5199\u5165\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}\u3002\u82E5\u5DF2\u6709\u90E8\u5206\u6587\u4EF6\uFF0C\u8BF7\u5237\u65B0\u5E76\u68C0\u67E5\u3002`);
5935
+ } finally {
5936
+ setProjectBusy(false);
5937
+ }
5938
+ };
5791
5939
  const refresh = (0, import_react4.useCallback)(() => {
5792
5940
  void remote.readInit(workspace).then((r) => {
5793
5941
  if (r.ok) setView(r.value);
@@ -5847,39 +5995,108 @@ function InitPanel({ workspace, remote }) {
5847
5995
  (0, import_react4.createElement)(
5848
5996
  "p",
5849
5997
  { style: styles.muted },
5850
- "\u626B\u63CF\u53EA\u8FD4\u56DE\u9879\u76EE\u8BC1\u636E\u4E0E\u5EFA\u8BAE\u540D\u79F0\uFF1B\u4F1A\u8BDD\u6A21\u578B\u636E\u6B64\u62DF\u5B9A\u8986\u76D6\u6574\u4E2A\u4ED3\u5E93\u7684\u9879\u76EE\u5730\u56FE\u3001\u6280\u672F\u6808\u3001\u7F16\u7801 Skill \u548C Rule\u3002\u5F53\u524D\u9700\u6C42\u7684\u4E13\u5C5E\u4FE1\u606F\u5E94\u5199\u5165\u4EFB\u52A1\u4EA7\u7269\u3002\u5148\u9884\u89C8\u751F\u6210\u5185\u5BB9\uFF0C\u786E\u8BA4\u540E\u624D\u5199\u5165\u9879\u76EE\uFF1B\u5DF2\u6709\u540C\u540D\u8D44\u6E90\u4E0D\u4F1A\u88AB\u8986\u76D6\u3002"
5998
+ "\u5728\u6B64\u626B\u63CF\u4ED3\u5E93\u5E76\u751F\u6210\u9879\u76EE Skill / Rule \u63D0\u6848\u3002\u9879\u76EE\u5730\u56FE\u8986\u76D6\u6574\u4E2A\u4ED3\u5E93\uFF0C\u5F53\u524D\u9700\u6C42\u7684\u4E13\u5C5E\u4FE1\u606F\u5E94\u5199\u5165\u4EFB\u52A1\u4EA7\u7269\u3002\u9010\u9879\u5BA1\u9605\u540E\u786E\u8BA4\u5199\u5165\uFF1B\u5DF2\u6709\u540C\u540D\u8D44\u6E90\u4E0D\u4F1A\u88AB\u8986\u76D6\u3002"
5851
5999
  ),
5852
6000
  (0, import_react4.createElement)(
5853
6001
  "p",
5854
6002
  { style: styles.muted },
5855
6003
  "\u56E2\u961F\u5171\u4EAB\u65F6\uFF0C\u8BF7\u5C06\u751F\u6210\u7684 .dsh/skills\u3001.dsh/rules \u548C .dsh/meta.json \u7EB3\u5165 Git\uFF1B\u5BA1\u6838\u62A5\u544A\u53EF\u4FDD\u7559\u5728\u672C\u5730\u3002"
5856
6004
  ),
5857
- (0, import_react4.createElement)(
5858
- "p",
5859
- { style: styles.muted },
5860
- "\u4F7F\u7528\u65B9\u6CD5\uFF1A\u5173\u95ED\u6B64\u9762\u677F\uFF0C\u5728\u5F53\u524D\u9879\u76EE\u6839\u5DE5\u4F5C\u533A\u9009\u62E9\u201C\u5DE5\u7A0B\u5316\u5F00\u53D1\u5F15\u64CE\u201D\uFF0C\u628A\u4E0B\u9762\u7684\u8BF7\u6C42\u53D1\u7ED9\u65B0\u4F1A\u8BDD\u3002"
5861
- ),
5862
- (0, import_react4.createElement)("textarea", {
5863
- style: { ...styles.textarea, minHeight: 100 },
5864
- readOnly: true,
5865
- "aria-label": "\u9879\u76EE Skill \u548C Rule \u521D\u59CB\u5316\u8BF7\u6C42",
5866
- value: projectInitPrompt(workspace)
5867
- }),
5868
6005
  (0, import_react4.createElement)(
5869
6006
  "div",
5870
6007
  { style: styles.row },
5871
- (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "primary", size: "md", onClick: () => {
5872
- if (!navigator.clipboard?.writeText) {
5873
- setProjectInitMsg("\u5F53\u524D\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u4E00\u952E\u590D\u5236\u3002\u8BF7\u76F4\u63A5\u9009\u4E2D\u4E0A\u65B9\u8BF7\u6C42\u6587\u672C\u5E76\u590D\u5236\u3002");
5874
- return;
6008
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
6009
+ variant: "primary",
6010
+ size: "md",
6011
+ disabled: projectBusy,
6012
+ onClick: () => {
6013
+ void generateProject();
5875
6014
  }
5876
- void navigator.clipboard.writeText(projectInitPrompt(workspace)).then(
5877
- () => setProjectInitMsg("\u5DF2\u590D\u5236\u521D\u59CB\u5316\u8BF7\u6C42\u3002\u8BF7\u5728\u5DE5\u7A0B\u5316\u5F00\u53D1\u5F15\u64CE\u4F1A\u8BDD\u4E2D\u7C98\u8D34\u53D1\u9001\u3002"),
5878
- () => setProjectInitMsg("\u590D\u5236\u5931\u8D25\u3002\u8BF7\u76F4\u63A5\u9009\u4E2D\u4E0A\u65B9\u8BF7\u6C42\u6587\u672C\u5E76\u590D\u5236\u3002")
5879
- );
5880
- } }, "\u590D\u5236\u521D\u59CB\u5316\u8BF7\u6C42"),
5881
- projectInitMsg ? (0, import_react4.createElement)("span", { role: "status", style: styles.status }, projectInitMsg) : null
5882
- )
6015
+ }, projectBusy ? "\u626B\u63CF\u4E0E\u751F\u6210\u4E2D\u2026" : "\u626B\u63CF\u5E76\u751F\u6210\u63D0\u6848"),
6016
+ projectBusy ? (0, import_react4.createElement)("span", { style: styles.status }, `\u5DF2\u8017\u65F6 ${elapsed} \u79D2`) : null
6017
+ ),
6018
+ projectResources.length > 0 ? (0, import_react4.createElement)(
6019
+ "div",
6020
+ { style: styles.section },
6021
+ (0, import_react4.createElement)(
6022
+ "p",
6023
+ { style: styles.muted },
6024
+ `\u9879\u76EE\uFF1A${workspace}\u3002\u63D0\u6848\u5305\u542B ${projectResources.length} \u4E2A Skill / Rule\uFF1B\u9879\u76EE\u5730\u56FE\u9700\u8986\u76D6\uFF1A${projectDraft?.project_map_coverage.join("\u3001") ?? "\u68C0\u67E5\u4FEE\u6539\u540E\u663E\u793A"}\u3002`
6025
+ ),
6026
+ ...projectResources.map((resource, index) => (0, import_react4.createElement)(
6027
+ "div",
6028
+ { key: `${resource.kind}-${resource.name}`, style: card2 },
6029
+ (0, import_react4.createElement)(
6030
+ "div",
6031
+ { style: styles.row },
6032
+ (0, import_react4.createElement)("strong", null, `${resource.kind === "skill" ? "Skill" : "Rule"} \xB7 ${resource.name}`),
6033
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
6034
+ variant: "ghost",
6035
+ size: "sm",
6036
+ disabled: projectBusy,
6037
+ onClick: () => {
6038
+ setProjectResources((current) => current.filter((_, at) => at !== index));
6039
+ setProjectDraft(null);
6040
+ setProjectInitMsg("\u5DF2\u79FB\u9664\u5EFA\u8BAE\u3002\u8BF7\u91CD\u65B0\u68C0\u67E5\u63D0\u6848\u3002");
6041
+ }
6042
+ }, "\u79FB\u9664\u5EFA\u8BAE")
6043
+ ),
6044
+ resource.kind === "skill" ? (0, import_react4.createElement)(
6045
+ "div",
6046
+ { style: styles.section },
6047
+ (0, import_react4.createElement)("label", null, "\u7B80\u4ECB", (0, import_react4.createElement)("input", {
6048
+ style: styles.input,
6049
+ value: resource.description ?? "",
6050
+ onChange: (event) => {
6051
+ updateProjectResource(index, { description: event.target.value });
6052
+ }
6053
+ })),
6054
+ (0, import_react4.createElement)("label", null, "\u6302\u8F7D\u5143\u6280\u80FD\uFF08\u9017\u53F7\u5206\u9694\uFF09", (0, import_react4.createElement)("input", {
6055
+ style: styles.input,
6056
+ value: (resource.meta_skills ?? []).join(", "),
6057
+ onChange: (event) => {
6058
+ updateProjectResource(index, { meta_skills: event.target.value.split(",").map((item) => item.trim()).filter(Boolean) });
6059
+ }
6060
+ })),
6061
+ (0, import_react4.createElement)("label", null, "\u5173\u8054 Rule\uFF08\u9017\u53F7\u5206\u9694\uFF09", (0, import_react4.createElement)("input", {
6062
+ style: styles.input,
6063
+ value: (resource.rules ?? []).join(", "),
6064
+ onChange: (event) => {
6065
+ updateProjectResource(index, { rules: event.target.value.split(",").map((item) => item.trim()).filter(Boolean) });
6066
+ }
6067
+ }))
6068
+ ) : null,
6069
+ (0, import_react4.createElement)("label", null, "\u5185\u5BB9", (0, import_react4.createElement)("textarea", {
6070
+ style: { ...styles.textarea, minHeight: 180 },
6071
+ value: resource.content,
6072
+ onChange: (event) => {
6073
+ updateProjectResource(index, { content: event.target.value });
6074
+ }
6075
+ }))
6076
+ )),
6077
+ (0, import_react4.createElement)(
6078
+ "div",
6079
+ { style: styles.row },
6080
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
6081
+ variant: "outline",
6082
+ size: "md",
6083
+ disabled: projectBusy,
6084
+ onClick: () => {
6085
+ void checkProject();
6086
+ }
6087
+ }, "\u68C0\u67E5\u4FEE\u6539"),
6088
+ (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, {
6089
+ variant: "primary",
6090
+ size: "md",
6091
+ disabled: projectBusy || projectDraft === null,
6092
+ onClick: () => {
6093
+ void applyProject();
6094
+ }
6095
+ }, "\u786E\u8BA4\u5199\u5165\u9879\u76EE")
6096
+ ),
6097
+ projectDraft !== null ? (0, import_react4.createElement)("p", { style: styles.muted }, `\u5C06\u521B\u5EFA\uFF1A${projectDraft.files_to_create.join("\u3001")}\uFF0C\u5E76\u66F4\u65B0 .dsh/meta.json`) : null
6098
+ ) : null,
6099
+ projectInitMsg ? (0, import_react4.createElement)("p", { role: "status", style: styles.status }, projectInitMsg) : null
5883
6100
  ),
5884
6101
  (0, import_react4.createElement)(
5885
6102
  "div",
@@ -6736,19 +6953,21 @@ function sonarAudit(task) {
6736
6953
  const audit = task.sonar.audit;
6737
6954
  if (!audit) return (0, import_react8.createElement)("div", { style: metaLine }, "SonarQube \u5DF2\u542F\u7528\uFF0C\u5C1A\u672A\u8FD0\u884C\u4EE3\u7801\u5BA1\u6838\u3002");
6738
6955
  const source = { "ide-local": "\u672C\u5730\u89C4\u5219\u5BA1\u6838", local: "\u672C\u673A\u4E0A\u4F20\u626B\u63CF", ci: "CI \u626B\u63CF" }[task.sonar.source] ?? task.sonar.source;
6739
- const outcome = audit.gate === "OK" ? "\u901A\u8FC7" : "\u672A\u901A\u8FC7";
6956
+ const reviewGate = audit.review_gate ?? audit.gate;
6957
+ const outcome = reviewGate === "OK" ? "\u901A\u8FC7" : "\u672A\u901A\u8FC7";
6958
+ const unresolved = audit.unresolved_count ?? audit.blocking_count;
6740
6959
  return (0, import_react8.createElement)(
6741
6960
  "details",
6742
6961
  { style: { borderTop: "1px solid var(--dsw-alias-border-l2)", paddingTop: 8 } },
6743
6962
  (0, import_react8.createElement)(
6744
6963
  "summary",
6745
6964
  { style: { cursor: "pointer", fontSize: 13 } },
6746
- `\u6700\u8FD1\u4E00\u6B21 SonarQube \u5BA1\u6838\uFF1A${outcome} \xB7 \u963B\u65AD ${audit.blocking_count} \u6761 \xB7 \u5168\u90E8 ${audit.findings.length} \u6761 \xB7 ${timeText(audit.checked_at)}`
6965
+ `\u6700\u8FD1\u4E00\u6B21 SonarQube \u5BA1\u6838\uFF1A${outcome} \xB7 \u672A\u89E3\u51B3 ${unresolved} \u6761 \xB7 \u539F\u59CB\u547D\u4E2D ${audit.blocking_count} \u6761 \xB7 ${timeText(audit.checked_at)}`
6747
6966
  ),
6748
6967
  (0, import_react8.createElement)(
6749
6968
  "p",
6750
6969
  { style: metaLine },
6751
- `\u6765\u6E90\uFF1A${source}\uFF1B\u5206\u6790\u76EE\u6807\uFF1A${audit.target}\u3002\u8FD9\u662F\u8BE5\u6B21\u5BA1\u6838\u8BB0\u5F55\uFF1B\u4EE3\u7801\u6216\u89C4\u5219\u53D8\u66F4\u540E\u9700\u91CD\u65B0\u6D4B\u8BD5\u5E76\u5BA1\u6838\u3002`
6970
+ `\u6765\u6E90\uFF1A${source}\uFF1B\u5206\u6790\u76EE\u6807\uFF1A${audit.target}\uFF1B\u539F\u59CB\u7ED3\u679C\uFF1A${audit.gate}\u3002\u8FD9\u662F\u8BE5\u6B21\u5BA1\u6838\u8BB0\u5F55\uFF1B\u4EE3\u7801\u6216\u89C4\u5219\u53D8\u66F4\u540E\u9700\u91CD\u65B0\u6D4B\u8BD5\u5E76\u5BA1\u6838\u3002`
6752
6971
  ),
6753
6972
  audit.report_path ? (0, import_react8.createElement)("p", { style: metaLine }, `\u5BA1\u6838\u6587\u4EF6\uFF1A${audit.report_path}`) : null,
6754
6973
  audit.scanned_files?.length ? (0, import_react8.createElement)(
@@ -6762,6 +6981,11 @@ function sonarAudit(task) {
6762
6981
  { key: `uncovered-${file}`, style: metaLine },
6763
6982
  `\u672A\u8986\u76D6\uFF1A${file}`
6764
6983
  )),
6984
+ ...(audit.dispositions ?? []).map((entry) => (0, import_react8.createElement)(
6985
+ "div",
6986
+ { key: `disposition-${entry.issue_key}`, style: metaLine },
6987
+ `\u4EBA\u5DE5\u786E\u8BA4\u8BEF\u62A5\uFF1A${entry.issue_key} \xB7 ${entry.reason} \xB7 ${entry.approved_at}`
6988
+ )),
6765
6989
  audit.findings.length === 0 ? (0, import_react8.createElement)("p", { style: metaLine }, "\u6CA1\u6709\u65B0\u589E\u4EE3\u7801\u95EE\u9898\u3002") : (0, import_react8.createElement)(
6766
6990
  "div",
6767
6991
  { style: { display: "flex", flexDirection: "column", gap: 6 } },