Skip to content

Commit 75727c7

Browse files
committed
chore(release): prepare v0.17.0
1 parent 5d45de4 commit 75727c7

File tree

18 files changed

+332
-43
lines changed

18 files changed

+332
-43
lines changed

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.17.0] - 2026-04-07
11+
12+
See [docs/releases/v0.17.0.md](docs/releases/v0.17.0.md) for full notes and [docs/releases/v0.17.0/assets.md](docs/releases/v0.17.0/assets.md) for release asset inventory.
13+
14+
### Added
15+
16+
- Add stale worktree pruning controls in the sidebar.
17+
- Add merged worktree cleanup flow and cleanup dialog.
18+
- Add floating chat widget shell for the mobile layout.
19+
- Add cached syntax highlighting for chat diffs.
20+
- Add copy buttons to assistant responses.
21+
- Add collapsible diff file headers.
22+
- Add PR review workspace helper scripts.
23+
- Add persistent saved layout preferences.
24+
25+
### Changed
26+
27+
- Unify the right panel into tabbed Files, Editor, and Diffs views.
28+
- Open terminal file links directly in the code viewer.
29+
- Show an open-diff action when file summaries are unavailable.
30+
- Import package scripts when creating projects.
31+
- Improve sidebar thread shortcuts, header spacing, controls, and project-header contrast.
32+
- Remove sidebar blur and side-panel hint text from code viewers.
33+
- Tighten preview blocking so empty toast overlays do not hide the browser preview.
34+
- Shorten chat shortcut guide titles.
35+
- Add PR request-changes tone setting support.
36+
- Prevent the review pane from scrolling independently.
37+
- Streamline thread UI and desktop build packaging.
38+
39+
### Fixed
40+
41+
- Fix theme hydration and terminal and file navigation stability.
42+
- Fix desktop release packaging regressions before ship.
43+
1044
## [0.16.1] - 2026-04-06
1145

1246
See [docs/releases/v0.16.1.md](docs/releases/v0.16.1.md) for full notes and [docs/releases/v0.16.1/assets.md](docs/releases/v0.16.1/assets.md) for release asset inventory.
@@ -517,3 +551,4 @@ First public version tag. See [docs/releases/v0.0.1.md](docs/releases/v0.0.1.md)
517551
[0.14.0]: https://github.com/OpenKnots/okcode/releases/tag/v0.14.0
518552
[0.13.0]: https://github.com/OpenKnots/okcode/releases/tag/v0.13.0
519553
[0.16.1]: https://github.com/OpenKnots/okcode/releases/tag/v0.16.1
554+
[0.17.0]: https://github.com/OpenKnots/okcode/releases/tag/v0.17.0

apps/desktop/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@okcode/desktop",
3-
"version": "0.16.0",
3+
"version": "0.17.0",
44
"private": true,
55
"main": "dist-electron/main.js",
66
"scripts": {

apps/mobile/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ android {
88
minSdkVersion rootProject.ext.minSdkVersion
99
targetSdkVersion rootProject.ext.targetSdkVersion
1010
versionCode 1
11-
versionName "0.16.0"
11+
versionName "0.17.0"
1212
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1313
aaptOptions {
1414
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

apps/mobile/ios/App/App.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@
303303
"$(inherited)",
304304
"@executable_path/Frameworks",
305305
);
306-
MARKETING_VERSION = 0.16.0;
306+
MARKETING_VERSION = 0.17.0;
307307
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
308308
PRODUCT_BUNDLE_IDENTIFIER = com.openknots.okcode.mobile;
309309
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -325,7 +325,7 @@
325325
"$(inherited)",
326326
"@executable_path/Frameworks",
327327
);
328-
MARKETING_VERSION = 0.16.0;
328+
MARKETING_VERSION = 0.17.0;
329329
PRODUCT_BUNDLE_IDENTIFIER = com.openknots.okcode.mobile;
330330
PRODUCT_NAME = "$(TARGET_NAME)";
331331
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "";

apps/mobile/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@okcode/mobile",
3-
"version": "0.16.0",
3+
"version": "0.17.0",
44
"private": true,
55
"type": "module",
66
"scripts": {

apps/server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "okcodes",
3-
"version": "0.16.0",
3+
"version": "0.17.0",
44
"license": "MIT",
55
"repository": {
66
"type": "git",

apps/server/src/wsServer.test.ts

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import type { GitCoreShape } from "./git/Services/GitCore.ts";
5454
import { GitCore } from "./git/Services/GitCore.ts";
5555
import { GitActionExecutionError, GitCommandError } from "./git/Errors.ts";
5656
import { MigrationError } from "@effect/sql-sqlite-bun/SqliteMigrator";
57+
import { serverBuildInfo } from "./buildInfo";
5758

5859
const asEventId = (value: string): EventId => EventId.makeUnsafe(value);
5960
const asProviderItemId = (value: string): ProviderItemId => ProviderItemId.makeUnsafe(value);
@@ -81,6 +82,11 @@ const defaultProviderHealthService: ProviderHealthShape = {
8182
getStatuses: Effect.succeed(defaultProviderStatuses),
8283
};
8384

85+
const expectedServerBuildInfo = expect.objectContaining({
86+
surface: "server",
87+
version: serverBuildInfo.version,
88+
});
89+
8490
class MockTerminalManager implements TerminalManagerShape {
8591
private readonly sessions = new Map<string, TerminalSessionSnapshot>();
8692
private readonly listeners = new Set<(event: TerminalEvent) => void>();
@@ -873,10 +879,7 @@ describe("WebSocket Server", () => {
873879
issues: [],
874880
providers: defaultProviderStatuses,
875881
availableEditors: expect.any(Array),
876-
buildInfo: expect.objectContaining({
877-
surface: "server",
878-
version: "0.16.0",
879-
}),
882+
buildInfo: expectedServerBuildInfo,
880883
});
881884
expectAvailableEditors((response.result as { availableEditors: unknown }).availableEditors);
882885
});
@@ -903,10 +906,7 @@ describe("WebSocket Server", () => {
903906
issues: [],
904907
providers: defaultProviderStatuses,
905908
availableEditors: expect.any(Array),
906-
buildInfo: expect.objectContaining({
907-
surface: "server",
908-
version: "0.16.0",
909-
}),
909+
buildInfo: expectedServerBuildInfo,
910910
});
911911
expectAvailableEditors((response.result as { availableEditors: unknown }).availableEditors);
912912

@@ -944,10 +944,7 @@ describe("WebSocket Server", () => {
944944
],
945945
providers: defaultProviderStatuses,
946946
availableEditors: expect.any(Array),
947-
buildInfo: expect.objectContaining({
948-
surface: "server",
949-
version: "0.16.0",
950-
}),
947+
buildInfo: expectedServerBuildInfo,
951948
});
952949
expectAvailableEditors((response.result as { availableEditors: unknown }).availableEditors);
953950
expect(fs.readFileSync(keybindingsPath, "utf8")).toBe("{ not-json");
@@ -1164,10 +1161,7 @@ describe("WebSocket Server", () => {
11641161
issues: [],
11651162
providers: defaultProviderStatuses,
11661163
availableEditors: expect.any(Array),
1167-
buildInfo: expect.objectContaining({
1168-
surface: "server",
1169-
version: "0.16.0",
1170-
}),
1164+
buildInfo: expectedServerBuildInfo,
11711165
});
11721166
expectAvailableEditors((response.result as { availableEditors: unknown }).availableEditors);
11731167
});
@@ -1217,10 +1211,7 @@ describe("WebSocket Server", () => {
12171211
issues: [],
12181212
providers: defaultProviderStatuses,
12191213
availableEditors: expect.any(Array),
1220-
buildInfo: expect.objectContaining({
1221-
surface: "server",
1222-
version: "0.16.0",
1223-
}),
1214+
buildInfo: expectedServerBuildInfo,
12241215
});
12251216
expectAvailableEditors(
12261217
(configResponse.result as { availableEditors: unknown }).availableEditors,

apps/web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@okcode/web",
3-
"version": "0.16.0",
3+
"version": "0.17.0",
44
"private": true,
55
"type": "module",
66
"scripts": {

apps/web/src/components/CodeViewerPanel.test.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ describe("CodeViewerFileContent", () => {
230230
data: {
231231
relativePath: "photo.heic",
232232
contents: "",
233+
hasTextContents: false,
233234
truncated: false,
234235
sizeBytes: 32,
235236
previewDataUrl: "data:image/heic;base64,AAAA",
@@ -281,6 +282,7 @@ describe("CodeViewerFileContent", () => {
281282
data: {
282283
relativePath: "icon.svg",
283284
contents: "<svg />",
285+
hasTextContents: true,
284286
truncated: false,
285287
sizeBytes: 7,
286288
previewDataUrl: "data:image/svg+xml;base64,PHN2ZyAvPg==",

apps/web/src/components/CodeViewerPanel.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,21 @@ const AUTOSAVE_DELAY_MS = 750;
3434
const MANUAL_SAVE_SUCCESS_FLASH_MS = 2200;
3535

3636
function hasTextContentsFromQuery(
37-
data: { contents?: string | null } | undefined,
37+
data: { contents?: string | null; hasTextContents?: boolean } | undefined,
3838
): data is { contents: string } {
39+
if (data?.hasTextContents === false) {
40+
return false;
41+
}
3942
return typeof data?.contents === "string";
4043
}
4144

4245
function hasPreviewFromQuery(
43-
data: { previewDataUrl?: string | null; previewMimeType?: string | null } | undefined,
46+
data:
47+
| {
48+
previewDataUrl?: string | null | undefined;
49+
previewMimeType?: string | null | undefined;
50+
}
51+
| undefined,
4452
): data is { previewDataUrl: string; previewMimeType: string } {
4553
return typeof data?.previewDataUrl === "string" && typeof data?.previewMimeType === "string";
4654
}
@@ -446,7 +454,7 @@ export const CodeViewerFileContent = memo(function CodeViewerFileContent(
446454
);
447455
}
448456

449-
if (!hasTextContents && !hasImage) {
457+
if (!hasTextContents && preview === null) {
450458
return (
451459
<div className="flex flex-1 items-center justify-center px-5 text-center text-xs text-muted-foreground/70">
452460
No content available.

0 commit comments

Comments
 (0)