@godv61/dsh-task-engine 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -140,4 +140,5 @@ dsh plugin --profile <name> add .
140
140
  - **全屏工作台 + 在线编辑(0.7.0)**:配置页从设置弹窗迁出,改为侧边栏 `sidebar.footer.action`「工程流程」按钮,点开 `shell.overlay` 全屏工作台(触发按钮与覆盖层共享一个 store 控制开关)。工作台分「流程配置 / 技能 skill / 规则 rule」三个标签页;技能和规则列表支持在线编辑——`readSkill`/`readRule` 读回正文、改 description/whenToUse/正文、`writeSkill`/`writeRule` 写回;内置项只读,项目/用户项可原地编辑,新建同时支持项目级/用户级。旧的 `settings.section` 入口移除,统一走侧边栏按钮。浏览器 e2e 全绿。
141
141
  - **按预设激活(0.8.0)**:`dev_task` 工具与内置技能从 host 全局层拆到 agent 层。host 入口只挂 `task-engine` Remote 控制器 + 工作台 UI(`src/index.ts`);新增 `src/agent.ts`(`./agent` 出品)、`src/dev-task.ts`、`src/shipped-skills.ts`,由预设的 `agent.cordis.yml` 命名后,在**该预设的 scope** 里注册工具与技能。实机 boot 验证:`standard` 会话工具目录不含 `dev_task`(26 个工具),加了 `@godv61/dsh-task-engine/agent` 行的 `eng` 会话含 `dev_task`(27 个工具)且描述正确,换回 `standard` 再次不含——切换预设即切换流程激活状态。
142
142
  - **一键激活(0.8.1)**:新增 `preset/enable.mjs`(bin: `dsh-task-engine-enable`),一条命令自动复制 `standard` → `eng`、把 persona 换成工程人设、追加 agent 行、写 `preset.yml`。persona 从「必须换」降级为「可选」——`eng-delivery` 技能自带 `whenToUse`,即使不加人设,模型遇到开发请求也自己加载技能走 `dev_task`;最简激活只剩「复制预设 + 追加一行 agent 行」。实机验证:脚本生成的 `eng` 预设挂载后 `dev_task` 可见、persona 以工程人设(含「铁律」)渲染、`standard` 仍无 `dev_task`。
143
- - **点选即用(0.9.0)**:host 入口新增 `src/seed-preset.ts`——首次启动自动把当前 `standard` 复制成 `eng` 预设(换工程人设 + 追加 agent 行,幂等、不覆盖手改)。装 bundle 重启后预设列表直接出现「工程化开发引擎」,点选即激活、切走即不激活,零复制/零编辑/零脚本。实机 boot 验证:boot 后 `.agent-presets/eng` 自动生成(agent 行 + 工程人设齐全)、roster 列出 `eng`(user)、`eng` 会话有 `dev_task` 且 persona 含「铁律」、`standard` 会话无 `dev_task`。
143
+ - **点选即用(0.9.0)**:host 入口新增 `src/seed-preset.ts`——首次启动自动把当前 `standard` 复制成 `eng` 预设(换工程人设 + 追加 agent 行,幂等、不覆盖手改)。装 bundle 重启后预设列表直接出现「工程化开发引擎」,点选即激活、切走即不激活,零复制/零编辑/零脚本。实机 boot 验证:boot 后 `.agent-presets/eng` 自动生成(agent 行 + 工程人设齐全)、roster 列出 `eng`(user)、`eng` 会话有 `dev_task` 且 persona 含「铁律」、`standard` 会话无 `dev_task`。
144
+ - **工作台可用性(0.9.1)**:修复「新建 skill / 新建 rule」按钮点击不弹出表单(`formOpen` 只认编辑态,新建态缺少显式标志);给六个守卫补 hover 说明、把「产物齐全」改名「产物字段已填全」并讲清「产物 = 阶段要写清楚的记录、字段 = 这份记录里必填的空」,「节点挂载」改名「阶段技能 / 规则」。
package/lib/client.js CHANGED
@@ -4168,6 +4168,25 @@ var readRuleResultSchema = external_exports.object({
4168
4168
  content: external_exports.string(),
4169
4169
  error: external_exports.string().optional()
4170
4170
  });
4171
+ var taskLedgerItemSchema = external_exports.object({
4172
+ id: external_exports.string(),
4173
+ title: external_exports.string(),
4174
+ status: external_exports.string(),
4175
+ dispatch: external_exports.object({ description: external_exports.string(), at: external_exports.string() }).optional(),
4176
+ review: external_exports.object({
4177
+ spec: external_exports.object({ outcome: external_exports.enum(["pass", "fail"]), notes: external_exports.array(external_exports.string()).optional() }),
4178
+ quality: external_exports.object({ outcome: external_exports.enum(["pass", "fail"]), notes: external_exports.array(external_exports.string()).optional() })
4179
+ }).optional()
4180
+ });
4181
+ var taskLedgerViewSchema = external_exports.object({
4182
+ tasks: external_exports.array(external_exports.object({
4183
+ task_id: external_exports.string(),
4184
+ title: external_exports.string(),
4185
+ stage: external_exports.string(),
4186
+ branch: external_exports.string(),
4187
+ items: external_exports.array(taskLedgerItemSchema)
4188
+ }))
4189
+ });
4171
4190
  var PACKAGE = "@godv61/dsh-task-engine";
