mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-07 02:51:50 +00:00
feat(kanban-dashboard): workspace kind + path inputs in inline create form (#19679)
Closes #18718. Exposes the existing `workspace_kind` + `workspace_path` fields (already accepted by POST /api/plugins/kanban/tasks) in the dashboard's per-column inline-create form so users can create tasks targeting a git worktree or an explicit directory without dropping back to the CLI. - Add a workspace-kind Select (scratch / worktree / dir) to InlineCreate in plugins/kanban/dashboard/dist/index.js. - Conditionally render a workspace_path Input next to the select when kind != scratch; placeholder tells the user whether the path is required (dir) or optional (worktree — derived from assignee when blank). - Submit wires `workspace_kind` / `workspace_path` into the POST body only when they're non-default, keeping the request shape small and interoperable with older dispatcher versions. E2E verified in a dashboard pointed at the worktree: selecting dir + typing /tmp/test-18718 produces a POST body with {workspace_kind: 'dir', workspace_path: '/tmp/test-18718'} and the task lands in sqlite with those fields set. 42/42 kanban dashboard plugin tests pass.
This commit is contained in:
parent
a219a0a4df
commit
33f554d83c
1 changed files with 37 additions and 0 deletions
37
plugins/kanban/dashboard/dist/index.js
vendored
37
plugins/kanban/dashboard/dist/index.js
vendored
|
|
@ -919,6 +919,12 @@
|
||||||
const [priority, setPriority] = useState(0);
|
const [priority, setPriority] = useState(0);
|
||||||
const [parent, setParent] = useState("");
|
const [parent, setParent] = useState("");
|
||||||
const [skills, setSkills] = useState("");
|
const [skills, setSkills] = useState("");
|
||||||
|
// Workspace controls. `scratch` (default) ignores path; `worktree` optionally
|
||||||
|
// takes a path (dispatcher derives one from the assignee profile otherwise);
|
||||||
|
// `dir` requires a path. Backend enforces the rule — we only hide/show the
|
||||||
|
// input here to save vertical space in the common `scratch` case.
|
||||||
|
const [workspaceKind, setWorkspaceKind] = useState("scratch");
|
||||||
|
const [workspacePath, setWorkspacePath] = useState("");
|
||||||
|
|
||||||
const submit = function () {
|
const submit = function () {
|
||||||
const trimmed = title.trim();
|
const trimmed = title.trim();
|
||||||
|
|
@ -938,10 +944,23 @@
|
||||||
.map(function (s) { return s.trim(); })
|
.map(function (s) { return s.trim(); })
|
||||||
.filter(function (s) { return s.length > 0; });
|
.filter(function (s) { return s.length > 0; });
|
||||||
if (skillList.length > 0) body.skills = skillList;
|
if (skillList.length > 0) body.skills = skillList;
|
||||||
|
// Only send workspace_kind when it's non-default. Keeps the request
|
||||||
|
// shape small and interoperable with older dispatcher versions.
|
||||||
|
if (workspaceKind && workspaceKind !== "scratch") {
|
||||||
|
body.workspace_kind = workspaceKind;
|
||||||
|
}
|
||||||
|
const wpTrim = workspacePath.trim();
|
||||||
|
if (wpTrim) body.workspace_path = wpTrim;
|
||||||
props.onSubmit(body);
|
props.onSubmit(body);
|
||||||
setTitle(""); setAssignee(""); setPriority(0); setParent(""); setSkills("");
|
setTitle(""); setAssignee(""); setPriority(0); setParent(""); setSkills("");
|
||||||
|
setWorkspaceKind("scratch"); setWorkspacePath("");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showPathInput = workspaceKind !== "scratch";
|
||||||
|
const pathPlaceholder = workspaceKind === "dir"
|
||||||
|
? "workspace path (required, e.g. ~/projects/my-app)"
|
||||||
|
: "workspace path (optional, derived from assignee if blank)";
|
||||||
|
|
||||||
return h("div", { className: "hermes-kanban-inline-create" },
|
return h("div", { className: "hermes-kanban-inline-create" },
|
||||||
h(Input, {
|
h(Input, {
|
||||||
value: title,
|
value: title,
|
||||||
|
|
@ -978,6 +997,24 @@
|
||||||
title: "Force-load these skills into the worker (in addition to the built-in kanban-worker).",
|
title: "Force-load these skills into the worker (in addition to the built-in kanban-worker).",
|
||||||
className: "h-7 text-xs",
|
className: "h-7 text-xs",
|
||||||
}),
|
}),
|
||||||
|
h("div", { className: "flex gap-2" },
|
||||||
|
h(Select, {
|
||||||
|
value: workspaceKind,
|
||||||
|
onChange: function (e) { setWorkspaceKind(e.target.value); },
|
||||||
|
title: "scratch: isolated temp dir (default). worktree: git worktree on the assignee profile. dir: exact path (required below).",
|
||||||
|
className: "h-7 text-xs w-28",
|
||||||
|
},
|
||||||
|
h(SelectOption, { value: "scratch" }, "scratch"),
|
||||||
|
h(SelectOption, { value: "worktree" }, "worktree"),
|
||||||
|
h(SelectOption, { value: "dir" }, "dir"),
|
||||||
|
),
|
||||||
|
showPathInput ? h(Input, {
|
||||||
|
value: workspacePath,
|
||||||
|
onChange: function (e) { setWorkspacePath(e.target.value); },
|
||||||
|
placeholder: pathPlaceholder,
|
||||||
|
className: "h-7 text-xs flex-1",
|
||||||
|
}) : null,
|
||||||
|
),
|
||||||
h(Select, {
|
h(Select, {
|
||||||
value: parent,
|
value: parent,
|
||||||
onChange: function (e) { setParent(e.target.value); },
|
onChange: function (e) { setParent(e.target.value); },
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue