Repository navigation
fix(host): taskboard_list 校验 workspaceId 与 status/urgency 值域,消除静默假阴性 - #52
Merged
Merged
Conversation
…ing 0 taskboard_list compared workspaceId/status/urgency as plain strings, so an unknown workspace id or a misspelled enum silently filtered to zero rows — indistinguishable from a genuinely empty project and a false negative for the check-the-board-first discipline. An unregistered workspaceId now throws not_found (same message as taskboard_create) and status/urgency go through asStatus/asUrgency, whose plain Errors the existing fail() wraps as invalid_input. A legitimately empty project and omitted filters keep returning rows unchanged. lib/ rebuilt from src.
cloader
added a commit
that referenced
this pull request
Oct 23, 2026
lib/ moves back to build output (gitignored, regenerated by npm run build); prepublishOnly now builds and tests so the npm tarball always ships fresh lib. Changelog gains the 0.9.3 entry (#52 stays in 0.9.2 — v0.9.2 tag already exists), READMEs add 0.9.3, and the version bumps to 0.9.3.
This was referenced Oct 24, 2026
cloader
pushed a commit
that referenced
this pull request
Oct 25, 2026
#52 made an unknown `workspaceId` fail loudly instead of silently matching nothing, but a bare `unknown workspaceId <x>` still strands the caller: the registry keys projects by uuid, no tool answers "which project am I in", and the error just repeats back the value that was already known to be wrong. Name the expected shape, then hand back the calling session's own project (`callerWorkspace()` already resolves cwd) and, when that is unavailable (cwd in a subdirectory or in an unregistered directory), the registered projects — capped at 8 with a `+N more` tail. That is enough to correct in one round trip. Message-only: the rejection itself, its error code, and the read-only guarantee are untouched, and every existing assertion in tests/list-filters.spec.ts still holds as written. tests: R8/R9/R10 pin the detail (own project, unaffiliated fallback, create).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
现象(真实环境复现)
开工查板时把工作区路径当成
workspaceId传进去,得到「任务 0 条:无匹配任务」——与「确实没有任务」在返回文本上完全同形,模型拿不到纠正信号:同一个参数在写侧是硬的:
taskboard_create({ workspaceId: <路径> })报not_found: unknown workspaceId。status/urgency拼错同理,静默返回 0 条。根因
taskboard_list把过滤参数当成纯字符串比较(src/host/tools.ts:348-352),同一闭包里的workspaces、asStatus、asUrgency却都可用(create已在用,src/host/tools.ts:462-466)。文件第 31-32 行本来就 import 了asStatus/asUrgency,差异是纯逻辑遗漏。fail()(src/host/tools.ts:268)会把ToolError原样重抛、普通Error包成invalid_input,所以两条路径的错误码天然不同。为什么会传路径:模型知道自己会话的
cwd,但工具面里没有「我属于哪个项目」的自查询,callerWorkspace()→resolveByPath(cwd)已存在却没暴露成工具。解法
在
taskboard_list.execute的过滤之前补三行校验(src/host/tools.ts:348-350,与create共用同一组函数):验证
新增
tests/list-filters.spec.ts(mock deps 直调execute,不依赖宿主),覆盖:workspaceId=<未注册 uuid>not_foundworkspaceId=<文件系统路径>not_foundstatus=bogusinvalid_input,消息含合法状态清单urgency=bogusinvalid_input,消息含urgent, normal, relaxedstatus/urgency/真实 idnpx tsc --noEmit通过npx vitest run全量通过:39 files / 508 testssrc/host/tools.ts跑同一 spec,5 项失败(R1–R4、R7),R5/R6/R6b 通过——证明测的是真缺陷,且合法路径不受影响。lib/已用npm run build重建(作者在 #50 说过 lib 供 GitHub 安装使用)。刻意不动的地方
workspaceId仍返回 0 条——这是正确行为,不收紧。undefined)继续全量,不在缺失时报错。src/client/controller.ts的loadView()从 localStorage 恢复失效filters.workspaceId会把卡片滤空,见 [bug] 0.8.2 看板与项目下拉同时空白,响应体被截断/为空却报错误报为 "taskboard: HTTP 200" #42 附注)本次未处理,可作为后续单独一条。defineTool参数 schema 没有 enum 能力,值域校验只能手写进execute;这是其余过滤参数共同的坑,本次只补已确认的同源两处。是否该报错,还是该给「自查询工具」
status/urgency属于纯 bug(拼错就该报错)。workspaceId那条涉及契约判断:另一种解法是暴露callerWorkspace()成只读工具,让模型直接拿到自己的工作区 id,而不是靠报错教育。我倾向两者都要:报错拦住静默假阴性,自查询降低猜的成本。如果维护者认为后者才是正解,本 PR 可以只保留status/urgency两条。