Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,765 changes: 0 additions & 1,765 deletions openless-all/app/src/lib/ipc.ts

This file was deleted.

66 changes: 66 additions & 0 deletions openless-all/app/src/lib/ipc/asr-credentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import type { CredentialsStatus } from "../types"
import { invokeOrMock } from "./shared"
import { mockCredentialsStatus } from "./mock-data"

export interface ProviderCheckResult {
ok: boolean
}

export interface ProviderModelsResult {
models: string[]
}

export function getCredentials(): Promise<CredentialsStatus> {
return invokeOrMock(
"get_credentials",
undefined,
() => mockCredentialsStatus,
)
}

export function setCredential(account: string, value: string): Promise<void> {
return invokeOrMock("set_credential", { account, value }, () => undefined)
}

export function setActiveAsrProvider(provider: string): Promise<void> {
return invokeOrMock(
"set_active_asr_provider",
{ provider },
() => undefined,
)
}

export function setActiveLlmProvider(provider: string): Promise<void> {
return invokeOrMock(
"set_active_llm_provider",
{ provider },
() => undefined,
)
}

export function readCredential(account: string): Promise<string | null> {
return invokeOrMock<string | null>(
"read_credential",
{ account },
() => null,
)
}

export function validateProviderCredentials(
kind: "llm" | "asr",
): Promise<ProviderCheckResult> {
return invokeOrMock("validate_provider_credentials", { kind }, () => ({
ok: true,
}))
}

export function listProviderModels(
kind: "llm" | "asr",
): Promise<ProviderModelsResult> {
return invokeOrMock("list_provider_models", { kind }, () => ({
models:
kind === "llm"
? ["gpt-4o", "deepseek-v4-flash", "deepseek-v4-pro"]
: ["whisper-1"],
}))
}
69 changes: 69 additions & 0 deletions openless-all/app/src/lib/ipc/coding-agent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import type { CodingAgentPermissionMode } from "../types"
export type { CodingAgentPermissionMode }
import { invokeOrMock } from "./shared"

export type McpHealth = "connected" | "failed" | "needs_auth" | "unknown"

export interface McpServerStatus {
name: string
detail: string
health: McpHealth
}

export interface ClaudeDetection {
installed: boolean
version: string | null
exe: string
mcpServers: McpServerStatus[]
hasComputerUse: boolean
}

/** 无头 Claude 运行事件,由后端 `coding-agent:test` 流式推送(tag 为 `kind`)。 */
export type CodingAgentEvent =
| { kind: "started"; session_id: string }
| { kind: "delta"; session_id: string; text: string }
| { kind: "tool_use"; session_id: string; name: string }
| {
kind: "completed"
session_id: string
text: string
cost_usd: number | null
duration_ms: number | null
}
| { kind: "cancelled"; session_id: string }
| { kind: "error"; session_id: string; message: string }

export function codingAgentDetect(exe?: string): Promise<ClaudeDetection> {
return invokeOrMock(
"coding_agent_detect",
{ exe },
() => ({
installed: false,
version: null,
exe: exe || "claude",
mcpServers: [],
hasComputerUse: false,
}),
)
}

export interface CodingAgentRunTestArgs {
prompt: string
exe?: string
permissionMode?: CodingAgentPermissionMode
workdir?: string
model?: string
maxBudgetUsd?: number
}

export function codingAgentRunTest(args: CodingAgentRunTestArgs): Promise<void> {
return invokeOrMock("coding_agent_run_test", { ...args }, () => undefined)
}

export function codingAgentCancelTest(): Promise<void> {
return invokeOrMock("coding_agent_cancel_test", undefined, () => undefined)
}

export function codingAgentCommandRisk(command: string): Promise<string | null> {
return invokeOrMock("coding_agent_command_risk", { command }, () => null)
}
43 changes: 43 additions & 0 deletions openless-all/app/src/lib/ipc/devices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { MicrophoneDevice } from "../types"
import { invokeOrMock } from "./shared"
import { mockMicrophoneDevices } from "./mock-data"

