mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-15 02:20:38 +09:00
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Agents run shell commands during workspace provisioning (git worktree creation, runtime services) > - When `process.env.SHELL` is unset, the code falls back to `/bin/sh` > - But on Windows with Git Bash, `/bin/sh` doesn't exist as an absolute path — Git Bash provides `sh` on PATH instead > - This causes `child_process.spawn` to throw `ENOENT`, crashing workspace provisioning on Windows > - This PR extracts a `resolveShell()` helper that uses `$SHELL` when set, falls back to `sh` (bare) on Windows or `/bin/sh` on Unix > - The benefit is that agents running on Windows via Git Bash can provision workspaces without shell resolution errors ## Summary - `workspace-runtime.ts` falls back to `/bin/sh` when `process.env.SHELL` is unset - On Windows, `/bin/sh` doesn't exist → `spawn /bin/sh ENOENT` - Fix: extract `resolveShell()` helper that uses `$SHELL` when set, falls back to `sh` on Windows (Git Bash PATH lookup) or `/bin/sh` on Unix Three call sites updated to use the new helper. Fixes #892 ## Root cause When Paperclip spawns shell commands in workspace operations (e.g., git worktree creation), it uses `process.env.SHELL` if set, otherwise defaults to `/bin/sh`. On Windows with Git Bash, `$SHELL` is typically unset and `/bin/sh` is not a valid path — Git Bash provides `sh` on PATH but not at the absolute `/bin/sh` location. This causes `child_process.spawn` to throw `ENOENT`. ## Approach Rather than hard-coding a Windows-specific absolute path (e.g., `C:\Program Files\Git\bin\sh.exe`), we use the bare `"sh"` command which relies on PATH resolution. This works because: 1. Git Bash adds its `usr/bin` directory to PATH, making `sh` resolvable 2. On Unix/macOS, `/bin/sh` remains the correct default (it's the POSIX standard location) 3. `process.env.SHELL` takes priority when set, so this only affects the fallback ## Test plan - [x] 7 unit tests for `resolveShell()`: SHELL set, trimmed, empty, whitespace-only, linux/darwin/win32 fallbacks - [x] Run a workspace provision command on Windows with `git_worktree` strategy - [x] Verify Unix/macOS is unaffected 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Devin Foley <devin@devinfoley.com> |
||
|---|---|---|
| .. | ||
| helpers | ||
| activity-routes.test.ts | ||
| adapter-models.test.ts | ||
| adapter-session-codecs.test.ts | ||
| agent-auth-jwt.test.ts | ||
| agent-instructions-routes.test.ts | ||
| agent-instructions-service.test.ts | ||
| agent-permissions-routes.test.ts | ||
| agent-shortname-collision.test.ts | ||
| agent-skill-contract.test.ts | ||
| agent-skills-routes.test.ts | ||
| app-hmr-port.test.ts | ||
| approval-routes-idempotency.test.ts | ||
| approvals-service.test.ts | ||
| assets.test.ts | ||
| attachment-types.test.ts | ||
| board-mutation-guard.test.ts | ||
| budgets-service.test.ts | ||
| claude-local-adapter-environment.test.ts | ||
| claude-local-adapter.test.ts | ||
| claude-local-execute.test.ts | ||
| claude-local-skill-sync.test.ts | ||
| cli-auth-routes.test.ts | ||
| codex-local-adapter-environment.test.ts | ||
| codex-local-adapter.test.ts | ||
| codex-local-execute.test.ts | ||
| codex-local-skill-injection.test.ts | ||
| codex-local-skill-sync.test.ts | ||
| companies-route-path-guard.test.ts | ||
| company-branding-route.test.ts | ||
| company-portability-routes.test.ts | ||
| company-portability.test.ts | ||
| company-skills-routes.test.ts | ||
| company-skills.test.ts | ||
| costs-service.test.ts | ||
| cursor-local-adapter-environment.test.ts | ||
| cursor-local-adapter.test.ts | ||
| cursor-local-execute.test.ts | ||
| cursor-local-skill-injection.test.ts | ||
| cursor-local-skill-sync.test.ts | ||
| dev-runner-paths.test.ts | ||
| dev-server-status.test.ts | ||
| dev-watch-ignore.test.ts | ||
| documents.test.ts | ||
| error-handler.test.ts | ||
| execution-workspace-policy.test.ts | ||
| execution-workspaces-service.test.ts | ||
| feedback-service.test.ts | ||
| forbidden-tokens.test.ts | ||
| gemini-local-adapter-environment.test.ts | ||
| gemini-local-adapter.test.ts | ||
| gemini-local-execute.test.ts | ||
| gemini-local-skill-sync.test.ts | ||
| health.test.ts | ||
| heartbeat-process-recovery.test.ts | ||
| heartbeat-run-summary.test.ts | ||
| heartbeat-workspace-session.test.ts | ||
| hire-hook.test.ts | ||
| instance-settings-routes.test.ts | ||
| invite-accept-gateway-defaults.test.ts | ||
| invite-accept-replay.test.ts | ||
| invite-expiry.test.ts | ||
| invite-join-grants.test.ts | ||
| invite-join-manager.test.ts | ||
| invite-onboarding-text.test.ts | ||
| issue-comment-reopen-routes.test.ts | ||
| issue-document-restore-routes.test.ts | ||
| issue-feedback-routes.test.ts | ||
| issue-goal-fallback.test.ts | ||
| issue-telemetry-routes.test.ts | ||
| issues-checkout-wakeup.test.ts | ||
| issues-goal-context-routes.test.ts | ||
| issues-service.test.ts | ||
| issues-user-context.test.ts | ||
| log-redaction.test.ts | ||
| monthly-spend-service.test.ts | ||
| normalize-agent-mention-token.test.ts | ||
| openclaw-gateway-adapter.test.ts | ||
| openclaw-invite-prompt-route.test.ts | ||
| opencode-local-adapter-environment.test.ts | ||
| opencode-local-adapter.test.ts | ||
| opencode-local-skill-sync.test.ts | ||
| paperclip-env.test.ts | ||
| paperclip-skill-utils.test.ts | ||
| pi-local-adapter-environment.test.ts | ||
| pi-local-skill-sync.test.ts | ||
| plugin-dev-watcher.test.ts | ||
| plugin-telemetry-bridge.test.ts | ||
| plugin-worker-manager.test.ts | ||
| private-hostname-guard.test.ts | ||
| project-shortname-resolution.test.ts | ||
| quota-windows-service.test.ts | ||
| quota-windows.test.ts | ||
| redaction.test.ts | ||
| routines-e2e.test.ts | ||
| routines-routes.test.ts | ||
| routines-service.test.ts | ||
| server-startup-feedback-export.test.ts | ||
| storage-local-provider.test.ts | ||
| telemetry-client-flush.test.ts | ||
| ui-branding.test.ts | ||
| work-products.test.ts | ||
| workspace-runtime.test.ts | ||
| worktree-config.test.ts | ||