Skip to content

fix: handle plugin base URL for host binding#512

Merged
shantur merged 1 commit into
NeuralNomadsAI:devfrom
omercnet:fix/host-binding-plugin-base-url
May 31, 2026
Merged

fix: handle plugin base URL for host binding#512
shantur merged 1 commit into
NeuralNomadsAI:devfrom
omercnet:fix/host-binding-plugin-base-url

Conversation

@omercnet
Copy link
Copy Markdown
Contributor

Summary

  • Resolve the plugin fetch/SSE base URL from actual listener bindings instead of always publishing 127.0.0.1.
  • Preserve loopback plugin loading for default local, localhost, wildcard, and mixed HTTP/HTTPS listener setups.
  • Make the git clone destination test portable so server tests run with zero skips.

Validation

  • npm run typecheck --workspace @neuralnomads/codenomad
  • node --import tsx --test packages/server/src/server/tests/listener-base-url.test.ts packages/server/src/server/tests/network-addresses.test.ts packages/server/src/workspaces/tests/git-clone.test.ts — 15 pass / 0 fail / 0 skipped
  • shopt -s globstar && node --import tsx --test packages/server/src/**/*.test.ts — 59 pass / 0 fail / 0 skipped

Notes

  • Nomad task/evidence artifacts intentionally excluded from the commit per maintainer request.

Use the listener binding metadata to choose the plugin fetch/SSE base URL so concrete non-loopback --host values receive a reachable server URL instead of always using 127.0.0.1.

Preserve loopback behavior for default, localhost, wildcard, and mixed listener setups, and add listener selection coverage. Make the existing git clone destination test portable so the server test suite runs without skipped tests.
@github-actions
Copy link
Copy Markdown

PR builds are available as GitHub Actions artifacts:

https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/26679740183

Artifacts expire in 7 days.
Artifacts:

  • pr-512-433f8781331824c343f649d5e7add952cce53ed9-electron-macos
  • pr-512-433f8781331824c343f649d5e7add952cce53ed9-tauri-macos
  • pr-512-433f8781331824c343f649d5e7add952cce53ed9-tauri-windows
  • pr-512-433f8781331824c343f649d5e7add952cce53ed9-tauri-linux
  • pr-512-433f8781331824c343f649d5e7add952cce53ed9-tauri-macos-arm64
  • pr-512-433f8781331824c343f649d5e7add952cce53ed9-electron-windows
  • pr-512-433f8781331824c343f649d5e7add952cce53ed9-electron-linux

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented May 31, 2026

@CodeNomadBot

I want you to perform the gatekeeper checks for latest PR state

check for regressions
check for better possible implementations
Be the PR gatekeeper
Be ruthless about code quality

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot Bot commented May 31, 2026

Gatekeeper review for latest PR state.

Assumption: the requested scope is review/validation only, not code changes.

Findings:

No blocking code-quality or regression findings from static review of the PR diff. The listener-base-url change is tightly scoped, preserves the old loopback preference for local/default and mixed HTTP/HTTPS setups, and correctly avoids advertising 127.0.0.1 when the only listener is bound to a concrete LAN host. The git-clone test change keeps the Windows root-child coverage on Windows while removing the non-Windows skip.

Non-blocking quality notes:

  • packages/server/src/server/listener-base-url.ts adds a third loopback-host predicate variant alongside similar local helpers in packages/server/src/index.ts, packages/server/src/server/http-server.ts, and packages/server/src/server/routes/meta.ts. This is acceptable for this small fix, but the next networking touch should consolidate host classification to avoid drift.
  • The new tests cover 127.0.0.1, 0.0.0.0, LAN-only, and mixed HTTP/HTTPS. I would add follow-up coverage for IPv6 wildcard/concrete host behavior if IPv6 binding is a supported user path, because URL formatting and dual-stack assumptions are easy to regress.

Validation attempted:

  • npm run typecheck --workspace @neuralnomads/codenomad failed before checking the PR code because this webhook worktree cannot resolve @types/node.
  • node --import tsx --test packages/server/src/server/__tests__/listener-base-url.test.ts packages/server/src/server/__tests__/network-addresses.test.ts packages/server/src/workspaces/__tests__/git-clone.test.ts failed before running tests because this webhook worktree cannot resolve tsx.

I did not mutate dependencies to repair the local worktree. Based on static review, I do not see a reason to block this PR, but I cannot claim independent local test/typecheck success from this run.

--
Yours,
CodeNomadBot

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented May 31, 2026

Hey @omercnet

Thanks for the PR
Can you explain what was failing?
IIRC the codenomad plugin is fetched via file:// not http url and we don't manage other plugins

@omercnet
Copy link
Copy Markdown
Contributor Author

I noticed an error in opencode logs, seems that when host is customized (in my case to a tailscale ip) it's not load via file but defaults to https://127.0.0.1:9898

@shantur
Copy link
Copy Markdown
Collaborator

shantur commented May 31, 2026

@CodeNomadBot

Can you confirm what url the codenomad sets in the inline opencode variable for loading codenomad plugin from packages/codenomad-plugin packages/server

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot Bot commented May 31, 2026

Confirmed from the current PR code.

The inline OpenCode config variable is OPENCODE_CONFIG_CONTENT, set in packages/server/src/workspaces/manager.ts via:

const opencodeConfigContent = buildOpencodeConfigContent(
  resolveExistingOpencodeConfigContent(userEnvironment),
  this.codeNomadPluginUrl,
)

this.codeNomadPluginUrl is resolved once from getCodeNomadPluginUrl() in packages/server/src/opencode-plugin.ts.

For loading the CodeNomad OpenCode plugin, the URL/spec inserted into OPENCODE_CONFIG_CONTENT.plugin[] is:

  • Dev/source run: file://.../packages/opencode-plugin/plugin/codenomad.ts
  • Packaged/prod run: @codenomad/codenomad-opencode-plugin@file:<absolute-path-to-codenomad-plugin-tarball.tgz>
  • Existing user plugins are preserved; this CodeNomad plugin entry is appended only if it is not already present.

So: plugin loading itself is not via https://127.0.0.1:9898. It is file-based/source-or-tarball-based.

The HTTP(S) URL from this PR is a different variable used by the loaded plugin to call back into CodeNomad:

CODENOMAD_BASE_URL: serverBaseUrl

The plugin reads that in packages/opencode-plugin/plugin/lib/request.ts:

baseUrl: requireEnv("CODENOMAD_BASE_URL")

Then it builds plugin API/SSE URLs as:

${CODENOMAD_BASE_URL}/workspaces/${CODENOMAD_INSTANCE_ID}/plugin/events

That means an OpenCode log mentioning https://127.0.0.1:9898/.../plugin/events is about the already-loaded CodeNomad plugin connecting back to the CodeNomad server, not about OpenCode loading the plugin package/module.

This PR changes the value feeding CODENOMAD_BASE_URL by changing serverMeta.localUrl resolution. It does not change the OPENCODE_CONFIG_CONTENT.plugin[] loading spec.

--
Yours,
CodeNomadBot

@shantur shantur merged commit b2855f4 into NeuralNomadsAI:dev May 31, 2026
11 checks passed
@omercnet omercnet deleted the fix/host-binding-plugin-base-url branch June 1, 2026 05:23
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.

2 participants