Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.16.0] - 2026-04-05

See [docs/releases/v0.16.0.md](docs/releases/v0.16.0.md) for full notes and [docs/releases/v0.16.0/assets.md](docs/releases/v0.16.0/assets.md) for release asset inventory.

### Added

- Add right-panel turn diff viewer.
- Add editable code preview state and autosave support.
- Add hidden provider input for prompt enhancements.
- Add viewport presets and orientation controls.
- Add optional rebase before commit flow.
- Add GitHub repo cloning entry points.
- Add build metadata across server and web.

### Changed

- Refine diff viewer panel defaults and opening behavior.
- Standardize modal button styling.
- Restart provider sessions when worktree cwd changes.
- Stabilize release train and split Intel compatibility build.
- Preserve prompt enhancement when sending messages.
- Stabilize browser test runner and related types.
- Refresh tracked worktree bases before creation.
- Expose reasoning content in the work log.
- Refactor home empty state into focused components.

### Fixed

- Fix branch sync to use explicit upstream refs.
- Fix post-merge lint warnings.
- Sanitize shell env before launching agent sessions.

### Removed

- Remove diff preview panel.

## [0.15.0] - 2026-04-05

See [docs/releases/v0.15.0.md](docs/releases/v0.15.0.md) for full notes and [docs/releases/v0.15.0/assets.md](docs/releases/v0.15.0/assets.md) for release asset inventory.
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@okcode/desktop",
"version": "0.15.0",
"version": "0.16.0",
"private": true,
"main": "dist-electron/main.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "0.14.0"
versionName "0.16.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/ios/App/App.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.14.0;
MARKETING_VERSION = 0.16.0;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = com.openknots.okcode.mobile;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -325,7 +325,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 0.14.0;
MARKETING_VERSION = 0.16.0;
PRODUCT_BUNDLE_IDENTIFIER = com.openknots.okcode.mobile;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@okcode/mobile",
"version": "0.15.0",
"version": "0.16.0",
"private": true,
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion apps/server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "okcodes",
"version": "0.15.0",
"version": "0.16.0",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
69 changes: 36 additions & 33 deletions apps/server/src/git/Layers/GitManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -781,45 +781,48 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => {
}),
);

it.effect("rebases onto the latest default branch before commit when enabled", () =>
Effect.gen(function* () {
const repoDir = yield* makeTempDir("okcode-git-manager-");
yield* initRepo(repoDir);
const remoteDir = yield* createBareRemote();
yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
yield* runGit(repoDir, ["checkout", "-b", "feature/rebase-before-commit"]);
it.effect(
"rebases onto the latest default branch before commit when enabled",
() =>
Effect.gen(function* () {
const repoDir = yield* makeTempDir("okcode-git-manager-");
yield* initRepo(repoDir);
const remoteDir = yield* createBareRemote();
yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
yield* runGit(repoDir, ["checkout", "-b", "feature/rebase-before-commit"]);

const updaterDir = yield* makeTempDir("okcode-git-manager-updater-");
yield* runGit(updaterDir, ["clone", "--branch", "main", remoteDir, "."]);
yield* runGit(updaterDir, ["config", "user.email", "test@example.com"]);
yield* runGit(updaterDir, ["config", "user.name", "Test User"]);
fs.writeFileSync(path.join(updaterDir, "base.txt"), "remote main update\n");
yield* runGit(updaterDir, ["add", "base.txt"]);
yield* runGit(updaterDir, ["commit", "-m", "Remote main update"]);
yield* runGit(updaterDir, ["push", "origin", "main"]);
const updaterDir = yield* makeTempDir("okcode-git-manager-updater-");
yield* runGit(updaterDir, ["clone", "--branch", "main", remoteDir, "."]);
yield* runGit(updaterDir, ["config", "user.email", "test@example.com"]);
yield* runGit(updaterDir, ["config", "user.name", "Test User"]);
fs.writeFileSync(path.join(updaterDir, "base.txt"), "remote main update\n");
yield* runGit(updaterDir, ["add", "base.txt"]);
yield* runGit(updaterDir, ["commit", "-m", "Remote main update"]);
yield* runGit(updaterDir, ["push", "origin", "main"]);

fs.writeFileSync(path.join(repoDir, "README.md"), "hello\nrebased feature work\n");
fs.writeFileSync(path.join(repoDir, "README.md"), "hello\nrebased feature work\n");

const { manager } = yield* makeManager();
const result = yield* runStackedAction(manager, {
cwd: repoDir,
action: "commit",
commitMessage: "feat: rebase before commit",
rebaseBeforeCommit: true,
});
const { manager } = yield* makeManager();
const result = yield* runStackedAction(manager, {
cwd: repoDir,
action: "commit",
commitMessage: "feat: rebase before commit",
rebaseBeforeCommit: true,
});

expect(result.commit.status).toBe("created");
expect(result.commit.status).toBe("created");

const remoteMainSha = yield* runGit(repoDir, ["rev-parse", "origin/main"]).pipe(
Effect.map((gitResult) => gitResult.stdout.trim()),
);
const mergeBase = yield* runGit(repoDir, ["merge-base", "HEAD", "origin/main"]).pipe(
Effect.map((gitResult) => gitResult.stdout.trim()),
);
const remoteMainSha = yield* runGit(repoDir, ["rev-parse", "origin/main"]).pipe(
Effect.map((gitResult) => gitResult.stdout.trim()),
);
const mergeBase = yield* runGit(repoDir, ["merge-base", "HEAD", "origin/main"]).pipe(
Effect.map((gitResult) => gitResult.stdout.trim()),
);

expect(mergeBase).toBe(remoteMainSha);
}),
expect(mergeBase).toBe(remoteMainSha);
}),
30_000,
);

it.effect("uses custom commit message when provided", () =>
Expand Down
20 changes: 20 additions & 0 deletions apps/server/src/wsServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,10 @@ describe("WebSocket Server", () => {
issues: [],
providers: defaultProviderStatuses,
availableEditors: expect.any(Array),
buildInfo: expect.objectContaining({
surface: "server",
version: "0.16.0",
}),
});
expectAvailableEditors((response.result as { availableEditors: unknown }).availableEditors);
});
Expand All @@ -899,6 +903,10 @@ describe("WebSocket Server", () => {
issues: [],
providers: defaultProviderStatuses,
availableEditors: expect.any(Array),
buildInfo: expect.objectContaining({
surface: "server",
version: "0.16.0",
}),
});
expectAvailableEditors((response.result as { availableEditors: unknown }).availableEditors);

Expand Down Expand Up @@ -936,6 +944,10 @@ describe("WebSocket Server", () => {
],
providers: defaultProviderStatuses,
availableEditors: expect.any(Array),
buildInfo: expect.objectContaining({
surface: "server",
version: "0.16.0",
}),
});
expectAvailableEditors((response.result as { availableEditors: unknown }).availableEditors);
expect(fs.readFileSync(keybindingsPath, "utf8")).toBe("{ not-json");
Expand Down Expand Up @@ -1152,6 +1164,10 @@ describe("WebSocket Server", () => {
issues: [],
providers: defaultProviderStatuses,
availableEditors: expect.any(Array),
buildInfo: expect.objectContaining({
surface: "server",
version: "0.16.0",
}),
});
expectAvailableEditors((response.result as { availableEditors: unknown }).availableEditors);
});
Expand Down Expand Up @@ -1201,6 +1217,10 @@ describe("WebSocket Server", () => {
issues: [],
providers: defaultProviderStatuses,
availableEditors: expect.any(Array),
buildInfo: expect.objectContaining({
surface: "server",
version: "0.16.0",
}),
});
expectAvailableEditors(
(configResponse.result as { availableEditors: unknown }).availableEditors,
Expand Down
2 changes: 1 addition & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@okcode/web",
"version": "0.15.0",
"version": "0.16.0",
"private": true,
"type": "module",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/ChatView.logic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ describe("buildHiddenProviderInput", () => {
expect(providerInput).toContain(
'Before responding, improve the user\'s request using the "Add specificity" enhancement mode',
);
expect(providerInput).toContain("Fix this [terminal-1:4-6] button");
expect(providerInput).toContain("Fix this @terminal-1:4-6 button");
expect(providerInput).toContain("<terminal_context>");
expect(providerInput).toContain("bun lint");
});
Expand Down
10 changes: 5 additions & 5 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions docs/releases/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,10 @@ Use this directory for versioned release notes and asset manifests only:
- `docs/releases/vX.Y.Z.md`
- `docs/releases/vX.Y.Z/assets.md`

| Version | Summary | Assets |
| -------------------- | ------------------------------------------------------------------------------------------ | ----------------------------- |
| [0.16.0](v0.16.0.md) | Right-panel diff review, editable code previews, and stronger release stability | [manifest](v0.16.0/assets.md) |
| [0.15.0](v0.15.0.md) | Brand refresh, scoped preview tabs, redesigned chat home, and rebase-aware branch sync | [manifest](v0.15.0/assets.md) |
| [0.14.0](v0.14.0.md) | Inline diffs, prompt enhancement, auto-refreshing file tree, and link-based mobile pairing | [manifest](v0.14.0/assets.md) |

When release policy changes, update [`docs/release.md`](../release.md) instead of duplicating the workflow matrix here.
46 changes: 46 additions & 0 deletions docs/releases/v0.0.13/assets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# v0.0.13 — Release assets (manifest)

Binaries are **not** stored in this git repository; they are attached to the [GitHub Release for `v0.0.13`](https://github.com/OpenKnots/okcode/releases/tag/v0.0.13) by the [Release Desktop workflow](../../.github/workflows/release.yml).

The GitHub Release also includes **documentation attachments** (same content as in-repo, stable filenames for download):

| File | Source in repo |
| --------------------------- | ------------------------------------- |
| `okcode-CHANGELOG.md` | [CHANGELOG.md](../../../CHANGELOG.md) |
| `okcode-RELEASE-NOTES.md` | [v0.0.13.md](../v0.0.13.md) |
| `okcode-ASSETS-MANIFEST.md` | This file |

After the workflow completes, expect **installer and updater** artifacts similar to the following (exact names may include the product name `OK Code` and version `0.0.13`).

## Desktop installers and payloads

| Platform | Kind | Typical pattern |
| ------------------- | -------------- | --------------- |
| macOS Apple Silicon | DMG | `*.dmg` (arm64) |
| macOS Intel | DMG | `*.dmg` (x64) |
| macOS | ZIP (updater) | `*.zip` |
| Linux x64 | AppImage | `*.AppImage` |
| Windows x64 | NSIS installer | `*.exe` |

## Electron updater metadata

| File | Purpose |
| ------------------ | --------------------------------------------------------- |
| `latest-mac.yml` | macOS update manifest (merged from per-arch builds in CI) |
| `latest-linux.yml` | Linux update manifest |
| `latest.yml` | Windows update manifest |
| `*.blockmap` | Differential download block maps |

## iOS (TestFlight)

The mobile companion features in this release ship through the native app build pipeline rather than as GitHub release assets.

| Detail | Value |
| ----------------- | ------------------------------------------ |
| Bundle ID | `com.openknots.okcode.mobile` |
| Marketing version | `0.0.13` |
| Build number | Set from `GITHUB_RUN_NUMBER` at build time |

## Checksums

SHA-256 checksums are not committed here; verify downloads via GitHub's release UI or `gh release download` if you use the GitHub CLI.
33 changes: 33 additions & 0 deletions docs/releases/v0.16.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# OK Code v0.16.0

**Date:** 2026-04-05
**Tag:** [`v0.16.0`](https://github.com/OpenKnots/okcode/releases/tag/v0.16.0)

## Summary

Right-panel diff review, editable code previews, stronger branch/worktree handling, and a more stable coordinated release train.

## Highlights

- **Add a right-panel turn diff viewer.** Diffs now open in a dedicated side panel with improved defaults and opening behavior for faster review.
- **Add editable code preview state with autosave.** Previewed code can now be edited directly and preserved automatically while you work.
- **Add viewport presets and orientation controls.** Preview tooling now supports faster device/layout switching without manual resizing.
- **Add optional rebase-before-commit flow.** Git workflows can now rebase before commit when that better matches the branch strategy.
- **Add GitHub repo cloning entry points.** Project creation can start directly from GitHub repository cloning flows.
- **Expose build metadata across server and web.** The UI and server now share build metadata so release/runtime state is easier to inspect.
- **Restart provider sessions when worktree cwd changes.** Provider sessions recover more predictably when the active worktree root changes.
- **Sanitize shell env before launching agent sessions.** Provider launches are more robust and less likely to inherit unsafe or incompatible environment state.

## Breaking changes

- **Diff preview panel removed.** Diff review now lives in the right-panel viewer instead of the previous preview panel surface.

## Upgrade and install

- **CLI:** `npm install -g okcodes@0.16.0` (after the package is published to npm manually).
- **Desktop:** Download from [GitHub Releases](https://github.com/OpenKnots/okcode/releases/tag/v0.16.0). This release includes signed macOS arm64/x64 DMGs, Linux x64 AppImage, and Windows x64 NSIS installer. Filenames are listed in [assets.md](v0.16.0/assets.md).
- **iOS:** Available via TestFlight (uploaded automatically by the coordinated release workflow).

## Known limitations

OK Code remains early work in progress. Keep an eye on reconnect behavior, long-running stream recovery, and platform-specific desktop packaging edge cases during RC soak and stable promotion.
Loading
Loading