Skip to content

Package CodeNomad OpenCode plugin#433

Merged
shantur merged 5 commits into
devfrom
opencode-config-merge
May 12, 2026
Merged

Package CodeNomad OpenCode plugin#433
shantur merged 5 commits into
devfrom
opencode-config-merge

Conversation

@shantur
Copy link
Copy Markdown
Collaborator

@shantur shantur commented May 11, 2026

Summary

  • Rename the OpenCode config template into a versioned npm-packable CodeNomad plugin package.
  • Build and package the plugin through the server bundle, with Electron/Tauri carrying it via existing server resources.
  • Replace OPENCODE_CONFIG_DIR injection with JSONC-aware OPENCODE_CONFIG_CONTENT merging that appends the CodeNomad plugin while preserving user config.

Validation

  • npm run build --workspace @codenomad/codenomad-opencode-plugin
  • npm run prepare-plugin --workspace @neuralnomads/codenomad
  • npm run typecheck --workspace @neuralnomads/codenomad
  • npm run typecheck --workspace @neuralnomads/codenomad-electron-app
  • node --import tsx --test "src/opencode-plugin.test.ts" "src/workspaces/tests/spawn.test.ts"

Notes

  • Production plugin loading uses an explicit npm file alias for the packaged tarball.
  • Dev loading still references the TypeScript plugin entry directly.

Replace the copied opencode config template with a versioned npm-packable CodeNomad OpenCode plugin package. The server now builds and packs the plugin artifact, and desktop bundles carry the packaged plugin through the existing server resources.

Workspace launches now merge any user or system OPENCODE_CONFIG_CONTENT JSONC with CodeNomad's plugin entry, preserving existing plugin config while ensuring the managed bridge is available. Production uses an explicit npm file alias for the packaged tarball, while dev keeps loading the TypeScript plugin source directly.

Validated with plugin build, server and Electron typechecks, targeted plugin config tests, and WSL spawn environment tests.
@shantur
Copy link
Copy Markdown
Collaborator Author

shantur commented May 11, 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

@github-actions
Copy link
Copy Markdown

PR builds are available as GitHub Actions artifacts:

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

Artifacts expire in 7 days.
Artifacts: (none found on this run)

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot Bot commented May 11, 2026

Gatekeeper review for the latest PR state.

Understood request: review this PR ruthlessly for regressions and implementation quality, not to make code changes. Assumption: the PR should preserve existing desktop packaging behavior across Electron, Tauri, Windows/WSL, Linux, and macOS.

Findings:

  1. Blocker: root install is now platform-specific and will break non-macOS-arm64 environments. package.json:28-31 adds @tauri-apps/cli-darwin-arm64 as a normal root dependency. That package has os/cpu restrictions, so Linux, Windows, and macOS x64 installs can fail with EBADPLATFORM; it also has no obvious relationship to packaging the OpenCode plugin. This should be removed from root dependencies and the lockfile. Keep Tauri CLI under packages/tauri-app dev dependencies or install platform binaries as optional/no-save tooling as the existing prebuild workaround already does.

  2. Blocker: production OpenCode plugin loading is broken for WSL binaries. packages/server/src/opencode-plugin.ts:71-72 embeds the host tarball path inside the plugin specifier, packages/server/src/workspaces/manager.ts:147-150 places that specifier inside OPENCODE_CONFIG_CONTENT, and packages/server/src/workspaces/spawn.ts:283-290 now propagates OPENCODE_CONFIG_CONTENT without WSL path translation. A WSL OpenCode process receives JSON containing a Windows host path such as @codenomad/codenomad-opencode-plugin@file:C:/.../codenomad-opencode-plugin.tgz, but that path is not valid inside Linux. The previous OPENCODE_CONFIG_DIR path was explicitly translated with /p; this PR removes that escape hatch. Fix by making the packaged plugin path resolvable from the target runtime before writing the config content, or by materializing/copying the plugin into a Linux-reachable location for WSL launches. Add a regression test that combines getCodeNomadPluginUrl() output with WSL spawning rather than only asserting WSLENV string shape.

  3. High: Tauri’s dependency self-healing no longer covers the server build path it invokes. packages/tauri-app/scripts/prebuild.js:42-46 only checks/installs server build dependencies, then packages/tauri-app/scripts/prebuild.js:64-75 runs the server build, which now calls packages/server/scripts/package-opencode-plugin.mjs:41-42. That new step requires the plugin workspace dev deps from packages/opencode-plugin/package.json:19-21 (typescript, @types/node), but prebuild never ensures them. In this workspace, npm run build --workspace @codenomad/codenomad-opencode-plugin fails with TS2688: Cannot find type definition file for 'node', which is exactly the missing dependency class this prebuild script is supposed to avoid for desktop packaging. Either include the plugin workspace in the prebuild dependency install/check or make prepare-plugin install/build from a dependency state that Tauri packaging guarantees.

