Repository navigation
fix(host): unknown-workspaceId 报错自带可用 id,workspaceId 接受项目路径(#58) - #59
Merged
Merged
Conversation
cloader#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).
Builds on the previous commit, which makes a miss self-explaining. This one removes the miss for the common case: a model passes its session cwd because that is the only project identity it can see, and `resolveByPath` — the resolver the claim boundary already uses — turns that path into the id. - `resolveWorkspaceArg`: registered id first, then `resolveByPath`. A `realpath` rejection means "not a project", not a tool failure, so it stays a plain miss. - `taskboard_list` filters on the resolved id; `taskboard_create` stores it, so a path-shaped argument can never reach the ledger. - Both parameter descriptions now say the path spelling is accepted, and the miss detail says "expected a project id or its directory path". Unchanged: an unresolvable id or path still fails with `not_found` (never zero rows), a registered project without tasks is still a legitimate zero, a valid cross-project id still filters, and refusals stay read-only. tests: R2 is rewritten (a registered path resolves and filters), R2b/R2c pin the unregistered path and the realpath-rejection arm, R11 covers create.
The detail rendered the calling session's project as `id (title)` — a spelling no resolver accepts, so a caller that copied the correction signal verbatim failed again on the next round trip. Render the id as an assignment instead (`retry with workspaceId=<id>`), never inside a parenthesis, and keep the title as an isolated quoted note: it stays readable for a human (ids are uuids) without touching the value's recoverability. Drop `own.path`. It echoes the caller's own cwd (this branch only exists when `callerWorkspace()` resolved that cwd), it is unbounded user-editable text that would undo the title clipping, and it recommends a value that starts failing the moment the directory is unreachable — list filtering is ledger-only, so the id keeps working then and a path does not. tests: R8/R8b updated, R8c added — extract `workspaceId=(\S+)` from the detail, feed it straight back to `taskboard_list`, assert rows === 2.
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.
现象
#52 之后传路径不再静默返回 0 条,改成报错(正确)。但报错本身没有可用的纠正信号:
调用方知道自己会话的
cwd,但注册表以 uuid 为键、工具面没有「我属于哪个项目」的自查询,于是它拿不到任何可用 id,只能再猜一次。更隐蔽的一层:即使详情里写出了 id,
id (title)这种展示拼接也是任何 resolver 都不接受的拼写——调用方照抄即再次失败,「纠错信号」形同虚设。三个提交
按 #58 里的讨论与维护者「就用 B」的决定,采用「报错自带本会话项目(A)+
workspaceId接受项目目录路径(B)」的组合,并把详情收敛成可原样回填的形态:301f22a184d0726954a7f301f22a):失败详情点名调用方自己的项目。纯文本改动,拒绝行为、错误码、只读保证全不动,既有断言一条不改。184d072):workspaceId接受项目目录路径。走 claim 边界本来就在用的resolveByPath;list用解析后的 id 过滤,create存解析后的 id(路径形状入参不进台账)。按 id 优先,路径只是别名。6954a7f):id 以赋值形态workspaceId=<id>给出,title 退为隔离旁注,去掉own.path。三个提交只改
src/host/tools.ts与tests/list-filters.spec.ts,可分别 review / 丢弃。提交 3 的实测依据
初版详情把两者拼成
this session's project is ws-a (A)。把该串原样回传给同一个工具:workspaceIdws-a/proj/aws-a (A)not_foundthis session's project is ws-a (A)not_found即菜单上的答案不可用。改为:
workspaceId=<id>独立成赋值形态、句末无标点,/workspaceId=(\S+)/摘取干净;title 用双引号隔离,即使被连带抄走也不影响取值。own.path一并去掉,理由三条:callerWorkspace()用 cwd 解析出来),信息增量为零;clipTitle收敛(单行 + 60 字符);list过滤是纯台账比对,目录被移走后 id 仍可用、path 必然失效——给出 path 等于推荐一个会坏的值。验证
npx tsc --noEmitnpx vitest run(全量)node verify.mjs lib/host/tools.js(构建产物回灌,R1–R9 + 路径别名 + 纠正信号)新增
R8c是本 PR 的关键用例:从详情里正则提取workspaceId=(\S+),把捕获组直接回传taskboard_list,断言rows === 2。既有用例全部只断报文形状,没有一条断「报文里的值真能用」,上面那个菜单不可用的问题正是这样漏过去的。R8b覆盖用户可编辑 title 的单行化 + 60 字符截断,防止换行/超长文本进上下文。刻意不动的地方
R7断言 revision 不变)。known projects: <id>, ...裸列表,未改成同样的赋值形态。clipTitle只压平空白与截断)。callerWorkspace()暴露成只读自查询工具;本 PR 只补入参侧与失败侧的纠正能力,可作为后续单独一条。refs #58