diff --git a/bun.lock b/bun.lock index 256373635..416da0135 100644 --- a/bun.lock +++ b/bun.lock @@ -484,7 +484,7 @@ "name": "opencode", "version": "1.15.13", "bin": { - "opencode": "./bin/opencode", + "zmo": "./bin/opencode", }, "dependencies": { "@actions/core": "1.11.1", diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 286fa2618..8b599f0a9 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -129,7 +129,7 @@ export const layer = Layer.effect( const global = yield* Global.Service const location = yield* Location.Service const policy = yield* Policy.Service - const names = ["config.json", "opencode.json", "opencode.jsonc"] + const names = ["config.json", "zmo.json", "zmo.jsonc", "opencode.json", "opencode.jsonc"] const loadFile = Effect.fnUntraced(function* (filepath: string) { const text = yield* fs.readFileStringSafe(filepath) diff --git a/packages/core/src/flag/flag.ts b/packages/core/src/flag/flag.ts index 804a385bc..099d6fcc9 100644 --- a/packages/core/src/flag/flag.ts +++ b/packages/core/src/flag/flag.ts @@ -1,14 +1,25 @@ import { Config } from "effect" +// zmo: 双读兼容 —— 优先读 ZMO_* 前缀,回退到原 OPENCODE_* 前缀。 +// 这样旧的 OPENCODE_* 环境变量仍然有效,同时支持新的 ZMO_* 前缀。 +function envOf(key: string): string | undefined { + if (key.startsWith("OPENCODE_")) { + const zmoKey = "ZMO_" + key.slice("OPENCODE_".length) + const zmoValue = process.env[zmoKey] + if (zmoValue !== undefined) return zmoValue + } + return process.env[key] +} + export function truthy(key: string) { - const value = process.env[key]?.toLowerCase() + const value = envOf(key)?.toLowerCase() return value === "true" || value === "1" } -const copy = process.env["OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT"] +const copy = envOf("OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT") function enabledByExperimental(key: string) { - return process.env[key] === undefined ? truthy("OPENCODE_EXPERIMENTAL") : truthy(key) + return envOf(key) === undefined ? truthy("OPENCODE_EXPERIMENTAL") : truthy(key) } export const Flag = { @@ -16,9 +27,9 @@ export const Flag = { OTEL_EXPORTER_OTLP_HEADERS: process.env["OTEL_EXPORTER_OTLP_HEADERS"], OPENCODE_AUTO_HEAP_SNAPSHOT: truthy("OPENCODE_AUTO_HEAP_SNAPSHOT"), - OPENCODE_GIT_BASH_PATH: process.env["OPENCODE_GIT_BASH_PATH"], - OPENCODE_CONFIG: process.env["OPENCODE_CONFIG"], - OPENCODE_CONFIG_CONTENT: process.env["OPENCODE_CONFIG_CONTENT"], + OPENCODE_GIT_BASH_PATH: envOf("OPENCODE_GIT_BASH_PATH"), + OPENCODE_CONFIG: envOf("OPENCODE_CONFIG"), + OPENCODE_CONFIG_CONTENT: envOf("OPENCODE_CONFIG_CONTENT"), OPENCODE_DISABLE_AUTOUPDATE: truthy("OPENCODE_DISABLE_AUTOUPDATE"), OPENCODE_ALWAYS_NOTIFY_UPDATE: truthy("OPENCODE_ALWAYS_NOTIFY_UPDATE"), OPENCODE_DISABLE_PRUNE: truthy("OPENCODE_DISABLE_PRUNE"), @@ -27,9 +38,9 @@ export const Flag = { OPENCODE_DISABLE_AUTOCOMPACT: truthy("OPENCODE_DISABLE_AUTOCOMPACT"), OPENCODE_DISABLE_MODELS_FETCH: truthy("OPENCODE_DISABLE_MODELS_FETCH"), OPENCODE_DISABLE_MOUSE: truthy("OPENCODE_DISABLE_MOUSE"), - OPENCODE_FAKE_VCS: process.env["OPENCODE_FAKE_VCS"], - OPENCODE_SERVER_PASSWORD: process.env["OPENCODE_SERVER_PASSWORD"], - OPENCODE_SERVER_USERNAME: process.env["OPENCODE_SERVER_USERNAME"], + OPENCODE_FAKE_VCS: envOf("OPENCODE_FAKE_VCS"), + OPENCODE_SERVER_PASSWORD: envOf("OPENCODE_SERVER_PASSWORD"), + OPENCODE_SERVER_USERNAME: envOf("OPENCODE_SERVER_USERNAME"), // Experimental OPENCODE_EXPERIMENTAL_FILEWATCHER: Config.boolean("OPENCODE_EXPERIMENTAL_FILEWATCHER").pipe( @@ -40,11 +51,11 @@ export const Flag = { ), OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT: copy === undefined ? process.platform === "win32" : truthy("OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT"), - OPENCODE_MODELS_URL: process.env["OPENCODE_MODELS_URL"], - OPENCODE_MODELS_PATH: process.env["OPENCODE_MODELS_PATH"], - OPENCODE_DB: process.env["OPENCODE_DB"], + OPENCODE_MODELS_URL: envOf("OPENCODE_MODELS_URL"), + OPENCODE_MODELS_PATH: envOf("OPENCODE_MODELS_PATH"), + OPENCODE_DB: envOf("OPENCODE_DB"), - OPENCODE_WORKSPACE_ID: process.env["OPENCODE_WORKSPACE_ID"], + OPENCODE_WORKSPACE_ID: envOf("OPENCODE_WORKSPACE_ID"), OPENCODE_EXPERIMENTAL_WORKSPACES: enabledByExperimental("OPENCODE_EXPERIMENTAL_WORKSPACES"), OPENCODE_EXPERIMENTAL_SESSION_SWITCHER: enabledByExperimental("OPENCODE_EXPERIMENTAL_SESSION_SWITCHER"), @@ -57,21 +68,21 @@ export const Flag = { return enabledByExperimental("OPENCODE_EXPERIMENTAL_REFERENCES") }, get OPENCODE_TUI_CONFIG() { - return process.env["OPENCODE_TUI_CONFIG"] + return envOf("OPENCODE_TUI_CONFIG") }, get OPENCODE_CONFIG_DIR() { - return process.env["OPENCODE_CONFIG_DIR"] + return envOf("OPENCODE_CONFIG_DIR") }, get OPENCODE_PURE() { return truthy("OPENCODE_PURE") }, get OPENCODE_PERMISSION() { - return process.env["OPENCODE_PERMISSION"] + return envOf("OPENCODE_PERMISSION") }, get OPENCODE_PLUGIN_META_FILE() { - return process.env["OPENCODE_PLUGIN_META_FILE"] + return envOf("OPENCODE_PLUGIN_META_FILE") }, get OPENCODE_CLIENT() { - return process.env["OPENCODE_CLIENT"] ?? "cli" + return envOf("OPENCODE_CLIENT") ?? "cli" }, } diff --git a/packages/core/src/global.ts b/packages/core/src/global.ts index 5f9799c25..c012bc131 100644 --- a/packages/core/src/global.ts +++ b/packages/core/src/global.ts @@ -6,7 +6,7 @@ import { Context, Effect, Layer } from "effect" import { Flock } from "./util/flock" import { Flag } from "./flag/flag" -const app = "opencode" +const app = "zmo" const data = path.join(xdgData!, app) const cache = path.join(xdgCache!, app) const config = path.join(xdgConfig!, app) @@ -15,7 +15,7 @@ const tmp = path.join(os.tmpdir(), app) const paths = { get home() { - return process.env.OPENCODE_TEST_HOME ?? os.homedir() + return process.env.ZMO_TEST_HOME ?? process.env.OPENCODE_TEST_HOME ?? os.homedir() }, data, bin: path.join(cache, "bin"), diff --git a/packages/opencode/package.json b/packages/opencode/package.json index cde08e035..16c9f4b98 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -17,7 +17,7 @@ "dev:temporary": "bun run --conditions=browser ./src/temporary.ts" }, "bin": { - "opencode": "./bin/opencode" + "zmo": "./bin/opencode" }, "exports": { "./*": "./src/*.ts" diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index c93ae46d1..f3ed5e60c 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -179,8 +179,8 @@ for (const item of targets) { autoloadTsconfig: true, autoloadPackageJson: true, target: name.replace(pkg.name, "bun") as any, - outfile: `dist/${name}/bin/opencode`, - execArgv: [`--user-agent=opencode/${Script.version}`, "--use-system-ca", "--"], + outfile: `dist/${name}/bin/zmo`, + execArgv: [`--user-agent=zmo/${Script.version}`, "--use-system-ca", "--"], windows: {}, }, files: embeddedFileMap ? { "opencode-web-ui.gen.ts": embeddedFileMap } : {}, @@ -197,7 +197,7 @@ for (const item of targets) { // Smoke test: only run if binary is for current platform if (item.os === process.platform && item.arch === process.arch && !item.abi) { - const binaryPath = `dist/${name}/bin/opencode` + const binaryPath = `dist/${name}/bin/zmo` console.log(`Running smoke test: ${binaryPath} --version`) try { const versionOutput = await $`${binaryPath} --version`.text() diff --git a/packages/opencode/src/cli/cmd/run.ts b/packages/opencode/src/cli/cmd/run.ts index 8a79885a4..88ea1268b 100644 --- a/packages/opencode/src/cli/cmd/run.ts +++ b/packages/opencode/src/cli/cmd/run.ts @@ -121,7 +121,7 @@ async function toolError(part: ToolPart) { export const RunCommand = effectCmd({ command: "run [message..]", - describe: "run opencode with a message", + describe: "run zmo with a message", // --attach connects to a remote server (no local instance needed); the // default path runs an in-process server and needs the project instance. instance: (args) => !args.attach, @@ -185,7 +185,7 @@ export const RunCommand = effectCmd({ }) .option("attach", { type: "string", - describe: "attach to a running opencode server (e.g., http://localhost:4096)", + describe: "attach to a running zmo server (e.g., http://localhost:4096)", }) .option("password", { alias: ["p"], diff --git a/packages/opencode/src/cli/cmd/serve.ts b/packages/opencode/src/cli/cmd/serve.ts index c0f62b3ca..153d8b298 100644 --- a/packages/opencode/src/cli/cmd/serve.ts +++ b/packages/opencode/src/cli/cmd/serve.ts @@ -6,7 +6,7 @@ import { Flag } from "@opencode-ai/core/flag/flag" export const ServeCommand = effectCmd({ command: "serve", builder: (yargs) => withNetworkOptions(yargs), - describe: "starts a headless opencode server", + describe: "starts a headless zmo server", // Server loads instances per-request via x-opencode-directory header — no // need for an ambient project InstanceContext at startup. instance: false, @@ -17,7 +17,7 @@ export const ServeCommand = effectCmd({ } const opts = yield* resolveNetworkOptions(args) const server = yield* Effect.promise(() => Server.listen(opts)) - console.log(`opencode server listening on http://${server.hostname}:${server.port}`) + console.log(`zmo server listening on http://${server.hostname}:${server.port}`) yield* Effect.never }), diff --git a/packages/opencode/src/cli/cmd/tui/attach.ts b/packages/opencode/src/cli/cmd/tui/attach.ts index f840266d4..07ef052b6 100644 --- a/packages/opencode/src/cli/cmd/tui/attach.ts +++ b/packages/opencode/src/cli/cmd/tui/attach.ts @@ -7,7 +7,7 @@ import { ServerAuth } from "@/server/auth" export const AttachCommand = cmd({ command: "attach ", - describe: "attach to a running opencode server", + describe: "attach to a running zmo server", builder: (yargs) => yargs .positional("url", { diff --git a/packages/opencode/src/cli/cmd/tui/thread.ts b/packages/opencode/src/cli/cmd/tui/thread.ts index 8b526158a..074c3c0ac 100644 --- a/packages/opencode/src/cli/cmd/tui/thread.ts +++ b/packages/opencode/src/cli/cmd/tui/thread.ts @@ -77,12 +77,12 @@ export function resolveThreadDirectory(project?: string, envPWD = process.env.PW export const TuiThreadCommand = cmd({ command: "$0 [project]", - describe: "start opencode tui", + describe: "start zmo tui", builder: (yargs) => withNetworkOptions(yargs) .positional("project", { type: "string", - describe: "path to start opencode in", + describe: "path to start zmo in", }) .option("model", { type: "string", diff --git a/packages/opencode/src/cli/cmd/uninstall.ts b/packages/opencode/src/cli/cmd/uninstall.ts index 0afdc5185..2ab11d9d2 100644 --- a/packages/opencode/src/cli/cmd/uninstall.ts +++ b/packages/opencode/src/cli/cmd/uninstall.ts @@ -24,7 +24,7 @@ interface RemovalTargets { export const UninstallCommand = { command: "uninstall", - describe: "uninstall opencode and remove all related files", + describe: "uninstall zmo and remove all related files", builder: (yargs: Argv) => yargs .option("keep-config", { diff --git a/packages/opencode/src/cli/cmd/upgrade.ts b/packages/opencode/src/cli/cmd/upgrade.ts index 3c1604a0b..31af8b2ea 100644 --- a/packages/opencode/src/cli/cmd/upgrade.ts +++ b/packages/opencode/src/cli/cmd/upgrade.ts @@ -6,7 +6,7 @@ import { InstallationVersion } from "@opencode-ai/core/installation/version" export const UpgradeCommand = { command: "upgrade [target]", - describe: "upgrade opencode to the latest or a specific version", + describe: "upgrade zmo to the latest or a specific version", builder: (yargs: Argv) => { return yargs .positional("target", { diff --git a/packages/opencode/src/cli/error.ts b/packages/opencode/src/cli/error.ts index ef724bbbe..69fb18596 100644 --- a/packages/opencode/src/cli/error.ts +++ b/packages/opencode/src/cli/error.ts @@ -47,7 +47,7 @@ export function FormatError(input: unknown): string | undefined { // MCPFailed: { name: string } if (NamedError.hasName(input, "MCPFailed")) { const data = isRecord(input) && isRecord(input.data) ? stringField(input.data, "name") : undefined - return `MCP server "${data}" failed. Note, opencode does not support MCP authentication yet.` + return `MCP server "${data}" failed. Note, zmo does not support MCP authentication yet.` } // AccountServiceError, AccountTransportError: TaggedErrorClass @@ -64,8 +64,8 @@ export function FormatError(input: unknown): string | undefined { return [ `Model not found: ${stringField(providerModelNotFound, "providerID")}/${stringField(providerModelNotFound, "modelID")}`, ...(suggestions.length ? ["Did you mean: " + suggestions.join(", ")] : []), - `Try: \`opencode models\` to list available models`, - `Or check your config (opencode.json) provider/model names`, + `Try: \`zmo models\` to list available models`, + `Or check your config (zmo.json) provider/model names`, ].join("\n") } diff --git a/packages/opencode/src/cli/logo.ts b/packages/opencode/src/cli/logo.ts index a58a8cf99..2c9ec3806 100644 --- a/packages/opencode/src/cli/logo.ts +++ b/packages/opencode/src/cli/logo.ts @@ -1,6 +1,6 @@ export const logo = { - left: [" ", "█▀▀█ █▀▀█ █▀▀█ █▀▀▄", "█__█ █__█ █^^^ █__█", "▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀~~▀"], - right: [" ▄ ", "█▀▀▀ █▀▀█ █▀▀█ █▀▀█", "█___ █__█ █__█ █^^^", "▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀"], + left: ["▀▀▀▀", " ▄▀", "▄▀ ", "▄▄▄▄"], + right: ["█▄ ▄█ ▄▀▀▄", "█ ▀ █ █ █", "█ █ █ █", "█ █ ▀▄▄▀"], } export const go = { diff --git a/packages/opencode/src/cli/ui.ts b/packages/opencode/src/cli/ui.ts index 6ad6495cf..1ed27b8a5 100644 --- a/packages/opencode/src/cli/ui.ts +++ b/packages/opencode/src/cli/ui.ts @@ -3,10 +3,10 @@ import { Schema } from "effect" import { logo as glyphs } from "./logo" const wordmark = [ - `⠀ ▄ `, - `█▀▀█ █▀▀█ █▀▀█ █▀▀▄ █▀▀▀ █▀▀█ █▀▀█ █▀▀█`, - `█ █ █ █ █▀▀▀ █ █ █ █ █ █ █ █▀▀▀`, - `▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀ ▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀`, + `▀▀▀▀ █▄ ▄█ ▄▀▀▄`, + ` ▄▀ █ ▀ █ █ █`, + `▄▀ █ █ █ █`, + `▄▄▄▄ █ █ ▀▄▄▀`, ] export class CancelledError extends Schema.TaggedErrorClass()("UICancelledError", {}) {} diff --git a/packages/opencode/src/index.ts b/packages/opencode/src/index.ts index 0c2251609..f436d56db 100644 --- a/packages/opencode/src/index.ts +++ b/packages/opencode/src/index.ts @@ -3,7 +3,7 @@ import { hideBin } from "yargs/helpers" import { RunCommand } from "./cli/cmd/run" import { GenerateCommand } from "./cli/cmd/generate" import * as Log from "@opencode-ai/core/util/log" -import { ConsoleCommand } from "./cli/cmd/account" +// import { ConsoleCommand } from "./cli/cmd/account" // zmo: 隐藏云账户命令 import { ProvidersCommand } from "./cli/cmd/providers" import { AgentCommand } from "./cli/cmd/agent" import { UpgradeCommand } from "./cli/cmd/upgrade" @@ -15,20 +15,20 @@ import { InstallationVersion } from "@opencode-ai/core/installation/version" import { NamedError } from "@opencode-ai/core/util/error" import { FormatError } from "./cli/error" import { ServeCommand } from "./cli/cmd/serve" -import { DebugCommand } from "./cli/cmd/debug" -import { StatsCommand } from "./cli/cmd/stats" +// import { DebugCommand } from "./cli/cmd/debug" // zmo: 隐藏 debug 命令 +// import { StatsCommand } from "./cli/cmd/stats" // zmo: 隐藏统计命令 import { McpCommand } from "./cli/cmd/mcp" -import { GithubCommand } from "./cli/cmd/github" -import { ExportCommand } from "./cli/cmd/export" -import { ImportCommand } from "./cli/cmd/import" +// import { GithubCommand } from "./cli/cmd/github" // zmo: 隐藏 github 命令 +// import { ExportCommand } from "./cli/cmd/export" // zmo: 隐藏导出命令 +// import { ImportCommand } from "./cli/cmd/import" // zmo: 隐藏导入命令 import { AttachCommand } from "./cli/cmd/tui/attach" import { TuiThreadCommand } from "./cli/cmd/tui/thread" import { AcpCommand } from "./cli/cmd/acp" import { EOL } from "os" -import { WebCommand } from "./cli/cmd/web" -import { PrCommand } from "./cli/cmd/pr" +// import { WebCommand } from "./cli/cmd/web" // zmo: 隐藏 web 命令 +// import { PrCommand } from "./cli/cmd/pr" // zmo: 隐藏 pr 命令 import { SessionCommand } from "./cli/cmd/session" -import { DbCommand } from "./cli/cmd/db" +// import { DbCommand } from "./cli/cmd/db" // zmo: 隐藏 db 命令 import { errorMessage } from "./util/error" import { PluginCommand } from "./cli/cmd/plug" import { Heap } from "./cli/heap" @@ -53,7 +53,7 @@ const args = hideBin(process.argv) function show(out: string) { const text = out.trimStart() - if (!text.startsWith("opencode ")) { + if (!text.startsWith("zmo ")) { process.stderr.write(UI.logo() + EOL + EOL) process.stderr.write(text) return @@ -63,7 +63,7 @@ function show(out: string) { const cli = yargs(args) .parserConfiguration({ "populate--": true }) - .scriptName("opencode") + .scriptName("zmo") .wrap(100) .help("help", "show help") .alias("help", "h") @@ -102,6 +102,8 @@ const cli = yargs(args) process.env.AGENT = "1" process.env.OPENCODE = "1" process.env.OPENCODE_PID = String(process.pid) + process.env.ZMO = "1" + process.env.ZMO_PID = String(process.pid) Log.Default.info("opencode", { version: InstallationVersion, @@ -118,23 +120,14 @@ const cli = yargs(args) .command(AttachCommand) .command(RunCommand) .command(GenerateCommand) - .command(DebugCommand) - .command(ConsoleCommand) .command(ProvidersCommand) .command(AgentCommand) .command(UpgradeCommand) .command(UninstallCommand) .command(ServeCommand) - .command(WebCommand) .command(ModelsCommand) - .command(StatsCommand) - .command(ExportCommand) - .command(ImportCommand) - .command(GithubCommand) - .command(PrCommand) .command(SessionCommand) .command(PluginCommand) - .command(DbCommand) .fail((msg, err) => { if ( msg?.startsWith("Unknown argument") ||