Validation performed:

  • git diff --check origin/dev...HEAD: passed.
  • npm run build --workspace @codenomad/codenomad-opencode-plugin: failed locally with missing @types/node (TS2688).
  • node --import tsx --test "packages/server/src/opencode-plugin.test.ts" "packages/server/src/workspaces/__tests__/spawn.test.ts": failed locally because tsx is not installed in this worktree.

Decision: changes requested. I would not merge this PR until the accidental platform dependency is removed and WSL production plugin loading is proven with a real path translation/accessibility test.

--
Yours,
CodeNomadBot

@github-actions
Copy link
Copy Markdown

PR builds are available as GitHub Actions artifacts:

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

Artifacts expire in 7 days.
Artifacts: (none found on this run)

Remove the accidental darwin-arm64 Tauri CLI root dependency so installs remain cross-platform.

For WSL OpenCode launches, rewrite packaged CodeNomad plugin file specs through a WSLENV-translated helper path before exec so the Linux process receives a reachable file path inside OPENCODE_CONFIG_CONTENT.

Ensure Tauri prebuild installs the OpenCode plugin workspace build dependencies before invoking the server build, since server packaging now builds the plugin package.

Validated with plugin build, server typecheck, targeted OpenCode plugin config and WSL spawn tests, and diff whitespace checks.
@shantur
Copy link
Copy Markdown
Collaborator Author

shantur commented May 11, 2026

@CodeNomadBot

Check again now

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot Bot commented May 11, 2026

Gatekeeper re-check for the updated PR state.

Understood request: re-review the latest pushed state and verify whether the prior blockers were addressed. Assumption: this PR must be mergeable with the validation commands listed in the PR body, especially the plugin build/package path.

Findings:

  1. Blocker: the plugin package still does not build, so server packaging cannot succeed. After installing the plugin workspace deps using the same command now added to Tauri prebuild, npm run build --workspace @codenomad/codenomad-opencode-plugin fails with declaration emit errors:
plugin/codenomad.ts(7,23): error TS2742: The inferred type of 'CodeNomadPlugin' cannot be named without a reference to '@opencode-ai/plugin/node_modules/zod'. This is likely not portable. A type annotation is necessary.
plugin/lib/background-process.ts(30,17): error TS2742: The inferred type of 'createBackgroundProcessTools' cannot be named without a reference to '@opencode-ai/plugin/node_modules/zod'. This is likely not portable. A type annotation is necessary.

Because packages/opencode-plugin/tsconfig.json:10 enables declaration, exported functions cannot rely on inferred types that leak transitive nested dependency types. This blocks packages/server/scripts/package-opencode-plugin.mjs, and npm run prepare-plugin --workspace @neuralnomads/codenomad fails for the same reason. Fix by adding explicit portable return type annotations for CodeNomadPlugin and createBackgroundProcessTools, or by otherwise preventing declaration emit from needing to name the nested zod types.

Resolved from prior review:

  • The accidental root @tauri-apps/cli-darwin-arm64 dependency is gone from package.json; that blocker looks fixed.
  • Tauri prebuild now has an explicit plugin workspace dependency bootstrap in packages/tauri-app/scripts/prebuild.js; the previous missing-deps path is addressed, but the build now gets far enough to expose the TS2742 declaration issue above.
  • The WSL plugin tarball path handling now rewrites the host file path through CODENOMAD_OPENCODE_PLUGIN_WSL_PATH with /p translation and replaces a placeholder inside OPENCODE_CONFIG_CONTENT. Static review says this is a reasonable targeted fix, and there is a regression test for the WSL rewrite path.

Validation performed:

  • git diff --check origin/dev...HEAD: passed.
  • npm install --workspace @codenomad/codenomad-opencode-plugin --include-workspace-root=false --install-strategy=nested --fund=false --audit=false: passed.
  • npm run build --workspace @codenomad/codenomad-opencode-plugin: failed with TS2742.
  • npm run prepare-plugin --workspace @neuralnomads/codenomad: failed because the plugin build fails with TS2742.
  • node --import tsx --test "packages/server/src/opencode-plugin.test.ts" "packages/server/src/workspaces/__tests__/spawn.test.ts": not runnable in this worktree because tsx is not installed here.

