Skip to content

Simplify rootPath: always use remote proxy, remove local build deps#4

Draft
Copilot wants to merge 4 commits intodevfrom
copilot/simplify-rootpath-implementation
Draft

Simplify rootPath: always use remote proxy, remove local build deps#4
Copilot wants to merge 4 commits intodevfrom
copilot/simplify-rootpath-implementation

Conversation

Copy link

Copilot AI commented Feb 3, 2026

What does this PR do?

Eliminates 150 LOC of local/remote fallback logic that prevented true single-binary distribution. Server now always fetches UI from https://app.opencode.ai with 5-minute caching, removing ../app/dist folder dependency.

Before:

  • Check local build exists → use serveStatic OR proxy
  • rootPath + no build = error
  • Two code paths, confusing warnings

After:

  • Always fetch remote + cache index.html (5min TTL)
  • rootPath injection via existing injectRootPath()
  • Single code path, no build checks

Key changes:

  • server.ts (-66 lines): Removed createStaticOrProxyHandler(), APP_DIST_PATH, and all Bun.file() checks
  • New functions: fetchAndInjectIndexHtml(), createIndexHandler() with caching, createStaticHandler()
  • listen(): No longer validates local build existence for rootPath
  • Tests: Updated to reflect remote-first behavior
  • Docs: Added deployment section explaining remote UI architecture
// Simple and consistent
async function fetchAndInjectIndexHtml(rootPath: string): Promise<string> {
  const response = await fetch(`${REMOTE_PROXY_URL}/index.html`)
  if (!response.ok) throw new Error(`Failed to fetch index.html: ${response.status}`)
  const html = await response.text()
  return rootPath ? injectRootPath(html, rootPath) : html
}

How did you verify your code works?

Code review completed with feedback addressed (extracted cache TTL constant). CodeQL security scan passed with zero alerts.

Original prompt

Objective

Simplify the rootPath implementation by using remote proxy as the default, eliminating local build dependencies for single-binary distribution.

Current Issues

  1. Complex local/remote fallback logic (~150 LOC)
  2. Folder structure dependency (../app/dist/) breaks single-binary deployment
  3. Confusing messages for end users who already have built distributions
  4. Unnecessary build checks for packaged installations

Required Changes

1. packages/opencode/src/server/server.ts

Remove:

  • APP_DIST_PATH and APP_INDEX_PATH constants
  • createStaticOrProxyHandler() function
  • Local build existence checks
  • All Bun.file() operations for local HTML

Simplify to:

const REMOTE_PROXY_URL = "https://app.opencode.ai"

async function fetchAndInjectIndexHtml(rootPath: string): Promise<string> {
  const response = await fetch(`${REMOTE_PROXY_URL}/index.html`)
  if (!response.ok) throw new Error(`Failed to fetch index.html: ${response.status}`)
  
  const html = await response.text()
  return rootPath ? injectRootPath(html, rootPath) : html
}

function createIndexHandler(rootPath: string) {
  let cachedHtml: string | null = null
  let cacheTime = 0
  const CACHE_TTL = 5 * 60 * 1000
  
  return async (c: any) => {
    const now = Date.now()
    if (cachedHtml && (now - cacheTime) < CACHE_TTL) {
      return c.html(cachedHtml, 200, { "Content-Security-Policy": HTML_CSP_HEADER })
    }
    
    cachedHtml = await fetchAndInjectIndexHtml(rootPath)
    cacheTime = now
    return c.html(cachedHtml, 200, { "Content-Security-Policy": HTML_CSP_HEADER })
  }
}

function createStaticHandler() {
  return async (c: any) => {
    const response = await proxy(`${REMOTE_PROXY_URL}${c.req.path}`, {
      ...c.req,
      headers: { ...c.req.raw.headers, host: "app.opencode.ai" }
    })
    return response
  }
}

Update listen() function:

  • Remove all local build checks
  • Remove createStaticOrProxyHandler() call
  • Simplify to always use remote proxy
  • Add optional network health check on startup
  • Keep existing rootPath mounting logic

2. packages/opencode/src/cli/network.ts

Keep existing validation:

if (rootPath && !rootPath.startsWith("/")) {
  throw new Error(
    `Invalid rootPath: must start with '/' (got: '${rootPath}')\n` +
    `Example: --root-path /jupyter/proxy/opencode`
  )
}

3. packages/opencode/src/server/html-utils.ts

No changes needed - keep existing injectRootPath() function as-is.

4. packages/web/src/content/docs/server.mdx

Simplify documentation:

### Deployment

OpenCode server uses remote UI (https://app.opencode.ai) by default.
All processing happens locally - only frontend assets are fetched remotely.

```bash
# Standard mode
opencode serve

# Behind reverse proxy
opencode serve --root-path /jupyter/proxy/opencode

Reverse Proxy Mode:

When using --root-path, all routes are prefixed:

opencode serve --root-path /jupyter/proxy/opencode
# Access at: http://your-server/jupyter/proxy/opencode/

### 5. `packages/opencode/test/server/rootpath.test.ts`

**Update tests:**
- Remove local build related tests
- Add network error handling tests
- Test HTML caching behavior
- Test remote fetch + rootPath injection

## Code Style Requirements

- Minimize comments (only when necessary for clarity)
- All comments must be in English
- Remove verbose logging messages
- Keep error messages concise and actionable

## Expected Benefits

- ✅ True single-binary distribution (no folder dependencies)
- ✅ ~50% code reduction (150 LOC → ~80 LOC)
- ✅ Eliminates confusion for packaged users
- ✅ Simpler maintenance and testing
- ✅ Performance optimization via caching

## Testing Checklist

- [ ] Server starts without local build
- [ ] rootPath injection works correctly
- [ ] Static assets proxy correctly
- [ ] WebSocket connections work
- [ ] Caching reduces redundant fetches
- [ ] Network errors are handled gracefully
- [ ] Jupyter proxy integration works

This pull request was created from Copilot chat.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits February 3, 2026 02:15
…ote proxy

Co-authored-by: DaehoYang <129835752+DaehoYang@users.noreply.github.com>
…test documentation

Co-authored-by: DaehoYang <129835752+DaehoYang@users.noreply.github.com>
Copilot AI changed the title [WIP] Simplify rootPath implementation with remote proxy Simplify rootPath: always use remote proxy, remove local build deps Feb 3, 2026
Copilot AI requested a review from DaehoYang February 3, 2026 02:20
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.

3 participants