Skip to content

fix(adapters): treat adapterConfig.cwd as remote-only for ssh/sandbox targets (FLO-542) - #7

Closed
Fl0p wants to merge 7 commits into
fork-patchesfrom
flo-542-remote-target-aware-cwd
Closed

fix(adapters): treat adapterConfig.cwd as remote-only for ssh/sandbox targets (FLO-542)#7
Fl0p wants to merge 7 commits into
fork-patchesfrom
flo-542-remote-target-aware-cwd

Conversation

@Fl0p

@Fl0p Fl0p commented Aug 9, 2026

Copy link
Copy Markdown

Summary

Fixes the fork bug where every adapter execute path did an unconditional local mkdir of the configured cwd even when the execution target is a remote ssh/sandbox env — the root cause of the EACCES: mkdir '/Users' crash that killed all of Robert's remote runs (FLO-535 / FLO-537).

Two coupled defects, both fixed:

  1. Local mkdir of a remote path. buildRuntimeConfig/execute called ensureAbsoluteDirectory(cwd, { createIfMissing }) before any remote branch. With a remote-only adapterConfig.cwd (Robert: /Users/rob/aignite) this ran mkdir -p /Users/rob/aignite on the Pi → EACCES → run died before any ssh.
  2. Remote path used as the local staging dir. Even with the mkdir skipped, cwd (the remote-only path) was passed as workspaceLocalDir to the remote runtime, which reads it locally — a real agent_home remote agent would sync an empty/wrong workspace up to the remote.

Change

Make every adapter execute path target-aware:

  • Only run the local directory ensure for local targets. For remote targets the working dir is ensured on the target by the remote runtime (mkdir -p over ssh/sandbox inside prepareRemoteManagedRuntime), so no explicit extra round-trip is added.
  • Gate useConfiguredInsteadOfAgentHome on !executionTargetIsRemote, so for remote targets adapterConfig.cwd no longer hijacks the LOCAL staging dir; the local workspace/agent-home is the sync source and the remote working dir keeps coming from environment.remoteWorkspacePath.

Applied to claude-local, codex-local, cursor-local, gemini-local, grok-local, opencode-local, pi-local and the shared acpx-engine execute path. hermes is local-only (no remote target) and left unchanged.

Decision (documented in docs/adapters/overview.md): for remote targets adapterConfig.cwd is not a local filesystem path; the remote dir is environment.remoteWorkspacePath. A remote-only cwd is ignored for local-FS purposes.

Tests / verification

  • New claude-local regression test: a remote-only adapterConfig.cwd is never local-mkdir-ed and is not used as the sync source (the local agent-home is). Passes.
  • typecheck green on all 8 changed packages (adapter-utils + 7 adapters).
  • Pre-existing unrelated red: execute.remote.test.ts > "prepares the workspace…" fails identically on baseline fork-patches (stale syncDirectoryToSsh call-count assertion, 1 vs 2) — not touched here.

Scope / governance

  • Fixes FLO-542; consolidates duplicate FLO-541 (cancelled).
  • paperclip is board-owned — do not merge to fork-patches without board owner approval. Requesting review + merge sign-off.

🤖 Generated with Claude Code

FlopBut and others added 7 commits July 25, 2026 01:01
At startup PAPERCLIP_RUNTIME_API_URL was overwritten unconditionally with the
URL derived from the first allowedHostnames entry, conflating the internal
agent->server callback URL with the public browser-facing hostname. Behind a
reverse proxy/tunnel that forces agents to call the server over the public,
access-gated origin instead of loopback.

- Honor a pre-set PAPERCLIP_RUNTIME_API_URL via an extracted resolveRuntimeApiUrl()
  helper (pre-set-then-fallback, mirroring the PAPERCLIP_API_URL line above it).
- Lead the runtime API candidates list (PAPERCLIP_RUNTIME_API_CANDIDATES_JSON)
  with a pre-set PAPERCLIP_RUNTIME_API_URL when present, so a pinned loopback
  callback isn't fronted by the public hostname an operator decoupled from.
  When it is unset the list still leads with the configured API URL, unchanged.
- Unit-test the precedence in runtime-api.test.ts (pre-set wins, trimmed,
  unset/blank fall back) and the pinned-runtime candidate ordering in
  server-startup-feedback-export.test.ts.

When neither var is pre-set, behavior is byte-for-byte identical to before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Local MCP artifacts (.playwright-mcp, .markdown_vault_mcp) should not be
tracked; add ignore patterns and remove stray docs/.markdown_vault_mcp/.