Decision: changes still requested. The prior architecture blockers are mostly addressed, but this PR is still not mergeable until the plugin package build and prepare-plugin pass cleanly.

--
Yours,
CodeNomadBot

Disable declaration output for the packaged OpenCode plugin and clean dist before builds so stale .d.ts files are not packed. The plugin is consumed as runtime JavaScript by OpenCode, and declaration generation can infer non-portable nested zod paths from @opencode-ai/plugin.

Add explicit hook return annotations on the plugin entry to keep exported runtime shapes clear while avoiding declaration generation in CI builds.

Validated with plugin build, server prepare-plugin packaging, server typecheck, and targeted plugin/WSL tests.
@github-actions
Copy link
Copy Markdown

PR builds are available as GitHub Actions artifacts:

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

Artifacts expire in 7 days.
Artifacts: (none found on this run)

@shantur
Copy link
Copy Markdown
Collaborator Author

shantur commented May 11, 2026

@CodeNomadBot

Now?

@codenomadbot
Copy link
Copy Markdown
Contributor

codenomadbot Bot commented May 11, 2026

Gatekeeper re-check for the latest pushed state.

Understood request: verify whether the remaining blocker is resolved now. Assumption: this pass should focus on the previously failing plugin build/package path and any obvious regressions in the touched code.

Findings:

  • No new blocking code findings in this pass. The previous TS2742 plugin build blocker is resolved on the current branch.

Previously requested fixes now verified:

  • Root package.json no longer includes the accidental platform-specific @tauri-apps/cli-darwin-arm64 dependency.
  • npm run build --workspace @codenomad/codenomad-opencode-plugin now passes.
  • npm run prepare-plugin --workspace @neuralnomads/codenomad now passes and produces packages/server/dist/opencode-plugin/codenomad-opencode-plugin.tgz.
  • The WSL plugin path rewrite remains covered by the added spawn test path and looks targeted to the production tarball path issue.

Validation performed:

  • git diff --check origin/dev...HEAD: passed.
  • npm run build --workspace @codenomad/codenomad-opencode-plugin: passed.
  • npm run prepare-plugin --workspace @neuralnomads/codenomad: passed.
  • npm run typecheck --workspace @neuralnomads/codenomad: could not be meaningfully validated in this worktree because server dependencies were missing; errors were module-resolution failures for packages like fastify, zod, undici, etc.
  • npm run typecheck --workspace @neuralnomads/codenomad-electron-app: could not be meaningfully validated in this worktree because Electron dependencies were missing; errors were module-resolution failures for packages like electron, electron-vite, vite-plugin-solid, etc.
  • I attempted to install the missing server/Electron workspace deps, but the local npm install failed with workspace/node_modules corruption and an esbuild spawn error, so I am not treating those dependency-environment failures as PR code regressions.
  • node --import tsx --test src/opencode-plugin.test.ts src/workspaces/__tests__/spawn.test.ts: still not runnable in this worktree because tsx is not installed/resolvable here.

Decision: no changes requested from this gatekeeper pass. The prior blocker I could reproduce is fixed. CI or a clean dependency install should still be used as the final authority for the broader typecheck/test commands that this local worktree could not execute cleanly.

--
Yours,
CodeNomadBot

@shantur
Copy link
Copy Markdown
Collaborator Author

shantur commented May 11, 2026

@pascalandr - Would you be able to test this on Windows and see if it still works in packaged binaries?

@pascalandr
Copy link
Copy Markdown
Contributor

pascalandr commented May 11, 2026

Tested locally on Windows: Tauri packaged build passes, Electron packaged build passes after the small Windows quoting fix in #436, and both packaged resources include the OpenCode plugin tarball.
It launches successfully and resolves the packaged OpenCode plugin path

## Summary
- Avoid routing the Electron resource-prep Node invocation through the
Windows shell.
- Fix local `build:win` when Node is installed under `C:\Program
Files\nodejs\node.exe`.

## Validation
- `npm run build:win --workspace @neuralnomads/codenomad-electron-app`

## Notes
- This targets `opencode-config-merge` so it can be merged into #433.
@shantur
Copy link
Copy Markdown
Collaborator Author

shantur commented May 12, 2026

Thanks for testing and the PR @pascalandr

@shantur shantur merged commit cf88dc0 into dev May 12, 2026
10 of 11 checks passed
@shantur shantur deleted the opencode-config-merge branch May 12, 2026 08:00
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