diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index d083a2c3..00000000 --- a/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -src-svelte/src/lib/bindings.ts \ No newline at end of file diff --git a/src-svelte/src/lib/bindings.ts b/src-svelte/src/lib/bindings.ts index 7b68cde6..4a80fa37 100644 --- a/src-svelte/src/lib/bindings.ts +++ b/src-svelte/src/lib/bindings.ts @@ -2,64 +2,111 @@ // This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually. declare global { - interface Window { - __TAURI_INVOKE__(cmd: string, args?: Record): Promise; - } + interface Window { + __TAURI_INVOKE__( + cmd: string, + args?: Record, + ): Promise; + } } // Function avoids 'window not defined' in SSR const invoke = () => window.__TAURI_INVOKE__; export function getApiKeys() { - return invoke()("get_api_keys") + return invoke()("get_api_keys"); } -export function setApiKey(filename: string | null, service: Service, apiKey: string) { - return invoke()("set_api_key", { filename,service,apiKey }) +export function setApiKey( + filename: string | null, + service: Service, + apiKey: string, +) { + return invoke()("set_api_key", { filename, service, apiKey }); } export function playSound(sound: Sound, volume: number, speed: number) { - return invoke()("play_sound", { sound,volume,speed }) + return invoke()("play_sound", { sound, volume, speed }); } export function getPreferences() { - return invoke()("get_preferences") + return invoke()("get_preferences"); } export function setPreferences(preferences: Preferences) { - return invoke()("set_preferences", { preferences }) + return invoke()("set_preferences", { preferences }); } export function getSystemInfo() { - return invoke()("get_system_info") + return invoke()("get_system_info"); } -export function chat(provider: Service, llm: string, temperature: number | null, prompt: ChatMessage[]) { - return invoke()("chat", { provider,llm,temperature,prompt }) +export function chat( + provider: Service, + llm: string, + temperature: number | null, + prompt: ChatMessage[], +) { + return invoke()("chat", { + provider, + llm, + temperature, + prompt, + }); } export function getApiCall(id: string) { - return invoke()("get_api_call", { id }) + return invoke()("get_api_call", { id }); } export function getApiCalls(offset: number) { - return invoke()("get_api_calls", { offset }) + return invoke()("get_api_calls", { offset }); } -export type ChatMessage = { role: "System"; text: string } | { role: "Human"; text: string } | { role: "AI"; text: string } -export type Prompt = ({ type: "Chat" } & ChatPrompt) -export type Response = { completion: ChatMessage } -export type Service = "OpenAI" -export type Request = { prompt: Prompt; temperature: number } -export type Preferences = { animations_on?: boolean | null; background_animation?: boolean | null; animation_speed?: number | null; transparency_on?: boolean | null; sound_on?: boolean | null; volume?: number | null } -export type Llm = { name: string; requested: string; provider: Service } -export type LightweightLlmCall = { id: EntityId; timestamp: string; response_message: ChatMessage } -export type LlmCall = { id: EntityId; timestamp: string; llm: Llm; request: Request; response: Response; tokens: TokenMetadata } -export type ApiKeys = { openai: string | null } -export type OS = "Mac" | "Linux" | "Windows" -export type Shell = "Bash" | "Zsh" | "PowerShell" -export type SystemInfo = { zamm_version: string; os: OS | null; shell: Shell | null; shell_init_file: string | null } -export type ChatPrompt = { messages: ChatMessage[] } -export type TokenMetadata = { prompt: number | null; response: number | null; total: number | null } -export type Sound = "Switch" | "Whoosh" -export type EntityId = { uuid: string } +export type ChatMessage = + | { role: "System"; text: string } + | { role: "Human"; text: string } + | { role: "AI"; text: string }; +export type Prompt = { type: "Chat" } & ChatPrompt; +export type Response = { completion: ChatMessage }; +export type Service = "OpenAI"; +export type Request = { prompt: Prompt; temperature: number }; +export type Preferences = { + animations_on?: boolean | null; + background_animation?: boolean | null; + animation_speed?: number | null; + transparency_on?: boolean | null; + sound_on?: boolean | null; + volume?: number | null; +}; +export type Llm = { name: string; requested: string; provider: Service }; +export type LightweightLlmCall = { + id: EntityId; + timestamp: string; + response_message: ChatMessage; +}; +export type LlmCall = { + id: EntityId; + timestamp: string; + llm: Llm; + request: Request; + response: Response; + tokens: TokenMetadata; +}; +export type ApiKeys = { openai: string | null }; +export type OS = "Mac" | "Linux" | "Windows"; +export type Shell = "Bash" | "Zsh" | "PowerShell"; +export type SystemInfo = { + zamm_version: string; + os: OS | null; + shell: Shell | null; + shell_init_file: string | null; +}; +export type ChatPrompt = { messages: ChatMessage[] }; +export type TokenMetadata = { + prompt: number | null; + response: number | null; + total: number | null; +}; +export type Sound = "Switch" | "Whoosh"; +export type EntityId = { uuid: string }; diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 0060e08e..21a2576d 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -84,6 +84,55 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.79" @@ -437,6 +486,46 @@ dependencies = [ "libloading", ] +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + [[package]] name = "claxon" version = "0.4.3" @@ -479,6 +568,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + [[package]] name = "combine" version = "4.6.6" @@ -709,7 +804,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] @@ -723,7 +818,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 2.0.48", ] @@ -1574,6 +1669,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.3" @@ -1832,6 +1933,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.10.5" @@ -3781,6 +3888,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum" version = "0.25.0" @@ -4638,6 +4751,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "uuid" version = "1.6.1" @@ -5431,6 +5550,7 @@ dependencies = [ "async-openai", "cfg-if", "chrono", + "clap", "diesel", "diesel_migrations", "directories", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 99ca84ca..5c9733c6 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -40,6 +40,7 @@ reqwest-middleware = "0.1.6" tokio = { version = "1.35.1", features = ["macros"] } chrono = { version = "0.4.31", features = ["serde"] } libsqlite3-sys = { version = "0.27.0", features = ["bundled"] } +clap = { version = "4.5.4", features = ["derive"] } [features] # this feature is used for production builds or when `devPath` points to the filesystem diff --git a/src-tauri/src/cli.rs b/src-tauri/src/cli.rs new file mode 100644 index 00000000..5a0724f8 --- /dev/null +++ b/src-tauri/src/cli.rs @@ -0,0 +1,24 @@ +use clap::{Parser, Subcommand}; + +#[derive(Subcommand)] +pub enum Commands { + /// Run the GUI. This is the default command. + Gui {}, + /// Export Specta bindings for development purposes + #[cfg(debug_assertions)] + ExportBindings {}, +} + +/// Zen and the Automation of Metaprogramming for the Masses +/// +/// This is an experimental tool meant for automating programming-related activities, +/// although none have been implemented yet. Blog posts on progress can be found at +/// https://zamm.dev/ +#[derive(Parser)] +#[command(name = "zamm")] +#[command(version)] +#[command(about = "Zen and the Automation of Metaprogramming for the Masses")] +pub struct Cli { + #[command(subcommand)] + pub command: Option, +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index b37875c6..b7856cd7 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,18 +1,7 @@ // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] -use diesel::sqlite::SqliteConnection; - -use setup::api_keys::{setup_api_keys, ApiKeys}; -#[cfg(all(debug_assertions, not(target_os = "windows")))] -use specta::collect_types; - -#[cfg(all(debug_assertions, not(target_os = "windows")))] -use tauri_specta::ts; - -use std::env; - -use tokio::sync::Mutex; +mod cli; mod commands; mod models; #[cfg(test)] @@ -21,6 +10,18 @@ mod schema; mod setup; #[cfg(test)] mod test_helpers; + +use clap::Parser; +use diesel::sqlite::SqliteConnection; +use setup::api_keys::{setup_api_keys, ApiKeys}; +#[cfg(debug_assertions)] +use specta::collect_types; +use std::env; +#[cfg(debug_assertions)] +use tauri_specta::ts; +use tokio::sync::Mutex; + +use cli::{Cli, Commands}; use commands::{ chat, get_api_call, get_api_calls, get_api_keys, get_preferences, get_system_info, play_sound, set_api_key, set_preferences, @@ -30,40 +31,48 @@ pub struct ZammDatabase(Mutex>); pub struct ZammApiKeys(Mutex); fn main() { - #[cfg(all(debug_assertions, not(target_os = "windows")))] - ts::export( - collect_types![ - get_api_keys, - set_api_key, - play_sound, - get_preferences, - set_preferences, - get_system_info, - chat, - get_api_call, - get_api_calls, - ], - "../src-svelte/src/lib/bindings.ts", - ) - .expect("Failed to export Specta bindings"); + let cli = Cli::parse(); - let mut possible_db = setup::get_db(); - let api_keys = setup_api_keys(&mut possible_db); + match &cli.command { + #[cfg(debug_assertions)] + Some(Commands::ExportBindings {}) => { + ts::export( + collect_types![ + get_api_keys, + set_api_key, + play_sound, + get_preferences, + set_preferences, + get_system_info, + chat, + get_api_call, + get_api_calls, + ], + "../src-svelte/src/lib/bindings.ts", + ) + .expect("Failed to export Specta bindings"); + println!("Specta bindings should be exported to ../src-svelte/src/lib/bindings.ts"); + } + Some(Commands::Gui {}) | None => { + let mut possible_db = setup::get_db(); + let api_keys = setup_api_keys(&mut possible_db); - tauri::Builder::default() - .manage(ZammDatabase(Mutex::new(possible_db))) - .manage(ZammApiKeys(Mutex::new(api_keys))) - .invoke_handler(tauri::generate_handler![ - get_api_keys, - set_api_key, - play_sound, - get_preferences, - set_preferences, - get_system_info, - chat, - get_api_call, - get_api_calls, - ]) - .run(tauri::generate_context!()) - .expect("error while running tauri application"); + tauri::Builder::default() + .manage(ZammDatabase(Mutex::new(possible_db))) + .manage(ZammApiKeys(Mutex::new(api_keys))) + .invoke_handler(tauri::generate_handler![ + get_api_keys, + set_api_key, + play_sound, + get_preferences, + set_preferences, + get_system_info, + chat, + get_api_call, + get_api_calls, + ]) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); + } + } }