export interface NetworkCheckResult {
online: boolean
latencyMs: number | null
}

export function checkNetwork(): Promise<NetworkCheckResult> {
return invokeOrMock<NetworkCheckResult>("check_network", undefined, () => ({
online: true,
latencyMs: 42,
}))
}

export function listMicrophoneDevices(): Promise<MicrophoneDevice[]> {
return invokeOrMock(
"list_microphone_devices",
undefined,
() => mockMicrophoneDevices,
)
}

export function startMicrophoneLevelMonitor(deviceName: string): Promise<void> {
return invokeOrMock(
"start_microphone_level_monitor",
{ deviceName },
() => undefined,
)
}

export function stopMicrophoneLevelMonitor(): Promise<void> {
return invokeOrMock(
"stop_microphone_level_monitor",
undefined,
() => undefined,
)
}

export function isWaylandCliMode(): Promise<boolean> {
return invokeOrMock("is_wayland_cli_mode", undefined, () => false)
}
31 changes: 31 additions & 0 deletions openless-all/app/src/lib/ipc/dictation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { invokeOrMock, platformCapabilities } from "./shared"

export function startDictation(): Promise<void> {
return invokeOrMock("start_dictation", undefined, () => undefined)
}

export function stopDictation(): Promise<void> {
return invokeOrMock("stop_dictation", undefined, () => undefined)
}

export function cancelDictation(): Promise<void> {
return invokeOrMock("cancel_dictation", undefined, () => undefined)
}

export function handleWindowHotkeyEvent(
eventType: "keydown" | "keyup",
key: string,
code: string,
repeat: boolean,
): Promise<void> {
return platformCapabilities().then((caps) => {
if (!caps.supportsDesktopHotkey) {
return undefined
}
return invokeOrMock(
"handle_window_hotkey_event",
{ event_type: eventType, key, code, repeat },
() => undefined,
)
})
}
42 changes: 42 additions & 0 deletions openless-all/app/src/lib/ipc/github-oauth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { invokeOrMock } from "./shared"

export interface GithubDeviceStartResponse {
deviceCode: string
userCode: string
verificationUri: string
interval: number
expiresIn: number
}

export type GithubDevicePollResult =
| { kind: "authorized"; login: string }
| { kind: "pending" }
| { kind: "slowDown" }
| { kind: "error"; message: string }

export function githubDeviceFlowStart(): Promise<GithubDeviceStartResponse> {
return invokeOrMock<GithubDeviceStartResponse>(
"github_device_flow_start",
undefined,
() => ({
deviceCode: "mock-device-code-xxxxxxxx",
userCode: "MOCK-CODE",
verificationUri: "https://github.com/login/device",
interval: 5,
expiresIn: 900,
}),
)
}

export function githubDeviceFlowPoll(
deviceCode: string,
): Promise<GithubDevicePollResult> {
return invokeOrMock<GithubDevicePollResult>(
"github_device_flow_poll",
{ deviceCode },
() => ({
kind: "authorized" as const,
login: "mock-user",
}),
)
}
42 changes: 42 additions & 0 deletions openless-all/app/src/lib/ipc/history.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { DictationSession } from "../types"
import { invokeOrMock } from "./shared"
import { mockHistory } from "./mock-data"

export function listHistory(): Promise<DictationSession[]> {
return invokeOrMock("list_history", undefined, () => mockHistory)
}

export function deleteHistoryEntry(id: string): Promise<void> {
return invokeOrMock("delete_history_entry", { id }, () => undefined)
}

export function clearHistory(): Promise<void> {
return invokeOrMock("clear_history", undefined, () => undefined)
}

