nexus/server/src/services
Octasoft Ltd f843a45a84
fix: use sh instead of /bin/sh as shell fallback on Windows (#891)
## 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>
2026-04-02 17:34:26 -07:00
..
access.ts Remove api trigger kind and mark webhook as coming soon 2026-03-20 06:54:03 -05:00
activity-log.ts Add username log censor setting 2026-03-20 08:50:00 -05:00
activity.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
agent-instructions.ts chore: mark bootstrapPromptTemplate as deprecated 2026-03-26 11:12:25 -05:00
agent-permissions.ts Implement agent hiring, approval workflows, config revisions, LLM reflection, and sidebar badges 2026-02-19 13:02:41 -06:00
agents.ts Fix budget auth and monthly spend rollups 2026-03-16 15:41:48 -05:00
approvals.ts Add username log censor setting 2026-03-20 08:50:00 -05:00
assets.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
board-auth.ts Address Greptile review on board CLI auth 2026-03-23 08:46:05 -05:00
budgets.ts Fix budget incident resolution edge cases 2026-03-16 16:48:13 -05:00
companies.ts Add feedback voting and thumbs capture flow 2026-04-02 09:11:49 -05:00
company-export-readme.ts fix: link Agent Company to agentcompanies.io in export README 2026-03-20 08:06:04 -05:00
company-portability.ts feat(routines): add workspace-aware routine runs 2026-04-02 11:38:57 -05:00
company-skills.ts refactor: rename URL validators to looksLikeRepoUrl 2026-04-01 23:21:22 +00:00
costs.ts Fix budget auth and monthly spend rollups 2026-03-16 15:41:48 -05:00
cron.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
dashboard.ts feat(costs): add billing, quota, and budget control plane 2026-03-16 15:11:01 -05:00
default-agent-instructions.ts Add default agent instructions bundle 2026-03-20 07:42:36 -05:00
documents.ts Add feedback voting and thumbs capture flow 2026-04-02 09:11:49 -05:00
execution-workspace-policy.ts fix: address latest Greptile runtime review 2026-03-23 19:43:50 -05:00
execution-workspaces.ts Fix shared workspace close semantics 2026-03-29 10:55:26 -05:00
feedback-redaction.ts Add feedback voting and thumbs capture flow 2026-04-02 09:11:49 -05:00
feedback-share-client.ts Add feedback voting and thumbs capture flow 2026-04-02 09:11:49 -05:00
feedback.ts Fix feedback review findings 2026-04-02 10:03:07 -05:00
finance.ts feat(costs): add billing, quota, and budget control plane 2026-03-16 15:11:01 -05:00
github-fetch.ts fix: harden GHE URL detection and extract shared GitHub helpers 2026-04-01 21:05:48 +00:00
goals.ts Improve onboarding defaults and issue goal fallback 2026-03-12 08:50:31 -05:00
heartbeat-run-summary.ts Fix issue run lookup and heartbeat run summaries 2026-03-11 17:23:33 -05:00
heartbeat.ts fix: use agent role for first heartbeat telemetry 2026-04-02 10:47:30 -05:00
hire-hook.ts feat(openclaw): add adapter hire-approved hooks 2026-03-06 08:17:42 -06:00
index.ts Add feedback voting and thumbs capture flow 2026-04-02 09:11:49 -05:00
instance-settings.ts feat(inbox): add operator search and keyboard controls 2026-04-02 11:45:15 -05:00
issue-approvals.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
issue-assignment-wakeup.ts fix: close remaining routine merge blockers 2026-03-20 16:40:27 -05:00
issue-goal-fallback.ts Seed onboarding project and issue goal context 2026-03-24 11:48:59 -05:00
issues.ts feat(routines): add workspace-aware routine runs 2026-04-02 11:38:57 -05:00
live-events.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
local-service-supervisor.ts Add idempotent local dev service management 2026-03-29 10:55:26 -05:00
plugin-capability-validator.ts Add plugin telemetry bridge capability 2026-04-02 10:47:29 -05:00
plugin-config-validator.ts Refactor secret-ref format registration to use a UI hint for Paperclip secret UUIDs 2026-03-14 15:43:56 -07:00
plugin-dev-watcher.ts Tighten plugin dev file watching 2026-03-14 12:07:04 -05:00
plugin-event-bus.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-host-service-cleanup.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-host-services.ts Add plugin telemetry bridge capability 2026-04-02 10:47:29 -05:00
plugin-job-coordinator.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-job-scheduler.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-job-store.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-lifecycle.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-loader.ts Enhance plugin loading and toolbar integration 2026-03-14 15:27:45 -07:00
plugin-log-retention.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-manifest-validator.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-registry.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-runtime-sandbox.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-secrets-handler.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-state-store.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-stream-bus.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-tool-dispatcher.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-tool-registry.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-worker-manager.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
project-workspace-runtime-config.ts Add workspace runtime controls 2026-03-29 10:55:26 -05:00
projects.ts fix: append short UUID suffix to project slugs when non-ASCII characters are stripped to prevent slug collisions 2026-03-31 16:35:30 +00:00
quota-windows.ts feat(costs): add billing, quota, and budget control plane 2026-03-16 15:11:01 -05:00
routines.ts fix(routines): address Greptile review findings 2026-04-02 12:09:02 -05:00
run-log-store.ts fix(server): use home-based path for run logs instead of cwd 2026-03-07 16:18:14 -08:00
secrets.ts Add routines automation workflows 2026-03-19 08:39:24 -05:00
sidebar-badges.ts Add touched/unread inbox issue semantics 2026-03-06 08:21:03 -06:00
work-products.ts Address remaining Greptile workspace review 2026-03-17 10:12:44 -05:00
workspace-operation-log-store.ts Add workspace operation tracking and fix project properties JSX 2026-03-17 09:36:35 -05:00
workspace-operations.ts Add username log censor setting 2026-03-20 08:50:00 -05:00
workspace-runtime.ts fix: use sh instead of /bin/sh as shell fallback on Windows (#891) 2026-04-02 17:34:26 -07:00