@godv61/dsh-task-engine 0.29.2 → 0.29.8

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 (62) hide show
  1. package/.adaptive-test.mjs +302 -149
  2. package/.codex-project-test.mjs +18 -18
  3. package/.evidence-test.mjs +16 -3
  4. package/.hook-test.mjs +19 -19
  5. package/.resource-test.mjs +19 -2
  6. package/.roundtrip-test.mjs +8 -3
  7. package/.sonar-credential-test.mjs +38 -0
  8. package/.sonarlint-local-test.mjs +65 -0
  9. package/.workflow-test.mjs +29 -12
  10. package/README.md +22 -22
  11. package/docs/CHANGELOG.md +33 -14
  12. package/docs/README.md +6 -6
  13. package/docs/adaptive-workflows.md +85 -71
  14. package/docs/configuration.md +4 -4
  15. package/docs/faq.md +21 -11
  16. package/docs/getting-started.md +9 -9
  17. package/docs/manual-legacy.html +1 -1
  18. package/docs/manual.html +124 -116
  19. package/docs/roadmap.md +7 -7
  20. package/hooks/commit-msg +1 -1
  21. package/lib/adaptive.js +1 -1
  22. package/lib/adaptive.js.map +1 -1
  23. package/lib/client.js +337 -20
  24. package/lib/client.js.map +2 -2
  25. package/lib/controller.d.ts +35 -0
  26. package/lib/controller.js +68 -0
  27. package/lib/controller.js.map +1 -1
  28. package/lib/dev-task.d.ts +2 -0
  29. package/lib/dev-task.js +261 -31
  30. package/lib/dev-task.js.map +1 -1
  31. package/lib/engine.d.ts +1 -1
  32. package/lib/hook.js +3 -3
  33. package/lib/hook.js.map +1 -1
  34. package/lib/project-init.d.ts +4 -0
  35. package/lib/project-init.js +21 -2
  36. package/lib/project-init.js.map +1 -1
  37. package/lib/skill-audit.js +9 -1
  38. package/lib/skill-audit.js.map +1 -1
  39. package/lib/sonar-credential.d.ts +17 -0
  40. package/lib/sonar-credential.js +17 -0
  41. package/lib/sonar-credential.js.map +1 -0
  42. package/lib/sonar-report.d.ts +4 -0
  43. package/lib/sonar-report.js +40 -0
  44. package/lib/sonar-report.js.map +1 -0
  45. package/lib/sonar.d.ts +23 -2
  46. package/lib/sonar.js +55 -4
  47. package/lib/sonar.js.map +1 -1
  48. package/lib/sonarlint-local.d.ts +15 -0
  49. package/lib/sonarlint-local.js +307 -0
  50. package/lib/sonarlint-local.js.map +1 -0
  51. package/package.json +9 -7
  52. package/preset/enable.mjs +2 -2
  53. package/preset/persona.md +4 -4
  54. package/scripts/verify-dsh-compat.mjs +14 -14
  55. package/scripts/verify-package.mjs +7 -7
  56. package/skills/architecture-design/SKILL.md +11 -11
  57. package/skills/code-development/SKILL.md +11 -11
  58. package/skills/code-review/SKILL.md +11 -11
  59. package/skills/eng-delivery/SKILL.md +6 -4
  60. package/skills/requirements-analysis/SKILL.md +11 -11
  61. package/skills/task-orchestration/SKILL.md +11 -11
  62. package/skills/test-validation/SKILL.md +11 -11
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 = [];
@@ -4248,6 +4248,26 @@ var taskLedgerViewSchema = external_exports.object({
4248
4248
  updated_at: external_exports.string().optional(),
4249
4249
  verification_passed: external_exports.boolean().optional(),
4250
4250
  review_outcome: external_exports.string().optional(),
4251
+ sonar: external_exports.object({
4252
+ source: external_exports.string(),
4253
+ audit: external_exports.object({
4254
+ gate: external_exports.string(),
4255
+ checked_at: external_exports.string(),
4256
+ target: external_exports.string(),
4257
+ blocking_count: external_exports.number(),
4258
+ uncovered_files: external_exports.array(external_exports.string()),
4259
+ report_path: external_exports.string().optional(),
4260
+ scanned_files: external_exports.array(external_exports.string()).optional(),
4261
+ findings: external_exports.array(external_exports.object({
4262
+ key: external_exports.string(),
4263
+ rule: external_exports.string(),
4264
+ message: external_exports.string(),
4265
+ severity: external_exports.string(),
4266
+ file: external_exports.string(),
4267
+ line: external_exports.number().optional()
4268
+ }))
4269
+ }).optional()
4270
+ }).optional(),
4251
4271
  task_id: external_exports.string(),
4252
4272
  title: external_exports.string(),
4253
4273
  stage: external_exports.string(),
@@ -4298,7 +4318,11 @@ var adaptiveConfigSchema = external_exports.object({
4298
4318
  host_url: external_exports.string().optional(),
4299
4319
  project_key: external_exports.string().optional(),
4300
4320
  mode: external_exports.enum(["branch", "pull-request"]).optional(),
4301
- token_env: external_exports.string().optional()
4321
+ token_env: external_exports.string().optional(),
4322
+ source: external_exports.enum(["ci", "local", "ide-local"]).optional(),
4323
+ reference_branch: external_exports.string().optional(),
4324
+ scan_command: external_exports.string().optional(),
4325
+ include_paths: external_exports.array(external_exports.string()).optional()
4302
4326
  }).optional()
4303
4327
  });
