Compare commits

...

1 commit

Author SHA1 Message Date
d29aacda08 Skeleton
Some checks failed
CI / ci (pull_request) Has been cancelled
CI / ci (push) Has been cancelled
2026-02-23 22:12:54 -08:00
9 changed files with 3452 additions and 0 deletions

35
.forgejo/workflows/ci.yml Normal file
View file

@ -0,0 +1,35 @@
name: CI
on:
push:
pull_request:
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: https://github.com/dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: Build
run: cargo build
- name: Format
run: cargo fmt --check
- name: Clippy
run: cargo clippy -- -D warnings

3335
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

16
Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "skate"
version = "0.1.0"
edition = "2024"
[dependencies]
ratatui = "0.30"
crossterm = "0.29"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "2"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
reqwest = { version = "0.13", features = ["stream"] }
futures = "0.3"

1
src/app/mod.rs Normal file
View file

@ -0,0 +1 @@

1
src/core/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod types;

56
src/core/types.rs Normal file
View file

@ -0,0 +1,56 @@
// Types are scaffolding — used in later phases.
#![allow(dead_code)]
/// A streaming event emitted by the model provider.
#[derive(Debug)]
pub enum StreamEvent {
/// A text chunk from the assistant's response.
TextDelta(String),
/// Number of input tokens used in this request.
InputTokens(u32),
/// Number of output tokens generated so far.
OutputTokens(u32),
/// The stream has completed successfully.
Done,
/// An error occurred during streaming.
Error(String),
}
/// An action sent from the TUI to the core orchestrator.
#[derive(Debug)]
pub enum UserAction {
/// The user has submitted a message.
SendMessage(String),
/// The user has requested to quit.
Quit,
}
/// An event sent from the core orchestrator to the TUI.
#[derive(Debug)]
pub enum UIEvent {
/// A text chunk to append to the current assistant message.
StreamDelta(String),
/// The current assistant turn has completed.
TurnComplete,
/// An error to display to the user.
Error(String),
}
/// The role of a participant in a conversation.
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Role {
/// A message from the human user.
User,
/// A message from the AI assistant.
Assistant,
}
/// A single message in the conversation history.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ConversationMessage {
/// The role of the message author.
pub role: Role,
/// The text content of the message.
pub content: String,
}

6
src/main.rs Normal file
View file

@ -0,0 +1,6 @@
mod app;
mod core;
mod provider;
mod tui;
fn main() {}

1
src/provider/mod.rs Normal file
View file

@ -0,0 +1 @@

1
src/tui/mod.rs Normal file
View file

@ -0,0 +1 @@