Skip to content

Commit 26e7043

Browse files
feat(core): optional mdns service (anomalyco#6192)
Co-authored-by: Github Action <action@github.com>
1 parent dd569c9 commit 26e7043

File tree

17 files changed

+238
-116
lines changed

17 files changed

+238
-116
lines changed

bun.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nix/hashes.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"nodeModules": "sha256-hotsyeWJA6/dP6DvZTN1Ak2RSKcsyvXlXPI/jexBHME="
2+
"nodeModules": "sha256-okbViEKf1mRSmzbJgKdB9SJ875q84Bwu8d3ChHuaQ1g="
33
}

packages/opencode/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"@standard-schema/spec": "1.0.0",
8282
"@zip.js/zip.js": "2.7.62",
8383
"ai": "catalog:",
84+
"bonjour-service": "1.3.0",
8485
"bun-pty": "0.4.2",
8586
"chokidar": "4.0.3",
8687
"clipboardy": "4.0.0",

packages/opencode/src/cli/cmd/acp.ts

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import { bootstrap } from "../bootstrap"
33
import { cmd } from "./cmd"
44
import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"
55
import { ACP } from "@/acp/agent"
6+
import { Config } from "@/config/config"
67
import { Server } from "@/server/server"
78
import { createOpencodeClient } from "@opencode-ai/sdk/v2"
9+
import { withNetworkOptions, resolveNetworkOptions } from "../network"
810

911
const log = Log.create({ service: "acp-command" })
1012

