Skip to main content

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.

Swordfish also ships with a built-in MCP (Model Context Protocol) server. The MCP gives AI agents — such as Claude — two complementary capabilities: full programmatic access to the GemStone Smalltalk codebase (read source, compile methods, run tests, refactor, trace callers, …) and direct control of the live IDE itself (navigate to a class, open a method in the editor, open the debugger, narrow the list of senders in the Find dialog, compose UML diagrams, and more). This means you can literally ask your AI assistant to show you something in the IDE, or have it step through a failing test with the debugger open in front of you.

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
  • UML class and object diagrams — build and explore class structure diagrams and live object graphs interactively; diagrams open as tabs alongside the browser and can be driven manually or by an AI agent via MCP
  • Embedded MCP server — lets AI agents interact with both the codebase and the live IDE

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 .

# Or, for development including the test suite, install with the test extra
pip install -e '.[test]'

The test extra pulls in the test-only dependencies (reahl-tofu, pytest-xvfb, setuptools<81) required to run pytest; a plain pip install -e . installs only what is needed to run the application. Quote '.[test]' so the shell does not treat the brackets as a glob pattern.

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 starts the embedded MCP server automatically):

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

stdio mode cannot attach to an already-running process. Use the MCP menu in the GUI to start/stop the embedded server and edit runtime policy and network settings.

Add MCP to Claude Code and Codex (Docker-over-SSH)

For Docker and SSH setup details, see How to Develop (Docker) at the end of this README.

Start the development container with SSH enabled:

./docker-start.sh --enable-ssh --ssh-pubkey-file ~/.ssh/id_ed25519.pub --foreground

Then 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

Add --allow-eval and --allow-commit to enable evaluation and transaction commits; both require explicit human confirmation at each call.

Configuration

Swordfish stores its configuration in ~/.config/swordfish/swordfish.json (or $XDG_CONFIG_HOME/swordfish/swordfish.json if set). Most settings are editable via the GUI; the sections below cover config-file-only options.

GemStone executable configuration file

gemstone_exe_conf sets the GEMSTONE_EXE_CONF environment variable at process startup, pointing GemStone to a specific executable configuration file. This is a process-level setting that takes effect before any session is opened. If GEMSTONE_EXE_CONF is already set in the environment and the config file specifies a different path, the config file wins and a warning is logged.

{
  "schema_version": 2,
  "gemstone_exe_conf": "/path/to/gemstone.conf"
}

MCP runtime permissions

The mcp_runtime_config section controls which MCP capabilities are active. These can also be set at startup via command-line flags (--allow-compile, --allow-eval, etc.) or toggled in the GUI's MCP menu.

{
  "schema_version": 2,
  "mcp_runtime_config": {
    "allow_source_read": true,
    "allow_source_write": false,
    "allow_eval_arbitrary": false,
    "allow_test_execution": false,
    "allow_ide_read": true,
    "allow_ide_write": false,
    "allow_commit": false,
    "allow_tracing": false,
    "require_gemstone_ast": false,
    "mcp_host": "127.0.0.1",
    "mcp_port": 8000,
    "mcp_http_path": "/mcp"
  }
}

Locking permissions for protected databases

If the config file is read-only, mcp_permission_policy controls whether users can still change MCP permission toggles for the current session. The Smalltalk expression must evaluate to true (session changes allowed) or false (all toggles locked). Swordfish fails closed if the expression errors or returns a non-boolean.

{
  "schema_version": 2,
  "mcp_permission_policy": {
    "allow_session_permission_changes_condition_source": "System stoneName ~= 'prod'"
  }
}

Run GemStone code on login

A login script is evaluated immediately after a successful GemStone login, before the IDE opens. If the script raises an error, login is aborted and the session is closed.

{
  "schema_version": 2,
  "login": {
    "gemstone_script_source": "System stoneName"
  }
}

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

Release Process

To create a new release:

  1. Update the version in src/reahl/swordfish/__init__.py
  2. Commit your changes and push to main branch
  3. Create and push a version tag:
    git tag v1.0.0
    git push origin v1.0.0
    
  4. 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 or submit an Issue.

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/bin to PATH and 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/bin is added to PATH
  • 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
#    (use '.[test]' instead to also install the test dependencies for pytest)
pip install -e '.[test]'

# 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

reahl_swordfish-0.14.0.tar.gz (338.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

reahl_swordfish-0.14.0-py3-none-any.whl (221.3 kB view details)

Uploaded Python 3

File details

Details for the file reahl_swordfish-0.14.0.tar.gz.

File metadata

  • Download URL: reahl_swordfish-0.14.0.tar.gz
  • Upload date:
  • Size: 338.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for reahl_swordfish-0.14.0.tar.gz
Algorithm Hash digest
SHA256 e1eb441211188ab07afb4617bdfd3576802d238f5801dd92e991eff432b75bb1
MD5 3d2cb3ca10560b70f69d7ff4daaacedc
BLAKE2b-256 1cae7c3848c8ea06b70af5b76f1ced024f069e918a7ecb3a0309027d1d2c729d

See more details on using hashes here.

File details

Details for the file reahl_swordfish-0.14.0-py3-none-any.whl.

File metadata

File hashes

Hashes for reahl_swordfish-0.14.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3fe6980aa407b22c0f4d89f36eb4786fec3374dd312d5c7a4ab6838963638a04
MD5 ba9527723500275aadb67dac2110fb63
BLAKE2b-256 f2b61b501edf6cbf8640e778cd250290db6db40320883394b0b02dba4c9fc270

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page