Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
13d99ac
fix: hide skill prompt text from chat UI
lgarceau768 Apr 8, 2026
617403c
fix: respect tool_call: false capability flag at runtime
lgarceau768 Apr 8, 2026
66628a0
docs: add local build and AWS Bedrock setup instructions
lgarceau768 Apr 15, 2026
f934ae0
fix: re-sign macOS binaries after Bun compile to fix Darwin 25+ SIGKILL
rgoshen Apr 16, 2026
d48e717
fix(bedrock): add inference profile prefixes and fix reasoning for ad…
sfradkin Apr 20, 2026
4d341ba
docs: update LOCAL_AWS_SETUP.md with corrected model config keys and …
sfradkin Apr 20, 2026
85ea381
docs: update opencode-work shell function with credential check and s…
sfradkin Apr 21, 2026
efcbc6c
chore: change profile name
lgarceau768 Apr 21, 2026
b331f83
chore: change aws profile name
lgarceau768 Apr 21, 2026
a58836e
chore: add install-flex automated setup script and update docs
lgarceau768 Apr 22, 2026
c53d7b3
fix - pin OPENCODE_CHANNEL=flex at build time to prevent per-branch D…
lgarceau768 Apr 22, 2026
64004f7
fix - install unzip and extend setup-bun to handle ARM64 Blacksmith r…
lgarceau768 Apr 22, 2026
58798a7
fix - also install build-essential for node-gyp native addon compilat…
lgarceau768 Apr 22, 2026
83879e8
fix - cache npm registry and pre-warm @opencode-ai/plugin to fix plug…
lgarceau768 Apr 22, 2026
1bb626b
fix - skip arborist plugin deps install in tests; bump snapshot rever…
lgarceau768 Apr 22, 2026
62ee845
chore - add session persistence for chore/bolster-install
lgarceau768 Apr 22, 2026
98c3b43
fix - raise BusyError-when-loop test timeout from 3 s to 15 s for ARM…
lgarceau768 Apr 22, 2026
cfd9074
Update model identifiers in LOCAL_AWS_SETUP.md
lgarceau768 Apr 23, 2026
896d373
fix - harden install-flex against injection, input and supply-chain r…
lgarceau768 Apr 23, 2026
956e748
fix - address shellcheck SC1003 and SC2088 findings in install-flex
lgarceau768 Apr 23, 2026
4cc5645
chore: enable opp-capture pre-commit hook to catch security issues be…
lgarceau768 Apr 23, 2026
56ff428
fix: reject control characters in CLONE_DIR and restrict config file …
lgarceau768 Apr 23, 2026
e7eb24c
chore: migrate from pre-commit to prek for faster hook execution
lgarceau768 Apr 23, 2026
aeaed54
chore - disable autoupdate in install-flex config
lgarceau768 Apr 24, 2026
c5f5eeb
fix: let IAM credentials take precedence over stored Bedrock API key
lgarceau768 Apr 28, 2026
c43d4c4
fix: disable media in tool results for AWS Bedrock
lgarceau768 Apr 27, 2026
fbe6977
fix: skip reasoning parts from different models to prevent Anthropic …
lgarceau768 Apr 27, 2026
cfe45db
fix: disable tools for deepseek-reasoner and strip <think> tags from …
lgarceau768 Apr 27, 2026
6cb0745
fix: extend isDeepSeekR1 guard to cover Bedrock-hosted R1 via family …
lgarceau768 Apr 27, 2026
b506080
update failing test case
lgarceau768 Apr 29, 2026
7ee0b2a
docs: simplify LOCAL_AWS_SETUP.md to defer to flexcamp-ai for AWS setup
lgarceau768 May 1, 2026
cb7c336
chore: remove AWS SSO setup from install-flex, defer to flexcamp-ai
lgarceau768 May 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions .github/actions/setup-bun/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,37 @@ inputs:
runs:
using: "composite"
steps:
- name: Get baseline download URL
- name: Ensure build tools are available
if: runner.os == 'Linux'
shell: bash
# Blacksmith's ARM64 ubuntu-2404 runners ship a minimal image that is missing:
# unzip — needed by oven-sh/setup-bun to extract the downloaded bun zip
# build-essential (make, g++) — needed by node-gyp to compile native addons
# (e.g. tree-sitter-powershell) during `bun install`
run: |
PKGS=()
command -v unzip >/dev/null 2>&1 || PKGS+=(unzip)
command -v make >/dev/null 2>&1 || PKGS+=(build-essential)
[ ${#PKGS[@]} -gt 0 ] && sudo apt-get install -y --no-install-recommends "${PKGS[@]}"
true

- name: Get bun download URL
id: bun-url
shell: bash
run: |
if [ "$RUNNER_ARCH" = "X64" ]; then
V=$(node -p "require('./package.json').packageManager.split('@')[1]")
case "$RUNNER_OS" in
macOS) OS=darwin ;;
Linux) OS=linux ;;
Windows) OS=windows ;;
esac
echo "url=https://github.com/oven-sh/bun/releases/download/bun-v${V}/bun-${OS}-x64-baseline.zip" >> "$GITHUB_OUTPUT"
fi
V=$(node -p "require('./package.json').packageManager.split('@')[1]")
case "$RUNNER_OS" in
macOS) OS=darwin ;;
Linux) OS=linux ;;
Windows) OS=windows ;;
*) exit 0 ;;
esac
case "$RUNNER_ARCH" in
X64) ARCH=x64-baseline ;;
ARM64) ARCH=aarch64 ;;
*) exit 0 ;;
esac
echo "url=https://github.com/oven-sh/bun/releases/download/bun-v${V}/bun-${OS}-${ARCH}.zip" >> "$GITHUB_OUTPUT"

- name: Setup Bun
uses: oven-sh/setup-bun@v2
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ jobs:
turbo-${{ runner.os }}-${{ hashFiles('turbo.json', '**/package.json') }}-
turbo-${{ runner.os }}-

- name: Cache npm registry packages
# Plugin integration tests install @opencode-ai/plugin into fresh temp dirs
# using @npmcli/arborist, which fetches from the npm registry and caches
# tarballs in ~/.npm. Without this cache, each test does a full network
# download, easily hitting the 30 s bun test timeout on Blacksmith ARM64.
uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ runner.arch }}-opencode-ai-plugin-${{ hashFiles('**/package.json') }}
restore-keys: |
npm-${{ runner.os }}-${{ runner.arch }}-opencode-ai-plugin-

- name: Warm npm cache for @opencode-ai/plugin
# Pre-populate ~/.npm so arborist can satisfy @opencode-ai/plugin from
# cache during plugin integration tests instead of hitting the registry.
if: runner.os == 'Linux'
run: npm install --prefix /tmp/plugin-warmup @opencode-ai/plugin

- name: Run unit tests
run: bun turbo test:ci
env:
Expand Down
6 changes: 6 additions & 0 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
#!/bin/sh
set -e

# Run prek hooks (if installed)
if command -v prek >/dev/null 2>&1; then
prek run --stage pre-push
fi

# Check if bun version matches package.json
# keep in sync with packages/script/src/index.ts semver qualifier
bun -e '
Expand Down
80 changes: 80 additions & 0 deletions .opencode/sessions/chore-bolster-install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Session: Bolster Install — Blacksmith ARM64 CI Fixes

**Branch**: chore/bolster-install
**Issue**: N/A
**Created**: 2026-04-22
**Status**: complete — PR #11 open, awaiting merge

## Goal
Harden the `install-flex` automated installer and fix all Blacksmith ARM64 CI
failures that were blocking the unit and e2e test jobs on the Flexion fork.

## Approach
Fix issues in layers as they surfaced during CI runs:
1. Add `install-flex` installer script
2. Pin `OPENCODE_CHANNEL=flex` to prevent per-branch SQLite DB fragmentation
3. Fix missing build tools on Blacksmith ARM64 runners
4. Fix unit test timeouts caused by arborist npm installs during tests
5. Bump individual test timeouts that are tight on ARM64

## Session Log
- 2026-04-22: Session created
- 2026-04-22: Added `install-flex` script (already existed on branch), fixed DB fragmentation
- 2026-04-22: CI round 1 — fixed `unzip` missing (setup-bun)
- 2026-04-22: CI round 2 — fixed `make`/`g++` missing (build-essential for node-gyp)
- 2026-04-22: CI round 3 — 7 test timeouts; root-caused to `@npmcli/arborist.reify()` in tests
- 2026-04-22: CI round 4 — 1 remaining timeout; fixed shell-loop test 3s → 15s
- 2026-04-22: All CI jobs passing. PR updated.
- 2026-04-22: CI round 5 — 1 new timeout; "shell rejects with BusyError when loop running" 3s → 15s

## Key Decisions

### `OPENCODE_CHANNEL=flex` in `install-flex`
OpenCode bakes `InstallationChannel` from the git branch at build time and uses it
as the SQLite DB name suffix (`opencode-<channel>.db`). Without pinning, each
rebuild from a different branch creates a fresh empty database, losing all session
history. Pinning to `"flex"` ensures all Flexion builds share `opencode-flex.db`.
See: `packages/opencode/src/storage/db.ts:getChannelPath()`.

### `OPENCODE_DISABLE_PLUGIN_DEPS_INSTALL` flag
`config.ts` fires a background `@npmcli/arborist.reify()` for `@opencode-ai/plugin`
in every `.opencode/` directory it discovers. In tests, 7 tests were timing out
because: plugin/tool tests called `waitForDependencies()` which joined the arborist
fiber (10–30 s per test on ARM64), and the resulting CPU saturation starved
concurrent session/snapshot tests. The flag skips the install in tests; safe because
bun resolves `@opencode-ai/plugin` from the workspace `node_modules` directly.
Set unconditionally in `test/preload.ts`.

### Blacksmith ARM64 runner gaps
`blacksmith-4vcpu-ubuntu-2404` uses ARM64 and ships a minimal Ubuntu image missing:
- `unzip` — needed by `oven-sh/setup-bun@v2` to extract the downloaded bun zip
- `make`/`g++` (build-essential) — needed by `node-gyp` for `tree-sitter-powershell`
Both now installed in a single `Ensure build tools are available` step in
`.github/actions/setup-bun/action.yml` (Linux only, no-op if already present).

### Test timeout bumps
- `snapshot.test.ts` "revert handles large mixed batches": 30 s → 60 s
(280 files + multiple git commits/patches/reverts on ARM64)
- `prompt-effect.test.ts` "loop waits while shell runs": 3 s → 15 s
(spawns a real `sleep 0.2` subprocess; ARM64 fork/exec overhead exceeds 3 s)
- `prompt-effect.test.ts` "shell rejects with BusyError when loop running": 3 s → 15 s
(fiber fork + session init before `llm.wait(1)` exceeds 3 s on ARM64)

## Files Changed
- `install-flex` — `OPENCODE_CHANNEL=flex` added to build command
- `.github/actions/setup-bun/action.yml` — build tools prereq + ARM64/X64 URL construction
- `.github/workflows/test.yml` — npm cache + pre-warm step (unit job)
- `packages/opencode/src/flag/flag.ts` — `OPENCODE_DISABLE_PLUGIN_DEPS_INSTALL` flag
- `packages/opencode/src/config/config.ts` — guard arborist install with new flag
- `packages/opencode/test/preload.ts` — set `OPENCODE_DISABLE_PLUGIN_DEPS_INSTALL=true`
- `packages/opencode/test/snapshot/snapshot.test.ts` — 60 s timeout on 280-file test
- `packages/opencode/test/session/prompt-effect.test.ts` — 15 s timeout on shell-loop test

## Side Effects Applied Outside the Repo
- `~/.opencode/bin/opencode` — rebuilt from this branch with `OPENCODE_CHANNEL=flex`;
now reports `0.0.0-flex-<timestamp>` and uses `~/.local/share/opencode/opencode-flex.db`

## Next Steps
- [ ] Merge PR #11 into flex: https://github.com/flexion/opencode/pull/11
- [ ] After merge, other developers run `install-flex` to pick up all fixes
- [ ] Consider periodically running `install-flex` to stay current with `flex` branch
44 changes: 44 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
# Standard pre-commit hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
exclude: 'tsconfig\.json$|\.oxlintrc\.json$'
- id: check-toml
- id: check-added-large-files
args: [ "--maxkb=1000" ]
- id: detect-aws-credentials
args: [ '--allow-missing-credentials' ]

# Detect secrets with GitLeaks
- repo: https://github.com/zricethezav/gitleaks
rev: v8.30.1
hooks:
- id: gitleaks-docker

# Lint GitHub Actions
- repo: https://github.com/rhysd/actionlint
rev: v1.7.10
hooks:
- id: actionlint-docker

- repo: https://github.com/lalten/check-gha-pinning
rev: v1.3.1
hooks:
- id: check-gha-pinning

# Block forbidden files (.env, etc.)
- repo: local
hooks:
- id: block-env-files
name: Block .env files
entry: scripts/block-env-files.sh
language: script
pass_filenames: false
always_run: true
40 changes: 40 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,46 @@ https://github.com/anomalyco/models.dev
bun dev
```

### Setting Up Pre-Commit Hooks

Pre-commit hooks automatically validate code before pushing. This includes:
- Secret detection (GitLeaks)
- GitHub Actions linting (actionlint, GHA pinning)
- Standard checks (trailing whitespace, JSON/YAML validation, etc.)
- `.env` file protection

We use [prek](https://prek.j178.dev/), a fast Rust-based drop-in replacement for pre-commit.

To install prek:

```bash
# Using uv (recommended)
uv tool install prek

# Using pip
pip install prek

# Using Homebrew
brew install prek

