mirror of
https://github.com/anomalyco/opencode.git
synced 2026-04-24 06:45:22 +00:00
cleanup
This commit is contained in:
@@ -43,7 +43,7 @@ function UiI18nBridge(props: ParentProps) {
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__OPENCODE__?: { updaterEnabled?: boolean; serverPassword?: string; deepLinks?: string[] }
|
||||
__OPENCODE__?: { updaterEnabled?: boolean; serverPassword?: string; deepLinks?: string[]; wsl?: boolean }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -367,10 +367,10 @@ export const SettingsGeneral: Component = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Show when={platform.platform === "desktop" && platform.os === "windows" && platform.getWslConfig}>
|
||||
<Show when={platform.platform === "desktop" && platform.os === "windows" && platform.getWslEnabled}>
|
||||
{(_) => {
|
||||
const [valueResource, actions] = createResource(() => platform.getWslConfig?.())
|
||||
const value = () => (valueResource.state === "pending" ? undefined : valueResource.latest)
|
||||
const [enabledResource, actions] = createResource(() => platform.getWslEnabled?.())
|
||||
const enabled = () => (enabledResource.state === "pending" ? undefined : enabledResource.latest)
|
||||
|
||||
return (
|
||||
<div class="flex flex-col gap-1">
|
||||
@@ -383,11 +383,9 @@ export const SettingsGeneral: Component = () => {
|
||||
>
|
||||
<div data-action="settings-wsl">
|
||||
<Switch
|
||||
checked={value()?.enabled ?? false}
|
||||
disabled={valueResource.state === "pending"}
|
||||
onChange={(checked) =>
|
||||
platform.setWslConfig?.({ enabled: checked })?.finally(() => actions.refetch())
|
||||
}
|
||||
checked={enabled() ?? false}
|
||||
disabled={enabledResource.state === "pending"}
|
||||
onChange={(checked) => platform.setWslEnabled?.(checked)?.finally(() => actions.refetch())}
|
||||
/>
|
||||
</div>
|
||||
</SettingsRow>
|
||||
|
||||
@@ -61,10 +61,10 @@ export type Platform = {
|
||||
setDefaultServerUrl?(url: string | null): Promise<void> | void
|
||||
|
||||
/** Get the configured WSL integration (desktop only) */
|
||||
getWslConfig?(): Promise<{ enabled: boolean } | null> | { enabled: boolean } | null
|
||||
getWslEnabled?(): Promise<boolean>
|
||||
|
||||
/** Set the configured WSL integration (desktop only) */
|
||||
setWslConfig?(config: { enabled: boolean }): Promise<void> | void
|
||||
setWslEnabled?(config: boolean): Promise<void> | void
|
||||
|
||||
/** Get the preferred display backend (desktop only) */
|
||||
getDisplayBackend?(): Promise<DisplayBackend | null> | DisplayBackend | null
|
||||
|
||||
@@ -46,8 +46,7 @@ export default function Home() {
|
||||
}
|
||||
}
|
||||
|
||||
const wslEnabled = platform.wslEnabled?.() === true
|
||||
if (platform.openDirectoryPickerDialog && server.isLocal() && !wslEnabled) {
|
||||
if (platform.openDirectoryPickerDialog && server.isLocal() && !(await platform.getWslEnabled?.())) {
|
||||
const result = await platform.openDirectoryPickerDialog?.({
|
||||
title: language.t("command.project.open"),
|
||||
multiple: true,
|
||||
|
||||
@@ -1182,8 +1182,7 @@ export default function Layout(props: ParentProps) {
|
||||
}
|
||||
}
|
||||
|
||||
const wslEnabled = platform.wslEnabled?.() === true
|
||||
if (platform.openDirectoryPickerDialog && server.isLocal() && !wslEnabled) {
|
||||
if (platform.openDirectoryPickerDialog && server.isLocal() && !(await platform.getWslEnabled?.())) {
|
||||
const result = await platform.openDirectoryPickerDialog?.({
|
||||
title: language.t("command.project.open"),
|
||||
multiple: true,
|
||||
|
||||
@@ -204,57 +204,55 @@ pub fn create_command(app: &tauri::AppHandle, args: &str, extra_env: &[(&str, St
|
||||
.map(|(key, value)| (key.to_string(), value.clone())),
|
||||
);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
if is_wsl_enabled(app) {
|
||||
let version = app.package_info().version.to_string();
|
||||
let mut script = vec![
|
||||
"set -e".to_string(),
|
||||
"BIN=\"$HOME/.opencode/bin/opencode\"".to_string(),
|
||||
"if [ ! -x \"$BIN\" ]; then".to_string(),
|
||||
format!(
|
||||
" curl -fsSL https://opencode.ai/install | bash -s -- --version {} --no-modify-path",
|
||||
shell_escape(&version)
|
||||
),
|
||||
"fi".to_string(),
|
||||
];
|
||||
if cfg!(windows) {
|
||||
if is_wsl_enabled(app) {
|
||||
let version = app.package_info().version.to_string();
|
||||
let mut script = vec![
|
||||
"set -e".to_string(),
|
||||
"BIN=\"$HOME/.opencode/bin/opencode\"".to_string(),
|
||||
"if [ ! -x \"$BIN\" ]; then".to_string(),
|
||||
format!(
|
||||
" curl -fsSL https://opencode.ai/install | bash -s -- --version {} --no-modify-path",
|
||||
shell_escape(&version)
|
||||
),
|
||||
"fi".to_string(),
|
||||
];
|
||||
|
||||
let mut env_prefix = vec![
|
||||
"OPENCODE_EXPERIMENTAL_ICON_DISCOVERY=true".to_string(),
|
||||
"OPENCODE_EXPERIMENTAL_FILEWATCHER=true".to_string(),
|
||||
"OPENCODE_CLIENT=desktop".to_string(),
|
||||
"XDG_STATE_HOME=\"$HOME/.local/state\"".to_string(),
|
||||
];
|
||||
env_prefix.extend(
|
||||
envs.iter()
|
||||
.filter(|(key, _)| key != "OPENCODE_EXPERIMENTAL_ICON_DISCOVERY")
|
||||
.filter(|(key, _)| key != "OPENCODE_EXPERIMENTAL_FILEWATCHER")
|
||||
.filter(|(key, _)| key != "OPENCODE_CLIENT")
|
||||
.filter(|(key, _)| key != "XDG_STATE_HOME")
|
||||
.map(|(key, value)| format!("{}={}", key, shell_escape(value))),
|
||||
);
|
||||
let mut env_prefix = vec![
|
||||
"OPENCODE_EXPERIMENTAL_ICON_DISCOVERY=true".to_string(),
|
||||
"OPENCODE_EXPERIMENTAL_FILEWATCHER=true".to_string(),
|
||||
"OPENCODE_CLIENT=desktop".to_string(),
|
||||
"XDG_STATE_HOME=\"$HOME/.local/state\"".to_string(),
|
||||
];
|
||||
env_prefix.extend(
|
||||
envs.iter()
|
||||
.filter(|(key, _)| key != "OPENCODE_EXPERIMENTAL_ICON_DISCOVERY")
|
||||
.filter(|(key, _)| key != "OPENCODE_EXPERIMENTAL_FILEWATCHER")
|
||||
.filter(|(key, _)| key != "OPENCODE_CLIENT")
|
||||
.filter(|(key, _)| key != "XDG_STATE_HOME")
|
||||
.map(|(key, value)| format!("{}={}", key, shell_escape(value))),
|
||||
);
|
||||
|
||||
script.push(format!("{} exec \"$BIN\" {}", env_prefix.join(" "), args));
|
||||
script.push(format!("{} exec \"$BIN\" {}", env_prefix.join(" "), args));
|
||||
|
||||
return app
|
||||
.shell()
|
||||
.command("wsl")
|
||||
.args(["-e", "bash", "-lc", &script.join("\n")]);
|
||||
}
|
||||
return app
|
||||
.shell()
|
||||
.command("wsl")
|
||||
.args(["-e", "bash", "-lc", &script.join("\n")]);
|
||||
} else {
|
||||
let mut cmd = app
|
||||
.shell()
|
||||
.sidecar("opencode-cli")
|
||||
.unwrap()
|
||||
.args(args.split_whitespace());
|
||||
|
||||
let mut cmd = app
|
||||
.shell()
|
||||
.sidecar("opencode-cli")
|
||||
.unwrap()
|
||||
.args(args.split_whitespace());
|
||||
for (key, value) in envs {
|
||||
cmd = cmd.env(key, value);
|
||||
}
|
||||
|
||||
for (key, value) in envs {
|
||||
cmd = cmd.env(key, value);
|
||||
}
|
||||
|
||||
return cmd;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
return {
|
||||
return cmd;
|
||||
}
|
||||
} else {
|
||||
let sidecar = get_sidecar_path(app);
|
||||
let shell = get_user_shell();
|
||||
|
||||
@@ -271,7 +269,7 @@ pub fn create_command(app: &tauri::AppHandle, args: &str, extra_env: &[(&str, St
|
||||
}
|
||||
|
||||
cmd
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn serve(app: &AppHandle, hostname: &str, port: u32, password: &str) -> CommandChild {
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use crate::constants::{UPDATER_ENABLED, window_state_flags};
|
||||
use crate::{
|
||||
constants::{UPDATER_ENABLED, window_state_flags},
|
||||
server::get_wsl_config,
|
||||
};
|
||||
use std::{ops::Deref, time::Duration};
|
||||
use tauri::{AppHandle, Manager, Runtime, WebviewUrl, WebviewWindow, WebviewWindowBuilder};
|
||||
use tauri_plugin_window_state::AppHandleExt;
|
||||
@@ -22,6 +25,11 @@ impl MainWindow {
|
||||
return Ok(Self(window));
|
||||
}
|
||||
|
||||
let wsl_enabled = get_wsl_config(app.clone())
|
||||
.ok()
|
||||
.map(|v| v.enabled)
|
||||
.unwrap_or(false);
|
||||
|
||||
let window_builder = base_window_config(
|
||||
WebviewWindowBuilder::new(app, Self::LABEL, WebviewUrl::App("/".into())),
|
||||
app,
|
||||
@@ -36,6 +44,7 @@ impl MainWindow {
|
||||
r#"
|
||||
window.__OPENCODE__ ??= {{}};
|
||||
window.__OPENCODE__.updaterEnabled = {UPDATER_ENABLED};
|
||||
window.__OPENCODE__.wsl = {wsl_enabled};
|
||||
"#
|
||||
));
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ export const commands = {
|
||||
setDefaultServerUrl: (url: string | null) => __TAURI_INVOKE<null>("set_default_server_url", { url }),
|
||||
getWslConfig: () => __TAURI_INVOKE<WslConfig>("get_wsl_config"),
|
||||
setWslConfig: (config: WslConfig) => __TAURI_INVOKE<null>("set_wsl_config", { config }),
|
||||
getDisplayBackend: () => __TAURI_INVOKE<DisplayBackend | null>("get_display_backend"),
|
||||
setDisplayBackend: (backend: DisplayBackend) => __TAURI_INVOKE<null>("set_display_backend", { backend }),
|
||||
getDisplayBackend: () => __TAURI_INVOKE<"wayland" | "auto" | null>("get_display_backend"),
|
||||
setDisplayBackend: (backend: LinuxDisplayBackend) => __TAURI_INVOKE<null>("set_display_backend", { backend }),
|
||||
parseMarkdownCommand: (markdown: string) => __TAURI_INVOKE<string>("parse_markdown_command", { markdown }),
|
||||
checkAppExists: (appName: string) => __TAURI_INVOKE<boolean>("check_app_exists", { appName }),
|
||||
wslPath: (path: string, mode: "windows" | "linux" | null) => __TAURI_INVOKE<string>("wsl_path", { path, mode }),
|
||||
@@ -25,14 +25,10 @@ export const events = {
|
||||
};
|
||||
|
||||
/* Types */
|
||||
export type WslConfig = {
|
||||
enabled: boolean,
|
||||
};
|
||||
|
||||
export type DisplayBackend = "wayland" | "auto";
|
||||
|
||||
export type InitStep = { phase: "server_waiting" } | { phase: "sqlite_waiting" } | { phase: "done" };
|
||||
|
||||
export type LinuxDisplayBackend = "wayland" | "auto";
|
||||
|
||||
export type LoadingWindowComplete = null;
|
||||
|
||||
export type ServerReadyData = {
|
||||
@@ -40,6 +36,10 @@ export type ServerReadyData = {
|
||||
password: string | null,
|
||||
};
|
||||
|
||||
export type WslConfig = {
|
||||
enabled: boolean,
|
||||
};
|
||||
|
||||
export type WslPathMode = "windows" | "linux";
|
||||
|
||||
/* Tauri Specta runtime */
|
||||
@@ -58,3 +58,4 @@ function makeEvent<T>(name: string) {
|
||||
|
||||
return Object.assign(fn, base);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,13 +58,10 @@ const listenForDeepLinks = async () => {
|
||||
await onOpenUrl((urls) => emitDeepLinks(urls)).catch(() => undefined)
|
||||
}
|
||||
|
||||
const defaultWsl: WslConfig = { enabled: false }
|
||||
|
||||
const createPlatform = (
|
||||
password: Accessor<string | null>,
|
||||
wsl: Accessor<WslConfig>,
|
||||
wsl: Accessor<boolean>,
|
||||
setWsl: (next: WslConfig) => void,
|
||||
fetchWsl: () => Promise<WslConfig | null>,
|
||||
): Platform => {
|
||||
const os = (() => {
|
||||
const type = ostype()
|
||||
@@ -78,7 +75,6 @@ const createPlatform = (
|
||||
version: pkg.version,
|
||||
|
||||
async openDirectoryPickerDialog(opts) {
|
||||
if (wsl().enabled) return null
|
||||
const result = await open({
|
||||
directory: true,
|
||||
multiple: opts?.multiple ?? false,
|
||||
@@ -109,7 +105,7 @@ const createPlatform = (
|
||||
},
|
||||
|
||||
async openPath(path: string, app?: string) {
|
||||
if (wsl().enabled && os === "windows") {
|
||||
if (wsl() && os === "windows") {
|
||||
const converted = await commands.wslPath(path, "windows").catch(() => null)
|
||||
return openerOpenPath(converted && converted.length > 0 ? converted : path, app)
|
||||
}
|
||||
@@ -331,18 +327,37 @@ const createPlatform = (
|
||||
.catch(() => undefined)
|
||||
},
|
||||
|
||||
getWslConfig: async () => {
|
||||
const next = await fetchWsl()
|
||||
if (next) return next
|
||||
fetch: (input, init) => {
|
||||
const pw = password()
|
||||
|
||||
const addHeader = (headers: Headers, password: string) => {
|
||||
headers.append("Authorization", `Basic ${btoa(`opencode:${password}`)}`)
|
||||
}
|
||||
|
||||
if (input instanceof Request) {
|
||||
if (pw) addHeader(input.headers, pw)
|
||||
return tauriFetch(input)
|
||||
} else {
|
||||
const headers = new Headers(init?.headers)
|
||||
if (pw) addHeader(headers, pw)
|
||||
return tauriFetch(input, {
|
||||
...(init as any),
|
||||
headers: headers,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
getWslEnabled: async () => {
|
||||
const next = await commands.getWslConfig().catch(() => null)
|
||||
if (next) return next.enabled
|
||||
return wsl()
|
||||
},
|
||||
|
||||
setWslConfig: async (config: WslConfig) => {
|
||||
setWsl(config)
|
||||
await commands.setWslConfig(config).catch(() => undefined)
|
||||
setWslEnabled: async (enabled) => {
|
||||
await commands.setWslConfig({ enabled })
|
||||
},
|
||||
|
||||
wslEnabled: () => wsl().enabled,
|
||||
wslEnabled: () => wsl(),
|
||||
|
||||
getDefaultServerUrl: async () => {
|
||||
const result = await commands.getDefaultServerUrl().catch(() => null)
|
||||
@@ -359,7 +374,7 @@ const createPlatform = (
|
||||
},
|
||||
|
||||
setDisplayBackend: async (backend) => {
|
||||
await commands.setDisplayBackend(backend).catch(() => undefined)
|
||||
await commands.setDisplayBackend(backend)
|
||||
},
|
||||
|
||||
parseMarkdown: (markdown: string) => commands.parseMarkdownCommand(markdown),
|
||||
@@ -403,16 +418,9 @@ void listenForDeepLinks()
|
||||
|
||||
render(() => {
|
||||
const [serverPassword, setServerPassword] = createSignal<string | null>(null)
|
||||
const [wsl, setWsl] = createSignal<WslConfig>(defaultWsl)
|
||||
const [wsl, setWsl] = createSignal(window.__OPENCODE__?.wsl ?? false)
|
||||
|
||||
const fetchWsl = async () => {
|
||||
const next = await commands.getWslConfig().catch(() => null)
|
||||
if (!next) return null
|
||||
setWsl(next)
|
||||
return next
|
||||
}
|
||||
|
||||
const platform = createPlatform(() => serverPassword(), wsl, setWsl, fetchWsl)
|
||||
const platform = createPlatform(() => serverPassword(), wsl, setWsl)
|
||||
|
||||
function handleClick(e: MouseEvent) {
|
||||
const link = (e.target as HTMLElement).closest("a.external-link") as HTMLAnchorElement | null
|
||||
@@ -424,7 +432,6 @@ render(() => {
|
||||
|
||||
onMount(() => {
|
||||
document.addEventListener("click", handleClick)
|
||||
void fetchWsl()
|
||||
onCleanup(() => {
|
||||
document.removeEventListener("click", handleClick)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user