4172
4191
  var TYPERT_REMOTE = {
4173
4192
  package: PACKAGE,
@@ -4299,14 +4318,30 @@ var TYPERT_REMOTE = {
4299
4318
  }
4300
4319
  ],
4301
4320
  result: { mode: "strict", typeSymbol: `${PACKAGE}/types#ReadRuleResult`, schema: readRuleResultSchema }
4321
+ },
4322
+ {
4323
+ id: `${PACKAGE}#task-engine/readTasks`,
4324
+ service: "taskEngineController",
4325
+ namespace: "task-engine",
4326
+ method: "readTasks",
4327
+ invocation: { kind: "direct" },
4328
+ parameters: [
4329
+ {
4330
+ name: "path",
4331
+ wire: "path",
4332
+ source: "json",
4333
+ codec: { mode: "strict", typeSymbol: "string", schema: external_exports.string() }
4334
+ }
4335
+ ],
4336
+ result: { mode: "strict", typeSymbol: `${PACKAGE}/types#TaskLedgerView`, schema: taskLedgerViewSchema }
4302
4337
  }
4303
4338
  ]
4304
4339
  };
4305
4340
  var remote_default = TYPERT_REMOTE;
4306
4341
 
4307
4342
  // src/client/Workbench.tsx
4308
- var import_react5 = require("react");
4309
- var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
4343
+ var import_react6 = require("react");
4344
+ var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
4310
4345
 
4311
4346
  // src/client/styles.ts
4312
4347
  var text = "var(--dsw-alias-label-primary)";
@@ -4816,12 +4851,12 @@ var cardV = {
4816
4851
  padding: "10px 12px"
4817
4852
  };
4818
4853
  var GUARD_OPTIONS = [
4819
- { value: "requirement_confirmation", label: "\u9700\u6C42\u786E\u8BA4" },
4820
- { value: "solution_confirmation", label: "\u65B9\u6848\u786E\u8BA4" },
4821
- { value: "todos_done", label: "\u5F85\u529E\u5B8C\u6210" },
4822
- { value: "verified", label: "\u5DF2\u9A8C\u8BC1" },
4823
- { value: "review_passed", label: "\u8BC4\u5BA1\u901A\u8FC7" },
4824
- { value: "artifacts_present", label: "\u4EA7\u7269\u9F50\u5168" }
4854
+ { value: "requirement_confirmation", label: "\u9700\u6C42\u786E\u8BA4", hint: "\u9700\u6C42\u5DF2\u7ECF\u4EBA\u786E\u8BA4\u8FC7" },
4855
+ { value: "solution_confirmation", label: "\u65B9\u6848\u786E\u8BA4", hint: "\u65B9\u6848\u5DF2\u7ECF\u4EBA\u786E\u8BA4\u8FC7" },
4856
+ { value: "todos_done", label: "\u5F85\u529E\u5B8C\u6210", hint: "\u4EFB\u52A1\u6E05\u5355\u91CC\u7684\u6BCF\u4E00\u9879\u90FD\u5DF2\u52FE\u9009\u5B8C\u6210" },
4857
+ { value: "verified", label: "\u5DF2\u9A8C\u8BC1", hint: "\u5DF2\u901A\u8FC7\u9A8C\u8BC1\uFF08\u9AD8\u98CE\u9669\u4EFB\u52A1\u8FD8\u5FC5\u987B\u9644\u9A8C\u8BC1\u8BC1\u636E\uFF09" },
4858
+ { value: "review_passed", label: "\u8BC4\u5BA1\u901A\u8FC7", hint: "\u4EE3\u7801\u5BA1\u6838\u7ED3\u8BBA\u4E3A\u901A\u8FC7" },
4859
+ { value: "artifacts_present", label: "\u4EA7\u7269\u5B57\u6BB5\u5DF2\u586B\u5168", hint: "\u8BE5\u9636\u6BB5\u58F0\u660E\u7684\u6BCF\u4E00\u4E2A\u4EA7\u7269\u5B57\u6BB5\u90FD\u5DF2\u586B\u4E0A\u5185\u5BB9" }
4825
4860
  ];