@@ -19,29 +21,17 @@ export const AcpCommand = cmd({
1921
command: "acp",
2022
describe: "start ACP (Agent Client Protocol) server",
2123
builder: (yargs) => {
22-
return yargs
23-
.option("cwd", {
24-
describe: "working directory",
25-
type: "string",
26-
default: process.cwd(),
27-
})
28-
.option("port", {
29-
type: "number",
30-
describe: "port to listen on",
31-
default: 0,
32-
})
33-
.option("hostname", {
34-
type: "string",
35-
describe: "hostname to listen on",
36-
default: "127.0.0.1",
37-
})
24+
return withNetworkOptions(yargs).option("cwd", {
25+
describe: "working directory",
26+
type: "string",
27+
default: process.cwd(),
28+
})
3829
},
3930
handler: async (args) => {
4031
await bootstrap(process.cwd(), async () => {
41-
const server = Server.listen({
42-
port: args.port,
43-
hostname: args.hostname,
44-
})
32+
const config = await Config.get()
33+
const opts = resolveNetworkOptions(args, config)
34+
const server = Server.listen(opts)
4535

4636
const sdk = createOpencodeClient({
4737
baseUrl: `http://${server.hostname}:${server.port}`,

packages/opencode/src/cli/cmd/serve.ts

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,16 @@
1+
import { Config } from "../../config/config"
12
import { Server } from "../../server/server"
23
import { cmd } from "./cmd"
4+
import { withNetworkOptions, resolveNetworkOptions } from "../network"
35

46
export const ServeCommand = cmd({
57
command: "serve",
6-
builder: (yargs) =>
7-
yargs
8-
.option("port", {
9-
alias: ["p"],
10-
type: "number",
11-
describe: "port to listen on",
12-
default: 0,
13-
})
14-
.option("hostname", {
15-
type: "string",
16-
describe: "hostname to listen on",
17-
default: "127.0.0.1",
18-
}),
8+
builder: (yargs) => withNetworkOptions(yargs),
199
describe: "starts a headless opencode server",
2010
handler: async (args) => {
21-
const hostname = args.hostname
22-
const port = args.port
23-
const server = Server.listen({
24-
port,
25-
hostname,
26-
})
11+
const config = await Config.get()
12+
const opts = resolveNetworkOptions(args, config)
13+
const server = Server.listen(opts)
2714
console.log(`opencode server listening on http://${server.hostname}:${server.port}`)
2815
await new Promise(() => {})
2916
await server.stop()

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

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,23 @@
11
import { cmd } from "@/cli/cmd/cmd"
2+
import { Config } from "@/config/config"
23
import { Instance } from "@/project/instance"
34
import path from "path"
45
import { Server } from "@/server/server"
56
import { upgrade } from "@/cli/upgrade"
7+
import { withNetworkOptions, resolveNetworkOptions } from "@/cli/network"
68

79
export const TuiSpawnCommand = cmd({
810
command: "spawn [project]",
911
builder: (yargs) =>
10-
yargs
11-
.positional("project", {
12-
type: "string",
13-
describe: "path to start opencode in",
14-
})
15-
.option("port", {
16-
type: "number",
17-
describe: "port to listen on",
18-
default: 0,
19-
})
20-
.option("hostname", {
21-
type: "string",
22-
describe: "hostname to listen on",
23-
default: "127.0.0.1",
24-
}),
12+
withNetworkOptions(yargs).positional("project", {
13+
type: "string",
14+
describe: "path to start opencode in",
15+
}),
2516
handler: async (args) => {
2617
upgrade()
27-
const server = Server.listen({
28-
port: args.port,
29-
hostname: "127.0.0.1",
30-
})
18+
const config = await Config.get()
19+
const opts = resolveNetworkOptions(args, config)
20+
const server = Server.listen(opts)
3121
const bin = process.execPath
3222
const cmd = []
3323
let cwd = process.cwd()

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

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import path from "path"
66
import { UI } from "@/cli/ui"
77
import { iife } from "@/util/iife"
88
import { Log } from "@/util/log"
9+
import { withNetworkOptions, resolveNetworkOptions } from "@/cli/network"
10+
import { Config } from "@/config/config"
911

1012
declare global {
1113
const OPENCODE_WORKER_PATH: string
@@ -15,7 +17,7 @@ export const TuiThreadCommand = cmd({
1517
command: "$0 [project]",
1618
describe: "start opencode tui",
1719
builder: (yargs) =>
18-
yargs
20+
withNetworkOptions(yargs)
1921
.positional("project", {
2022
type: "string",
2123
describe: "path to start opencode in",
@@ -36,23 +38,12 @@ export const TuiThreadCommand = cmd({
3638
describe: "session id to continue",
3739
})
3840
.option("prompt", {
39-
alias: ["p"],
4041
type: "string",
4142
describe: "prompt to use",
4243
})
4344
.option("agent", {
4445
type: "string",
4546
describe: "agent to use",
46-
})
47-
.option("port", {
48-
type: "number",
49-
describe: "port to listen on",
50-
default: 0,
51-
})
52-
.option("hostname", {
53-
type: "string",
54-
describe: "hostname to listen on",
55-
default: "127.0.0.1",
5647
}),
5748
handler: async (args) => {
5849
// Resolve relative paths against PWD to preserve behavior when using --cwd flag
@@ -87,10 +78,9 @@ export const TuiThreadCommand = cmd({
8778
process.on("unhandledRejection", (e) => {
8879
Log.Default.error(e)
8980
})
90-
const server = await client.call("server", {
91-
port: args.port,
92-
hostname: args.hostname,
93-
})
81+
const config = await Config.get()
82+
const networkOpts = resolveNetworkOptions(args, config)
83+
const server = await client.call("server", networkOpts)
9484
const prompt = await iife(async () => {
9585
const piped = !process.stdin.isTTY ? await Bun.stdin.text() : undefined
9686
if (!args.prompt) return piped

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ process.on("uncaughtException", (e) => {
3030

3131
let server: Bun.Server<BunWebSocketData>
3232
export const rpc = {
33-
async server(input: { port: number; hostname: string }) {
33+
async server(input: { port: number; hostname: string; mdns?: boolean }) {
3434
if (server) await server.stop(true)
3535
try {
3636
server = Server.listen(input)

packages/opencode/src/cli/cmd/web.ts

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { Config } from "../../config/config"
12
import { Server } from "../../server/server"
23
import { UI } from "../ui"
34
import { cmd } from "./cmd"
5+
import { withNetworkOptions, resolveNetworkOptions } from "../network"
46
import open from "open"
57
import { networkInterfaces } from "os"
68

@@ -28,32 +30,17 @@ function getNetworkIPs() {
2830

2931
export const WebCommand = cmd({
3032
command: "web",
31-
builder: (yargs) =>
32-
yargs
33-
.option("port", {
34-
alias: ["p"],
35-
type: "number",
36-
describe: "port to listen on",
37-
default: 0,
38-
})
39-
.option("hostname", {
40-
type: "string",
41-
describe: "hostname to listen on",
42-
default: "127.0.0.1",
43-
}),
33+
builder: (yargs) => withNetworkOptions(yargs),
4434
describe: "starts a headless opencode server",
4535
handler: async (args) => {
46-
const hostname = args.hostname
47-
const port = args.port
48-
const server = Server.listen({
49-
port,
50-
hostname,
51-
})
36+
const config = await Config.get()
37+
const opts = resolveNetworkOptions(args, config)
38+
const server = Server.listen(opts)
5239
UI.empty()
5340
UI.println(UI.logo(" "))
5441
UI.empty()
5542

56-
if (hostname === "0.0.0.0") {
43+
if (opts.hostname === "0.0.0.0") {
5744
// Show localhost for local access
5845
const localhostUrl = `http://localhost:${server.port}`
5946
UI.println(UI.Style.TEXT_INFO_BOLD + " Local access: ", UI.Style.TEXT_NORMAL, localhostUrl)
@@ -70,6 +57,10 @@ export const WebCommand = cmd({
7057
}
7158
}
7259

60+
if (opts.mdns) {
61+
UI.println(UI.Style.TEXT_INFO_BOLD + " mDNS: ", UI.Style.TEXT_NORMAL, "opencode.local")
62+
}
63+
7364
// Open localhost in browser
7465
open(localhostUrl.toString()).catch(() => {})
7566
} else {

0 commit comments

Comments
 (0)