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