Assume paths are relative to .cursor/skills/example/
The docs specify to include skill executables like this: scripts/helper.sh
and add corresponding instructions for the agent in SKILL.md to use scripts/helper.sh when needed.
This does not seem to translate into a predictable tool call.
Rather the agent will call the shell tool with either:
full path of the helper.sh called from the project root
command: .cursor/skills/example/scripts/helper.sh
or:
call it by the specified relative path with working_directory set to the skills directory
command: scripts/helper.sh
working_directory: .cursor/skills/example/
This leads to differing working directories.
Question: Is the scripts/ directory inside a skill just a suggestion or is it actually parsed and hooked up in some way when the skill is used?
Hey, thanks for the request. scripts/ inside a skill is just an org convention, not something that gets parsed or hooked at runtime. Nothing resolves scripts/helper.sh relative to the skill root, and nothing pins the cwd for skill scripts.
How it actually works: the agent gets SKILL.md by absolute path, reads it, then decides how to run the script using the normal shell tool. The shell tool default working directory is the workspace root, so you see two options: .cursor/skills/example/scripts/helper.sh from the root, or scripts/helper.sh with working_directory set to the skill folder. Both are functionally correct. The variation comes from the LLM-driven call, not from a bug.
To make it predictable, make the script independent of cwd:
Have the script detect its own directory, for example:
and reference nearby files and assets relative to $SCRIPT_DIR, not $PWD.
Or, in SKILL.md, explicitly say how to run the script, like run it via absolute path or run it from the skill directory.
Also keep in mind there is a known limitation. The shell tool does not always reliably follow working_directory, especially in multi-root workspaces. That is another reason to prefer the BASH_SOURCE[0] approach instead of relying on working_directory.
If you need a strict cwd guarantee, that is more about hooks hooks.json. Hooks have a defined cwd contract, unlike skill scripts. Let me know if this does not cover your case.