/** 读取某次会话的原始麦克风 wav 字节流。仅当 prefs.recordAudioForDebug 当时打开
* 并且文件没被 retention 清理掉时才有内容;其他情况后端会返回 "recording not found" 错。
* 调用方应仅在 session.hasAudioRecording === true 时触发,避免无效 IPC。 */
export function readAudioRecording(sessionId: string): Promise<Uint8Array> {
return invokeOrMock(
"read_audio_recording",
{ sessionId },
() => new Uint8Array(),
).then((value) => {
// Tauri 默认把 Vec<u8> 序列化为 number[],前端拿到的是普通数组;统一转 Uint8Array。
if (value instanceof Uint8Array) return value
if (Array.isArray(value)) return new Uint8Array(value as number[])
return new Uint8Array(value as ArrayBuffer)
})
}

/** 用当前 ASR provider 对一条「转录失败」历史条目的归档录音重新转录(issue #613)。
* 成功时后端原地回写该条历史的 rawTranscript / finalText 并清除错误码,返回更新后的整条记录。
* 失败时抛出错误(如「重新转录仍未识别到语音」/「recording not found」),录音保留不丢。 */
export function retranscribeRecording(sessionId: string): Promise<DictationSession> {
return invokeOrMock(
"retranscribe_recording",
{ sessionId },
() => mockHistory[0],
) as Promise<DictationSession>
}
81 changes: 81 additions & 0 deletions openless-all/app/src/lib/ipc/hotkeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { ComboBinding, HotkeyCapability, HotkeyStatus, ShortcutBinding, WindowsImeStatus } from "../types"
import { invokeOrMock, platformCapabilities, androidHotkeyStatus, androidHotkeyCapability, androidWindowsImeStatus } from "./shared"
import { mockHotkeyStatus, mockHotkeyCapability, mockWindowsImeStatus } from "./mock-data"

export function getHotkeyStatus(): Promise<HotkeyStatus> {
return platformCapabilities().then((caps) => {
if (!caps.supportsDesktopHotkey) {
return androidHotkeyStatus
}
return invokeOrMock("get_hotkey_status", undefined, () => mockHotkeyStatus)
})
}

export function getHotkeyCapability(): Promise<HotkeyCapability> {
return platformCapabilities().then((caps) => {
if (!caps.supportsDesktopHotkey) {
return androidHotkeyCapability
}
return invokeOrMock(
"get_hotkey_capability",
undefined,
() => mockHotkeyCapability,
)
})
}

export function getWindowsImeStatus(): Promise<WindowsImeStatus> {
return platformCapabilities().then((caps) => {
if (caps.platform === "android") {
return androidWindowsImeStatus
}
return invokeOrMock(
"get_windows_ime_status",
undefined,
() => mockWindowsImeStatus,
)
})
}

export function validateComboHotkey(binding: ComboBinding): Promise<void> {
return invokeOrMock("validate_combo_hotkey", { binding }, () => undefined)
}

export function setComboHotkey(binding: ComboBinding): Promise<void> {
return invokeOrMock("set_combo_hotkey", { binding }, () => undefined)
}

export function validateShortcutBinding(
binding: ShortcutBinding,
): Promise<void> {
return invokeOrMock(
"validate_shortcut_binding",
{ binding },
() => undefined,
)
}

export function setDictationHotkey(binding: ShortcutBinding): Promise<void> {
return invokeOrMock("set_dictation_hotkey", { binding }, () => undefined)
}

export function setTranslationHotkey(binding: ShortcutBinding): Promise<void> {
return invokeOrMock("set_translation_hotkey", { binding }, () => undefined)
}

// binding = null 表示停用(清空全局键),与 set_qa_hotkey 一致(issue #576)。
export function setSwitchStyleHotkey(binding: ShortcutBinding | null): Promise<void> {
return invokeOrMock("set_switch_style_hotkey", { binding }, () => undefined)
}

export function setOpenAppHotkey(binding: ShortcutBinding | null): Promise<void> {
return invokeOrMock("set_open_app_hotkey", { binding }, () => undefined)
}

export function setShortcutRecordingActive(active: boolean): Promise<void> {
return invokeOrMock(
"set_shortcut_recording_active",
{ active },
() => undefined,
)
}
Loading
Loading