From 6f1a2f24456ae9b5920da1ecb7ecab8ca881da75 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 16 Nov 2025 00:36:20 +0000 Subject: [PATCH 1/3] Add Stack proxy configuration workaround for Claude Code web Documents the TLS/SSL handshake failure issue that occurs when using Stack in Claude Code web environments. Stack's HTTP library doesn't automatically use the https_proxy environment variable, causing connection failures to Hackage and other Haskell resources. The workaround involves creating ~/.stack/config.yaml with explicit proxy settings pointing to the internal egress proxy service. --- cli/docs/claude-code-web.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cli/docs/claude-code-web.md b/cli/docs/claude-code-web.md index 4047718..9e70361 100644 --- a/cli/docs/claude-code-web.md +++ b/cli/docs/claude-code-web.md @@ -26,6 +26,30 @@ We recommend using ghcup to install Stack: echo 'source ~/.ghcup/env' >> ~/.bashrc # or ~/.zshrc ``` +## Proxy Configuration for Claude Code Web + +**IMPORTANT:** When using Claude Code in a web/container environment, Stack requires explicit proxy configuration to download packages from Hackage and other Haskell resources. + +### Why This Is Needed + +In Claude Code web environments, all HTTPS connections must go through a proxy. While most tools (like `curl` and `wget`) automatically use the `https_proxy` environment variable, Stack's HTTP library does not. This causes TLS/SSL handshake failures when Stack tries to download GHC, packages, or the Hackage index. + +### Configuring the Proxy + +Before running any Stack commands, create a Stack configuration file with proxy settings: + +```bash +mkdir -p ~/.stack +cat > ~/.stack/config.yaml << 'EOF' +http-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 +https-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 +EOF +``` + +This configuration tells Stack to route all HTTP and HTTPS traffic through the Claude Code web environment's internal proxy, which has access to the necessary Haskell package repositories. + +**Note:** You only need to do this once. The configuration file will persist across Stack commands. If you see errors like "TLS HandshakeFailed" or "Network.Socket.connect", verify that this configuration file exists and contains the correct proxy settings. + ## Running Tests From the `cli/` directory, run: From 21cd22751f12d5e7308df0c3c081717d61d8faec Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 16 Nov 2025 00:42:53 +0000 Subject: [PATCH 2/3] Streamline and reorganize Haskell setup documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Major improvements to cli/docs/claude-code-web.md: - Add Quick Start section for experienced users with complete setup script - Reorganize into logical flow: Install → Configure → Verify → Develop - Move proxy configuration earlier (before any Stack commands) - Remove STACK_ROOT=~/.stack references (not needed with proper config) - Add comprehensive Troubleshooting section - Improve formatting and clarity throughout - Consolidate Development Workflow section - Add concrete examples for running the CLI The new structure makes it much easier to follow and reduces setup errors. --- cli/docs/claude-code-web.md | 229 +++++++++++++++++++++++++----------- 1 file changed, 158 insertions(+), 71 deletions(-) diff --git a/cli/docs/claude-code-web.md b/cli/docs/claude-code-web.md index 9e70361..5773300 100644 --- a/cli/docs/claude-code-web.md +++ b/cli/docs/claude-code-web.md @@ -1,42 +1,64 @@ -# Setting Up Haskell Development Environment +# Haskell Development Environment for Claude Code Web -The CLI project uses Stack as its build tool. To set up your development environment: +This guide helps you set up the Haskell CLI development environment in Claude Code's web/container environment. -## Installing Stack +## Quick Start -We recommend using ghcup to install Stack: +For experienced users, here's the complete setup in one script: -1. Install ghcup (the Haskell toolchain installer): - ```bash - curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh - ``` +```bash +# Install ghcup and Stack +curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | \ + BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh +source ~/.ghcup/env +ghcup install stack -2. Source the ghcup environment: - ```bash - source ~/.ghcup/env - ``` +# Configure proxy (REQUIRED for Claude Code Web) +mkdir -p ~/.stack +cat > ~/.stack/config.yaml << 'EOF' +http-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 +https-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 +EOF -3. Install Stack using ghcup: - ```bash - ghcup install stack - ``` +# Run tests +cd cli +stack test +``` -4. Add the ghcup environment to your shell configuration (e.g., `~/.bashrc` or `~/.zshrc`): - ```bash - echo 'source ~/.ghcup/env' >> ~/.bashrc # or ~/.zshrc - ``` +## Step-by-Step Setup -## Proxy Configuration for Claude Code Web +### 1. Install the Haskell Toolchain -**IMPORTANT:** When using Claude Code in a web/container environment, Stack requires explicit proxy configuration to download packages from Hackage and other Haskell resources. +Install ghcup (the Haskell toolchain installer): -### Why This Is Needed +```bash +curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | \ + BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh +``` -In Claude Code web environments, all HTTPS connections must go through a proxy. While most tools (like `curl` and `wget`) automatically use the `https_proxy` environment variable, Stack's HTTP library does not. This causes TLS/SSL handshake failures when Stack tries to download GHC, packages, or the Hackage index. +Activate the ghcup environment: -### Configuring the Proxy +```bash +source ~/.ghcup/env +``` -Before running any Stack commands, create a Stack configuration file with proxy settings: +Install Stack: + +```bash +ghcup install stack +``` + +**Optional:** Add ghcup to your shell configuration to persist across sessions: + +```bash +echo 'source ~/.ghcup/env' >> ~/.bashrc # or ~/.zshrc +``` + +### 2. Configure Proxy (REQUIRED for Claude Code Web) + +**This step is critical.** Claude Code's web environment requires all HTTPS connections to go through a proxy. Stack doesn't automatically use the `https_proxy` environment variable, so you must configure it manually. + +Create the Stack configuration file: ```bash mkdir -p ~/.stack @@ -46,108 +68,173 @@ https-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 EOF ``` -This configuration tells Stack to route all HTTP and HTTPS traffic through the Claude Code web environment's internal proxy, which has access to the necessary Haskell package repositories. +**You only need to do this once.** The configuration persists across Stack commands. -**Note:** You only need to do this once. The configuration file will persist across Stack commands. If you see errors like "TLS HandshakeFailed" or "Network.Socket.connect", verify that this configuration file exists and contains the correct proxy settings. +### 3. Verify Your Setup -## Running Tests - -From the `cli/` directory, run: +Run the test suite: ```bash -STACK_ROOT=~/.stack stack test +cd cli +stack test ``` -**Note:** The `STACK_ROOT=~/.stack` prefix is required in web/container environments to avoid permission issues with the default Stack root directory. - On first run, Stack will: -- Download and install GHC (Glasgow Haskell Compiler) +- Download and install GHC (Glasgow Haskell Compiler) - ~200MB - Download the Hackage package index - Build all project dependencies - Build and run the tests -This initial setup can take several minutes. Subsequent runs will be much faster. +This initial build takes several minutes. Subsequent builds are much faster. + +## Development Workflow -## Building the CLI +### Building the Project -To build the CLI executable: +Build the CLI executable: ```bash cd cli -STACK_ROOT=~/.stack stack build +stack build ``` -To run the CLI: +For faster builds during development (skips optimizations): ```bash -STACK_ROOT=~/.stack stack exec graph -- +stack build --fast ``` -# Code Quality +### Running Tests -## Formatting Code - Ormolu -This project uses [ormolu](https://github.com/tweag/ormolu) for consistent Haskell code formatting. All Haskell files must be formatted with ormolu before committing. +Run the full test suite: -### Installing Ormolu +```bash +cd cli +stack test +``` -Install ormolu using ghcup: +Run tests with fast compilation: ```bash -ghcup install ormolu +stack test --fast ``` -Or download it directly: +### Running the CLI + +Execute the CLI directly: ```bash -curl -L https://github.com/tweag/ormolu/releases/download/0.7.4.0/ormolu-x86_64-linux.zip -o ormolu.zip -unzip ormolu.zip -chmod +x ormolu -sudo mv ormolu /usr/local/bin/ +cd cli +stack exec graph -- ``` -### Formatting Files - -To format a single Haskell file: +Examples: ```bash -ormolu --mode inplace path/to/File.hs +stack exec graph -- --help +stack exec graph -- ls ``` -To format all Haskell files in the project: +## Code Quality Tools + +### Ormolu (Code Formatting) + +This project requires [ormolu](https://github.com/tweag/ormolu) for consistent formatting. All Haskell files must be formatted before committing. + +**Install ormolu:** ```bash -find . -name '*.hs' -type f -print0 | xargs -0 ormolu --mode inplace +ghcup install ormolu ``` -To check if files are formatted correctly without modifying them: +**Format files:** ```bash -find . -name '*.hs' -type f -print0 | xargs -0 ormolu --mode check +# Format a single file +ormolu --mode inplace path/to/File.hs + +# Format all Haskell files in the project +find cli -name '*.hs' -type f -print0 | xargs -0 ormolu --mode inplace + +# Check formatting without modifying files +find cli -name '*.hs' -type f -print0 | xargs -0 ormolu --mode check ``` -**Note:** The GitHub CI will automatically check that all Haskell files are properly formatted. Make sure to format your code before pushing. +**Note:** GitHub CI automatically checks formatting on all PRs. + +### HLint (Linting) -## HLint -HLint is a linting tool that suggests improvements to Haskell code. The project is configured with a `.hlint.yaml` file at the repository root, and a GitHub Actions workflow enforces that shows HLint warnings on PRs. +HLint suggests code improvements. The project includes a `.hlint.yaml` configuration, and GitHub Actions shows HLint warnings on PRs. + +**Install HLint:** -**Installing HLint:** ```bash -# Using Stack (recommended for this project) stack install hlint apply-refact ``` -**Running HLint locally:** +**Run HLint:** + ```bash -# Check all Haskell files in the cli directory +# Check all files in the cli directory hlint cli/ # Check a specific file hlint cli/src/Graph/Command.hs -# Apply suggestions automatically (use with caution, only applicable to individual files) +# Auto-apply suggestions (use with caution) hlint cli/src/Graph/Command.hs --refactor --refactor-options="--inplace" ``` -**Common workflow:** -1. Run `hlint cli/` before committing your changes -2. Review the suggestions and apply fixes manually or using `--refactor` +**Recommended workflow:** +1. Run `hlint cli/` before committing +2. Review suggestions and apply manually or with `--refactor` + +## Troubleshooting + +### TLS/SSL Handshake Failures + +If you see errors like: + +``` +TLS HandshakeFailed (Error_Protocol ... HandshakeFailure) +``` + +or + +``` +Network.Socket.connect: ... connection refused +``` + +**Solution:** Verify your proxy configuration exists: + +```bash +cat ~/.stack/config.yaml +``` + +It should contain: + +```yaml +http-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 +https-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 +``` + +If the file is missing or incorrect, recreate it using the command in Step 2 above. + +### Unrecognized Fields Warning + +You may see a warning: + +``` +Warning: /root/.stack/config.yaml: Unrecognized fields in ConfigMonoid: http-proxy, https-proxy +``` + +**This is normal and can be ignored.** Stack still uses the proxy settings correctly despite the warning. + +### Build Failures After Environment Reset + +If your environment resets (e.g., container restart), you may need to: + +1. Re-source the ghcup environment: `source ~/.ghcup/env` +2. Verify the proxy config still exists: `cat ~/.stack/config.yaml` + +The ghcup installation and Stack proxy config should persist in your home directory (`~/.ghcup` and `~/.stack`), but you need to source the environment in each new shell session. From 02ffa97f6f743a09f2f79dc347898c9211e9815c Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 16 Nov 2025 00:45:18 +0000 Subject: [PATCH 3/3] Rewrite claude-code-web.md for maximum practicality Complete rewrite focused on actionable commands and quick reference: - Lead with copy-paste setup commands (no fluff) - Clear sections: First Time Setup, Every Session, Common Commands - Explicit "Errors You Can Ignore" vs "Real Errors" sections - Quick checks for debugging - Build time expectations - Pro tips for efficient workflow - Removed verbose explanations - Added inline comments in code blocks This is now a practical reference card rather than tutorial documentation. --- cli/docs/claude-code-web.md | 257 ++++++++++++------------------------ 1 file changed, 85 insertions(+), 172 deletions(-) diff --git a/cli/docs/claude-code-web.md b/cli/docs/claude-code-web.md index 5773300..763fc82 100644 --- a/cli/docs/claude-code-web.md +++ b/cli/docs/claude-code-web.md @@ -1,240 +1,153 @@ -# Haskell Development Environment for Claude Code Web +# Haskell Setup for Claude Code Web -This guide helps you set up the Haskell CLI development environment in Claude Code's web/container environment. +**For Claude:** This is your reference for setting up Haskell in web environments. Copy-paste the commands and move on. -## Quick Start +## First Time Setup -For experienced users, here's the complete setup in one script: +Run this once per environment: ```bash -# Install ghcup and Stack +# Install toolchain curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | \ BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh + +# Activate (do this in EVERY new shell) source ~/.ghcup/env + +# Install Stack ghcup install stack -# Configure proxy (REQUIRED for Claude Code Web) +# CRITICAL: Configure proxy (Stack won't work without this) mkdir -p ~/.stack cat > ~/.stack/config.yaml << 'EOF' http-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 https-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 EOF - -# Run tests -cd cli -stack test ``` -## Step-by-Step Setup - -### 1. Install the Haskell Toolchain - -Install ghcup (the Haskell toolchain installer): - +**Verify it worked:** ```bash -curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | \ - BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_MINIMAL=1 sh +stack --version # Should show: Version 3.3.1 or similar +cat ~/.stack/config.yaml # Should show the proxy config ``` -Activate the ghcup environment: +## Every New Shell Session ```bash source ~/.ghcup/env ``` -Install Stack: - -```bash -ghcup install stack -``` - -**Optional:** Add ghcup to your shell configuration to persist across sessions: - -```bash -echo 'source ~/.ghcup/env' >> ~/.bashrc # or ~/.zshrc -``` - -### 2. Configure Proxy (REQUIRED for Claude Code Web) - -**This step is critical.** Claude Code's web environment requires all HTTPS connections to go through a proxy. Stack doesn't automatically use the `https_proxy` environment variable, so you must configure it manually. - -Create the Stack configuration file: - -```bash -mkdir -p ~/.stack -cat > ~/.stack/config.yaml << 'EOF' -http-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 -https-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 -EOF -``` - -**You only need to do this once.** The configuration persists across Stack commands. - -### 3. Verify Your Setup +That's it. The proxy config persists, ghcup/stack binaries persist, but the PATH doesn't. -Run the test suite: +## Common Commands ```bash -cd cli -stack test -``` - -On first run, Stack will: -- Download and install GHC (Glasgow Haskell Compiler) - ~200MB -- Download the Hackage package index -- Build all project dependencies -- Build and run the tests - -This initial build takes several minutes. Subsequent builds are much faster. - -## Development Workflow - -### Building the Project - -Build the CLI executable: +# Build the project +cd cli && stack build -```bash -cd cli -stack build -``` - -For faster builds during development (skips optimizations): - -```bash +# Fast build (no optimizations, use during development) stack build --fast -``` -### Running Tests - -Run the full test suite: - -```bash -cd cli +# Run tests stack test -``` - -Run tests with fast compilation: -```bash +# Run tests fast stack test --fast -``` - -### Running the CLI - -Execute the CLI directly: - -```bash -cd cli -stack exec graph -- -``` -Examples: - -```bash +# Run the CLI +stack exec graph -- stack exec graph -- --help stack exec graph -- ls -``` - -## Code Quality Tools - -### Ormolu (Code Formatting) - -This project requires [ormolu](https://github.com/tweag/ormolu) for consistent formatting. All Haskell files must be formatted before committing. -**Install ormolu:** +# Format code (REQUIRED before commits) +ghcup install ormolu # once +find cli -name '*.hs' -exec ormolu --mode inplace {} \; -```bash -ghcup install ormolu +# Lint code +stack install hlint # once +hlint cli/ ``` -**Format files:** - -```bash -# Format a single file -ormolu --mode inplace path/to/File.hs - -# Format all Haskell files in the project -find cli -name '*.hs' -type f -print0 | xargs -0 ormolu --mode inplace +## Errors You'll See (and Can Ignore) -# Check formatting without modifying files -find cli -name '*.hs' -type f -print0 | xargs -0 ormolu --mode check +**This is NORMAL:** ``` - -**Note:** GitHub CI automatically checks formatting on all PRs. - -### HLint (Linting) - -HLint suggests code improvements. The project includes a `.hlint.yaml` configuration, and GitHub Actions shows HLint warnings on PRs. - -**Install HLint:** - -```bash -stack install hlint apply-refact +Warning: /root/.stack/config.yaml: Unrecognized fields in ConfigMonoid: http-proxy, https-proxy ``` +Stack doesn't officially support these fields but uses them anyway. Ignore. -**Run HLint:** - -```bash -# Check all files in the cli directory -hlint cli/ - -# Check a specific file -hlint cli/src/Graph/Command.hs - -# Auto-apply suggestions (use with caution) -hlint cli/src/Graph/Command.hs --refactor --refactor-options="--inplace" +**This is NORMAL on first build:** ``` +Preparing to download ghc-tinfo6-9.6.7 ... +ghc-tinfo6-9.6.7: download has begun +ghc-tinfo6-9.6.7: ... (lots of progress lines) +``` +First build downloads ~200MB of GHC. Takes a few minutes. Subsequent builds are fast. -**Recommended workflow:** -1. Run `hlint cli/` before committing -2. Review suggestions and apply manually or with `--refactor` - -## Troubleshooting - -### TLS/SSL Handshake Failures - -If you see errors like: +## Errors That Mean Something Is Wrong +**TLS/SSL handshake failures:** ``` TLS HandshakeFailed (Error_Protocol ... HandshakeFailure) ``` +**Fix:** You forgot the proxy config. Run the proxy config commands from "First Time Setup" above. -or - +**stack: command not found:** ``` -Network.Socket.connect: ... connection refused +/bin/bash: stack: command not found ``` +**Fix:** Run `source ~/.ghcup/env` -**Solution:** Verify your proxy configuration exists: - -```bash -cat ~/.stack/config.yaml +**Permission denied on ~/.stack:** +``` +Permission denied ... ~/.stack ``` +**Fix:** This shouldn't happen with the config above, but if it does: `chmod -R u+w ~/.stack` -It should contain: +## How It Works (for debugging) -```yaml -http-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 -https-proxy: http://egress.public-claude-proxy.svc.cluster.local:80 -``` +1. **ghcup** installs to `~/.ghcup/` and manages GHC/Stack/etc versions +2. **Stack** installs to `~/.ghcup/bin/stack` and stores its data in `~/.stack/` +3. The `~/.stack/config.yaml` file forces Stack to use the egress proxy +4. Without the proxy, Stack can't reach downloads.haskell.org or hackage.haskell.org +5. `source ~/.ghcup/env` adds `~/.ghcup/bin` to PATH + +## Quick Checks -If the file is missing or incorrect, recreate it using the command in Step 2 above. +```bash +# Is ghcup installed? +ls ~/.ghcup/bin/ -### Unrecognized Fields Warning +# Is Stack installed? +source ~/.ghcup/env && stack --version -You may see a warning: +# Is proxy configured? +cat ~/.stack/config.yaml +# Can Stack reach the internet? +stack update # Should download Hackage index ``` -Warning: /root/.stack/config.yaml: Unrecognized fields in ConfigMonoid: http-proxy, https-proxy -``` -**This is normal and can be ignored.** Stack still uses the proxy settings correctly despite the warning. +## Build Times Reference + +- **First build:** 5-15 minutes (downloads GHC + all dependencies) +- **Subsequent clean builds:** 3-5 minutes +- **Incremental builds:** 10-30 seconds +- **Fast incremental builds:** 5-15 seconds + +## Code Quality Requirements -### Build Failures After Environment Reset +Before committing: +1. Format with ormolu: `find cli -name '*.hs' -exec ormolu --mode inplace {} \;` +2. Check lint: `hlint cli/` (fix what's reasonable) +3. Tests pass: `stack test` -If your environment resets (e.g., container restart), you may need to: +GitHub CI will fail if formatting is wrong. -1. Re-source the ghcup environment: `source ~/.ghcup/env` -2. Verify the proxy config still exists: `cat ~/.stack/config.yaml` +## Pro Tips -The ghcup installation and Stack proxy config should persist in your home directory (`~/.ghcup` and `~/.stack`), but you need to source the environment in each new shell session. +- Use `--fast` during development, full builds only for final testing +- Install ormolu once: `ghcup install ormolu` +- The first Stack command in a new environment is slow (downloads GHC), be patient +- If builds seem stuck, they're probably downloading packages - check with `ps aux | grep stack` +- Stack caches aggressively - if something seems wrong, `stack clean` and rebuild