Skip to content

Commit c07919f

Browse files
committed
nix flake: initial flake and patches for ts
1 parent d3e0808 commit c07919f

File tree

4 files changed

+124
-25
lines changed

4 files changed

+124
-25
lines changed

flake.nix

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
description = "OpenCode development flake";
3+
4+
inputs = {
5+
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
6+
};
7+
8+
outputs =
9+
{
10+
nixpkgs,
11+
...
12+
}:
13+
let
14+
systems = [
15+
"aarch64-linux"
16+
"x86_64-linux"
17+
];
18+
forEachSystem = nixpkgs.lib.genAttrs systems;
19+
in
20+
{
21+
devShells = forEachSystem (
22+
system:
23+
let
24+
pkgs = import nixpkgs { inherit system; };
25+
in
26+
{
27+
default = pkgs.mkShell {
28+
packages = with pkgs; [
29+
bun
30+
nodejs_20
31+
pkg-config
32+
openssl
33+
git
34+
];
35+
};
36+
}
37+
);
38+
39+
apps = forEachSystem (
40+
system:
41+
let
42+
pkgs = import nixpkgs { inherit system; };
43+
in
44+
{
45+
opencode-dev = {
46+
type = "app";
47+
program = pkgs.writeShellApplication {
48+
name = "opencode-dev";
49+
runtimeInputs = [ pkgs.bun ];
50+
text = ''
51+
exec bun run dev "$@"
52+
'';
53+
};
54+
};
55+
}
56+
);
57+
};
58+
}

packages/opencode/src/cli/cmd/tui/thread.ts

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { Session } from "@/session"
77
import { bootstrap } from "@/cli/bootstrap"
88
import path from "path"
99
import { UI } from "@/cli/ui"
10+
import { Server } from "@/server/server"
11+
import { Instance } from "@/project/instance"
1012

1113
declare global {
1214
const OPENCODE_WORKER_PATH: string
@@ -65,11 +67,9 @@ export const TuiThreadCommand = cmd({
6567
// Resolve relative paths against PWD to preserve behavior when using --cwd flag
6668
const baseCwd = process.env.PWD ?? process.cwd()
6769
const cwd = args.project ? path.resolve(baseCwd, args.project) : process.cwd()
68-
let workerPath: string | URL = new URL("./worker.ts", import.meta.url)
69-
70-
if (typeof OPENCODE_WORKER_PATH !== "undefined") {
71-
workerPath = OPENCODE_WORKER_PATH
72-
}
70+
const defaultWorker = new URL("./worker.ts", import.meta.url)
71+
const workerPath =
72+
typeof OPENCODE_WORKER_PATH !== "undefined" ? OPENCODE_WORKER_PATH : defaultWorker
7373
try {
7474
process.chdir(cwd)
7575
} catch (e) {
@@ -100,33 +100,64 @@ export const TuiThreadCommand = cmd({
100100
return undefined
101101
})()
102102

103-
const worker = new Worker(workerPath, {
104-
env: Object.fromEntries(
103+
const setup = await (async () => {
104+
const env = Object.fromEntries(
105105
Object.entries(process.env).filter(
106106
(entry): entry is [string, string] => entry[1] !== undefined,
107107
),
108-
),
109-
})
110-
worker.onerror = console.error
111-
const client = Rpc.client<typeof rpc>(worker)
112-
process.on("uncaughtException", (e) => {
113-
console.error(e)
114-
})
115-
process.on("unhandledRejection", (e) => {
116-
console.error(e)
117-
})
118-
const server = await client.call("server", {
119-
port: args.port,
120-
hostname: args.hostname,
121-
})
108+
)
109+
const worker = await Promise.resolve()
110+
.then(
111+
() =>
112+
new Worker(workerPath, {
113+
env,
114+
}),
115+
)
116+
.catch((error) => {
117+
console.debug("opencode tui worker disabled", error)
118+
return undefined
119+
})
120+
if (worker) {
121+
worker.onerror = console.error
122+
const client = Rpc.client<typeof rpc>(worker)
123+
process.on("uncaughtException", (error) => {
124+
console.error(error)
125+
})
126+
process.on("unhandledRejection", (error) => {
127+
console.error(error)
128+
})
129+
const remote = await client.call("server", {
130+
port: args.port,
131+
hostname: args.hostname,
132+
})
133+
return {
134+
url: remote.url,
135+
stop: async () => {
136+
await client.call("shutdown", undefined)
137+
worker.terminate()
138+
},
139+
}
140+
}
141+
const inline = Server.listen({
142+
port: args.port ?? 0,
143+
hostname: args.hostname ?? "127.0.0.1",
144+
})
145+
return {
146+
url: inline.url.toString(),
147+
stop: async () => {
148+
await Instance.disposeAll()
149+
await inline.stop(true)
150+
},
151+
}
152+
})()
122153
await tui({
123-
url: server.url,
154+
url: setup.url,
124155
sessionID,
125156
model: args.model,
126157
agent: args.agent,
127158
prompt,
128159
onExit: async () => {
129-
await client.call("shutdown", undefined)
160+
await setup.stop()
130161
},
131162
})
132163
})
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
export async function data() {
2+
const path = Bun.env.MODELS_DEV_API_JSON
3+
if (path) {
4+
const file = Bun.file(path)
5+
if (await file.exists()) {
6+
return await file.text()
7+
}
8+
}
29
const json = await fetch("https://models.dev/api.json").then((x) => x.text())
310
return json
411
}

packages/sdk/js/src/gen/client/utils.gen.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,11 @@ export const buildUrl: Client["buildUrl"] = (options) =>
169169

170170
export const mergeConfigs = (a: Config, b: Config): Config => {
171171
const config = { ...a, ...b }
172-
if (config.baseUrl?.endsWith("/")) {
173-
config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1)
172+
if (config.baseUrl) {
173+
const base =
174+
typeof config.baseUrl === "string" ? config.baseUrl : String(config.baseUrl)
175+
const trimmed = base.endsWith("/") ? base.substring(0, base.length - 1) : base
176+
config.baseUrl = trimmed
174177
}
175178
config.headers = mergeHeaders(a.headers, b.headers)
176179
return config

0 commit comments

Comments
 (0)