Co-authored-by: Soren <soren@agents.flopbut.local>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Cursor <cursoragent@cursor.com>
…xy (#4)

Behind Cloudflare Access the console threw on every load:
- A CORS error because /site.webmanifest was fetched without credentials
  and 302-redirected cross-origin to the Access login.
- `TypeError: Failed to convert value to 'Response'` because the SW catch
  handler passed `caches.match(request)` (undefined on a miss) straight
  into `event.respondWith`.

Changes:
- SW now skips cross-origin requests and the auth-sensitive /site.webmanifest
  and /sw.js paths, letting the network/auth proxy own them untouched.
- Never caches redirected / opaqueredirect responses (auth challenges).
- Both catch branches await the cache lookup and fall back to a real
  Response (503 navigate, 504 otherwise) — respondWith never sees undefined.
- Bump CACHE_NAME paperclip-v2 -> paperclip-v3 so the new worker replaces
  the cached old one.
- index.html manifest link gains crossorigin="use-credentials".

Co-authored-by: Wayland <wayland@agents.flopbut.local>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The actions/dependency-review-action errors at startup with "Dependency
review is not supported on this repository" because the Dependency graph
feature is disabled in repo settings. That made the `review` check red on
100% of PRs, training reviewers to ignore CI failures.

Add continue-on-error: true to the step so the `review` check goes red
only on real quality-gate failures. Remove the guard once Dependency
graph is enabled in Settings -> Code security & analysis.

Refs FLO-252.

Co-authored-by: Daedalus <daedalus@agents.flopbut.local>
Co-authored-by: Paperclip <noreply@paperclip.ing>
…ler footer

Upstream paperclip skill mandated `Co-Authored-By: Paperclip
<noreply@paperclip.ing>` on every commit and told agents not to use their own
name. That trailer is prohibited by FlopBut governance and conflicts with our
two-trailer (agent + model) footer rule. Board approved Option A on FLO-490
(interaction f74e5d6b): patch the fork's SKILL.md to match our governance.
Kept as a fork-patch so it survives the weekly upstream rebase.

Co-Authored-By: Prospero <prospero@agents.flopbut.local>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The adapter execute paths called ensureAbsoluteDirectory(cwd, {
createIfMissing: true }) unconditionally before any remote branch. For an
agent bound to an SSH/sandbox environment whose configured cwd is a
remote-only path (e.g. adapterConfig.cwd "/Users/rob/aignite"), this ran
`mkdir -p` on the Pi and died with EACCES before any ssh happened,
killing every run.

Gate the local ensure behind !executionTargetIsRemote in every adapter
execute path (claude / gemini / cursor / pi / opencode / grok / codex-local
and the acpx engine). For remote targets the execution cwd lives on the
remote host and is ensured there by the remote runtime path; local agents
are unchanged. hermes is left as-is: it has no remote-execution support and
its ensure is already wrapped in a non-fatal try/catch.

Adds a claude-local remote regression test: a remote SSH run with a
remote-only cwd must not invoke the local directory helper and must still
reach the CLI spawn.

FLO-541

Co-Authored-By: Daedalus <daedalus@agents.flopbut.local>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… targets

For remote (SSH/sandbox) execution targets the adapter execute paths ran an
unconditional local `ensureAbsoluteDirectory(cwd, { createIfMissing })` and used
`cwd` (which can resolve to a remote-only adapterConfig.cwd such as
"/Users/rob/aignite") as the local staging dir. On the Paperclip host that
mkdir failed with EACCES and killed the run before any ssh; even with the mkdir
skipped, the remote-only path would have been synced up as an empty/wrong local
workspace.

Make every adapter execute path target-aware:
- Only run the local directory ensure for local targets; the remote cwd is
  ensured on the target by the remote runtime (mkdir -p over ssh/sandbox).
- For remote targets adapterConfig.cwd no longer overrides agent-home as the
  LOCAL staging dir (useConfiguredInsteadOfAgentHome is gated on
  !executionTargetIsRemote), so the local workspace/agent-home is the sync
  source and a remote-only cwd never touches the local filesystem. The remote
  working dir comes from environment.remoteWorkspacePath, as before.

Applied to claude-local, codex-local, cursor-local, gemini-local, grok-local,
opencode-local, pi-local and the shared acpx-engine execute path (hermes is
local-only and unchanged). Adds a claude-local regression test proving a
remote-only adapterConfig.cwd is neither local-mkdir'd nor used as the sync
source, and documents adapterConfig.cwd semantics for remote targets.

Fixes FLO-542. Consolidates duplicate FLO-541.

Co-Authored-By: Daedalus <daedalus@agents.flopbut.local>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d98c660c-6a53-4b05-bf23-180b61268488

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Fl0p
Fl0p force-pushed the fork-patches branch 2 times, most recently from ea6f3a6 to dc2e238 Compare August 9, 2026 12:30
@Fl0p

Fl0p commented Aug 9, 2026

Copy link
Copy Markdown
Author

Rebased merged

@Fl0p Fl0p closed this Aug 9, 2026
@Fl0p
Fl0p deleted the flo-542-remote-target-aware-cwd branch August 9, 2026 12:37
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