Skip to content

fix: enable linux-portable mode on Linux/macOS hosts#3

Merged
mjenkinsx9 merged 3 commits intomainfrom
gimli/fix-linux-portability
Mar 26, 2026
Merged

fix: enable linux-portable mode on Linux/macOS hosts#3
mjenkinsx9 merged 3 commits intomainfrom
gimli/fix-linux-portability

Conversation

@mjenkinsx9
Copy link
Copy Markdown
Collaborator

Summary

This PR fixes the portability issue - mode now works on Linux/macOS hosts instead of failing with 'linux-portable mode is currently implemented for Windows hosts only'.

Problem

Mike's original goal was to make Claude Code portable - run from a folder without installing on the local machine. However, the mode was only implemented for Windows (using bundled QEMU VM), and it failed on Linux/macOS.

Solution

On non-Windows hosts, mode now uses portable-native execution:

  • Runs tools directly on the host (no VM needed on Linux/macOS)
  • Uses portable auth isolation - OAuth tokens stored in instead of or
  • This provides true portability without requiring Docker/Podman

Changes

  1. scripts/pcoder.cjs: Added function and modified to call it on non-Windows platforms

  2. README.md:

    • Added Goal statement explaining the portable concept
    • Added Platform-Specific Behavior table
    • Added How It Works section explaining portable auth isolation
    • Added Directory Structure overview
    • Added Testing section
  3. scripts/runtime/linux/smoke-check.sh: New smoke test for Linux/macOS

Testing

All smoke tests pass:

  • [ok] dir:runtime -> /home/gimli/repos/PortableCoder/runtime
    [ok] dir:apps -> /home/gimli/repos/PortableCoder/apps
    [ok] dir:profiles -> /home/gimli/repos/PortableCoder/profiles
    [ok] dir:state -> /home/gimli/repos/PortableCoder/state
    [ok] dir:scripts -> /home/gimli/repos/PortableCoder/scripts
    [ok] settings:file -> state/settings.json
    [ok] active-profile -> openai
    [ok] profile:openai:env-files -> optional profile uses external env injection
    [ok] profile:openai:required-env -> selected for codex in oauth mode
    [ok] profile:anthropic:env-files -> optional profile uses external env injection
    [ok] profile:anthropic:required-env -> selected for claude in oauth mode
    [ok] tool:codex:runner -> codex (auth=oauth)
    [ok] tool:claude:runner -> claude (auth=oauth)

Doctor completed: all checks passed. - All checks pass

  • [portable-native] Running codex with isolated auth state...
    codex-cli 0.104.0 - Works
  • [portable-native] Running claude with isolated auth state...
    2.1.71 (Claude Code) - Works
  • === PortableCoder Smoke Test ===
    Repo root: /home/gimli/repos/PortableCoder

OK: pcoder launcher found

=== Running doctor ===
[ok] dir:runtime -> /home/gimli/repos/PortableCoder/runtime
[ok] dir:apps -> /home/gimli/repos/PortableCoder/apps
[ok] dir:profiles -> /home/gimli/repos/PortableCoder/profiles
[ok] dir:state -> /home/gimli/repos/PortableCoder/state
[ok] dir:scripts -> /home/gimli/repos/PortableCoder/scripts
[ok] settings:file -> state/settings.json
[ok] active-profile -> openai
[ok] profile:openai:env-files -> optional profile uses external env injection
[ok] profile:openai:required-env -> selected for codex in oauth mode
[ok] profile:anthropic:env-files -> optional profile uses external env injection
[ok] profile:anthropic:required-env -> selected for claude in oauth mode
[ok] tool:codex:runner -> codex (auth=oauth)
[ok] tool:claude:runner -> claude (auth=oauth)

Doctor completed: all checks passed.

=== Testing codex in portable-native mode ===
OK: codex works in portable-native mode

=== Testing claude in portable-native mode ===
OK: claude works in portable-native mode

=== Auth status ===
Auth status
settings initialized: yes
codex: oauth
codex host oauth home: state/auth/codex/host/home
codex vm oauth home: /home/portable/.pcoder-auth/codex
claude: oauth
claude host oauth home: state/auth/claude/host/home
claude vm oauth home: /home/portable/.pcoder-auth/claude

=== All smoke tests passed === - All tests pass

Verified Working

  • Linux host-native mode
  • Linux portable-native mode (linux-portable on Linux)
  • Both Codex and Claude Code work
  • Portable auth isolation functional
  • README updated with clear documentation

Remaining Work

  • Windows VM mode needs testing on actual Windows host
  • No automated test suite yet
  • Auth login/logout flows need testing

Gimli and others added 3 commits March 26, 2026 06:03
Problem:
- linux-portable mode was failing on Linux/macOS with 'linux-portable mode
  is currently implemented for Windows hosts only'
- This prevented true portability - the goal was to run Claude Code portably
  from a folder without installing on the host

Solution:
- On non-Windows hosts, linux-portable mode now uses 'portable-native'
  execution instead of failing
- portable-native runs tools directly on the host but with portable auth
  isolation (auth state stored in state/auth/<tool>/host/ instead of ~)
- Added runPortableHostNative() function for this behavior
- Updated README with cross-platform documentation and platform-specific
  behavior table

Changes:
- scripts/pcoder.cjs: Added runPortableHostNative(), modified
  runInLinuxPortableVm() to call it on non-Windows platforms
- README.md: Added Goal statement, Platform-Specific Behavior table,
  How It Works section, Directory Structure, and Testing section
- scripts/runtime/linux/smoke-check.sh: New smoke test for Linux/macOS

Testing:
- ./scripts/pcoder doctor: All checks pass
- ./scripts/pcoder run codex --mode linux-portable -- --version: Works
- ./scripts/pcoder run claude --mode linux-portable -- --version: Works
- ./scripts/runtime/linux/smoke-check.sh: All tests pass
- Add pwsh adapter to catalog.json
- Add 'local' profile for tools that don't need external env
- PowerShell works through PortableCoder on Linux

Tested:
  ./scripts/pcoder run pwsh -- -NoProfile -Command 'Write-Host Test'
  PowerShell 7.6.0 ConsoleHost
@mjenkinsx9 mjenkinsx9 merged commit 9d08d59 into main Mar 26, 2026
1 check failed
@mjenkinsx9 mjenkinsx9 deleted the gimli/fix-linux-portability branch March 26, 2026 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant