feat: 全面清除用户/AI可见的 opencode 痕迹
- system.ts 不再把真实 model id 喂给 LLM(修复"底层是opencode/big-pickle") - TUI 首页 tips、窗口标题、ACP 弹窗、命令提示文案全部 → zmo - config schema URL → zmo.dev;配置路径提示 → ~/.config/zmo、.zmo/ - 发给各家 LLM API 的标识头(X-Title/Referer/Source/UA/originator)→ zmo - 保留:opencode provider 路由id、@opencode-ai 包名、opencode.json/OPENCODE_* 兼容 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@ export const CerebrasPlugin = PluginV2.define({
|
|||||||
if (item.provider.api.type !== "aisdk") continue
|
if (item.provider.api.type !== "aisdk") continue
|
||||||
if (item.provider.api.package !== "@ai-sdk/cerebras") continue
|
if (item.provider.api.package !== "@ai-sdk/cerebras") continue
|
||||||
ctx.provider.update(item.provider.id, (provider) => {
|
ctx.provider.update(item.provider.id, (provider) => {
|
||||||
provider.request.headers["X-Cerebras-3rd-Party-Integration"] = "opencode"
|
provider.request.headers["X-Cerebras-3rd-Party-Integration"] = "zmo"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ function gatewayOptions(options: Record<string, unknown>, metadata: unknown) {
|
|||||||
skipCache: options.skipCache,
|
skipCache: options.skipCache,
|
||||||
collectLog: options.collectLog,
|
collectLog: options.collectLog,
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": `opencode/${InstallationVersion} cloudflare-ai-gateway (${os.platform()} ${os.release()}; ${os.arch()})`,
|
"User-Agent": `zmo/${InstallationVersion} cloudflare-ai-gateway (${os.platform()} ${os.release()}; ${os.arch()})`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ function sdkOptions(options: Record<string, any>) {
|
|||||||
baseURL: expandAccountId(options.baseURL),
|
baseURL: expandAccountId(options.baseURL),
|
||||||
apiKey: process.env.CLOUDFLARE_API_KEY ?? options.apiKey,
|
apiKey: process.env.CLOUDFLARE_API_KEY ?? options.apiKey,
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": `opencode/${InstallationVersion} cloudflare-workers-ai (${os.platform()} ${os.release()}; ${os.arch()})`,
|
"User-Agent": `zmo/${InstallationVersion} cloudflare-workers-ai (${os.platform()} ${os.release()}; ${os.arch()})`,
|
||||||
...options.headers,
|
...options.headers,
|
||||||
},
|
},
|
||||||
name: providerID,
|
name: providerID,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const GitLabPlugin = PluginV2.define({
|
|||||||
: (process.env.GITLAB_INSTANCE_URL ?? "https://gitlab.com"),
|
: (process.env.GITLAB_INSTANCE_URL ?? "https://gitlab.com"),
|
||||||
apiKey: typeof evt.options.apiKey === "string" ? evt.options.apiKey : process.env.GITLAB_TOKEN,
|
apiKey: typeof evt.options.apiKey === "string" ? evt.options.apiKey : process.env.GITLAB_TOKEN,
|
||||||
aiGatewayHeaders: {
|
aiGatewayHeaders: {
|
||||||
"User-Agent": `opencode/${InstallationVersion} gitlab-ai-provider/${mod.VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
|
"User-Agent": `zmo/${InstallationVersion} gitlab-ai-provider/${mod.VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
|
||||||
"anthropic-beta": "context-1m-2025-08-07",
|
"anthropic-beta": "context-1m-2025-08-07",
|
||||||
...evt.options.aiGatewayHeaders,
|
...evt.options.aiGatewayHeaders,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ export const KiloPlugin = PluginV2.define({
|
|||||||
if (item.provider.api.package !== "@ai-sdk/openai-compatible") continue
|
if (item.provider.api.package !== "@ai-sdk/openai-compatible") continue
|
||||||
if (item.provider.api.url !== "https://api.kilo.ai/api/gateway") continue
|
if (item.provider.api.url !== "https://api.kilo.ai/api/gateway") continue
|
||||||
evt.provider.update(item.provider.id, (provider) => {
|
evt.provider.update(item.provider.id, (provider) => {
|
||||||
provider.request.headers["HTTP-Referer"] = "https://opencode.ai/"
|
provider.request.headers["HTTP-Referer"] = "https://github.com/helpLogin/zmo-cli"
|
||||||
provider.request.headers["X-Title"] = "opencode"
|
provider.request.headers["X-Title"] = "zmo"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ export const LLMGatewayPlugin = PluginV2.define({
|
|||||||
if (item.provider.api.package !== "@ai-sdk/openai-compatible") continue
|
if (item.provider.api.package !== "@ai-sdk/openai-compatible") continue
|
||||||
if (item.provider.api.url !== "https://api.llmgateway.io/v1") continue
|
if (item.provider.api.url !== "https://api.llmgateway.io/v1") continue
|
||||||
evt.provider.update(item.provider.id, (provider) => {
|
evt.provider.update(item.provider.id, (provider) => {
|
||||||
provider.request.headers["HTTP-Referer"] = "https://opencode.ai/"
|
provider.request.headers["HTTP-Referer"] = "https://github.com/helpLogin/zmo-cli"
|
||||||
provider.request.headers["X-Title"] = "opencode"
|
provider.request.headers["X-Title"] = "zmo"
|
||||||
provider.request.headers["X-Source"] = "opencode"
|
provider.request.headers["X-Source"] = "zmo"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ export const NvidiaPlugin = PluginV2.define({
|
|||||||
if (item.provider.api.package !== "@ai-sdk/openai-compatible") continue
|
if (item.provider.api.package !== "@ai-sdk/openai-compatible") continue
|
||||||
if (item.provider.api.url !== "https://integrate.api.nvidia.com/v1") continue
|
if (item.provider.api.url !== "https://integrate.api.nvidia.com/v1") continue
|
||||||
evt.provider.update(item.provider.id, (provider) => {
|
evt.provider.update(item.provider.id, (provider) => {
|
||||||
provider.request.headers["HTTP-Referer"] = "https://opencode.ai/"
|
provider.request.headers["HTTP-Referer"] = "https://github.com/helpLogin/zmo-cli"
|
||||||
provider.request.headers["X-Title"] = "opencode"
|
provider.request.headers["X-Title"] = "zmo"
|
||||||
provider.request.headers["X-BILLING-INVOKE-ORIGIN"] ??= "OpenCode"
|
provider.request.headers["X-BILLING-INVOKE-ORIGIN"] ??= "zmo"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ export const OpenRouterPlugin = PluginV2.define({
|
|||||||
if (item.provider.api.type !== "aisdk") continue
|
if (item.provider.api.type !== "aisdk") continue
|
||||||
if (item.provider.api.package !== "@openrouter/ai-sdk-provider") continue
|
if (item.provider.api.package !== "@openrouter/ai-sdk-provider") continue
|
||||||
evt.provider.update(item.provider.id, (provider) => {
|
evt.provider.update(item.provider.id, (provider) => {
|
||||||
provider.request.headers["HTTP-Referer"] = "https://opencode.ai/"
|
provider.request.headers["HTTP-Referer"] = "https://github.com/helpLogin/zmo-cli"
|
||||||
provider.request.headers["X-Title"] = "opencode"
|
provider.request.headers["X-Title"] = "zmo"
|
||||||
})
|
})
|
||||||
for (const modelID of [ModelV2.ID.make("gpt-5-chat-latest"), ModelV2.ID.make("openai/gpt-5-chat")]) {
|
for (const modelID of [ModelV2.ID.make("gpt-5-chat-latest"), ModelV2.ID.make("openai/gpt-5-chat")]) {
|
||||||
if (!item.models.has(modelID)) continue
|
if (!item.models.has(modelID)) continue
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ export const VercelPlugin = PluginV2.define({
|
|||||||
if (item.provider.api.type !== "aisdk") continue
|
if (item.provider.api.type !== "aisdk") continue
|
||||||
if (item.provider.api.package !== "@ai-sdk/vercel") continue
|
if (item.provider.api.package !== "@ai-sdk/vercel") continue
|
||||||
evt.provider.update(item.provider.id, (provider) => {
|
evt.provider.update(item.provider.id, (provider) => {
|
||||||
provider.request.headers["http-referer"] = "https://opencode.ai/"
|
provider.request.headers["http-referer"] = "https://github.com/helpLogin/zmo-cli"
|
||||||
provider.request.headers["x-title"] = "opencode"
|
provider.request.headers["x-title"] = "zmo"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -93,17 +93,17 @@ export function make(input: {
|
|||||||
const initialize = Effect.fn("ACP.initialize")(function* (params: InitializeRequest) {
|
const initialize = Effect.fn("ACP.initialize")(function* (params: InitializeRequest) {
|
||||||
const started = performance.now()
|
const started = performance.now()
|
||||||
const authMethod: AuthMethod = {
|
const authMethod: AuthMethod = {
|
||||||
description: "Run `opencode auth login` in the terminal",
|
description: "Run `zmo auth login` in the terminal",
|
||||||
name: "Login with opencode",
|
name: "Login with zmo",
|
||||||
id: AuthMethodID,
|
id: AuthMethodID,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.clientCapabilities?._meta?.["terminal-auth"] === true) {
|
if (params.clientCapabilities?._meta?.["terminal-auth"] === true) {
|
||||||
authMethod._meta = {
|
authMethod._meta = {
|
||||||
"terminal-auth": {
|
"terminal-auth": {
|
||||||
command: "opencode",
|
command: "zmo",
|
||||||
args: ["auth", "login"],
|
args: ["auth", "login"],
|
||||||
label: "OpenCode Login",
|
label: "zmo Login",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ export function make(input: {
|
|||||||
},
|
},
|
||||||
authMethods: [authMethod],
|
authMethods: [authMethod],
|
||||||
agentInfo: {
|
agentInfo: {
|
||||||
name: "OpenCode",
|
name: "zmo",
|
||||||
version: InstallationVersion,
|
version: InstallationVersion,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ export const ProvidersLoginCommand = effectCmd({
|
|||||||
builder: (yargs) =>
|
builder: (yargs) =>
|
||||||
yargs
|
yargs
|
||||||
.positional("url", {
|
.positional("url", {
|
||||||
describe: "opencode auth provider",
|
describe: "zmo auth provider",
|
||||||
type: "string",
|
type: "string",
|
||||||
})
|
})
|
||||||
.option("provider", {
|
.option("provider", {
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ function build(input: SplashWriterInput, kind: "entry" | "exit", ctx: Scrollback
|
|||||||
lines,
|
lines,
|
||||||
body_left + label.length,
|
body_left + label.length,
|
||||||
top + 1,
|
top + 1,
|
||||||
`opencode run -i -s ${meta.session_id}`,
|
`zmo run -i -s ${meta.session_id}`,
|
||||||
right,
|
right,
|
||||||
undefined,
|
undefined,
|
||||||
TextAttributes.BOLD,
|
TextAttributes.BOLD,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ type TuiAttentionHost = TuiAttention & {
|
|||||||
|
|
||||||
const log = Log.create({ service: "tui.attention" })
|
const log = Log.create({ service: "tui.attention" })
|
||||||
|
|
||||||
const DEFAULT_TITLE = "opencode"
|
const DEFAULT_TITLE = "zmo"
|
||||||
const DEFAULT_PACK_ID = "opencode.default"
|
const DEFAULT_PACK_ID = "opencode.default"
|
||||||
const KV_SOUND_PACK = "attention_sound_pack"
|
const KV_SOUND_PACK = "attention_sound_pack"
|
||||||
const TITLE_LIMIT = 80
|
const TITLE_LIMIT = 80
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import * as ConfigPaths from "@/config/paths"
|
|||||||
|
|
||||||
const log = Log.create({ service: "tui.migrate" })
|
const log = Log.create({ service: "tui.migrate" })
|
||||||
|
|
||||||
const TUI_SCHEMA_URL = "https://opencode.ai/tui.json"
|
const TUI_SCHEMA_URL = "https://zmo.dev/tui.json"
|
||||||
|
|
||||||
const decodeTheme = Schema.decodeUnknownOption(Schema.String)
|
const decodeTheme = Schema.decodeUnknownOption(Schema.String)
|
||||||
const decodeRecord = Schema.decodeUnknownOption(Schema.Record(Schema.String, Schema.Unknown))
|
const decodeRecord = Schema.decodeUnknownOption(Schema.Record(Schema.String, Schema.Unknown))
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ const TIPS: Tip[] = [
|
|||||||
(shortcuts) => press(shortcuts.agentCycle(), "to cycle between Build and Plan agents"),
|
(shortcuts) => press(shortcuts.agentCycle(), "to cycle between Build and Plan agents"),
|
||||||
"Use {highlight}/undo{/highlight} to revert the last message and file changes",
|
"Use {highlight}/undo{/highlight} to revert the last message and file changes",
|
||||||
"Use {highlight}/redo{/highlight} to restore previously undone messages and file changes",
|
"Use {highlight}/redo{/highlight} to restore previously undone messages and file changes",
|
||||||
"Run {highlight}/share{/highlight} to create a public link to your conversation at opencode.ai",
|
"Run {highlight}/share{/highlight} to create a public link to your conversation",
|
||||||
"Drag and drop images or PDFs into the terminal to add them as context",
|
"Drag and drop images or PDFs into the terminal to add them as context",
|
||||||
(shortcuts) => press(shortcuts.inputPaste(), "to paste images from your clipboard into the prompt"),
|
(shortcuts) => press(shortcuts.inputPaste(), "to paste images from your clipboard into the prompt"),
|
||||||
(shortcuts) => `Use ${commandText("/editor", shortcuts.editorOpen())} to compose messages in your external editor`,
|
(shortcuts) => `Use ${commandText("/editor", shortcuts.editorOpen())} to compose messages in your external editor`,
|
||||||
@@ -210,17 +210,17 @@ const TIPS: Tip[] = [
|
|||||||
if (!items.length) return undefined
|
if (!items.length) return undefined
|
||||||
return `Use ${items.map(shortcutText).join(" / ")} to move between parent and child sessions`
|
return `Use ${items.map(shortcutText).join(" / ")} to move between parent and child sessions`
|
||||||
},
|
},
|
||||||
"Create {highlight}opencode.json{/highlight} for server settings and {highlight}tui.json{/highlight} for TUI settings",
|
"Create {highlight}zmo.json{/highlight} for server settings and {highlight}tui.json{/highlight} for TUI settings",
|
||||||
"Place TUI settings in {highlight}~/.config/opencode/tui.json{/highlight} for global config",
|
"Place TUI settings in {highlight}~/.config/zmo/tui.json{/highlight} for global config",
|
||||||
"Add {highlight}$schema{/highlight} to your config for autocomplete in your editor",
|
"Add {highlight}$schema{/highlight} to your config for autocomplete in your editor",
|
||||||
"Configure {highlight}model{/highlight} in config to set your default model",
|
"Configure {highlight}model{/highlight} in config to set your default model",
|
||||||
"Override any keybind in {highlight}tui.json{/highlight} via the {highlight}keybinds{/highlight} section",
|
"Override any keybind in {highlight}tui.json{/highlight} via the {highlight}keybinds{/highlight} section",
|
||||||
"Set any keybind to {highlight}none{/highlight} to disable it completely",
|
"Set any keybind to {highlight}none{/highlight} to disable it completely",
|
||||||
"Configure local or remote MCP servers in the {highlight}mcp{/highlight} config section",
|
"Configure local or remote MCP servers in the {highlight}mcp{/highlight} config section",
|
||||||
"Add {highlight}.md{/highlight} files to {highlight}.opencode/commands/{/highlight} to define reusable custom prompts",
|
"Add {highlight}.md{/highlight} files to {highlight}.zmo/commands/{/highlight} to define reusable custom prompts",
|
||||||
"Use {highlight}$ARGUMENTS{/highlight}, {highlight}$1{/highlight}, {highlight}$2{/highlight} in custom commands for dynamic input",
|
"Use {highlight}$ARGUMENTS{/highlight}, {highlight}$1{/highlight}, {highlight}$2{/highlight} in custom commands for dynamic input",
|
||||||
"Use backticks in commands to inject shell output (e.g., {highlight}`git status`{/highlight})",
|
"Use backticks in commands to inject shell output (e.g., {highlight}`git status`{/highlight})",
|
||||||
"Add {highlight}.md{/highlight} files to {highlight}.opencode/agents/{/highlight} for specialized AI personas",
|
"Add {highlight}.md{/highlight} files to {highlight}.zmo/agents/{/highlight} for specialized AI personas",
|
||||||
"Configure per-agent permissions for {highlight}edit{/highlight}, {highlight}bash{/highlight}, and {highlight}webfetch{/highlight} tools",
|
"Configure per-agent permissions for {highlight}edit{/highlight}, {highlight}bash{/highlight}, and {highlight}webfetch{/highlight} tools",
|
||||||
'Use patterns like {highlight}"git *": "allow"{/highlight} for granular bash permissions',
|
'Use patterns like {highlight}"git *": "allow"{/highlight} for granular bash permissions',
|
||||||
'Set {highlight}"rm -rf *": "deny"{/highlight} to block destructive commands',
|
'Set {highlight}"rm -rf *": "deny"{/highlight} to block destructive commands',
|
||||||
@@ -229,26 +229,25 @@ const TIPS: Tip[] = [
|
|||||||
'Set {highlight}"formatter": false{/highlight} in config to disable formatters enabled by another config layer',
|
'Set {highlight}"formatter": false{/highlight} in config to disable formatters enabled by another config layer',
|
||||||
"Define custom formatter commands with file extensions in config",
|
"Define custom formatter commands with file extensions in config",
|
||||||
'Set {highlight}"lsp": true{/highlight} in config to enable built-in LSP servers for code analysis',
|
'Set {highlight}"lsp": true{/highlight} in config to enable built-in LSP servers for code analysis',
|
||||||
"Create {highlight}.ts{/highlight} files in {highlight}.opencode/tools/{/highlight} to define new LLM tools",
|
"Create {highlight}.ts{/highlight} files in {highlight}.zmo/tools/{/highlight} to define new LLM tools",
|
||||||
"Tool definitions can invoke scripts written in Python, Go, etc",
|
"Tool definitions can invoke scripts written in Python, Go, etc",
|
||||||
"Add {highlight}.ts{/highlight} files to {highlight}.opencode/plugins/{/highlight} for event hooks",
|
"Add {highlight}.ts{/highlight} files to {highlight}.zmo/plugins/{/highlight} for event hooks",
|
||||||
"Use plugins to send OS notifications when sessions complete",
|
"Use plugins to send OS notifications when sessions complete",
|
||||||
"Create a plugin to prevent OpenCode from reading sensitive files",
|
"Create a plugin to prevent zmo from reading sensitive files",
|
||||||
"Use {highlight}opencode run{/highlight} for non-interactive scripting",
|
"Use {highlight}zmo run{/highlight} for non-interactive scripting",
|
||||||
"Use {highlight}opencode --continue{/highlight} to resume the last session",
|
"Use {highlight}zmo --continue{/highlight} to resume the last session",
|
||||||
"Use {highlight}opencode run -f file.ts{/highlight} to attach files via CLI",
|
"Use {highlight}zmo run -f file.ts{/highlight} to attach files via CLI",
|
||||||
"Use {highlight}--format json{/highlight} for machine-readable output in scripts",
|
"Use {highlight}--format json{/highlight} for machine-readable output in scripts",
|
||||||
"Run {highlight}opencode serve{/highlight} for headless API access to OpenCode",
|
"Run {highlight}zmo serve{/highlight} for headless API access to zmo",
|
||||||
"Use {highlight}opencode run --attach{/highlight} to connect to a running server",
|
"Use {highlight}zmo run --attach{/highlight} to connect to a running server",
|
||||||
"Run {highlight}opencode upgrade{/highlight} to update to the latest version",
|
"Run {highlight}zmo upgrade{/highlight} to update to the latest version",
|
||||||
"Run {highlight}opencode auth list{/highlight} to see all configured providers",
|
"Run {highlight}zmo auth list{/highlight} to see all configured providers",
|
||||||
"Run {highlight}opencode agent create{/highlight} for guided agent creation",
|
"Run {highlight}zmo agent create{/highlight} for guided agent creation",
|
||||||
"Use {highlight}/opencode{/highlight} in GitHub issues/PRs to trigger AI actions",
|
"Use {highlight}--format json{/highlight} to integrate zmo into your scripts",
|
||||||
"Run {highlight}opencode github install{/highlight} to set up the GitHub workflow",
|
"Use {highlight}zmo run --continue{/highlight} to continue the last session non-interactively",
|
||||||
"Comment {highlight}/opencode fix this{/highlight} on issues to auto-create PRs",
|
|
||||||
"Comment {highlight}/oc{/highlight} on PR code lines for targeted code reviews",
|
"Comment {highlight}/oc{/highlight} on PR code lines for targeted code reviews",
|
||||||
'Use {highlight}"theme": "system"{/highlight} to match your terminal\'s colors',
|
'Use {highlight}"theme": "system"{/highlight} to match your terminal\'s colors',
|
||||||
"Create JSON theme files in {highlight}.opencode/themes/{/highlight} directory",
|
"Create JSON theme files in {highlight}.zmo/themes/{/highlight} directory",
|
||||||
"Themes support dark/light variants for both modes",
|
"Themes support dark/light variants for both modes",
|
||||||
"Use numeric xterm color codes 0-255 in custom theme JSON",
|
"Use numeric xterm color codes 0-255 in custom theme JSON",
|
||||||
"Use {highlight}{env:VAR_NAME}{/highlight} syntax to reference environment variables in config",
|
"Use {highlight}{env:VAR_NAME}{/highlight} syntax to reference environment variables in config",
|
||||||
@@ -264,7 +263,7 @@ const TIPS: Tip[] = [
|
|||||||
"Run {highlight}/unshare{/highlight} to remove a session from public access",
|
"Run {highlight}/unshare{/highlight} to remove a session from public access",
|
||||||
"Permission {highlight}doom_loop{/highlight} prevents infinite tool call loops",
|
"Permission {highlight}doom_loop{/highlight} prevents infinite tool call loops",
|
||||||
"Permission {highlight}external_directory{/highlight} protects files outside project",
|
"Permission {highlight}external_directory{/highlight} protects files outside project",
|
||||||
"Run {highlight}opencode debug config{/highlight} to troubleshoot configuration",
|
"Run {highlight}zmo debug config{/highlight} to troubleshoot configuration",
|
||||||
"Use {highlight}--print-logs{/highlight} flag to see detailed logs in stderr",
|
"Use {highlight}--print-logs{/highlight} flag to see detailed logs in stderr",
|
||||||
(shortcuts) => `Use ${commandText("/timeline", shortcuts.sessionTimeline())} to jump to specific messages`,
|
(shortcuts) => `Use ${commandText("/timeline", shortcuts.sessionTimeline())} to jump to specific messages`,
|
||||||
(shortcuts) => press(shortcuts.messagesToggleConceal(), "to toggle code block visibility in messages"),
|
(shortcuts) => press(shortcuts.messagesToggleConceal(), "to toggle code block visibility in messages"),
|
||||||
@@ -274,8 +273,8 @@ const TIPS: Tip[] = [
|
|||||||
shortcuts.commandList()
|
shortcuts.commandList()
|
||||||
? `Toggle username display in chat via the command palette (${shortcutText(shortcuts.commandList())})`
|
? `Toggle username display in chat via the command palette (${shortcutText(shortcuts.commandList())})`
|
||||||
: "Toggle username display in chat via the command palette",
|
: "Toggle username display in chat via the command palette",
|
||||||
"Run {highlight}docker run -it --rm ghcr.io/anomalyco/opencode{/highlight} for containerized use",
|
"Switch between models mid-session to use the best tool for each task",
|
||||||
"Use {highlight}/connect{/highlight} with OpenCode Zen for curated, tested models",
|
"Configure any OpenAI-compatible provider via {highlight}baseURL{/highlight} in your config",
|
||||||
"Commit your project's {highlight}AGENTS.md{/highlight} file to Git for team sharing",
|
"Commit your project's {highlight}AGENTS.md{/highlight} file to Git for team sharing",
|
||||||
"Use {highlight}/review{/highlight} to review uncommitted changes, branches, or PRs",
|
"Use {highlight}/review{/highlight} to review uncommitted changes, branches, or PRs",
|
||||||
(shortcuts) => `Use ${commandText("/help", shortcuts.helpShow())} to show the help dialog`,
|
(shortcuts) => `Use ${commandText("/help", shortcuts.helpShow())} to show the help dialog`,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const UpgradeCommand = {
|
|||||||
const detectedMethod = await Installation.method()
|
const detectedMethod = await Installation.method()
|
||||||
const method = (args.method as Installation.Method) ?? detectedMethod
|
const method = (args.method as Installation.Method) ?? detectedMethod
|
||||||
if (method === "unknown") {
|
if (method === "unknown") {
|
||||||
prompts.log.error(`opencode is installed to ${process.execPath} and may be managed by a package manager`)
|
prompts.log.error(`zmo is installed to ${process.execPath} and may be managed by a package manager`)
|
||||||
const install = await prompts.select({
|
const install = await prompts.select({
|
||||||
message: "Install anyways?",
|
message: "Install anyways?",
|
||||||
options: [
|
options: [
|
||||||
|
|||||||
@@ -221,8 +221,8 @@ export const layer = Layer.effect(
|
|||||||
|
|
||||||
yield* Effect.promise(() => resolveLoadedPlugins(data, options.path))
|
yield* Effect.promise(() => resolveLoadedPlugins(data, options.path))
|
||||||
if (!data.$schema) {
|
if (!data.$schema) {
|
||||||
data.$schema = "https://opencode.ai/config.json"
|
data.$schema = "https://zmo.dev/config.json"
|
||||||
const updated = text.replace(/^\s*\{/, '{\n "$schema": "https://opencode.ai/config.json",')
|
const updated = text.replace(/^\s*\{/, '{\n "$schema": "https://zmo.dev/config.json",')
|
||||||
yield* fs.writeFileString(options.path, updated).pipe(Effect.catch(() => Effect.void))
|
yield* fs.writeFileString(options.path, updated).pipe(Effect.catch(() => Effect.void))
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
@@ -243,7 +243,7 @@ export const layer = Layer.effect(
|
|||||||
const file = globalConfigFile()
|
const file = globalConfigFile()
|
||||||
if (!existsSync(file)) {
|
if (!existsSync(file)) {
|
||||||
yield* fs
|
yield* fs
|
||||||
.writeWithDirs(file, JSON.stringify({ $schema: "https://opencode.ai/config.json" }, null, 2))
|
.writeWithDirs(file, JSON.stringify({ $schema: "https://zmo.dev/config.json" }, null, 2))
|
||||||
.pipe(Effect.catch(() => Effect.void))
|
.pipe(Effect.catch(() => Effect.void))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,7 +258,7 @@ export const layer = Layer.effect(
|
|||||||
.then(async (mod) => {
|
.then(async (mod) => {
|
||||||
const { provider, model, ...rest } = mod.default
|
const { provider, model, ...rest } = mod.default
|
||||||
if (provider && model) result.model = `${provider}/${model}`
|
if (provider && model) result.model = `${provider}/${model}`
|
||||||
result["$schema"] = "https://opencode.ai/config.json"
|
result["$schema"] = "https://zmo.dev/config.json"
|
||||||
result = mergeConfig(result, rest)
|
result = mergeConfig(result, rest)
|
||||||
await fsNode.writeFile(path.join(Global.Path.config, "config.json"), JSON.stringify(result, null, 2))
|
await fsNode.writeFile(path.join(Global.Path.config, "config.json"), JSON.stringify(result, null, 2))
|
||||||
await fsNode.unlink(legacy)
|
await fsNode.unlink(legacy)
|
||||||
@@ -371,7 +371,7 @@ export const layer = Layer.effect(
|
|||||||
})
|
})
|
||||||
: {}
|
: {}
|
||||||
const remoteConfig = mergeConfig(isRecord(wellknown.config) ? wellknown.config : {}, fetchedConfig)
|
const remoteConfig = mergeConfig(isRecord(wellknown.config) ? wellknown.config : {}, fetchedConfig)
|
||||||
if (!remoteConfig.$schema) remoteConfig.$schema = "https://opencode.ai/config.json"
|
if (!remoteConfig.$schema) remoteConfig.$schema = "https://zmo.dev/config.json"
|
||||||
const source = wellknownURL
|
const source = wellknownURL
|
||||||
const next = yield* loadConfig(
|
const next = yield* loadConfig(
|
||||||
JSON.stringify(remoteConfig),
|
JSON.stringify(remoteConfig),
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ function buildAuthorizeUrl(redirectUri: string, pkce: PkceCodes, state: string):
|
|||||||
id_token_add_organizations: "true",
|
id_token_add_organizations: "true",
|
||||||
codex_cli_simplified_flow: "true",
|
codex_cli_simplified_flow: "true",
|
||||||
state,
|
state,
|
||||||
originator: "opencode",
|
originator: "zmo",
|
||||||
})
|
})
|
||||||
return `${ISSUER}/oauth/authorize?${params.toString()}`
|
return `${ISSUER}/oauth/authorize?${params.toString()}`
|
||||||
}
|
}
|
||||||
@@ -547,7 +547,7 @@ export async function CodexAuthPlugin(input: PluginInput, options: CodexAuthPlug
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": `opencode/${InstallationVersion}`,
|
"User-Agent": `zmo/${InstallationVersion}`,
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ client_id: CLIENT_ID }),
|
body: JSON.stringify({ client_id: CLIENT_ID }),
|
||||||
})
|
})
|
||||||
@@ -571,7 +571,7 @@ export async function CodexAuthPlugin(input: PluginInput, options: CodexAuthPlug
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": `opencode/${InstallationVersion}`,
|
"User-Agent": `zmo/${InstallationVersion}`,
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
device_auth_id: deviceData.device_auth_id,
|
device_auth_id: deviceData.device_auth_id,
|
||||||
@@ -630,8 +630,8 @@ export async function CodexAuthPlugin(input: PluginInput, options: CodexAuthPlug
|
|||||||
},
|
},
|
||||||
"chat.headers": async (input, output) => {
|
"chat.headers": async (input, output) => {
|
||||||
if (input.model.providerID !== "openai") return
|
if (input.model.providerID !== "openai") return
|
||||||
output.headers.originator = "opencode"
|
output.headers.originator = "zmo"
|
||||||
output.headers["User-Agent"] = `opencode/${InstallationVersion} (${os.platform()} ${os.release()}; ${os.arch()})`
|
output.headers["User-Agent"] = `zmo/${InstallationVersion} (${os.platform()} ${os.release()}; ${os.arch()})`
|
||||||
output.headers["session-id"] = input.sessionID
|
output.headers["session-id"] = input.sessionID
|
||||||
// Temporary fetch-layer hack: title generation currently shares the conversation
|
// Temporary fetch-layer hack: title generation currently shares the conversation
|
||||||
// session ID, so the OpenAI plugin marks it for HTTP fallback until transport
|
// session ID, so the OpenAI plugin marks it for HTTP fallback until transport
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ function authHeaders() {
|
|||||||
return {
|
return {
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
"User-Agent": `opencode/${InstallationVersion}`,
|
"User-Agent": `zmo/${InstallationVersion}`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ export function buildAuthorizeUrl(
|
|||||||
state,
|
state,
|
||||||
nonce,
|
nonce,
|
||||||
plan: "generic",
|
plan: "generic",
|
||||||
referrer: "opencode",
|
referrer: "zmo",
|
||||||
})
|
})
|
||||||
return `${options.authorizeUrl ?? AUTHORIZE_URL}?${params.toString()}`
|
return `${options.authorizeUrl ?? AUTHORIZE_URL}?${params.toString()}`
|
||||||
}
|
}
|
||||||
@@ -655,7 +655,7 @@ export async function XaiAuthPlugin(input: PluginInput, options: XaiAuthPluginOp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
headers.set("authorization", `Bearer ${currentAuth.access}`)
|
headers.set("authorization", `Bearer ${currentAuth.access}`)
|
||||||
headers.set("User-Agent", `opencode/${InstallationVersion}`)
|
headers.set("User-Agent", `zmo/${InstallationVersion}`)
|
||||||
|
|
||||||
return fetch(requestInput, { ...init, headers })
|
return fetch(requestInput, { ...init, headers })
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -435,9 +435,9 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
autoload: false,
|
autoload: false,
|
||||||
options: {
|
options: {
|
||||||
headers: {
|
headers: {
|
||||||
"HTTP-Referer": "https://opencode.ai/",
|
"HTTP-Referer": "https://github.com/helpLogin/zmo-cli",
|
||||||
"X-Title": "opencode",
|
"X-Title": "zmo",
|
||||||
"X-Source": "opencode",
|
"X-Source": "zmo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@@ -446,8 +446,8 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
autoload: false,
|
autoload: false,
|
||||||
options: {
|
options: {
|
||||||
headers: {
|
headers: {
|
||||||
"HTTP-Referer": "https://opencode.ai/",
|
"HTTP-Referer": "https://github.com/helpLogin/zmo-cli",
|
||||||
"X-Title": "opencode",
|
"X-Title": "zmo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@@ -456,9 +456,9 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
autoload: provider.source === "config",
|
autoload: provider.source === "config",
|
||||||
options: {
|
options: {
|
||||||
headers: {
|
headers: {
|
||||||
"HTTP-Referer": "https://opencode.ai/",
|
"HTTP-Referer": "https://github.com/helpLogin/zmo-cli",
|
||||||
"X-Title": "opencode",
|
"X-Title": "zmo",
|
||||||
"X-BILLING-INVOKE-ORIGIN": "OpenCode",
|
"X-BILLING-INVOKE-ORIGIN": "zmo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@@ -467,8 +467,8 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
autoload: false,
|
autoload: false,
|
||||||
options: {
|
options: {
|
||||||
headers: {
|
headers: {
|
||||||
"http-referer": "https://opencode.ai/",
|
"http-referer": "https://github.com/helpLogin/zmo-cli",
|
||||||
"x-title": "opencode",
|
"x-title": "zmo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@@ -573,8 +573,8 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
autoload: false,
|
autoload: false,
|
||||||
options: {
|
options: {
|
||||||
headers: {
|
headers: {
|
||||||
"HTTP-Referer": "https://opencode.ai/",
|
"HTTP-Referer": "https://github.com/helpLogin/zmo-cli",
|
||||||
"X-Title": "opencode",
|
"X-Title": "zmo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@@ -595,7 +595,7 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
const directory = yield* InstanceState.directory
|
const directory = yield* InstanceState.directory
|
||||||
|
|
||||||
const aiGatewayHeaders = {
|
const aiGatewayHeaders = {
|
||||||
"User-Agent": `opencode/${InstallationVersion} gitlab-ai-provider/${GITLAB_PROVIDER_VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
|
"User-Agent": `zmo/${InstallationVersion} gitlab-ai-provider/${GITLAB_PROVIDER_VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`,
|
||||||
"anthropic-beta": "context-1m-2025-08-07",
|
"anthropic-beta": "context-1m-2025-08-07",
|
||||||
...providerConfig?.options?.aiGatewayHeaders,
|
...providerConfig?.options?.aiGatewayHeaders,
|
||||||
}
|
}
|
||||||
@@ -743,7 +743,7 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
options: {
|
options: {
|
||||||
apiKey,
|
apiKey,
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": `opencode/${InstallationVersion} cloudflare-workers-ai (${os.platform()} ${os.release()}; ${os.arch()})`,
|
"User-Agent": `zmo/${InstallationVersion} cloudflare-workers-ai (${os.platform()} ${os.release()}; ${os.arch()})`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async getModel(sdk: any, modelID: string) {
|
async getModel(sdk: any, modelID: string) {
|
||||||
@@ -788,7 +788,7 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
if (!apiToken) {
|
if (!apiToken) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"CLOUDFLARE_API_TOKEN (or CF_AIG_TOKEN) is required for Cloudflare AI Gateway. " +
|
"CLOUDFLARE_API_TOKEN (or CF_AIG_TOKEN) is required for Cloudflare AI Gateway. " +
|
||||||
"Set it via environment variable or run `opencode auth cloudflare-ai-gateway`.",
|
"Set it via environment variable or run `zmo auth cloudflare-ai-gateway`.",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -811,7 +811,7 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
skipCache: input.options?.skipCache,
|
skipCache: input.options?.skipCache,
|
||||||
collectLog: input.options?.collectLog,
|
collectLog: input.options?.collectLog,
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": `opencode/${InstallationVersion} cloudflare-ai-gateway (${os.platform()} ${os.release()}; ${os.arch()})`,
|
"User-Agent": `zmo/${InstallationVersion} cloudflare-ai-gateway (${os.platform()} ${os.release()}; ${os.arch()})`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -837,7 +837,7 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
autoload: false,
|
autoload: false,
|
||||||
options: {
|
options: {
|
||||||
headers: {
|
headers: {
|
||||||
"X-Cerebras-3rd-Party-Integration": "opencode",
|
"X-Cerebras-3rd-Party-Integration": "zmo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@@ -846,8 +846,8 @@ function custom(dep: CustomDep): Record<string, CustomLoader> {
|
|||||||
autoload: false,
|
autoload: false,
|
||||||
options: {
|
options: {
|
||||||
headers: {
|
headers: {
|
||||||
"HTTP-Referer": "https://opencode.ai/",
|
"HTTP-Referer": "https://github.com/helpLogin/zmo-cli",
|
||||||
"X-Title": "opencode",
|
"X-Title": "zmo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export const layer = Layer.effect(
|
|||||||
const ctx = yield* InstanceState.context
|
const ctx = yield* InstanceState.context
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
`You are powered by the model named ${model.api.id}. The exact model ID is ${model.providerID}/${model.api.id}`,
|
`You are zmo, an AI coding assistant running in the terminal.`,
|
||||||
`Here is some useful information about the environment you are running in:`,
|
`Here is some useful information about the environment you are running in:`,
|
||||||
`<env>`,
|
`<env>`,
|
||||||
` Working directory: ${ctx.directory}`,
|
` Working directory: ${ctx.directory}`,
|
||||||
|
|||||||
Reference in New Issue
Block a user