From smalltalk-dev
Implements Pharo Smalltalk development workflow using Tonel format: editing class/package .st files, absolute-path imports, linting, testing cycle, and best practices like patterns and categorization.
How this skill is triggered — by the user, by Claude, or both
Slash command
/smalltalk-dev:smalltalk-developerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Implement the standard workflow for Pharo Smalltalk development using AI editors and the Tonel file format.
Implement the standard workflow for Pharo Smalltalk development using AI editors and the Tonel file format.
Before starting development, ensure the environment is ready:
src/ or .project): Use smalltalk-dev:st-setup-project skill to create boilerplatesmalltalk-dev:st-init skill to verify connection and set up environmentThe fundamental workflow for Smalltalk development consists of three steps that repeat:
Edit Tonel files directly in the AI editor. The AI editor is the single source of truth for code.
Key principle: All code changes happen in .st files, not in the Pharo image.
Tonel basics:
.st filepackage.stFor detailed Tonel syntax and examples, see Tonel Format Reference.
Follow the Style Guide for idiomatic Smalltalk.
Refer to Implementation Patterns for common patterns (Singleton, Settings, etc.).
Before importing, run lint to check code quality:
/st-lint src/MyPackage # Check Smalltalk best practices
Then import the package into the running Pharo image using absolute paths:
mcp__smalltalk-interop__import_package: 'MyPackage' path: '/home/user/project/src'
Critical rules:
After import, run tests to verify changes:
mcp__smalltalk-interop__run_class_test: 'MyClassTest'
mcp__smalltalk-interop__run_package_test: 'MyPackage-Tests'
If tests fail, return to step 1, fix the Tonel file, and repeat.
Always use absolute paths for imports:
✅ /home/user/myproject/src
❌ ./src
❌ ../myproject/src
Finding the source directory:
.project file for srcDirectory fieldsrc/, repositories/<project_root>/<srcDirectory>See Best Practices Reference for details.
Check BaselineOf<ProjectName> to determine correct import order:
baseline: spec
<baseline>
spec for: #common do: [
spec
package: 'MyPackage-Core';
package: 'MyPackage-Json' with: [
spec requires: #('MyPackage-Core')
]
]
Import order: Dependencies first → MyPackage-Core → MyPackage-Json
See Best Practices: Dependencies for complete guide.
Re-import after every change - Pharo doesn't automatically reload files.
Standard sequence:
MyPackage/MyClass.stMyPackageMyPackage-Tests/MyClassTest.stMyPackage-TestsThe AI editor is the source of truth:
.st files → Import to Pharo.st filesUse export_package only for:
See Best Practices: File Editing for rationale.
1. Ensure .project file exists in project root (create if missing - see Best Practices)
2. Create src/MyPackage/MyClass.st with class definition
3. import_package: 'MyPackage' path: '/absolute/path/src'
4. run_class_test: 'MyClassTest'
1. Read existing src/MyPackage/MyClass.st
2. Add new method to file
3. import_package: 'MyPackage' path: '/absolute/path/src'
4. run_class_test: 'MyClassTest'
1. Check BaselineOf for dependency order
2. Import packages in correct sequence
3. Import test packages last
4. Run comprehensive tests
Renaming a class only in the Tonel file and importing leaves the old class in the Pharo image. Always rename in Pharo first, then import.
1. Rename the class in Pharo via eval:
(OldClassName rename: 'NewClassName') printString
2. Update the Tonel filename and class name in the .st file
3. Import the package
import_package: 'MyPackage' path: '/absolute/path/src'
Why? Tonel import creates or updates classes by name. If the old name still exists in the image and the new name is introduced as a new class, both will coexist — and any references to the old class remain broken.
When a required package is not present locally, use install_project — never use Metacello directly via eval:
mcp__smalltalk-interop__install_project
project_name: 'MyLib'
repository_url: 'github://owner/MyLib:branch/src'
Parameters:
project_name (required): the baseline/project namerepository_url (required): Metacello-style URL (e.g. github://owner/repo:branch/src)load_groups (optional): comma-separated groups to loadCritical rule: If a class or package is missing and is not in the local source tree, always reach for install_project first. Do NOT try to load it with Metacello new baseline:... load via eval — that approach bypasses the managed workflow and can corrupt the image state.
For complete examples, see Development Session Examples.
When this skill is active, automatically suggest:
Install external package (GitHub/remote):
mcp__smalltalk-interop__install_project
project_name: 'MyLib'
repository_url: 'github://owner/MyLib:branch/src'
Use this when a package is not present locally. Never use Metacello via eval for this purpose.
Import local package:
mcp__smalltalk-interop__import_package: 'PackageName' path: '/absolute/path'
Test:
mcp__smalltalk-interop__run_class_test: 'TestClassName'
mcp__smalltalk-interop__run_package_test: 'PackageName-Tests'
Debug:
mcp__smalltalk-interop__eval: 'Smalltalk code here'
Validate (optional):
mcp__smalltalk-validator__validate_tonel_smalltalk_from_file: '/path/to/file.st'
/st-import PackageName /path - Import package/st-test TestClass - Run tests/st-eval code - Execute Smalltalk snippet/st-validate file.st - Validate syntax"Package not found":
docker ps), use container-side path: typically /root/repos (check compose.yml for volume mounts)package.st exists in the directory"Syntax error":
validate_tonel_smalltalk_from_file first"Dependency not found" / missing external package:
mcp__smalltalk-interop__install_project
project_name: 'MyLib'
repository_url: 'github://owner/MyLib:branch/src'
Metacello new baseline: ... load via eval — use install_project instead/st-eval to debug incrementallySee Best Practices: Error Handling for complete guide.
This skill provides focused guidance for the core workflow. For comprehensive information:
Edit .st file
↓
Lint code (/st-lint)
↓
Import package (absolute path)
↓
Run tests
↓
Tests pass? → Done
↓
Tests fail? → Debug with /st-eval → Fix .st file → Re-import
Remember: The cycle is Edit → Lint → Import → Test. Never skip lint, import, or tests.
npx claudepluginhub mumez/smalltalk-dev-plugin --plugin smalltalk-devRoutes Pharo Smalltalk development queries to specialized skills for coding, debugging, code understanding, project setup, and workflow guidance.
Provides structured workflow packs for 7 common Claude Code tasks: codebase exploration, bug fixing, safe refactoring, TDD, repo review before merge, CLAUDE.md generation, and migration planning.
Systematic development workflow: Analyze → Plan → Execute → eLicit → eXamine. Use for ANY development task: features, bug fixes, refactoring, hotfixes. Triggers: "implement", "create", "build", "fix", "add feature", "refactor", "develop". Auto-detects project type (Laravel, Next.js, React, Swift) and loads framework-specific references. Enforces: files <100 lines, interfaces separated, SOLID principles, expert self-review, sniper validation. Modes: --auto (default), --manual, --skip-elicit