Skip to content

Attach command lost cwd auto-pass feature in upstream merge #283

@shuv1337

Description

@shuv1337

Problem

The shuvcode attach feature that automatically passes the client's current working directory (cwd) to the server via --dir has regressed. This was a fork-specific enhancement that ensured when attaching to a running server, the TUI operates in the directory where the client was launched, not where the server was started.

Current behavior (broken): When running shuvcode attach http://localhost:4096 from /home/user/project, the session operates in the server's launch directory.

Expected behavior: The session should operate in /home/user/project (the client's cwd).

Root Cause

The regression was introduced in commit dee022674 (upstream PR anomalyco#7150 "fix(tui): restore attach session lookup behavior") which changed:

// Before (our fix from 401b498c7)
const directory = process.cwd()
await tui({
  url: args.url,
  args: { sessionID: args.session },
  directory,
})

// After (regressed)
await tui({
  url: args.url,
  args: { sessionID: args.session },
  directory: args.dir ? process.cwd() : undefined,
})

The change makes directory conditional on --dir being explicitly provided, when it should ALWAYS be process.cwd().

Acceptance Criteria

  • When attaching without --dir, the client's cwd is passed to the SDK via x-opencode-directory header
  • File autocomplete, theme discovery, and exports use the client's directory
  • Sessions created via attach operate in the client's directory

Implementation

Restore the behavior from commit 401b498c7:

File: packages/opencode/src/cli/cmd/tui/attach.ts:23-29

handler: async (args) => {
  if (args.dir) process.chdir(args.dir)
  const directory = process.cwd()  // Always capture cwd
  await tui({
    url: args.url,
    args: { sessionID: args.session },
    directory,  // Always pass it
  })
},

Technical Context

The directory flows through:

  1. attach.ts → captures process.cwd()
  2. app.tsx → passes directory prop to SDKProvider
  3. sdk.tsx → passes to createOpencodeClient({ directory })
  4. client.ts → sets x-opencode-directory header on all SDK requests

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions