Skip to content

feat: auto-discover local shell skills from ./skills/#16

Merged
John-Lin merged 7 commits into
masterfrom
feature/local-shell-skills
Apr 6, 2026
Merged

feat: auto-discover local shell skills from ./skills/#16
John-Lin merged 7 commits into
masterfrom
feature/local-shell-skills

Conversation

@John-Lin
Copy link
Copy Markdown
Owner

@John-Lin John-Lin commented Apr 6, 2026

Summary

Enables the bot to load local shell skills (like obsidian-cli) through the agents SDK ShellTool with environment={"type": "local", ...}. Skills are auto-discovered from ./skills/*/SKILL.md at agent init — no config entries required.

Supersedes #9, which used an explicit shellSkills field in servers_config.json. Auto-discovery keeps the config file focused on MCP servers and instructions only.

How it works

  • bot/agents.py scans <repo>/skills/ for immediate subdirectories containing a SKILL.md
  • Skill name is the directory name
  • Description is parsed from the SKILL.md YAML frontmatter
  • Each discovered skill is passed to ShellTool as a ShellToolLocalSkill dict; the shared _shell_executor runs the resulting commands via create_subprocess_shell
  • skills/ is gitignored (except .gitignore itself) so users can drop their own skill directories in without polluting the repo

Config example

No config changes required. Drop a skill into ./skills/:

skills/
└── obsidian-cli/
    └── SKILL.md      # frontmatter: description is read from here

Test plan

  • uv run pytest tests/test_agents.py — 25 tests covering model selection, conversation state, history truncation, MCP config parsing, and _load_shell_skills (missing dir, single skill, multiple skills, dir without SKILL.md, MCP + skill coexistence)
  • Manual: point bot at a real vault via obsidian-cli skill and verify it can read/search/append notes

🤖 Generated with Claude Code

John-Lin and others added 4 commits April 6, 2026 22:06
Agents can now load local skill directories (e.g. ~/.claude/skills/) via
the shellSkills config key. Each skill's description is auto-read from its
SKILL.md frontmatter. A 30s-timeout async subprocess executor handles
command execution, respecting per-request timeout_ms when provided.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Skills are now loaded from <repo>/skills/*/SKILL.md at agent init
  instead of being listed in servers_config.json.
- Skill name is taken from the directory name; description is parsed
  from the SKILL.md YAML frontmatter.
- Rewrote _shell_executor to match the SDK ShellCommandRequest API:
  iterate action.commands and use create_subprocess_shell.
- Removed MagicMock-based executor tests; kept config-to-tool mapping
  tests against a monkeypatched SKILLS_DIR.
- Added skills/.gitignore so users can drop their own skills into the
  directory without polluting the repo.
mypy could not narrow the dict literal {"type": "local", "skills": ...}
to ShellToolLocalEnvironment; use the TypedDict constructors from the
agents SDK so the types are explicit.
@John-Lin John-Lin force-pushed the feature/local-shell-skills branch from 72cd2c4 to cdbbf12 Compare April 6, 2026 14:08
John-Lin added 3 commits April 6, 2026 22:14
- Strip matched quotes from YAML frontmatter description values
- Use ShellCommandRequest type instead of Any for executor parameter
- Use 'is not None' for timeout_ms check to distinguish 0 from None
- Catch OSError from create_subprocess_shell and return error message
- Append [exit code: N] to output for non-zero exit codes
- Add direct unit tests for _parse_skill_description and _shell_executor
Shell skills and ShellTool are now disabled by default. Set
SHELL_SKILLS_ENABLED=1 to opt in. Update README with the new env var,
add missing instructions.md mount in Docker example, and list shell
skills in the Features section.
@John-Lin John-Lin merged commit 058e38a into master Apr 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant