lib/resolve-subagent-path.ts exports an async resolveSubagentPath(projectsPath, projectName, sessionId, agentId) that probes three candidate paths in priority order and returns the first one that exists, or null. It uses fs/promises#access. There is no unit test.
- Create
__tests__/lib/resolve-subagent-path.test.ts — model it on __tests__/lib/paths.test.ts for the tmpdir setup pattern.
- Import:
import { resolveSubagentPath } from "@/lib/resolve-subagent-path";
- Use
os.tmpdir() + mkdtemp in a beforeEach to build a fresh fixture tree per test, and rm({ recursive: true, force: true }) in afterEach.
- Cover: (a) candidate 1 wins (file at
<projectsPath>/<projectName>/agent-<id>.jsonl), (b) candidate 2 wins when 1 is missing, (c) candidate 3 wins when 1 and 2 are missing, (d) returns null when nothing exists, (e) a path-traversal agentId like ../escape is refused (the function uses relative() to detect escape).
- Run
bun run test:run and confirm all cases pass.
Out of scope: changing resolve-subagent-path.ts itself.
lib/resolve-subagent-path.tsexports an asyncresolveSubagentPath(projectsPath, projectName, sessionId, agentId)that probes three candidate paths in priority order and returns the first one that exists, ornull. It usesfs/promises#access. There is no unit test.__tests__/lib/resolve-subagent-path.test.ts— model it on__tests__/lib/paths.test.tsfor the tmpdir setup pattern.import { resolveSubagentPath } from "@/lib/resolve-subagent-path";os.tmpdir()+mkdtempin abeforeEachto build a fresh fixture tree per test, andrm({ recursive: true, force: true })inafterEach.<projectsPath>/<projectName>/agent-<id>.jsonl), (b) candidate 2 wins when 1 is missing, (c) candidate 3 wins when 1 and 2 are missing, (d) returnsnullwhen nothing exists, (e) a path-traversalagentIdlike../escapeis refused (the function usesrelative()to detect escape).bun run test:runand confirm all cases pass.Out of scope: changing
resolve-subagent-path.tsitself.