feat(FN-702): add kb_task_update tool to pi extension

- Add kb_task_update tool enabling AI agents to update task title, size, and column
- Add extension tests for the new kb_task_update tool
- Clean up unused CSS styles, dead test code, and stale route handlers
- Include changeset for the new tool addition
This commit is contained in:
gsxdsm
2026-04-02 13:22:05 -07:00
parent 2052f93294
commit 06ffd8e35e
3 changed files with 174 additions and 0 deletions

View File

@@ -75,6 +75,7 @@ describe("kb pi extension", () => {
it("registers all expected tools", () => {
const expected = [
"kb_task_create",
"kb_task_update",
"kb_task_list",
"kb_task_show",
"kb_task_attach",
@@ -167,6 +168,96 @@ describe("kb pi extension", () => {
});
});
describe("kb_task_update", () => {
it("updates task title", async () => {
const createTool = api.tools.get("kb_task_create")!;
await createTool.execute("c1", { description: "Original" }, undefined, undefined, makeCtx(tmpDir));
const updateTool = api.tools.get("kb_task_update")!;
const result = await updateTool.execute(
"u1",
{ id: "FN-001", title: "New Title" },
undefined,
undefined,
makeCtx(tmpDir),
);
expect(result.content[0].text).toContain("Updated FN-001");
expect(result.content[0].text).toContain("title");
expect(result.details.updatedFields).toEqual(["title"]);
// Verify via show
const showTool = api.tools.get("kb_task_show")!;
const show = await showTool.execute("s1", { id: "FN-001" }, undefined, undefined, makeCtx(tmpDir));
expect(show.content[0].text).toContain("New Title");
});
it("updates task description", async () => {
const createTool = api.tools.get("kb_task_create")!;
await createTool.execute("c1", { description: "Original desc" }, undefined, undefined, makeCtx(tmpDir));
const updateTool = api.tools.get("kb_task_update")!;
const result = await updateTool.execute(
"u1",
{ id: "FN-001", description: "Updated description" },
undefined,
undefined,
makeCtx(tmpDir),
);
expect(result.content[0].text).toContain("Updated FN-001");
expect(result.details.updatedFields).toEqual(["description"]);
});
it("updates task dependencies", async () => {
const createTool = api.tools.get("kb_task_create")!;
await createTool.execute("c1", { description: "First" }, undefined, undefined, makeCtx(tmpDir));
await createTool.execute("c2", { description: "Second" }, undefined, undefined, makeCtx(tmpDir));
const updateTool = api.tools.get("kb_task_update")!;
const result = await updateTool.execute(
"u1",
{ id: "FN-002", depends: ["FN-001"] },
undefined,
undefined,
makeCtx(tmpDir),
);
expect(result.content[0].text).toContain("Updated FN-002");
expect(result.details.updatedFields).toEqual(["dependencies"]);
});
it("updates multiple fields at once", async () => {
const createTool = api.tools.get("kb_task_create")!;
await createTool.execute("c1", { description: "Original" }, undefined, undefined, makeCtx(tmpDir));
const updateTool = api.tools.get("kb_task_update")!;
const result = await updateTool.execute(
"u1",
{ id: "FN-001", title: "New Title", description: "New desc", depends: [] },
undefined,
undefined,
makeCtx(tmpDir),
);
expect(result.details.updatedFields).toEqual(["title", "description", "dependencies"]);
});
it("returns error when task not found", async () => {
const updateTool = api.tools.get("kb_task_update")!;
const result = await updateTool.execute(
"u1",
{ id: "FN-999", title: "Nope" },
undefined,
undefined,
makeCtx(tmpDir),
);
expect(result.isError).toBe(true);
expect(result.content[0].text).toContain("FN-999 not found");
});
});
describe("kb_task_list", () => {
it("returns empty message when no tasks", async () => {
const tool = api.tools.get("kb_task_list")!;