OpenSpace heredoc-file-write
Use shell heredoc syntax as a workaround when write_file fails on complex TypeScript/JSX/code files with encoding or escaping issues
install
source · Clone the upstream repo
git clone https://github.com/HKUDS/OpenSpace
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/HKUDS/OpenSpace "$T" && mkdir -p ~/.claude/skills && cp -r "$T/gdpval_bench/skills/heredoc-file-write" ~/.claude/skills/hkuds-openspace-heredoc-file-write && rm -rf "$T"
manifest:
gdpval_bench/skills/heredoc-file-write/SKILL.mdsource content
Heredoc File Write Workaround
When to Use This Skill
Use this pattern when:
repeatedly fails with "unknown error" or similar messageswrite_file- The target file contains complex code (TypeScript, JSX, JSON with special characters, etc.)
- Standard file writing approaches encounter encoding or escaping issues
- You need a reliable fallback method to create files
Core Technique
Switch from
write_file to run_shell using heredoc syntax with cat. The heredoc approach handles special characters, quotes, and complex content more reliably.
Step-by-Step Instructions
Step 1: Identify Write Failures
When
write_file fails repeatedly on the same file:
- Note the error message (e.g., "unknown error", encoding issues)
- Review the file content for special characters, nested quotes, or complex syntax
- Attempt the heredoc workaround below
Step 2: Use Heredoc Syntax
Execute shell command with heredoc:
cat > /path/to/file.tsx << 'EOF' // Your file content here import React from 'react'; const Component = () => { return <div>Hello</div>; }; export default Component; EOF
Step 3: Key Heredoc Rules
-
Use quoted delimiter (
not'EOF'
) to prevent variable expansion:EOF
= literal content (recommended for code files)'EOF'
= allows variable expansion (use only if needed)EOF
-
Match delimiters exactly: Opening and closing
must be on their own lines with no leading/trailing whitespaceEOF -
No escaping needed: Content between delimiters is taken literally when using quoted delimiter
Step 4: Verify File Creation
After executing the heredoc command:
- Check if file exists:
ls -la /path/to/file.tsx - Verify content:
orcat /path/to/file.tsxhead -20 /path/to/file.tsx - Proceed with subsequent tasks once confirmed
Example Scenarios
TypeScript/JSX Component
cat > src/components/Button.tsx << 'EOF' import React from 'react'; interface ButtonProps { label: string; onClick: () => void; } export const Button: React.FC<ButtonProps> = ({ label, onClick }) => { return ( <button onClick={onClick} className="btn-primary"> {label} </button> ); }; EOF
JSON Configuration
cat > tsconfig.json << 'EOF' { "compilerOptions": { "target": "ES2020", "module": "commonjs", "strict": true, "esModuleInterop": true }, "include": ["src/**/*"] } EOF
Complex Shell Script
cat > deploy.sh << 'EOF' #!/bin/bash set -e echo "Deploying..." if [ "$ENV" = "production" ]; then echo "Production deployment" fi EOF
Advantages Over write_file
- No escaping complexity: Quotes, backslashes, and special characters work naturally
- Preserves formatting: Indentation and line breaks remain exact
- Handles multi-line content: No need to concatenate strings or use base64
- More reliable: Shell handles file I/O directly with fewer abstraction layers
Limitations
- Creates files in shell execution context (ensure correct working directory)
- Less programmatic than
for dynamic content generationwrite_file - Requires shell access (may not work in restricted environments)
Troubleshooting
Problem: File not created at expected path
- Solution: Use absolute paths or verify current working directory with
pwd
Problem: Content appears corrupted
- Solution: Ensure delimiter is quoted (
) and closing delimiter has no trailing whitespace'EOF'
Problem: Permission denied
- Solution: Ensure target directory exists and you have write permissions