4826
4861
  var POLICY_OPTIONS = [
4827
4862
  { value: "task", label: "task", hint: "\u68C0\u67E5\u70B9\u4E00\u6B21\u63D0\u4EA4" },
@@ -4916,9 +4951,9 @@ function TaskEngineSection(props) {
4916
4951
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles.flowCard, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FlowDiagram, { config, onAddTransition: addTransition, onRemoveTransition: removeTransition }) }),
4917
4952
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconSettingsOutline16, { size: 16 }), title: "\u9636\u6BB5", hint: "\u6D41\u7A0B\u7531\u8FD9\u4E9B\u9636\u6BB5\u6309\u987A\u5E8F\u7EC4\u6210\u3002\u70B9\u4E00\u4E2A\u6807\u7B7E\u53EF\u5220\u9664\u5B83\uFF08\u8D77\u59CB\u9636\u6BB5\u9664\u5916\uFF09\uFF1B\u7528\u4E2D\u6587\u540D\u66F4\u6613\u61C2\uFF0C\u4F8B\u5982\u300C\u9700\u6C42\u8BC4\u5BA1\u300D\u300C\u5F00\u53D1\u300D\u3002", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StageEditor, { config, setConfig }) }),
4918
4953
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconBranchOutline16, { size: 16 }), title: "\u6D41\u8F6C\uFF08\u9636\u6BB5 \u2192 \u9636\u6BB5\uFF0C\u53EF\u5E26\u5B88\u536B\uFF09", defaultOpen: false, hint: "\u6BCF\u6761\u6D41\u8F6C = \u4ECE\u300C\u4E0A\u4E00\u6B65\u300D\u5230\u300C\u4E0B\u4E00\u6B65\u300D\u5141\u8BB8\u8D70\u7684\u8DEF\uFF1B\u53EF\u9644\u52A0\u5B88\u536B\uFF0C\u6EE1\u8DB3\u5B88\u536B\u624D\u653E\u884C\u3002\u4E5F\u53EF\u5728\u6D41\u7A0B\u56FE\u91CC\u76F4\u63A5\u8FDE\u7EBF/\u70B9\u7BAD\u5934\u5220\u9664\u3002", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TransitionEditor, { config, setConfig }) }),
4919
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconCheckOutline16, { size: 16 }), title: "\u4EA7\u7269\uFF08\u6BCF\u4E2A\u9636\u6BB5\u8981\u586B\u7684\u5B57\u6BB5\uFF09", defaultOpen: false, hint: "\u7ED9\u67D0\u9636\u6BB5\u58F0\u660E\u8981\u4EA4\u7684\u4EA7\u7269\u548C\u5FC5\u586B\u5B57\u6BB5\uFF1B\u914D\u5408\u6D41\u8F6C\u91CC\u7684\u300C\u4EA7\u7269\u9F50\u5168\u300D\u5B88\u536B\uFF0C\u5B57\u6BB5\u6CA1\u586B\u5168\u5C31\u8FC7\u4E0D\u53BB\u3002", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArtifactEditor, { config, setConfig }) }),
4954
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconCheckOutline16, { size: 16 }), title: "\u4EA7\u7269\uFF08\u6BCF\u4E2A\u9636\u6BB5\u8981\u5199\u6E05\u695A\u7684\u8BB0\u5F55\uFF09", defaultOpen: false, hint: "\u4EA7\u7269 = \u67D0\u9636\u6BB5\u5FC5\u987B\u4EA4\u4ED8\u7684\u4E00\u4EFD\u300C\u586B\u5199\u8BB0\u5F55\u300D\uFF1B\u5B57\u6BB5 = \u8FD9\u4EFD\u8BB0\u5F55\u91CC\u5927\u6A21\u578B\u5FC5\u987B\u586B\u4E0A\u7684\u7A7A\u3002\u4F8B\u5982\u300C\u9700\u6C42\u8BC4\u5BA1\u300D\u9636\u6BB5\u7684\u4EA7\u7269\u300C\u9700\u6C42\u8BF4\u660E\u300D\u8981\u586B scope\uFF08\u8303\u56F4\uFF09\u3001acceptance_criteria\uFF08\u9A8C\u6536\u6807\u51C6\uFF09\u4E24\u4E2A\u5B57\u6BB5\uFF1B\u518D\u7ED9\u300C\u9700\u6C42\u8BC4\u5BA1 \u2192 \u8BBE\u8BA1\u300D\u8FD9\u6761\u6D41\u8F6C\u6302\u4E0A\u300C\u4EA7\u7269\u5B57\u6BB5\u5DF2\u586B\u5168\u300D\u5B88\u536B\uFF0C\u5B57\u6BB5\u6CA1\u586B\u5168\u5C31\u8FDB\u4E0D\u4E86\u4E0B\u4E00\u9636\u6BB5\u3002", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArtifactEditor, { config, setConfig }) }),
4920
4955
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconEditOutline16, { size: 16 }), title: "\u63D0\u4EA4\u89C4\u5219", defaultOpen: false, hint: "\u63D0\u4EA4\u7B56\u7565\u3001\u6D88\u606F\u683C\u5F0F\u3001\u63D0\u4EA4\u68C0\u67E5\u70B9\u3001\u6587\u4EF6\u8303\u56F4\uFF0C\u4EE5\u53CA\u9AD8\u98CE\u9669\u662F\u5426\u5FC5\u987B\u9644\u9A8C\u8BC1\u8BC1\u636E\u3002", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitEditor, { config, setConfig }) }),
4921
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconBranchOutline16, { size: 16 }), title: "\u8282\u70B9\u6302\u8F7D\uFF08skill / rule\uFF09", hint: "\u7ED9\u6BCF\u4E2A\u9636\u6BB5\u6302\u300C\u8FD9\u4E2A\u9636\u6BB5\u7528\u4EC0\u4E48 skill\u300D\u548C\u300C\u5B88\u54EA\u6761 rule\u300D\u3002\u5927\u6A21\u578B\u8D70\u5230\u8BE5\u9636\u6BB5\u65F6\uFF0Cdev_task \u53EA\u62AB\u9732\u8FD9\u9636\u6BB5\u6302\u8F7D\u7684\u5185\u5BB9\uFF1B\u8981\u65B0\u5EFA\u6216\u6539\u6B63\u6587\uFF0C\u8BF7\u5207\u5230\u4E0A\u65B9\u7684\u300C\u6280\u80FD / \u89C4\u5219\u300D\u6807\u7B7E\u9875\u3002", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BindingEditor, { config, setConfig, skills, rules }) }),
4956
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionCard, { icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconBranchOutline16, { size: 16 }), title: "\u9636\u6BB5\u6280\u80FD / \u89C4\u5219", hint: "\u9009\u4E00\u4E2A\u9636\u6BB5\uFF0C\u52FE\u9009\u5B83\u300C\u7528\u4EC0\u4E48 skill\uFF08\u6280\u80FD\uFF09\u300D\u548C\u300C\u5B88\u54EA\u6761 rule\uFF08\u89C4\u5219\uFF09\u300D\u3002\u5927\u6A21\u578B\u8D70\u5230\u8BE5\u9636\u6BB5\u65F6\uFF0C\u53EA\u4F1A\u770B\u5230\u7ED9\u5B83\u6302\u8F7D\u7684\u8FD9\u51E0\u6761\u6280\u80FD\u4E0E\u89C4\u5219\uFF1B\u8981\u65B0\u5EFA\u6216\u6539\u6B63\u6587\uFF0C\u5207\u5230\u4E0A\u65B9\u7684\u300C\u6280\u80FD\u300D/\u300C\u89C4\u5219\u300D\u6807\u7B7E\u9875\u3002", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BindingEditor, { config, setConfig, skills, rules }) }),
4922
4957
  problems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.problems, children: [
4923
4958
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: styles.problemsTitle, children: [
4924
4959
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.StateDot, { state: "error" }),
@@ -5108,7 +5143,7 @@ function TransitionEditor({ config, setConfig }) {
5108
5143
  onClick: () => {
5109
5144
  toggleGuard(i, g.value);
5110
5145
  },
5111
- title: `\u5B88\u536B ${g.value}`,
5146
+ title: g.hint,
5112
5147
  children: g.label
5113
5148
  },
5114
5149
  g.value
@@ -5144,10 +5179,10 @@ function ArtifactEditor({ config, setConfig }) {
5144
5179
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { style: control, value: a.stage, onChange: (ev) => {
5145
5180
  setArtifact(i, { stage: ev.target.value });
5146
5181
  }, children: config.stages.map((s) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: s, children: s }, s)) }),
