rebrand: 将 opencode 改造为 zmo CLI 并隐藏非 CLI 命令
为打造自有纯 CLI 产品 zmo(类 Claude Code),在保留上游同步能力的前提下做套壳改造: - 入口隐藏 9 个非 CLI 命令(console/web/github/pr/stats/export/import/db/debug) - 全面 rebrand:scriptName、Logo、配置目录(~/.config/zmo)、bin 名、构建产物、可见文案 - env 双读兼容(ZMO_* 优先,回退 OPENCODE_*),配置文件名新增 zmo.json - 刻意保留 @opencode-ai/* 内部包名与 opencode provider,避免破坏功能与上游同步 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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"),
|
||||
|
||||
Reference in New Issue
Block a user