# Or via standalone installer
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/j178/prek/releases/latest/download/prek-installer.sh | sh
```

Then install the git hooks:

```bash
prek install
```

This integrates prek into the `pre-push` Husky hook. Hooks will run automatically when you push. To manually run:

```bash
prek run --stage pre-push # Run all hooks
prek run --stage pre-push --files <file> # Run on specific file
prek run gitleaks-docker --stage pre-push # Run single hook
```

### Running against a different directory

By default, `bun dev` runs OpenCode in the `packages/opencode` directory. To run it against a different directory or repository:
Expand Down
90 changes: 90 additions & 0 deletions LOCAL_AWS_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Local Build & AWS Bedrock Setup

Instructions for building and running the Flexion fork of opencode.

## AWS Credentials Setup

AWS credentials and opencode configuration are managed by **flexcamp-ai**:

```
https://github.com/flexion/flexcamp-ai
```

Follow the setup instructions there before building or running this fork. flexcamp-ai handles AWS authentication, the `opencode-work` shell function, and `~/.config/opencode/opencode.json`.

---

## Prerequisites (build only)

- [Bun](https://bun.sh) v1.3+
- Git + SSH key configured for GitHub (with access to the `flexion` org)

## Clone & Build

```bash
git clone [email protected]:flexion/opencode.git
cd opencode

# Switch to the Flexion customizations branch
git checkout flex

# Install dependencies
# Note: if your global ~/.npmrc redirects to a private registry (e.g. CMS Artifactory),
# override it so public packages resolve correctly:
BUN_CONFIG_REGISTRY=https://registry.npmjs.org bun install

# Build for your current platform only
BUN_CONFIG_REGISTRY=https://registry.npmjs.org bun run --cwd packages/opencode build --single --skip-embed-web-ui
```

The binary will be at:
- macOS ARM64: `packages/opencode/dist/opencode-darwin-arm64/bin/opencode`
- macOS x64: `packages/opencode/dist/opencode-darwin-x64/bin/opencode`
- Linux ARM64: `packages/opencode/dist/opencode-linux-arm64/bin/opencode`
- Linux x64: `packages/opencode/dist/opencode-linux-x64/bin/opencode`

Verify the build:

```bash
./packages/opencode/dist/opencode-darwin-arm64/bin/opencode --version
```

> **Note on model config:** Config keys in `opencode.json` must match the snapshot model ID exactly (e.g. `writer.palmyra-x5-v1:0`) — the `us.` cross-region inference profile prefix is added automatically at runtime for supported models and regions.
>
> **`tool_call: false`:** Models marked with `tool_call: false` do not support tool use in streaming mode on Bedrock. This prevents opencode from sending tool definitions to those models.
>
> **`reasoning: false`:** Models marked with `reasoning: false` will have reasoning content stripped from message history before being sent to the model. Required for models like DeepSeek R1 on Bedrock that generate reasoning output but reject it as input in subsequent turns.

## Keeping the Fork Up to Date

When upstream releases a new version, sync `dev` and rebase `flex`:

```bash
git fetch upstream # upstream = https://github.com/anomalyco/opencode.git
git checkout dev
git reset --hard upstream/dev
git push origin dev --force

git checkout flex
git rebase dev
# Resolve any conflicts, then:
git push origin flex --force
```

See [flexion/opencode#2](https://github.com/flexion/opencode/pull/2) for the full list of Flexion customizations and conflict resolution notes.

## What's Different in This Fork (`flex` branch)

| Change | File(s) | Description |
|--------|---------|-------------|
| Hide skill prompt text from chat UI | `packages/opencode/src/session/prompt.ts` | Marks skill template as `synthetic` so the full prompt is sent to the model but hidden from the user |
| Respect `tool_call: false` at runtime | `packages/opencode/src/session/llm.ts` | Gates tool resolution behind `capabilities.toolcall` — fixes failures on Bedrock models that don't support streaming + tool use |
| Re-sign macOS binaries after build | `packages/opencode/script/build.ts` | Strips Bun's embedded signature and applies a fresh ad-hoc one — fixes SIGKILL (exit 137) on Darwin 25+ where Bun's signature format is rejected |
| Add inference profile prefixes for palmyra and pixtral | `packages/opencode/src/provider/provider.ts` | Adds `us.` cross-region inference profile prefix for Writer Palmyra and Mistral Pixtral models in US regions |
| Strip reasoning from history for non-reasoning models | `packages/opencode/src/provider/transform.ts` | Removes reasoning content parts from assistant message history before sending to models with `reasoning: false` — fixes Bedrock rejections when switching from a reasoning model |
| Exclude palmyra from reasoning variant generation | `packages/opencode/src/provider/transform.ts` | Prevents unsupported `reasoningConfig` parameters from being sent to Writer Palmyra models |
| Local build & AWS Bedrock setup docs | `LOCAL_AWS_SETUP.md` | This file |

Full details and upstream tracking: [flexion/opencode#2](https://github.com/flexion/opencode/pull/2)

Upstream issue: [anomalyco/opencode#19966](https://github.com/anomalyco/opencode/issues/19966)
Loading
Loading