5147
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { style: { ...control, flex: "1 1 120px" }, placeholder: "id", value: a.id, onChange: (ev) => {
5182
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { style: { ...control, flex: "1 1 110px" }, placeholder: "\u82F1\u6587 id\uFF08\u5982 requirement\uFF09", value: a.id, onChange: (ev) => {
5148
5183
  setArtifact(i, { id: ev.target.value });
5149
5184
  } }),
5150
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { style: { ...control, flex: "1 1 140px" }, placeholder: "\u540D\u79F0", value: a.name, onChange: (ev) => {
5185
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { style: { ...control, flex: "1 1 130px" }, placeholder: "\u540D\u79F0\uFF08\u7ED9\u4EBA\u770B\uFF0C\u5982 \u9700\u6C42\u8BF4\u660E\uFF09", value: a.name, onChange: (ev) => {
5151
5186
  setArtifact(i, { name: ev.target.value });
5152
5187
  } }),
5153
5188
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "ghost", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 }), onClick: () => {
@@ -5158,7 +5193,7 @@ function ArtifactEditor({ config, setConfig }) {
5158
5193
  "input",
5159
5194
  {
5160
5195
  style: control,
5161
- placeholder: "\u5B57\u6BB5\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u5982 scope, acceptance_criteria\uFF09",
5196
+ placeholder: "\u8981\u586B\u7684\u5B57\u6BB5\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u5982 scope, acceptance_criteria\uFF09",
5162
5197
  value: a.fields.join(", "),
5163
5198
  onChange: (ev) => {
5164
5199
  setArtifact(i, { fields: splitList(ev.target.value) });
@@ -5284,7 +5319,7 @@ function BindingEditor({ config, setConfig, skills, rules }) {
5284
5319
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: cardV, children: [
5285
5320
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.bindingStage, children: [
5286
5321
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.fieldLabel, children: "skill\uFF08\u8FD9\u4E2A\u9636\u6BB5\u505A\u4EC0\u4E48\uFF09" }),
5287
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles.chips, children: skills.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.sourceBadge, children: "\u6682\u65E0\u53EF\u7528 skill\uFF0C\u53EF\u5728\u300C\u65B0\u5EFA skill / rule\u300D\u91CC\u5EFA" }) : skills.map((sk) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dsh_client_ui_primitives.Pill, { active: boundSkills.includes(sk.name), onClick: () => {
5322
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles.chips, children: skills.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.sourceBadge, children: "\u6682\u65E0\u53EF\u7528 skill \u2014\u2014 \u5207\u5230\u4E0A\u65B9\u300C\u6280\u80FD\u300D\u6807\u7B7E\u9875\u65B0\u5EFA" }) : skills.map((sk) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dsh_client_ui_primitives.Pill, { active: boundSkills.includes(sk.name), onClick: () => {
5288
5323
  toggleSkill(sk.name);
5289
5324
  }, title: `${sk.description}\uFF08${sourceLabel(sk.source)}\uFF09`, children: [
5290
5325
  sk.name,
@@ -5297,7 +5332,7 @@ function BindingEditor({ config, setConfig, skills, rules }) {
5297
5332
  ] }),
5298
5333
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.bindingStage, children: [
5299
5334
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.fieldLabel, children: "rule\uFF08\u8FD9\u4E2A\u9636\u6BB5\u5B88\u4EC0\u4E48\uFF09" }),
5300
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles.chips, children: rules.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.sourceBadge, children: "\u6682\u65E0\u53EF\u7528 rule\uFF0C\u53EF\u5728\u300C\u65B0\u5EFA skill / rule\u300D\u91CC\u5EFA" }) : rules.map((rule) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dsh_client_ui_primitives.Pill, { active: boundRules.includes(rule.name), onClick: () => {
5335
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles.chips, children: rules.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.sourceBadge, children: "\u6682\u65E0\u53EF\u7528 rule \u2014\u2014 \u5207\u5230\u4E0A\u65B9\u300C\u89C4\u5219\u300D\u6807\u7B7E\u9875\u65B0\u5EFA" }) : rules.map((rule) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dsh_client_ui_primitives.Pill, { active: boundRules.includes(rule.name), onClick: () => {
5301
5336
  toggleRule(rule.name);
5302
5337
  }, title: `\u6765\u6E90\uFF1A${sourceLabel(rule.source)}`, children: [
5303
5338
  rule.name,
@@ -5356,6 +5391,7 @@ function SkillManager({ workspace, remote }) {
5356
5391
  const [skills, setSkills] = (0, import_react3.useState)([]);
5357
5392
  const [level, setLevel] = (0, import_react3.useState)("project");
5358
5393
  const [editing, setEditing] = (0, import_react3.useState)(null);
5394
+ const [creating, setCreating] = (0, import_react3.useState)(false);
5359
5395
  const [name, setName] = (0, import_react3.useState)("");
5360
5396
  const [description, setDescription] = (0, import_react3.useState)("");
5361
5397
  const [whenToUse, setWhenToUse] = (0, import_react3.useState)("");
@@ -5372,6 +5408,7 @@ function SkillManager({ workspace, remote }) {
5372
5408
  }, [refresh]);
5373
5409
  const startCreate = () => {
5374
5410
  setEditing(null);
5411
+ setCreating(true);
5375
5412
  setLevel("project");
5376
5413
  setName("");
5377
5414
  setDescription("");
@@ -5382,6 +5419,7 @@ function SkillManager({ workspace, remote }) {
5382
5419
  const startEdit = (sk) => {
5383
5420
  const lvl = levelOf(sk.source);
5384
5421
  setEditing(sk.name);
5422
+ setCreating(false);
5385
5423
  setLevel(lvl);
5386
5424
  setMsg("");
5387
5425
  void remote.readSkill({ name: sk.name, level: lvl, path: workspace }).then((r) => {
@@ -5416,9 +5454,10 @@ function SkillManager({ workspace, remote }) {
5416
5454
  }
5417
5455
  setMsg(`\u5DF2\u4FDD\u5B58 skill\u300C${result.value.name}\u300D`);
5418
5456
  setEditing(null);
5457
+ setCreating(false);
5419
5458
  refresh();
5420
5459
  };
5421
- const formOpen = editing !== null || name !== "" || description !== "" || body2 !== "";
5460
+ const formOpen = editing !== null || creating;
5422
5461
  return (0, import_react3.createElement)(
5423
5462
  "div",
5424
5463
  { style: styles.section },
@@ -5495,6 +5534,7 @@ function SkillManager({ workspace, remote }) {
5495
5534
  }, "\u4FDD\u5B58"),
5496
5535
  (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "ghost", size: "sm", onClick: () => {
5497
5536
  setEditing(null);
5537
+ setCreating(false);
5498
5538
  setName("");
5499
5539
  setDescription("");
5500
5540
  setWhenToUse("");
@@ -5538,6 +5578,7 @@ function RuleManager({ workspace, remote }) {
5538
5578
  const [rules, setRules] = (0, import_react4.useState)([]);
5539
5579
  const [level, setLevel] = (0, import_react4.useState)("project");
5540
5580
  const [editing, setEditing] = (0, import_react4.useState)(null);
5581
+ const [creating, setCreating] = (0, import_react4.useState)(false);
5541
5582
  const [name, setName] = (0, import_react4.useState)("");
5542
5583
  const [body2, setBody] = (0, import_react4.useState)("");
5543
5584
  const [msg, setMsg] = (0, import_react4.useState)("");
@@ -5552,6 +5593,7 @@ function RuleManager({ workspace, remote }) {
5552
5593
  }, [refresh]);
5553
5594
  const startCreate = () => {
5554
5595
  setEditing(null);
5596
+ setCreating(true);
5555
5597
  setLevel("project");
5556
5598
  setName("");
5557
5599
  setBody("");
@@ -5560,6 +5602,7 @@ function RuleManager({ workspace, remote }) {
5560
5602
  const startEdit = (rule) => {
5561
5603
  const lvl = levelOf2(rule.source);
5562
5604
  setEditing(rule.name);
5605
+ setCreating(false);
5563
5606
  setLevel(lvl);
5564
5607
  setMsg("");
5565
5608
  void remote.readRule({ name: rule.name, level: lvl, path: workspace }).then((r) => {
@@ -5589,9 +5632,10 @@ function RuleManager({ workspace, remote }) {
5589
5632
  }
5590
5633
  setMsg(`\u5DF2\u4FDD\u5B58 rule\u300C${result.value.name}\u300D`);
5591
5634
  setEditing(null);
5635
+ setCreating(false);
5592
5636
  refresh();
5593
5637
  };
5594
- const formOpen = editing !== null || name !== "" || body2 !== "";
5638
+ const formOpen = editing !== null || creating;
5595
5639
  return (0, import_react4.createElement)(
5596
5640
  "div",
5597
5641
  { style: styles.section },
@@ -5657,6 +5701,7 @@ function RuleManager({ workspace, remote }) {
5657
5701
  }, "\u4FDD\u5B58"),
5658
5702
  (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "ghost", size: "sm", onClick: () => {
5659
5703
  setEditing(null);
5704
+ setCreating(false);
5660
5705
  setName("");
5661
5706
  setBody("");
5662
5707
  setMsg("");
@@ -5671,6 +5716,152 @@ function RuleManager({ workspace, remote }) {
5671
5716
  );
5672
5717
  }
5673
5718
 
5719
+ // src/client/TaskLedger.tsx
5720
+ var import_react5 = require("react");
5721
+ var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
5722
+ var card3 = {
5723
+ display: "flex",
5724
+ flexDirection: "column",
5725
+ gap: 10,
5726
+ border: "1px solid var(--dsw-alias-border-l2)",
5727
+ borderRadius: 8,
5728
+ padding: "12px 14px"
5729
+ };
5730
+ var headerRow = {
5731
+ display: "flex",
5732
+ alignItems: "center",
5733
+ gap: 8,
5734
+ flexWrap: "wrap"
5735
+ };
5736
+ var itemRow = {
5737
+ display: "flex",
5738
+ flexDirection: "column",
5739
+ gap: 4,
5740
+ padding: "8px 0",
5741
+ borderTop: "1px solid var(--dsw-alias-border-l2)"
5742
+ };
5743
+ var metaLine = {
5744
+ display: "flex",
5745
+ alignItems: "center",
5746
+ gap: 6,
5747
+ flexWrap: "wrap",
5748
+ fontSize: 12,
5749
+ color: "var(--dsw-alias-label-secondary)"
5750
+ };
5751
+ var badge = {
5752
+ fontSize: 11,
5753
+ padding: "1px 7px",
5754
+ borderRadius: 10,
5755
+ border: "1px solid var(--dsw-alias-border-l2)",
5756
+ color: "var(--dsw-alias-label-secondary)"
5757
+ };
5758
+ function verdictDot(outcome) {
5759
+ return (0, import_react5.createElement)(import_dsh_client_ui_primitives4.StateDot, { state: outcome === "pass" ? "done" : "error" });
5760
+ }
5761
+ function itemStatusDot(status) {
5762
+ return (0, import_react5.createElement)(import_dsh_client_ui_primitives4.StateDot, { state: status === "done" ? "done" : "ongoing" });
5763
+ }
5764
+ function timeText(at) {
5765
+ return at.slice(0, 19).replace("T", " ");
5766
+ }
5767
+ function itemAudit(item) {
5768
+ const lines = [];
5769
+ if (item.dispatch !== void 0) {
5770
+ lines.push((0, import_react5.createElement)(
5771
+ "div",
5772
+ { key: "dispatch", style: metaLine },
5773
+ (0, import_react5.createElement)("span", { style: badge }, "\u5DF2\u6D3E\u53D1"),
5774
+ (0, import_react5.createElement)("span", null, item.dispatch.description === "" ? "\uFF08\u65E0\u63CF\u8FF0\uFF09" : item.dispatch.description),
5775
+ (0, import_react5.createElement)("span", { style: badge }, timeText(item.dispatch.at))
5776
+ ));
5777
+ }
5778
+ if (item.review !== void 0) {
5779
+ const spec = item.review.spec;
5780
+ const quality = item.review.quality;
5781
+ lines.push((0, import_react5.createElement)(
5782
+ "div",
5783
+ { key: "review", style: metaLine },
5784
+ verdictDot(spec.outcome),
5785
+ (0, import_react5.createElement)("span", null, `\u89C4\u683C\u7B26\u5408 ${spec.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`),
5786
+ (0, import_react5.createElement)("span", null, "\xB7"),
5787
+ verdictDot(quality.outcome),
5788
+ (0, import_react5.createElement)("span", null, `\u4EE3\u7801\u8D28\u91CF ${quality.outcome === "pass" ? "\u901A\u8FC7" : "\u4E0D\u901A\u8FC7"}`)
5789
+ ));
5790
+ const failNotes = [spec, quality].flatMap((stage) => stage.outcome === "fail" ? stage.notes ?? [] : []);
5791
+ if (failNotes.length > 0) {
5792
+ lines.push((0, import_react5.createElement)(
5793
+ "div",
5794
+ { key: "notes", style: metaLine },
5795
+ ...failNotes.map((note) => (0, import_react5.createElement)("span", { key: note, style: badge }, note))
5796
+ ));
5797
+ }
5798
+ }
5799
+ if (lines.length === 0) {
5800
+ lines.push((0, import_react5.createElement)("div", { key: "none", style: metaLine }, (0, import_react5.createElement)("span", { style: badge }, "\u672A\u6D3E\u53D1 / \u672A\u5BA1\u67E5")));
5801
+ }
5802
+ return (0, import_react5.createElement)("div", { style: { display: "flex", flexDirection: "column", gap: 4 } }, ...lines);
5803
+ }
5804
+ function TaskLedger({ workspace, remote }) {
5805
+ const [tasks, setTasks] = (0, import_react5.useState)([]);
5806
+ const [error, setError] = (0, import_react5.useState)("");
5807
+ const refresh = (0, import_react5.useCallback)(() => {
5808
+ if (workspace === "") return;
5809
+ setError("");
5810
+ void remote.readTasks(workspace).then((result) => {
5811
+ if (result.ok) setTasks(result.value.tasks);
5812
+ else setError("\u8BFB\u53D6\u53F0\u8D26\u5931\u8D25\uFF1A" + describeError(result.error));
5813
+ }, (reason) => {
5814
+ setError("\u8BFB\u53D6\u53F0\u8D26\u5931\u8D25\uFF1A" + describeError(reason));
5815
+ });
5816
+ }, [remote, workspace]);
5817
+ (0, import_react5.useEffect)(() => {
5818
+ refresh();
5819
+ }, [refresh]);
5820
+ return (0, import_react5.createElement)(
5821
+ "div",
5822
+ { style: styles.section },
5823
+ (0, import_react5.createElement)(
5824
+ "div",
5825
+ { style: headerRow },
5826
+ (0, import_react5.createElement)("span", { style: styles.bindingLabel }, "\u4EFB\u52A1\u53F0\u8D26"),
5827
+ (0, import_react5.createElement)("span", { style: styles.sourceBadge }, "\u53EA\u8BFB \xB7 \u6765\u81EA .dsh/task-*.json"),
5828
+ (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Button, { variant: "outline", size: "sm", onClick: refresh }, "\u5237\u65B0")
5829
+ ),
5830
+ error !== "" ? (0, import_react5.createElement)("p", { style: styles.status }, error) : tasks.length === 0 ? (0, import_react5.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") : (0, import_react5.createElement)(
5831
+ "div",
5832
+ { style: { display: "flex", flexDirection: "column", gap: 12 } },
5833
+ ...tasks.map((task) => (0, import_react5.createElement)(
5834
+ "div",
5835
+ { key: task.task_id, style: card3 },
5836
+ (0, import_react5.createElement)(
5837
+ "div",
5838
+ { style: headerRow },
5839
+ (0, import_react5.createElement)("span", { style: { fontSize: 14, fontWeight: 600, color: "var(--dsw-alias-label-primary)" } }, task.task_id),
5840
+ (0, import_react5.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, task.title),
5841
+ (0, import_react5.createElement)("span", { style: badge }, task.stage),
5842
+ (0, import_react5.createElement)("span", { style: badge }, task.branch)
5843
+ ),
5844
+ (0, import_react5.createElement)(
5845
+ "div",
5846
+ { style: { display: "flex", flexDirection: "column" } },
5847
+ ...task.items.map((item) => (0, import_react5.createElement)(
5848
+ "div",
5849
+ { key: item.id, style: itemRow },
5850
+ (0, import_react5.createElement)(
5851
+ "div",
5852
+ { style: headerRow },
5853
+ itemStatusDot(item.status),
5854
+ (0, import_react5.createElement)("span", { style: { fontSize: 13, color: "var(--dsw-alias-label-primary)" } }, item.id),
5855
+ (0, import_react5.createElement)("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, item.title)
5856
+ ),
5857
+ itemAudit(item)
5858
+ ))
5859
+ )
5860
+ ))
5861
+ )
5862
+ );
5863
+ }
5864
+
5674
5865
  // src/client/Workbench.tsx
5675
5866
  var overlay = {
5676
5867
  position: "absolute",
@@ -5722,58 +5913,59 @@ var closeStyle = {
5722
5913
  };
5723
5914
  var TABS = [
5724
5915
  { id: "flow", label: "\u6D41\u7A0B\u914D\u7F6E" },
5916
+ { id: "tasks", label: "\u4EFB\u52A1\u53F0\u8D26" },
5725
5917
  { id: "skills", label: "\u6280\u80FD skill" },
5726
5918
  { id: "rules", label: "\u89C4\u5219 rule" }
5727
5919
  ];
5728
5920
  function Workbench({ useStore, actions, useWorkspaces, remote }) {
5729
5921
  const open = useStore((s) => s.open);
5730
5922
  const workspaces = useWorkspaces((s) => s.items);
5731
- const [tab, setTab] = (0, import_react5.useState)("flow");
5732
- const [workspace, setWorkspace] = (0, import_react5.useState)("");
5923
+ const [tab, setTab] = (0, import_react6.useState)("flow");
5924
+ const [workspace, setWorkspace] = (0, import_react6.useState)("");
5733
5925
  if (!open) return null;
5734
5926
  const current = workspaces.some((w) => w.path === workspace) ? workspace : workspaces[0]?.path ?? "";
5735
- return (0, import_react5.createElement)(
5927
+ return (0, import_react6.createElement)(
5736
5928
  "div",
5737
5929
  { style: overlay },
5738
- (0, import_react5.createElement)(
5930
+ (0, import_react6.createElement)(
5739
5931
  "div",
5740
5932
  { style: header },
5741
- (0, import_react5.createElement)("span", { style: { fontSize: 15, fontWeight: 600, color: "var(--dsw-alias-label-primary)" } }, "\u5DE5\u7A0B\u6D41\u7A0B"),
5742
- (0, import_react5.createElement)(
5933
+ (0, import_react6.createElement)("span", { style: { fontSize: 15, fontWeight: 600, color: "var(--dsw-alias-label-primary)" } }, "\u5DE5\u7A0B\u6D41\u7A0B"),
5934
+ (0, import_react6.createElement)(
5743
5935
  "button",
5744
5936
  { type: "button", title: "\u5173\u95ED", onClick: () => {
5745
5937
  actions.close();
5746
5938
  }, style: closeStyle },
5747
- (0, import_react5.createElement)(import_dsh_client_ui_primitives4.IconCloseOutline16, { size: 16 })
5939
+ (0, import_react6.createElement)(import_dsh_client_ui_primitives5.IconCloseOutline16, { size: 16 })
5748
5940
  )
5749
5941
  ),
5750
- (0, import_react5.createElement)(
5942
+ (0, import_react6.createElement)(
5751
5943
  "div",
5752
5944
  { style: tabbar },
5753
- ...TABS.map((t) => (0, import_react5.createElement)(import_dsh_client_ui_primitives4.Pill, { key: t.id, active: tab === t.id, onClick: () => {
5945
+ ...TABS.map((t) => (0, import_react6.createElement)(import_dsh_client_ui_primitives5.Pill, { key: t.id, active: tab === t.id, onClick: () => {
5754
5946
  setTab(t.id);
5755
5947
  } }, t.label)),
5756
- workspaces.length > 0 ? (0, import_react5.createElement)("select", {
5948
+ workspaces.length > 0 ? (0, import_react6.createElement)("select", {
5757
5949
  style: selectStyle,
5758
5950
  value: current,
5759
5951
  onChange: (ev) => {
5760
5952
  setWorkspace(ev.target.value);
5761
5953
  }
5762
- }, ...workspaces.map((w) => (0, import_react5.createElement)("option", { key: w.path, value: w.path }, w.title || w.path))) : null
5954
+ }, ...workspaces.map((w) => (0, import_react6.createElement)("option", { key: w.path, value: w.path }, w.title || w.path))) : null
5763
5955
  ),
5764
- (0, import_react5.createElement)(
5956
+ (0, import_react6.createElement)(
5765
5957
  "div",
5766
5958
  { style: body },
5767
- current === "" ? (0, import_react5.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\uFF0C\u518D\u56DE\u6765\u914D\u7F6E\u6D41\u7A0B\u3002") : tab === "flow" ? (0, import_react5.createElement)(TaskEngineSection, { workspace: current, remote }) : tab === "skills" ? (0, import_react5.createElement)(SkillManager, { workspace: current, remote }) : (0, import_react5.createElement)(RuleManager, { workspace: current, remote })
5959
+ current === "" ? (0, import_react6.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\uFF0C\u518D\u56DE\u6765\u914D\u7F6E\u6D41\u7A0B\u3002") : tab === "flow" ? (0, import_react6.createElement)(TaskEngineSection, { workspace: current, remote }) : tab === "tasks" ? (0, import_react6.createElement)(TaskLedger, { workspace: current, remote }) : tab === "skills" ? (0, import_react6.createElement)(SkillManager, { workspace: current, remote }) : (0, import_react6.createElement)(RuleManager, { workspace: current, remote })
5768
5960
  )
5769
5961
  );
5770
5962
  }
5771
5963
 
5772
5964
  // src/client/TriggerButton.tsx
5773
- var import_react6 = require("react");
5774
- var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
5965
+ var import_react7 = require("react");
5966
+ var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
5775
5967
  function TriggerButton({ wide, actions }) {
5776
- return (0, import_react6.createElement)(
5968
+ return (0, import_react7.createElement)(
5777
5969
  "button",
5778
5970
  {
5779
5971
  type: "button",
@@ -5798,8 +5990,8 @@ function TriggerButton({ wide, actions }) {
5798
5990
  boxSizing: "border-box"
5799
5991
  }
5800
5992
  },
5801
- (0, import_react6.createElement)(import_dsh_client_ui_primitives5.IconSettingsOutline16, { size: wide ? 16 : 18 }),
5802
- wide ? (0, import_react6.createElement)("span", { style: { fontSize: 13 } }, "\u5DE5\u7A0B\u6D41\u7A0B") : null
5993
+ (0, import_react7.createElement)(import_dsh_client_ui_primitives6.IconSettingsOutline16, { size: wide ? 16 : 18 }),
5994
+ wide ? (0, import_react7.createElement)("span", { style: { fontSize: 13 } }, "\u5DE5\u7A0B\u6D41\u7A0B") : null
5803
5995
  );
5804
5996
  }
5805
5997