You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Devcontainer Build: automated VSIX emission from Developer Tools
Important
Problem
The existing Developer Tools "Rebuild Locally" build path is broken for all
linux users — not only devcontainers. The handler hardcodes darwin-only binary
resolution paths (opencode-darwin-arm64, opencode-darwin-x64), uses bun run build which fails to resolve pnpm workspace scripts, targets ~/.vscode/extensions/ (wrong on Remote/devcontainer hosts), and calls
macOS-only codesign. Any linux machine — bare metal, VM, WSL, or
devcontainer — hits "binary not found" after a successful build. The darwin
path still needs its own fix (follow-up #7); this feature provides an immediate working alternative for all linux users AND all devcontainer users
wanting convenience builds from the Developer Tools panel.
Approach
A new "Devcontainer mode (experimental)" toggle in Developer Tools that runs
the user's proven pnpm-based build workflow and emits a .vsix to a configurable
path — fully orthogonal to the existing developer mode (no eager actions, no
hot-reload, no window reload). Despite the "devcontainer" naming, the build
path is platform-agnostic and works on any host with bun + pnpm + node.
bun and pnpm are on PATH inside the container (the Dockerfile installs both)
The opencode repo is the harmoniqs/opencode fork (required by fetch_opencode.mjs)
vsce is available as a devDependency (resolved via pnpm exec)
The output directory is on a persistent volume
Note on applicability
While this feature was developed and primarily tested inside devcontainers, it
is not limited to devcontainer use. The underlying build workflow
(pnpm install → pnpm --filter amicode build → opencode:build → vsce package)
is the standard cross-platform build path and works on any linux or macOS host
with bun + pnpm + node installed. The feature is a reliable alternative to the
existing developer build for any scenario where a specific pair of opencode and
amicode branches need to be test-driven live — whether inside a devcontainer,
on a remote host via SSH, or on a local machine where the darwin hot-reload
path is undesirable or broken. Until the existing developer build is generalized
to support all platforms natively, this feature fills the gap.
Acceptance Criteria
"Devcontainer mode" toggle is visible and usable WITHOUT enabling developer mode
"Build VSIX" button is visible at the top when devcontainer mode is ON
Clicking "Build VSIX" produces a .vsix at the configured output path
No eager actions fire on path blur when developer mode is OFF
The built vsix installs correctly via right-click → "Install Extension VSIX"
Non-sibling repo layouts work (AMICODE_OPENCODE_SRC propagated)
Existing NODE_OPTIONS are preserved (not overwritten)
Key Decisions
Paths are shared settings keys between developer mode and devcontainer mode;
behavior differs (eager vs. inert on blur)
The handler sets AMICODE_OPENCODE_SRC in subprocess env, removing the
implicit sibling-directory requirement
NODE_OPTIONS is set as a default only (process.env.NODE_OPTIONS ?? "...")
The vsix filename includes a timestamp to prevent collisions
No window reload, no server restart, no settings mutation — pure file emission
Constraints & Invariants
Devcontainer mode must NEVER set amicode.opencodeBinary or amicode.devAssetRoot
Devcontainer mode must NEVER trigger sendUpdate() on path blur
Devcontainer mode must NEVER trigger a window reload
The handler must not assume repos are siblings (must use AMICODE_OPENCODE_SRC)
Implementation Detail (feature checklist)
opencode repo (packages/app/src/)
context/settings.tsx — devcontainerMode + vsixOutputPath in type, defaults, accessors
Deferred CodeRabbit findings (rolled into follow-up)
The following out-of-diff suggestions from CodeRabbit are acknowledged and tracked
as part of the follow-up iteration (issue #553). They are of similar nature and
severity to the already-listed follow-up items (pre-flight validation, progress
stages, etc.) and do not block the initial merge:
(feat) devcontainer VSIX build — app-side settings and UI opencode#252 — "Rename settings fields to snake_case + add persistence
migration" (rejected: contradicts existing camelCase convention in the settings
store; no migration needed for new fields that have no prior saved values)
The opencode PR (harmoniqs/opencode#252) must land on local/amicode first — the amicode PR's app-bundle-gate CI check verifies the committed app-bundle matches the fork's
state, which includes the new settings UI. Once harmoniqs/opencode#252 merges and the app-bundle
is re-derived, #554's gate will pass.
Devcontainer Build: automated VSIX emission from Developer Tools
Important
Problem
The existing Developer Tools "Rebuild Locally" build path is broken for all
linux users — not only devcontainers. The handler hardcodes darwin-only binary
resolution paths (
opencode-darwin-arm64,opencode-darwin-x64), usesbun run buildwhich fails to resolve pnpm workspace scripts, targets~/.vscode/extensions/(wrong on Remote/devcontainer hosts), and callsmacOS-only
codesign. Any linux machine — bare metal, VM, WSL, ordevcontainer — hits "binary not found" after a successful build. The darwin
path still needs its own fix (follow-up #7); this feature provides an
immediate working alternative for all linux users AND all devcontainer users
wanting convenience builds from the Developer Tools panel.
Approach
A new "Devcontainer mode (experimental)" toggle in Developer Tools that runs
the user's proven pnpm-based build workflow and emits a .vsix to a configurable
path — fully orthogonal to the existing developer mode (no eager actions, no
hot-reload, no window reload). Despite the "devcontainer" naming, the build
path is platform-agnostic and works on any host with bun + pnpm + node.
Approaches Considered
Scope
In: devcontainer toggle, VSIX output path field, "Build VSIX" button,
bridge handler executing the 5-step pnpm workflow, lane allowlist wiring,
AMICODE_OPENCODE_SRCenv var for non-sibling layouts,NODE_OPTIONSdefault-only semantics, decoupled eager-action guards.
Out: auto-install after build (follow-up #3), build log streaming (#4),
incremental builds (#6), replacing the existing rebuild path (#7), devcontainer
auto-detection (#8).
Assumptions
bunandpnpmare on PATH inside the container (the Dockerfile installs both)harmoniqs/opencodefork (required byfetch_opencode.mjs)vsceis available as a devDependency (resolved viapnpm exec)Note on applicability
While this feature was developed and primarily tested inside devcontainers, it
is not limited to devcontainer use. The underlying build workflow
(
pnpm install→pnpm --filter amicode build→opencode:build→vsce package)is the standard cross-platform build path and works on any linux or macOS host
with bun + pnpm + node installed. The feature is a reliable alternative to the
existing developer build for any scenario where a specific pair of opencode and
amicode branches need to be test-driven live — whether inside a devcontainer,
on a remote host via SSH, or on a local machine where the darwin hot-reload
path is undesirable or broken. Until the existing developer build is generalized
to support all platforms natively, this feature fills the gap.
Acceptance Criteria
Key Decisions
behavior differs (eager vs. inert on blur)
AMICODE_OPENCODE_SRCin subprocess env, removing theimplicit sibling-directory requirement
NODE_OPTIONSis set as a default only (process.env.NODE_OPTIONS ?? "...")Constraints & Invariants
amicode.opencodeBinaryoramicode.devAssetRootsendUpdate()on path blurImplementation Detail (feature checklist)
opencode repo (packages/app/src/)
context/settings.tsx— devcontainerMode + vsixOutputPath in type, defaults, accessorscomponents/settings-v2/developer-tools-controller.ts— signals, message handler, buildVsix action, blur guardscomponents/settings-v2/developer-tools.tsx— restructured UI: independent toggles, button placement, conditional visibilityamicode repo (packages/extension/src/)
chat_bridge.ts—dev-tools-build-vsixhandler (5-step build: install → build → package)chat_panel.ts— lane-1 and lane-2 allowlist entries (4 insertions)Follow-Up Items
code --install-extension)isModelConfigured()to check env varspath.resolve()for relative paths in AMICODE_OPENCODE_SRCSource
plans/devcontainer-build-improvements.mdnotes/research/containers/devcontainer-builds.md,devcontainer-build-addendum.mdnotes/research/ui/eager-devtools-bug.mdnotes/reviews/devcontainer-build-adr-review.mdPR Status & Deferred Review Comments
PRs
Addressed CodeRabbit findings (committed)
outputPathinterpolation inexec()execFile+ separate args (no shell)execFileimported in wrong IIFE scope (unused indev-tools-update, undefined indev-tools-build-vsix)vsixPathmay be undefined ondonestate (empty success display)string | undefinednot assignable tostringin JSX (typecheck)?? ""fallbackDeferred CodeRabbit findings (rolled into follow-up)
The following out-of-diff suggestions from CodeRabbit are acknowledged and tracked
as part of the follow-up iteration (issue #553). They are of similar nature and
severity to the already-listed follow-up items (pre-flight validation, progress
stages, etc.) and do not block the initial merge:
snake_case+ add persistencemigration" (rejected: contradicts existing camelCase convention in the settings
store; no migration needed for new fields that have no prior saved values)
(post
0ff0ce7): deferred to follow-up iteration alongside items 1-6.(post
076d7e1): deferred to follow-up iteration alongside items 1-6.Merge ordering
The opencode PR (harmoniqs/opencode#252) must land on
local/amicodefirst — the amicode PR'sapp-bundle-gateCI check verifies the committed app-bundle matches the fork'sstate, which includes the new settings UI. Once harmoniqs/opencode#252 merges and the app-bundle
is re-derived, #554's gate will pass.