@godv61/dsh-task-engine 0.9.0 → 0.10.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
@@ -4816,12 +4816,12 @@ var cardV = {
4816
4816
  padding: "10px 12px"
4817
4817
  };
4818
4818
  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" }
4819
+ { value: "requirement_confirmation", label: "\u9700\u6C42\u786E\u8BA4", hint: "\u9700\u6C42\u5DF2\u7ECF\u4EBA\u786E\u8BA4\u8FC7" },
4820
+ { value: "solution_confirmation", label: "\u65B9\u6848\u786E\u8BA4", hint: "\u65B9\u6848\u5DF2\u7ECF\u4EBA\u786E\u8BA4\u8FC7" },
4821
+ { value: "todos_done", label: "\u5F85\u529E\u5B8C\u6210", hint: "\u4EFB\u52A1\u6E05\u5355\u91CC\u7684\u6BCF\u4E00\u9879\u90FD\u5DF2\u52FE\u9009\u5B8C\u6210" },
4822
+ { 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" },
4823
+ { value: "review_passed", label: "\u8BC4\u5BA1\u901A\u8FC7", hint: "\u4EE3\u7801\u5BA1\u6838\u7ED3\u8BBA\u4E3A\u901A\u8FC7" },
4824
+ { 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
4825
  ];
4826
4826
  var POLICY_OPTIONS = [
4827
4827
  { value: "task", label: "task", hint: "\u68C0\u67E5\u70B9\u4E00\u6B21\u63D0\u4EA4" },
@@ -4916,9 +4916,9 @@ function TaskEngineSection(props) {
4916
4916
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles.flowCard, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FlowDiagram, { config, onAddTransition: addTransition, onRemoveTransition: removeTransition }) }),
4917
4917
  /* @__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
4918
  /* @__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 }) }),
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\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
4920
  /* @__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 }) }),
4921
+ /* @__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
4922
  problems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.problems, children: [
4923
4923
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: styles.problemsTitle, children: [
4924
4924
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.StateDot, { state: "error" }),
@@ -5108,7 +5108,7 @@ function TransitionEditor({ config, setConfig }) {
5108
5108
  onClick: () => {
5109
5109
  toggleGuard(i, g.value);
5110
5110
  },
5111
- title: `\u5B88\u536B ${g.value}`,
5111
+ title: g.hint,
5112
5112
  children: g.label
5113
5113
  },
5114
5114
  g.value
@@ -5144,10 +5144,10 @@ function ArtifactEditor({ config, setConfig }) {
5144
5144
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { style: control, value: a.stage, onChange: (ev) => {
5145
5145
  setArtifact(i, { stage: ev.target.value });
5146
5146
  }, 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) => {
5147
+ /* @__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
5148
  setArtifact(i, { id: ev.target.value });
5149
5149
  } }),
5150
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { style: { ...control, flex: "1 1 140px" }, placeholder: "\u540D\u79F0", value: a.name, onChange: (ev) => {
5150
+ /* @__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
5151
  setArtifact(i, { name: ev.target.value });
5152
5152
  } }),
5153
5153
  /* @__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 +5158,7 @@ function ArtifactEditor({ config, setConfig }) {
5158
5158
  "input",
5159
5159
  {
5160
5160
  style: control,
5161
- placeholder: "\u5B57\u6BB5\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u5982 scope, acceptance_criteria\uFF09",
5161
+ placeholder: "\u8981\u586B\u7684\u5B57\u6BB5\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u5982 scope, acceptance_criteria\uFF09",
5162
5162
  value: a.fields.join(", "),
5163
5163
  onChange: (ev) => {
5164
5164
  setArtifact(i, { fields: splitList(ev.target.value) });
@@ -5284,7 +5284,7 @@ function BindingEditor({ config, setConfig, skills, rules }) {
5284
5284
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: cardV, children: [
5285
5285
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.bindingStage, children: [
5286
5286
  /* @__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: () => {
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 \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
5288
  toggleSkill(sk.name);
5289
5289
  }, title: `${sk.description}\uFF08${sourceLabel(sk.source)}\uFF09`, children: [
5290
5290
  sk.name,
@@ -5297,7 +5297,7 @@ function BindingEditor({ config, setConfig, skills, rules }) {
5297
5297
  ] }),
5298
5298
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.bindingStage, children: [
5299
5299
  /* @__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: () => {
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 \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
5301
  toggleRule(rule.name);
5302
5302
  }, title: `\u6765\u6E90\uFF1A${sourceLabel(rule.source)}`, children: [
5303
5303
  rule.name,
@@ -5356,6 +5356,7 @@ function SkillManager({ workspace, remote }) {
5356
5356
  const [skills, setSkills] = (0, import_react3.useState)([]);
5357
5357
  const [level, setLevel] = (0, import_react3.useState)("project");
5358
5358
  const [editing, setEditing] = (0, import_react3.useState)(null);
5359
+ const [creating, setCreating] = (0, import_react3.useState)(false);
5359
5360
  const [name, setName] = (0, import_react3.useState)("");
5360
5361
  const [description, setDescription] = (0, import_react3.useState)("");
5361
5362
  const [whenToUse, setWhenToUse] = (0, import_react3.useState)("");
@@ -5372,6 +5373,7 @@ function SkillManager({ workspace, remote }) {
5372
5373
  }, [refresh]);
5373
5374
  const startCreate = () => {
5374
5375
  setEditing(null);
5376
+ setCreating(true);
5375
5377
  setLevel("project");
5376
5378
  setName("");
5377
5379
  setDescription("");
@@ -5382,6 +5384,7 @@ function SkillManager({ workspace, remote }) {
5382
5384
  const startEdit = (sk) => {
5383
5385
  const lvl = levelOf(sk.source);
5384
5386
  setEditing(sk.name);
5387
+ setCreating(false);
5385
5388
  setLevel(lvl);
5386
5389
  setMsg("");
5387
5390
  void remote.readSkill({ name: sk.name, level: lvl, path: workspace }).then((r) => {
@@ -5416,9 +5419,10 @@ function SkillManager({ workspace, remote }) {
5416
5419
  }
5417
5420
  setMsg(`\u5DF2\u4FDD\u5B58 skill\u300C${result.value.name}\u300D`);
5418
5421
  setEditing(null);
5422
+ setCreating(false);
5419
5423
  refresh();
5420
5424
  };
5421
- const formOpen = editing !== null || name !== "" || description !== "" || body2 !== "";
5425
+ const formOpen = editing !== null || creating;
5422
5426
  return (0, import_react3.createElement)(
5423
5427
  "div",
5424
5428
  { style: styles.section },
@@ -5495,6 +5499,7 @@ function SkillManager({ workspace, remote }) {
5495
5499
  }, "\u4FDD\u5B58"),
5496
5500
  (0, import_react3.createElement)(import_dsh_client_ui_primitives2.Button, { variant: "ghost", size: "sm", onClick: () => {
5497
5501
  setEditing(null);
5502
+ setCreating(false);
5498
5503
  setName("");
5499
5504
  setDescription("");
5500
5505
  setWhenToUse("");
@@ -5538,6 +5543,7 @@ function RuleManager({ workspace, remote }) {
5538
5543
  const [rules, setRules] = (0, import_react4.useState)([]);
5539
5544
  const [level, setLevel] = (0, import_react4.useState)("project");
5540
5545
  const [editing, setEditing] = (0, import_react4.useState)(null);
5546
+ const [creating, setCreating] = (0, import_react4.useState)(false);
5541
5547
  const [name, setName] = (0, import_react4.useState)("");
5542
5548
  const [body2, setBody] = (0, import_react4.useState)("");
5543
5549
  const [msg, setMsg] = (0, import_react4.useState)("");
@@ -5552,6 +5558,7 @@ function RuleManager({ workspace, remote }) {
5552
5558
  }, [refresh]);
5553
5559
  const startCreate = () => {
5554
5560
  setEditing(null);
5561
+ setCreating(true);
5555
5562
  setLevel("project");
5556
5563
  setName("");
5557
5564
  setBody("");
@@ -5560,6 +5567,7 @@ function RuleManager({ workspace, remote }) {
5560
5567
  const startEdit = (rule) => {
5561
5568
  const lvl = levelOf2(rule.source);
5562
5569
  setEditing(rule.name);
5570
+ setCreating(false);
5563
5571
  setLevel(lvl);
5564
5572
  setMsg("");
5565
5573
  void remote.readRule({ name: rule.name, level: lvl, path: workspace }).then((r) => {
@@ -5589,9 +5597,10 @@ function RuleManager({ workspace, remote }) {
5589
5597
  }
5590
5598
  setMsg(`\u5DF2\u4FDD\u5B58 rule\u300C${result.value.name}\u300D`);
5591
5599
  setEditing(null);
5600
+ setCreating(false);
5592
5601
  refresh();
5593
5602
  };
5594
- const formOpen = editing !== null || name !== "" || body2 !== "";
5603
+ const formOpen = editing !== null || creating;
5595
5604
  return (0, import_react4.createElement)(
5596
5605
  "div",
5597
5606
  { style: styles.section },
@@ -5657,6 +5666,7 @@ function RuleManager({ workspace, remote }) {
5657
5666
  }, "\u4FDD\u5B58"),
5658
5667
  (0, import_react4.createElement)(import_dsh_client_ui_primitives3.Button, { variant: "ghost", size: "sm", onClick: () => {
5659
5668
  setEditing(null);
5669
+ setCreating(false);
5660
5670
  setName("");
5661
5671
  setBody("");
5662
5672
  setMsg("");