A classic Smalltalk IDE for GemStone/Smalltalk
Project description
Swordfish
A classic Smalltalk IDE for GemStone/Smalltalk developed by Reahl Software Services.
Overview
Swordfish is a Python-based IDE that provides a classic Smalltalk development experience for GemStone/Smalltalk. It features class/method browsing, method editing, debugging capabilities with stepping functionality, and an object inspector.
This project was developed as an experiment in AI-assisted programming, with significant portions (including this README and other metadata) generated through collaboration between human developers and AI, followed by developer refinement and refactoring.
Features
- Class and method browsing
- Method editing
- Debugging with step execution
- Object inspection
- Classic Smalltalk IDE experience
Technical Details
Swordfish is built with:
- Python
- Tcl/Tk for the GUI interface (implemented without prior knowledge of the toolkit)
- Parseltongue (reahl-parseltongue) - library that enables calling GemStone/Smalltalk methods from Python
IDE
This section covers using Swordfish as a GUI IDE via the swordfish command.
Installation
For Docker-based development of both IDE and MCP, see How to Develop (Docker) at the end of this README.
From PyPI (Recommended)
# Create a virtual environment (optional but recommended)
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install from PyPI
pip install reahl-swordfish
From Source
# Clone the repository
git clone https://github.com/reahl/swordfish.git
cd swordfish
# Set up a virtual environment (optional but recommended)
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e .
Run the IDE
# After installation, run directly from command line
swordfish
# Or if installed from source
python -m swordfish
MCP
Swordfish includes MCP modes on the same swordfish executable.
Install
pip install reahl-swordfish
Run the server
swordfish --headless-mcp
Attach Claude to a running IDE/MCP process
To let Claude connect to an MCP server hosted inside an already-running IDE process, start the GUI (it now starts embedded MCP automatically):
# Run inside the container (GUI + embedded MCP)
swordfish --mcp-host 0.0.0.0 --mcp-port 9177 --mcp-http-path /mcp
Then configure Claude outside the container to use that URL:
claude mcp remove -s project swordfish 2>/dev/null || true
claude mcp add -s project --transport http swordfish http://127.0.0.1:9177/mcp
claude mcp list
If your IDE/MCP runs on a different host/port/path, change the URL
accordingly. stdio mode cannot attach to an already-running process.
In the GUI, use the MCP menu to start/stop the embedded server and edit
runtime MCP policy/network settings.
Add MCP to Claude Code and Codex (Docker-over-SSH)
For Docker and SSH setup details used by this flow, see How to Develop (Docker) at the end of this README.
Start the development container with SSH enabled in one terminal and keep it running:
./docker-start.sh --enable-ssh --ssh-pubkey-file ~/.ssh/id_ed25519.pub --foreground
In another terminal, from the project root, configure MCP clients to launch
swordfish --headless-mcp through docker-run-over-ssh.sh:
PROJECT_DIR="$(pwd)"
# Claude Code
claude mcp remove -s project swordfish 2>/dev/null || true
claude mcp add -s project swordfish -- "$PROJECT_DIR/docker-run-over-ssh.sh" swordfish --headless-mcp --allow-compile --allow-tracing
claude mcp list
# Codex
codex mcp remove swordfish 2>/dev/null || true
codex mcp add swordfish -- "$PROJECT_DIR/docker-run-over-ssh.sh" swordfish --headless-mcp --allow-compile --allow-tracing
codex mcp list --json
To enable eval/commit with human-approval handshakes, add:
--allow-eval --allow-commit
Add --allow-eval to enable gs_eval and gs_debug_eval.
When enabled, each eval call requires explicit human confirmation:
- Provide
approved_by_user=trueand a non-emptyapproval_note. - Keep
unsafe=Trueand a non-emptyreason. Add--allow-commitonly when you explicitly want transactions to persist. When enabled,gs_commitalways requires explicit human approval: - Provide
approved_by_user=trueand a non-emptyapproval_noteon eachgs_commitcall. Add--require-gemstone-astto enforce AST-strict refactoring mode; when enabled, heuristic refactoring tools are blocked unless real GemStone AST adapter support is available. In strict mode, refactoring actions attempt an automatic AST support install/refresh when possible. For new AI sessions, callgs_capabilitiesfirst to discover active policy switches and available workflows, then callgs_guidancefor task-specific tool selection and sequencing. For normal browse/edit/test workflows, prefer explicit tools like:gs_create_class,gs_create_class_in_package,gs_create_test_case_class,gs_compile_method, andgs_run_gemstone_tests. For selector exploration, usegs_find_implementorsandgs_find_sendersinstead of free-form evaluation. Both supportmax_resultsandcount_only. For method-level semantic navigation, usegs_method_ast,gs_method_sends,gs_method_structure_summary, andgs_method_control_flow_summaryto inspect statement structure, send sites, structural counts, and control-flow signals. For versioned image support of AST helpers, usegs_ast_statusto inspect manifest/hash status andgs_ast_installto install or refresh AST support code in the connected GemStone image. For pattern-based method discovery across a scope, usegs_query_methods_by_ast_patternand tune ranking withsort_by/sort_descending. For class-scoped method renames, usegs_preview_rename_methodandgs_apply_rename_methodinstead of a global selector rename. For class-scoped method moves, usegs_preview_move_methodbeforegs_apply_move_method, and review sender warnings before deleting the source. For class-scoped parameter addition with compatibility forwarding, usegs_preview_add_parameterthengs_apply_add_parameter. For class-scoped parameter removal with compatibility forwarding, usegs_preview_remove_parameterthengs_apply_remove_parameter; when you want to update same-class callers immediately, setrewrite_source_senders=true. For statement-level method extraction in one class/side, usegs_preview_extract_methodthengs_apply_extract_method. For conservative unary self-send inline in one caller method, usegs_preview_inline_methodthengs_apply_inline_method. For optional tracer installation, usegs_tracer_installand verify withgs_tracer_statusbefore enabling viags_tracer_enable. For runtime caller evidence, usegs_tracer_trace_selector, run your tests, then querygs_tracer_find_observed_senders. Tracer and evidence tools require MCP startup with--allow-tracing. Usegs_plan_evidence_teststo build a static candidate test superset andgs_collect_sender_evidenceto run that plan and collect observed callers. When you do usegs_eval, passunsafe=True,approved_by_user=true, a non-emptyapproval_note, and a non-emptyreason. Write tools require an explicit transaction: callgs_beginbefore writes, thengs_commit(orgs_abort) when done. With default policy,gs_commitis disabled unless the MCP server is started with--allow-commitand explicit confirmation is supplied.
The server identifies itself as SwordfishMCP and currently supports:
gs_connectgs_disconnectgs_begings_begin_if_neededgs_commitgs_abortgs_transaction_statusgs_capabilitiesgs_guidancegs_list_packagesgs_list_classesgs_list_method_categoriesgs_list_methodsgs_get_method_sourcegs_find_classesgs_find_selectorsgs_find_implementorsgs_find_sendersgs_ast_statusgs_ast_installgs_method_astgs_method_sendsgs_method_structure_summarygs_method_control_flow_summarygs_query_methods_by_ast_patterngs_preview_rename_methodgs_apply_rename_methodgs_preview_move_methodgs_apply_move_methodgs_preview_add_parametergs_apply_add_parametergs_preview_remove_parametergs_apply_remove_parametergs_preview_extract_methodgs_apply_extract_methodgs_preview_inline_methodgs_apply_inline_methodgs_tracer_statusgs_tracer_installgs_tracer_enablegs_tracer_disablegs_tracer_uninstallgs_tracer_trace_selectorgs_tracer_untrace_selectorgs_tracer_clear_observed_sendersgs_tracer_find_observed_sendersgs_plan_evidence_testsgs_collect_sender_evidencegs_create_classgs_create_test_case_classgs_get_class_definitiongs_delete_classgs_compile_methodgs_delete_methodgs_set_method_categorygs_preview_selector_renamegs_apply_selector_renamegs_list_test_case_classesgs_run_tests_in_packagegs_run_test_methodgs_global_setgs_global_removegs_global_existsgs_run_gemstone_testsgs_debug_evalgs_debug_stackgs_debug_continuegs_debug_step_overgs_debug_step_intogs_debug_step_throughgs_debug_stopgs_eval
Requirements
- Python 3.6+
- Tcl/Tk
- reahl-parseltongue
- Access to a GemStone/Smalltalk environment
AI-Assisted Development
This project serves as an exploration of how AI can be incorporated into software development workflows. Our key insights include:
- The initial framework of the app was developed entirely by prompting the AI.
- As the codebase grew, we started refactoring to extract duplication and address other important code smells.
- We introduced an event-handling mechanism to allow for better design regarding event handling.
- We found that refactoring helps tremendously by allowing us to give the AI smaller relevant chunks of context to work with.
Throughout the process, human developers provided domain expertise, drove architectural decisions, performed code reviews, and handled integration and testing. The project demonstrates how AI can be an effective collaborator in software development when combined with sound software engineering practices.
License
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
GemStone/S is proprietary software by GemTalk Systems and is not distributed as part of this project. You must obtain and use GemStone/S under separate GemTalk license terms. No rights to GemStone/S are granted by this project's GPL license.
Development & CI/CD
Continuous Integration
This project uses GitHub Actions for continuous integration and deployment:
-
CI Workflow: Automatically runs on pull requests and pushes to main branch
- Tests package installation across Python 3.8-3.12
- Validates code formatting with Black and isort
- Builds wheel packages for verification
- Runs import tests
-
Deploy Workflow: Automatically publishes to PyPI on version tags
- Triggers on tags matching
v*pattern (e.g.,v1.0.0) - Builds wheel and source distributions
- Publishes to PyPI using secure token authentication
- Creates GitHub releases with auto-generated notes
- Triggers on tags matching
Release Process
To create a new release:
- Update the version in
pyproject.toml - Commit your changes and push to main branch
- Create and push a version tag:
git tag v1.0.0 git push origin v1.0.0
- The GitHub Actions workflow will automatically:
- Build the package
- Publish to PyPI as
reahl-swordfish - Create a GitHub release
Repository Setup
To enable automated PyPI publishing, the repository must have a PYPI_API_TOKEN secret configured with a valid PyPI API token for the reahl-swordfish package.
Contributing
We welcome contributions! Please feel free to submit a Pull Request.
About Reahl Software Services
Reahl Software Services (Pty) Ltd is a software development company specializing in innovative software solutions. For more information, visit our website.
How to Develop (Docker)
This section applies to both IDE and MCP workflows.
Start the development container
# Clone the repository
git clone https://github.com/reahl/swordfish.git
cd swordfish
# Start the development environment
./docker-start.sh
Docker script options:
./docker-start.sh # Normal development mode
./docker-start.sh --no-cache # Clean rebuild (clears Docker cache)
./docker-start.sh --foreground # Foreground shell with entrypoint setup
./docker-start.sh --foreground --no-entry-point # Root shell without entrypoint setup
./docker-start.sh --enable-ssh # Start sshd in container (key-only auth)
./docker-start.sh --enable-ssh --ssh-pubkey-file ~/.ssh/id_ed25519.pub
./docker-start.sh --gemstone-version 3.6.5
The Docker setup includes:
- Ubuntu 24.04 base with Python 3.12
- GemStone/Smalltalk environment (default
3.7.4.3, configurable) - Python development tools (black, isort, pytest) in virtual environment
- X11 forwarding for GUI applications
- Volume mounts for live code editing
- Automatic user mapping for file permissions
- Entry-point setup that adds
~/.local/venv/bintoPATHand loads GemStone environment in interactive shells
SSH access for automated commands
# Start container with sshd enabled and your public key provisioned
./docker-start.sh --enable-ssh --ssh-pubkey-file ~/.ssh/id_ed25519.pub
# Optional overrides
export SF_SSH_PORT=2222
export SF_SSH_BIND_ADDRESS=127.0.0.1
export SF_MCP_PORT=9177
export SF_MCP_BIND_ADDRESS=127.0.0.1
Run commands from the host (recommended):
# Run any command in /workspace with ~/.local/venv activated
./docker-run-over-ssh.sh python -V
./docker-run-over-ssh.sh pytest -q
# Convenience wrapper for pytest
./docker-test-over-ssh.sh
./docker-test-over-ssh.sh tests/test_mcp_session_registry.py -q
Optional direct SSH session for troubleshooting:
ssh -p 2222 "$(whoami)"@127.0.0.1
GemStone server management
Once inside the container, you can start and manage the GemStone server:
# Start the GemStone server (stone name: gs64stone)
sudo -u gemstone bash -l -c "startstone gs64stone"
# Check server status
sudo -u gemstone bash -l -c "gslist"
# Stop the GemStone server
sudo -u gemstone bash -l -c "stopstone gs64stone"
# Alternative: Interactive gemstone user session
sudo -u gemstone -i
Note: GemStone server operations must be run as the gemstone user for proper permissions and security. The -l flag ensures the GemStone environment is loaded.
Run the IDE inside the container
When started normally (without --no-entry-point), the container entrypoint sets up your shell environment for Swordfish:
~/.local/venv/binis added toPATH- GemStone environment is loaded for interactive shells (including
GEMSTONE)
If you bypass the entrypoint (for example --no-entry-point), configure the environment manually:
source ~/.local/venv/bin/activate
. /opt/dev/gemstone/gemShell.sh "${GEMSTONE_VERSION:-3.7.4.3}"
To run and test specifically against GemStone 3.6.5:
GEMSTONE_VERSION=3.6.5 ./docker-start.sh --no-cache --enable-ssh --ssh-pubkey-file ~/.ssh/id_ed25519.pub
./docker-test-over-ssh.sh
# 1. Start the GemStone server
sudo -u gemstone bash -l -c "startstone gs64stone"
# 2. Verify the stone is running
sudo -u gemstone bash -l -c "gslist"
# 3. Install Swordfish in development mode
pip install -e .
# 4. Run Swordfish
swordfish
# 5. In the Swordfish GUI, connect to GemStone:
# - Use "Linked Session" connection type
# - Set stone name to: gs64stone
# - Leave other connection settings as defaults
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file reahl_swordfish-0.3.0.tar.gz.
File metadata
- Download URL: reahl_swordfish-0.3.0.tar.gz
- Upload date:
- Size: 180.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92314685146555cb115300d75d799531b3a36f6a970c22b25913aaa20a11fd34
|
|
| MD5 |
dbc42a6ec7fe5a42381471ac963acfd7
|
|
| BLAKE2b-256 |
e2510edd8bd2ae321097848be25b1e43a0ea1d33786f083b96b5a8202c0d83e6
|
File details
Details for the file reahl_swordfish-0.3.0-py3-none-any.whl.
File metadata
- Download URL: reahl_swordfish-0.3.0-py3-none-any.whl
- Upload date:
- Size: 124.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6869dac465eadbc2b7d81e1a4bf99a3e80a34c92aab1e7f1f1418bbb2052e75a
|
|
| MD5 |
6202f79855698b756adcfdc211e8c4f3
|
|
| BLAKE2b-256 |
8626bd2e5d49c1700ad29c5509c5ff5e5671f638922b83de3d1225ddbb5555a3
|