4304
4328
  var adaptiveViewSchema = external_exports.object({
@@ -4310,6 +4334,8 @@ var adaptiveViewSchema = external_exports.object({
4310
4334
  grades: external_exports.array(external_exports.object({ id: external_exports.string(), label: external_exports.string(), guidance: external_exports.string(), stages: external_exports.array(external_exports.string()) }))
4311
4335
  });
4312
4336
  var adaptiveWriteRequestSchema = external_exports.object({ path: external_exports.string(), config: adaptiveConfigSchema, expected_hash: external_exports.string() });
4337
+ var sonarTokenInfoSchema = external_exports.object({ configured: external_exports.boolean(), source: external_exports.string().optional(), writable: external_exports.boolean() });
4338
+ var sonarTokenWriteSchema = external_exports.object({ path: external_exports.string(), token: external_exports.string().min(1) });
4313
4339
  var projectSkillProfileRequestSchema = external_exports.object({ path: external_exports.string(), name: external_exports.string() });
4314
4340
  var projectSkillProfileWriteRequestSchema = projectSkillProfileRequestSchema.extend({
4315
4341
  profile: skillProfileSchema,
@@ -4348,6 +4374,48 @@ var TYPERT_REMOTE = {
4348
4374
  }],
4349
4375
  result: { mode: "strict", typeSymbol: `${PACKAGE}/types#AdaptiveConfigView`, create: () => adaptiveViewSchema, schema: adaptiveViewSchema }
4350
4376
  },
4377
+ {
4378
+ id: `${PACKAGE}#task-engine/describeSonarToken`,
4379
+ service: "taskEngineController",
4380
+ namespace: "task-engine",
4381
+ method: "describeSonarToken",
4382
+ invocation: { kind: "direct" },
4383
+ parameters: [{
4384
+ name: "path",
4385
+ wire: "path",
4386
+ source: "json",
4387
+ codec: { mode: "strict", typeSymbol: "string", create: () => external_exports.string(), schema: external_exports.string() }
4388
+ }],
4389
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#SonarTokenInfo`, create: () => sonarTokenInfoSchema, schema: sonarTokenInfoSchema }
4390
+ },
4391
+ {
4392
+ id: `${PACKAGE}#task-engine/setSonarToken`,
4393
+ service: "taskEngineController",
4394
+ namespace: "task-engine",
4395
+ method: "setSonarToken",
4396
+ invocation: { kind: "direct" },
4397
+ parameters: [{
4398
+ name: "request",
4399
+ wire: "request",
4400
+ source: "json",
4401
+ codec: { mode: "strict", typeSymbol: `${PACKAGE}/types#SonarTokenWrite`, create: () => sonarTokenWriteSchema, schema: sonarTokenWriteSchema }
4402
+ }],
4403
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#SonarTokenInfo`, create: () => sonarTokenInfoSchema, schema: sonarTokenInfoSchema }
4404
+ },
4405
+ {
4406
+ id: `${PACKAGE}#task-engine/unsetSonarToken`,
4407
+ service: "taskEngineController",
4408
+ namespace: "task-engine",
4409
+ method: "unsetSonarToken",
4410
+ invocation: { kind: "direct" },
4411
+ parameters: [{
4412
+ name: "path",
4413
+ wire: "path",
4414
+ source: "json",
4415
+ codec: { mode: "strict", typeSymbol: "string", create: () => external_exports.string(), schema: external_exports.string() }
4416
+ }],
4417
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#SonarTokenInfo`, create: () => sonarTokenInfoSchema, schema: sonarTokenInfoSchema }
4418
+ },
4351
4419
  {
4352
4420
  id: `${PACKAGE}#task-engine/readProjectSkillProfile`,
4353
4421
  service: "taskEngineController",
@@ -5248,7 +5316,7 @@ var SOURCE_ORDER = ["project", "codex-project", "user", "bundled"];
5248
5316
  function effectiveSource(entries, name) {
5249
5317
  return entries.filter((entry) => entry.name === name).sort((a, b) => SOURCE_ORDER.indexOf(a.source) - SOURCE_ORDER.indexOf(b.source))[0]?.source ?? "\u7F3A\u5931";
5250
5318
  }
5251
- function AdaptivePanel({ workspace, remote }) {
5319
+ function AdaptivePanel({ workspace, remote, onOpenInit }) {
5252
5320
  const [view, setView] = (0, import_react3.useState)(null);
5253
5321
  const [draft, setDraft] = (0, import_react3.useState)({});
5254
5322
  const [skills, setSkills] = (0, import_react3.useState)([]);
@@ -5258,9 +5326,18 @@ function AdaptivePanel({ workspace, remote }) {
5258
5326
  const [saving, setSaving] = (0, import_react3.useState)(false);
5259
5327
  const [dirty, setDirty] = (0, import_react3.useState)(false);
5260
5328
  const [message, setMessage] = (0, import_react3.useState)("");
5329
+ const [sonarToken, setSonarToken] = (0, import_react3.useState)("");
5330
+ const [tokenInfo, setTokenInfo] = (0, import_react3.useState)(null);
5331
+ const [tokenBusy, setTokenBusy] = (0, import_react3.useState)(false);
5261
5332
  const refresh = (0, import_react3.useCallback)(() => {
5262
5333
  setLoading(true);
5263
5334
  setMessage("");
5335
+ setSonarToken("");
5336
+ setTokenInfo(null);
5337
+ void remote.describeSonarToken(workspace).then((result) => {
5338
+ if (result.ok) setTokenInfo(result.value);
5339
+ }, () => {
5340
+ });
5264
5341
  void Promise.all([remote.readAdaptive(workspace), remote.listSkills(workspace), remote.listRules(workspace)]).then(([config, catalog, ruleCatalog]) => {
5265
5342
  setLoading(false);
5266
5343
  if (!config.ok) {
@@ -5397,11 +5474,50 @@ function AdaptivePanel({ workspace, remote }) {
5397
5474
  setMessage("\u4FDD\u5B58\u5931\u8D25\uFF1A" + describeError(error));
5398
5475
  });
5399
5476
  };
5477
+ const saveToken = () => {
5478
+ if (!sonarToken.trim()) return;
5479
+ setTokenBusy(true);
5480
+ void remote.setSonarToken({ path: workspace, token: sonarToken }).then((result) => {
5481
+ setTokenBusy(false);
5482
+ if (!result.ok) {
5483
+ setMessage("\u4FDD\u5B58 SonarQube Token \u5931\u8D25\uFF1A" + describeError(result.error));
5484
+ return;
5485
+ }
5486
+ setSonarToken("");
5487
+ setTokenInfo(result.value);
5488
+ setMessage("\u5F53\u524D\u9879\u76EE\u7684 SonarQube Token \u5DF2\u4FDD\u5B58\u5230\u672C\u673A DSH \u51ED\u636E\u5B58\u50A8\uFF0C\u53EF\u7ACB\u5373\u4F7F\u7528\u3002");
5489
+ }, (error) => {
5490
+ setTokenBusy(false);
5491
+ setMessage("\u4FDD\u5B58 SonarQube Token \u5931\u8D25\uFF1A" + describeError(error));
5492
+ });
5493
+ };
5494
+ const clearToken = () => {
5495
+ setTokenBusy(true);
5496
+ void remote.unsetSonarToken(workspace).then((result) => {
5497
+ setTokenBusy(false);
5498
+ if (!result.ok) {
5499
+ setMessage("\u79FB\u9664 SonarQube Token \u5931\u8D25\uFF1A" + describeError(result.error));
5500
+ return;
5501
+ }
5502
+ setSonarToken("");
5503
+ setTokenInfo(result.value);
5504
+ setMessage("\u5DF2\u79FB\u9664\u5F53\u524D\u9879\u76EE\u4FDD\u5B58\u5728\u672C\u673A\u7684 SonarQube Token\u3002");
5505
+ }, (error) => {
5506
+ setTokenBusy(false);
5507
+ setMessage("\u79FB\u9664 SonarQube Token \u5931\u8D25\uFF1A" + describeError(error));
5508
+ });
5509
+ };
5400
5510
  const candidates = [...new Set(skills.map((skill) => skill.name))].filter((name) => name !== "eng-delivery" && !(name in META_STAGES)).sort();
5401
5511
  const sonar = draft.sonar ?? {};
5402
5512
  return (0, import_react3.createElement)(
5403
5513
  "div",
5404
5514
  { style: { ...styles.section, display: "flex", flexDirection: "column", gap: 16 } },
5515
+ (0, import_react3.createElement)(
5516
+ "div",
5517
+ { style: row },
5518
+ (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "outline", size: "sm", onClick: onOpenInit }, "\u521D\u59CB\u5316\u9879\u76EE Skill / Rule"),
5519
+ (0, import_react3.createElement)("span", { style: label }, "\u626B\u63CF\u9879\u76EE\u540E\u5148\u9884\u89C8\uFF0C\u786E\u8BA4\u540E\u5199\u5165\u3002")
5520
+ ),
5405
5521
  (0, import_react3.createElement)(
5406
5522
  "div",
5407
5523
  { style: card },
@@ -5478,14 +5594,34 @@ function AdaptivePanel({ workspace, remote }) {
5478
5594
  "\u542F\u7528\uFF08\u4EC5\u4EE3\u7801\u5BA1\u6838\u9636\u6BB5\uFF09"
5479
5595
  )
5480
5596
  ),
5481
- (0, import_react3.createElement)("span", { style: label }, "\u590D\u7528 CI \u626B\u63CF\u7684 ceTaskId\uFF1B\u8D28\u91CF\u95E8\u7981\u6216\u65B0\u4EE3\u7801\u4E2D\u9AD8\u7B49\u7EA7\u95EE\u9898\u672A\u901A\u8FC7\u65F6\u963B\u6B62\u5BA1\u6838\u3002Token \u4EC5\u4ECE\u670D\u52A1\u8FDB\u7A0B\u73AF\u5883\u53D8\u91CF\u8BFB\u53D6\uFF0C\u4E0D\u5199\u5165\u4ED3\u5E93\u3002"),
5597
+ (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"),
5482
5598
  sonar.enabled === true ? (0, import_react3.createElement)(
5483
5599
  "div",
5484
5600
  { style: grid },
5601
+ (0, import_react3.createElement)(
5602
+ "label",
5603
+ { style: { display: "flex", flexDirection: "column", gap: 4 } },
5604
+ (0, import_react3.createElement)("span", { style: label }, "\u626B\u63CF\u6765\u6E90"),
5605
+ (0, import_react3.createElement)(
5606
+ "select",
5607
+ {
5608
+ style: input,
5609
+ value: sonar.source ?? "ci",
5610
+ onChange: (event) => updateSonar({
5611
+ source: event.target.value,
5612
+ ...event.target.value !== "ci" ? { mode: "branch" } : {},
5613
+ ...event.target.value !== "ide-local" ? { include_paths: [] } : {}
5614
+ })
5615
+ },
5616
+ (0, import_react3.createElement)("option", { value: "ci" }, "CI \u5DF2\u6709\u7ED3\u679C"),
5617
+ (0, import_react3.createElement)("option", { value: "ide-local" }, "\u672C\u5730\u89C4\u5219\u5BA1\u6838\uFF08\u65E0\u9700\u63D0\u4EA4\u6216\u63A8\u9001\uFF09"),
5618
+ (0, import_react3.createElement)("option", { value: "local" }, "\u672C\u673A\u626B\u63CF\u5E76\u4E0A\u4F20\uFF08\u9700 Developer Edition\uFF09")
5619
+ )
5620
+ ),
5485
5621
  ...[
5486
5622
  ["host_url", "\u670D\u52A1\u5730\u5740", "https://sonar.example"],
5487
5623
  ["project_key", "\u9879\u76EE Key", "my-project"],
5488
- ["token_env", "Token \u73AF\u5883\u53D8\u91CF\u540D", "SONAR_TOKEN"]
5624
+ ["token_env", "Token \u73AF\u5883\u53D8\u91CF\u540D\uFF08\u53EF\u9009\u540E\u5907\uFF09", "SONAR_TOKEN"]
5489
5625
  ].map(([key, title, placeholder]) => (0, import_react3.createElement)(
5490
5626
  "label",
5491
5627
  { key, style: { display: "flex", flexDirection: "column", gap: 4 } },
@@ -5506,11 +5642,86 @@ function AdaptivePanel({ workspace, remote }) {
5506
5642
  {
5507
5643
  style: input,
5508
5644
  value: sonar.mode ?? "branch",
5645
+ disabled: sonar.source === "local" || sonar.source === "ide-local",
5509
5646
  onChange: (event) => updateSonar({ mode: event.target.value })
5510
5647
  },
5511
5648
  (0, import_react3.createElement)("option", { value: "branch" }, "\u5206\u652F"),
5512
5649
  (0, import_react3.createElement)("option", { value: "pull-request" }, "\u5408\u5E76\u8BF7\u6C42")
5513
5650
  )
5651
+ ),
5652
+ sonar.source === "local" || sonar.source === "ide-local" ? (0, import_react3.createElement)(
5653
+ "label",
5654
+ { style: { display: "flex", flexDirection: "column", gap: 4 } },
5655
+ (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"),
5656
+ (0, import_react3.createElement)("input", {
5657
+ style: input,
5658
+ value: sonar.reference_branch ?? "",
5659
+ placeholder: "\u4F8B\u5982 qdm_sit",
5660
+ onChange: (event) => updateSonar({ reference_branch: event.target.value })
5661
+ })
5662
+ ) : null,
5663
+ sonar.source === "local" ? (0, import_react3.createElement)(
5664
+ "label",
5665
+ { style: { display: "flex", flexDirection: "column", gap: 4 } },
5666
+ (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"),
5667
+ (0, import_react3.createElement)("input", {
5668
+ style: input,
5669
+ value: sonar.scan_command ?? "",
5670
+ placeholder: "mvn org.sonarsource.scanner.maven:sonar-maven-plugin:5.5.0.6356:sonar",
5671
+ onChange: (event) => updateSonar({ scan_command: event.target.value })
5672
+ })
5673
+ ) : null,
5674
+ sonar.source === "local" ? (0, import_react3.createElement)(
5675
+ "span",
5676
+ { style: label },
5677
+ "\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"
5678
+ ) : null,
5679
+ sonar.source === "ide-local" ? (0, import_react3.createElement)(
5680
+ "label",
5681
+ { style: { display: "flex", flexDirection: "column", gap: 4 } },
5682
+ (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"),
5683
+ (0, import_react3.createElement)("textarea", {
5684
+ style: { ...input, minHeight: 76 },
5685
+ value: (sonar.include_paths ?? []).join("\n"),
5686
+ placeholder: "\u4F8B\u5982 fp-bussiness\nfp-ruoyi\nfp-ruoyi-spring-boot\npom.xml",
5687
+ onChange: (event) => updateSonar({
5688
+ include_paths: event.target.value.split(/\r?\n|,/u).map((path) => path.trim()).filter(Boolean)
5689
+ })
5690
+ })
5691
+ ) : null,
5692
+ sonar.source === "ide-local" ? (0, import_react3.createElement)(
5693
+ "span",
5694
+ { style: label },
5695
+ "\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"
5696
+ ) : null,
5697
+ (0, import_react3.createElement)(
5698
+ "div",
5699
+ { style: { display: "flex", flexDirection: "column", gap: 5 } },
5700
+ (0, import_react3.createElement)("span", { style: label }, `\u5F53\u524D\u9879\u76EE Token\uFF1A${tokenInfo === null ? "\u72B6\u6001\u4E0D\u53EF\u7528" : tokenInfo.configured ? "\u5DF2\u914D\u7F6E" : "\u672A\u914D\u7F6E"}`),
5701
+ (0, import_react3.createElement)("input", {
5702
+ type: "password",
5703
+ autoComplete: "new-password",
5704
+ style: input,
5705
+ value: sonarToken,
5706
+ placeholder: "\u8F93\u5165\u7528\u6237\u4EE4\u724C\uFF08\u4FDD\u5B58\u540E\u4E0D\u56DE\u663E\uFF09",
5707
+ onChange: (event) => setSonarToken(event.target.value)
5708
+ }),
5709
+ (0, import_react3.createElement)(
5710
+ "div",
5711
+ { style: row },
5712
+ (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, {
5713
+ variant: "outline",
5714
+ size: "sm",
5715
+ disabled: tokenBusy || !sonarToken.trim() || tokenInfo?.writable === false,
5716
+ onClick: saveToken
5717
+ }, tokenBusy ? "\u5904\u7406\u4E2D\u2026" : "\u4FDD\u5B58 Token"),
5718
+ tokenInfo?.configured ? (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, {
5719
+ variant: "outline",
5720
+ size: "sm",
5721
+ disabled: tokenBusy || tokenInfo.writable === false,
5722
+ onClick: clearToken
5723
+ }, "\u79FB\u9664 Token") : null
5724
+ )
5514
5725
  )
5515
5726
  ) : null
5516
5727
  ),
@@ -5523,7 +5734,7 @@ function AdaptivePanel({ workspace, remote }) {
5523
5734
  { variant: "primary", size: "sm", disabled: loading || saving || !dirty, onClick: save },
5524
5735
  saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u81EA\u9002\u5E94\u914D\u7F6E"
5525
5736
  ),
5526
- (0, import_react3.createElement)("span", { style: label }, "\u65B0\u9879\u76EE\u53EF\u5728\u5DE5\u7A0B\u4F1A\u8BDD\u4E2D\u8C03\u7528 dev_task init_project\uFF1A\u626B\u63CF \u2192 \u9884\u89C8 \u2192 \u5199\u5165\u9879\u76EE\u6280\u80FD\u4E0E\u89C4\u5219\u3002")
5737
+ (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")
5527
5738
  ),
5528
5739
  message ? (0, import_react3.createElement)("p", { role: "status", style: styles.status }, message) : null,
5529
5740
  view?.problems.length ? (0, import_react3.createElement)("p", { role: "alert", style: styles.status }, view.problems.join("\uFF1B")) : null,
@@ -5553,6 +5764,7 @@ var card2 = {
5553
5764
  borderRadius: 8,
5554
5765
  padding: "12px 14px"
5555
5766
  };
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`;
5556
5768
  function InitPanel({ workspace, remote }) {
5557
5769
  const [view, setView] = (0, import_react4.useState)(null);
5558
5770
  const [generating, setGenerating] = (0, import_react4.useState)(false);
@@ -5561,6 +5773,7 @@ function InitPanel({ workspace, remote }) {
5561
5773
  const [editing, setEditing] = (0, import_react4.useState)(false);
5562
5774
  const [body2, setBody] = (0, import_react4.useState)("");
5563
5775
  const [msg, setMsg] = (0, import_react4.useState)("");
5776
+ const [projectInitMsg, setProjectInitMsg] = (0, import_react4.useState)("");
5564
5777
  (0, import_react4.useEffect)(() => {
5565
5778
  if (!generating) {
5566
5779
  setElapsed(0);
@@ -5630,11 +5843,53 @@ function InitPanel({ workspace, remote }) {
5630
5843
  (0, import_react4.createElement)(
5631
5844
  "div",
5632
5845
  { style: card2 },
5846
+ (0, import_react4.createElement)("h2", { style: { margin: 0, fontSize: 17 } }, "\u9879\u76EE Skill / Rule \u521D\u59CB\u5316"),
5847
+ (0, import_react4.createElement)(
5848
+ "p",
5849
+ { 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"
5851
+ ),
5852
+ (0, import_react4.createElement)(
5853
+ "p",
5854
+ { style: styles.muted },
5855
+ "\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
+ ),
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
+ (0, import_react4.createElement)(
5869
+ "div",
5870
+ { 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;
5875
+ }
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
+ )
5883
+ ),
5884
+ (0, import_react4.createElement)(
5885
+ "div",
5886
+ { style: card2 },
5887
+ (0, import_react4.createElement)("h2", { style: { margin: 0, fontSize: 17 } }, "AGENTS.md \u521D\u59CB\u5316"),
5633
5888
  (0, import_react4.createElement)(
5634
5889
  "div",
5635
5890
  { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" } },
5636
5891
  (0, import_react4.createElement)(import_dsh_client_ui_primitives3.StateDot, { state: exists ? "done" : "ongoing" }),
5637
- (0, import_react4.createElement)("span", { style: styles.bindingLabel }, exists ? `\u5DF2\u521D\u59CB\u5316 \xB7 ${view.lines} \u884C\uFF08\u4E0A\u9650 200\uFF09` : "\u672A\u521D\u59CB\u5316"),
5892
+ (0, import_react4.createElement)("span", { style: styles.bindingLabel }, exists ? `AGENTS.md \u5DF2\u5B58\u5728 \xB7 ${view.lines} \u884C\uFF08\u4E0A\u9650 200\uFF09` : "AGENTS.md \u672A\u521B\u5EFA"),
5638
5893
  view?.path !== void 0 ? (0, import_react4.createElement)("span", { style: styles.sourceBadge }, `\u5DF2\u5B9A\u4F4D\u5230 ${view.path}`) : null
5639
5894
  ),
5640
5895
  (0, import_react4.createElement)(
@@ -5718,7 +5973,7 @@ function InitPanel({ workspace, remote }) {
5718
5973
  onClick: () => {
5719
5974
  void generate();
5720
5975
  }
5721
- }, exists ? "\u91CD\u65B0\u521D\u59CB\u5316\uFF08AI \u626B\u63CF\u8986\u76D6\uFF09" : "\u8BA9 AI \u521D\u59CB\u5316"),
5976
+ }, exists ? "\u91CD\u65B0\u751F\u6210 AGENTS.md" : "\u751F\u6210 AGENTS.md"),
5722
5977
  exists ? (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "outline", size: "md", onClick: startEdit }, "\u624B\u52A8\u7F16\u8F91") : null
5723
5978
  )
5724
5979
  )
@@ -6444,7 +6699,7 @@ function itemAudit(item) {
6444
6699
  lines.push((0, import_react8.createElement)(
6445
6700
  "div",
6446
6701
  { key: "dispatch", style: metaLine },
6447
- (0, import_react8.createElement)("span", { style: badge }, "\u5DF2\u6D3E\u53D1"),
6702
+ (0, import_react8.createElement)("span", { style: badge }, "\u5DF2\u5F00\u59CB"),
6448
6703
  (0, import_react8.createElement)("span", null, item.dispatch.description === "" ? "\uFF08\u65E0\u63CF\u8FF0\uFF09" : item.dispatch.description),
6449
6704
  (0, import_react8.createElement)("span", { style: badge }, timeText(item.dispatch.at))
6450
6705
  ));
@@ -6471,10 +6726,65 @@ function itemAudit(item) {
6471
6726
  }
6472
6727
  }
6473
6728
  if (lines.length === 0) {
6474
- lines.push((0, import_react8.createElement)("div", { key: "none", style: metaLine }, (0, import_react8.createElement)("span", { style: badge }, "\u672A\u6D3E\u53D1 / \u672A\u5BA1\u67E5")));
6729
+ const status = item.status === "done" ? "\u5DF2\u6807\u8BB0\u5B8C\u6210\uFF0C\u7F3A\u5C11\u5B9E\u65BD\u9879\u5BA1\u67E5\u8BB0\u5F55" : item.status === "doing" ? "\u5B9E\u65BD\u4E2D\uFF0C\u5F85\u5BA1\u67E5" : "\u5F85\u5F00\u59CB";
6730
+ lines.push((0, import_react8.createElement)("div", { key: "none", style: metaLine }, (0, import_react8.createElement)("span", { style: badge }, status)));
6475
6731
  }
6476
6732
  return (0, import_react8.createElement)("div", { style: { display: "flex", flexDirection: "column", gap: 4 } }, ...lines);
6477
6733
  }
6734
+ function sonarAudit(task) {
6735
+ if (!task.sonar) return null;
6736
+ const audit = task.sonar.audit;
6737
+ 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
+ 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";
6740
+ return (0, import_react8.createElement)(
6741
+ "details",
6742
+ { style: { borderTop: "1px solid var(--dsw-alias-border-l2)", paddingTop: 8 } },
6743
+ (0, import_react8.createElement)(
6744
+ "summary",
6745
+ { 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)}`
6747
+ ),
6748
+ (0, import_react8.createElement)(
6749
+ "p",
6750
+ { 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`
6752
+ ),
6753
+ audit.report_path ? (0, import_react8.createElement)("p", { style: metaLine }, `\u5BA1\u6838\u6587\u4EF6\uFF1A${audit.report_path}`) : null,
6754
+ audit.scanned_files?.length ? (0, import_react8.createElement)(
6755
+ "details",
6756
+ null,
6757
+ (0, import_react8.createElement)("summary", { style: { cursor: "pointer", fontSize: 12 } }, `\u672C\u6B21\u5206\u6790\u6587\u4EF6\uFF08${audit.scanned_files.length}\uFF09`),
6758
+ ...audit.scanned_files.map((file) => (0, import_react8.createElement)("div", { key: file, style: metaLine }, file))
6759
+ ) : null,
6760
+ ...audit.uncovered_files.map((file) => (0, import_react8.createElement)(
6761
+ "div",
6762
+ { key: `uncovered-${file}`, style: metaLine },
6763
+ `\u672A\u8986\u76D6\uFF1A${file}`
6764
+ )),
6765
+ 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
+ "div",
6767
+ { style: { display: "flex", flexDirection: "column", gap: 6 } },
6768
+ ...audit.findings.map((finding) => (0, import_react8.createElement)(
6769
+ "div",
6770
+ { key: finding.key, style: {
6771
+ ...itemRow,
6772
+ padding: "6px 0",
6773
+ fontSize: 12,
6774
+ overflowWrap: "anywhere"
6775
+ } },
6776
+ (0, import_react8.createElement)(
6777
+ "div",
6778
+ { style: headerRow },
6779
+ (0, import_react8.createElement)("strong", null, finding.severity),
6780
+ (0, import_react8.createElement)("code", null, finding.rule),
6781
+ (0, import_react8.createElement)("span", null, `${finding.file}${finding.line === void 0 ? "" : `:${finding.line}`}`)
6782
+ ),
6783
+ (0, import_react8.createElement)("span", null, finding.message)
6784
+ ))
6785
+ )
6786
+ );
6787
+ }
6478
6788
  function TaskLedger({ workspace, remote }) {
6479
6789
  const [tasks, setTasks] = (0, import_react8.useState)([]);
6480
6790
  const [error, setError] = (0, import_react8.useState)("");
@@ -6486,13 +6796,19 @@ function TaskLedger({ workspace, remote }) {
6486
6796
  if (workspace === "") return;
6487
6797
  setError("");
6488
6798
  setLoading(true);
6489
- void remote.readTasks(workspace).then((result) => {
6799
+ let timer;
6800
+ const timeout = new Promise((_, reject) => {
6801
+ timer = setTimeout(() => reject(new Error("\u8BFB\u53D6\u8D85\u65F6\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u6216\u91CD\u65B0\u767B\u5F55\u540E\u91CD\u8BD5")), 15e3);
6802
+ });
6803
+ void Promise.race([remote.readTasks(workspace), timeout]).then((result) => {
6490
6804
  setLoading(false);
6491
6805
  if (result.ok) setTasks(result.value.tasks);
6492
6806
  else setError("\u8BFB\u53D6\u53F0\u8D26\u5931\u8D25\uFF1A" + describeError(result.error));
6493
6807
  }, (reason) => {
6494
6808
  setLoading(false);
6495
6809
  setError("\u8BFB\u53D6\u53F0\u8D26\u5931\u8D25\uFF1A" + describeError(reason));
6810
+ }).finally(() => {
6811
+ if (timer !== void 0) clearTimeout(timer);
6496
6812
  });
6497
6813
  }, [remote, workspace]);
6498
6814
  (0, import_react8.useEffect)(() => {
@@ -6516,7 +6832,7 @@ function TaskLedger({ workspace, remote }) {
6516
6832
  (0, import_react8.createElement)("span", { style: styles.sourceBadge }, "\u53EA\u8BFB \xB7 \u6765\u81EA .dsh/task-*.json"),
6517
6833
  (0, import_react8.createElement)(import_dsh_client_ui_primitives5.Button, { variant: "outline", size: "sm", disabled: loading, onClick: refresh }, loading ? "\u8BFB\u53D6\u4E2D\u2026" : "\u5237\u65B0")
6518
6834
  ),
6519
- loading ? (0, import_react8.createElement)("p", { role: "status" }, "\u6B63\u5728\u8BFB\u53D6\u4EFB\u52A1\u2026") : error !== "" ? (0, import_react8.createElement)("p", { style: styles.status }, error) : tasks.length === 0 ? (0, import_react8.createElement)("p", { style: styles.muted }, "\u5F53\u524D\u5DE5\u4F5C\u533A\u8FD8\u6CA1\u6709\u4EFB\u52A1\uFF1A\u5F00\u5DE5\u540E\uFF08dev_task create\uFF09\u4F1A\u5728\u8FD9\u91CC\u5217\u51FA\u6D3E\u53D1\u4E0E\u5BA1\u67E5\u7559\u75D5\u3002") : visible.length === 0 ? (0, import_react8.createElement)("div", { className: "te-empty" }, "\u6CA1\u6709\u5339\u914D\u7684\u4EFB\u52A1\uFF0C\u8BF7\u8C03\u6574\u7B5B\u9009\u3002") : (0, import_react8.createElement)(
6835
+ loading ? (0, import_react8.createElement)("p", { role: "status" }, "\u6B63\u5728\u8BFB\u53D6\u4EFB\u52A1\u2026") : error !== "" ? (0, import_react8.createElement)("p", { style: styles.status }, error) : tasks.length === 0 ? (0, import_react8.createElement)("p", { style: styles.muted }, "\u5F53\u524D\u5DE5\u4F5C\u533A\u8FD8\u6CA1\u6709\u4EFB\u52A1\uFF1A\u5F00\u5DE5\u540E\uFF08dev_task create\uFF09\u4F1A\u5728\u8FD9\u91CC\u5217\u51FA\u5B9E\u65BD\u4E0E\u5BA1\u67E5\u8BB0\u5F55\u3002") : visible.length === 0 ? (0, import_react8.createElement)("div", { className: "te-empty" }, "\u6CA1\u6709\u5339\u914D\u7684\u4EFB\u52A1\uFF0C\u8BF7\u8C03\u6574\u7B5B\u9009\u3002") : (0, import_react8.createElement)(
6520
6836
  "div",
6521
6837
  { style: { display: "flex", flexDirection: "column", gap: 12 } },
6522
6838
  ...visible.map((task) => (0, import_react8.createElement)(
@@ -6535,6 +6851,7 @@ function TaskLedger({ workspace, remote }) {
6535
6851
  (0, import_react8.createElement)("span", { className: "te-badge" }, `\u5BA1\u6838\uFF1A${task.review_outcome ?? "pending"}`),
6536
6852
  task.updated_at ? (0, import_react8.createElement)("span", { style: metaLine }, "\u66F4\u65B0\u4E8E " + timeText(task.updated_at)) : null
6537
6853
  ),
6854
+ sonarAudit(task),
6538
6855
  (0, import_react8.createElement)(
6539
6856
  "div",
6540
6857
  { style: { display: "flex", flexDirection: "column" } },
@@ -6683,7 +7000,7 @@ function Workbench({ useStore, actions, useWorkspaces, remote }) {
6683
7000
  "div",
6684
7001
  { className: "te-content", key: current },
6685
7002
  (0, import_react9.createElement)("p", { style: { ...styles.hint, marginBottom: 10 }, title: current }, "\u5DE5\u4F5C\u533A \xB7 " + current),
6686
- current === "" ? (0, import_react9.createElement)("p", { style: styles.muted }, "\u5F53\u524D\u6CA1\u6709\u5DE5\u4F5C\u533A\uFF1A\u8BF7\u5148\u5728\u4FA7\u680F\u521B\u5EFA\u4E00\u4E2A\u5DE5\u4F5C\u533A\u3002") : tab === "init" ? (0, import_react9.createElement)(InitPanel, { workspace: current, remote }) : tab === "adaptive" ? (0, import_react9.createElement)(AdaptivePanel, { workspace: current, remote }) : tab === "tasks" ? (0, import_react9.createElement)(TaskLedger, { workspace: current, remote }) : tab === "skills" ? (0, import_react9.createElement)(SkillManager, { workspace: current, remote }) : (0, import_react9.createElement)(RuleManager, { workspace: current, remote })
7003
+ current === "" ? (0, import_react9.createElement)("p", { style: styles.muted }, "\u5F53\u524D\u6CA1\u6709\u5DE5\u4F5C\u533A\uFF1A\u8BF7\u5148\u5728\u4FA7\u680F\u521B\u5EFA\u4E00\u4E2A\u5DE5\u4F5C\u533A\u3002") : tab === "init" ? (0, import_react9.createElement)(InitPanel, { workspace: current, remote }) : tab === "adaptive" ? (0, import_react9.createElement)(AdaptivePanel, { workspace: current, remote, onOpenInit: () => setTab("init") }) : tab === "tasks" ? (0, import_react9.createElement)(TaskLedger, { workspace: current, remote }) : tab === "skills" ? (0, import_react9.createElement)(SkillManager, { workspace: current, remote }) : (0, import_react9.createElement)(RuleManager, { workspace: current, remote })
6687
7004
  )
6688
7005
  )
6689
7006
  );