[FEATURE] Mods API: give the working directory for each tool call and each configured command hook
Status Open
Reported on v2.1.296
Maintainer reply None cached
Activity 0 comments · opened Oct 11, 2026
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
A guard mod resolves relative paths. On Claude Code 2.1.296 (macOS), the Mods API gives one folder per session:
/** Returns the directory the session runs in, absolute. */
cwd: () => Promise<string>; // $.session.cwd()
tool.call input holds tool, tool_use_id, the arguments and agentId?. ToolCheckInput holds tool, input, tool_use_id?, agentId?, ceiling?. Neither names the calling loop's folder.
- A subagent in a worktree resolves relative paths in its own folder.
rg pattern, or Grep with nopath, searches a folder the mod cannot name. - A command hook such as
python3 .claude/hooks/guard.pyspawns in a folder the engine picks. #91226 shows it follows the Bash tool'scd.$.settings.read()returns the command as written, so the mod cannot tell which script runs.
Settings hooks get cwd on stdin. Module hooks do not: "classic.PreToolUse alone differs: its e is ToolCallEnvelope, no more."
Proposed Solution
- Add a read-only
cwd: stringtotool.callandtool.checkinput: the folder where this call resolves relative paths. - Add
$.hooks.list(args?: { agentId?: string }): Promise<CommandHookInfo[]>, each{ event, matcher?, command, source: SettingsSource | 'plugin', cwd }, wherecwdis the folder the engine spawns that hook in for that loop.
Alternative Solutions
agent.spawn'scwd?is set only when the call names a folder, not forisolation: "worktree".- The Agent result's
worktreePatharrives after a foreground agent's tools ran. - For part 2, documenting that hooks spawn in the call's
cwdwould do.
Priority
Medium - Would be very helpful
Feature Category
Developer tools/SDK
Use Case Example
Arrester (github.com/dot-agi/arrester) stops detours after a block. This closes two README limits:
- "Searches that name no folder" can read a blocked file.
- "A relative path, such as
python3 .claude/hooks/guard.py, adds no guard."
Additional Context
Related, not the same: #83952 (show people the resolved hook file in /hooks) and #87890 (hook spawn folder ignores EnterWorktree).