Skip to content

fix: make skill bash blocks work in Claude Code's shell (v3.7.0.1) - #120

Open
savvides wants to merge 1 commit into
mainfrom
fix/claude-code-shell-breakages
Open

savvides wants to merge 1 commit into
mainfrom
fix/claude-code-shell-breakages

Conversation

@savvides

Copy link
Copy Markdown
Owner

Why

Claude Code's Bash tool runs each skill block in the user's shell (zsh on macOS), with BSD tools, and in a new shell for each call. CI only ran bash, so several skill steps were broken for real users while every suite passed.

What was broken → fixed

Skill Problem Fix
course-export (IMSCC + SCORM) Package step used $_EXPORT_DIR from an earlier block → mv failed, rm -rf deleted the staging dir, step said "Export saved" Staging lives in the export folder; package step checks for and stops on PACKAGE_FAILED
course-export / course-import (Canvas) GNU-only head -n -1 → empty MODULE_ID on macOS, items posted to /modules//items sed '$d'
course-export / course-import (Canvas) Token had to be pasted into each command (variables don't survive between calls), which put it in the transcript .idstack/canvas.env (mode 600, git-ignored); every API block sources it; skills never ask for the token in chat
course-quality-review ls *.md *.docx … aborts in zsh when one glob has no match find
course-import (SCORM) for x in $SCO_HREFS doesn't word-split in zsh → reads one SCO while read loop
course-import Claimed Word support; Read can't parse .docx python3 stdlib extraction step (tested on 3.9)
10 report skills + pipeline templates/report.html.tmpl referenced relatively; doesn't exist in a course project Report block prints the plugin path; skill Reads it
pipeline, course-import, red-team AskUserQuestion given 5–9 options (tool max is 4) Regrouped / numbered list in chat; preamble documents the cap and plain-chat free text
preamble Update-check block exited 1 when no update → error on every skill start Exits 0

Tests

  • New test/test-skill-shell-zsh.sh (47 checks): extracts real blocks from the generated SKILL.md files and runs them under both bash and zsh -f in a scratch project — export packaging, Canvas flow with a fake curl, .docx, SCO loop, file discovery, and all six preamble blocks (same output in both shells). Hooked into smoke-test; CI installs zsh on Linux (test, mutation, release jobs).
  • New smoke-test guards for each pattern, each with a mutation case. mutation-test.sh: 148 guarded, 0 not guarded.
  • Locally: smoke-test, integration (51/51), setup (19/19), doctor (14/14), status (24/24), manifest-merge, preamble-python, check-doc-accuracy, check-citation-tiers all pass.

Not verified

  • A live Canvas push/import against a real Canvas instance (only the fake-curl flow is tested).
  • An end-to-end interactive run of each skill in Claude Code.

PR 2 (Claude-Code-only positioning, leak-guard extension, description triggers, removal of multi-host hedges) will stack on this branch.

🤖 Generated with Claude Code

Claude Code's Bash tool runs each block in the user's shell (zsh on macOS),
with BSD tools, in a new shell for each call. CI ran only bash, so these broke
for real users and passed every suite:

- course-export packaging used a folder variable from an earlier block, so
  mv failed, rm -rf deleted the staging dir, and the step reported success.
  Staging now lives in the export folder; the step stops with PACKAGE_FAILED.
  Same fix for SCORM.
- Canvas push/import used GNU-only `head -n -1` (empty MODULE_ID on macOS);
  now `sed '$d'`.
- Canvas token moved to .idstack/canvas.env (mode 600, git-ignored); every API
  block sources it, so the token never goes through the chat.
- course-quality-review bare-glob `ls` (zsh NOMATCH) -> find.
- course-import SCO loop relied on word-splitting (zsh) -> while read.
- course-import now extracts .docx text with python3 stdlib.
- Report steps print the plugin path of report.html.tmpl / report-format.md
  instead of a relative path that does not exist in a course project.
- AskUserQuestion questions capped at 4 options; free text goes to plain chat.
- Preamble update-check block no longer exits 1 when no update exists.

New test/test-skill-shell-zsh.sh runs the real blocks under bash and zsh
(smoke-test runs it; CI installs zsh on Linux). New smoke guards with
mutation cases for each pattern.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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