# Project export: Cosmiq

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: CruzHacks 2025
- Tagline: Cosmiq is a smart, markdown-based desktop app built for students. It lets you write notes, instantly summarize them into study guides, and generate quizzes — all powered by AI.
- Devpost: https://devpost.com/software/cosmiq
- GitHub: https://github.com/ethanokamura/cosmiq
- Team: 2 GitHub contributor(s) — Ethan (31 commits), dabrez (3 commits)

## Devpost submission (written by the team)

### Inspiration

Obisidian

### What it does

Note taking app that generates quizes and summaries for students to help them study

### Challenges we ran into

We had to learn Rust because Tauri is powered by Rust on the backend which is something we didn't know that we would need to learn at the beginning. Also we both weren't very experienced in React which we know is a virtual requirement nowadays.

### Accomplishments we're proud of

We learned Rust which is incredibly difficult, and Alex learned more specifically how to use Git in more detail which he is very happy about. I was able to get the Google Gemini API to work in their new Javascript format which I am fairly certain has very sophisticated technical reasons for existing but I was more used to the openai format of using LLMs.

### What we learned

React, Rust, Tailwind, Gemini API, Tauri

### What's next

Adding functionality for reading pdfs and handwriting recognition. I would also like to add an auto grader for math equations. 👨‍💻 Alex's Reflection This project pushed me to learn Git in more depth—especially in a team setting where its power becomes clear. My primary focus was integrating the Gemini API to both summarize user notes and generate quizzes. I adapted to their new API format, which was a shift from the OpenAI-style APIs I usually use for academic research. I also began learning React—my partner guided me a lot—and we used Rust for the backend. Rust feels like the Excalibur of programming languages: powerful, sharp, and a badge of true craftsmanship. Discovering that it shares traits with Python (my go-to language) was a nice surprise. This hackathon gave me the perfect opportunity to branch out. (Yes, that's a Git joke.) 👨‍💻 Ethan Okamura's Reflection Even though CruzHacks only lasted around 36 hours, I learned more than I have in a long time. Beyond technical skills, I improved my time management, collaboration, and prioritization. These are all lessons I can carry into my job at a small startup and my future career. From a technical perspective, I dove into: CruzHacks gave me a foundation and the confidence to continue growing as an engineer. I'm leaving with a full heart and a head packed with new skills.

## README (from the GitHub repository)

# `cosmiq` — CruzHacks 2025 Project

This is the main project document for **cosmiq**, built during CruzHacks 2025.

---

## 🧠 General Idea

A smart, markdown-based note-taking app designed for students:

- A WYSIWYG markdown editor for writing school notes
- Instantly summarize content with a click
- Generate challenging quizzes with detailed explanations

---

## 🛠️ Tech Stack

- **React** – Frontend
- **Tailwind CSS** – Styling
- **Tauri** – Desktop backend with Rust
- **Gemini APIs** – AI-powered summarization & quiz generation

---

## 🖥️ Frontend Pages

- **Home Page** - Interact with your local files system to access your directories 
- **Edit Files Page** – Write and manage markdown notes  
- **Summary Page** – Instantly generate cheat-sheets  
- **Quiz Page** – Take dynamic quizzes based on your notes  

---

## 🧰 Backend Responsibilities

- File system interaction via Tauri
- Integration with Gemini APIs for AI-powered features

---

## ✨ Features

- Write notes, papers, or documentation
- Summarize notes to create study guides or cheat-sheets
- Generate dynamic quizzes in one click

---

## How to Run:

To launch the the desktop application itself, execute the following commands:

```sh
cd cosmiq
npm i
npm run tauri dev
```

In a seperate terminal you can spin up backend with the following commands:
```sh
cd server
docker-compose up --build
```

Note that in order to run the backend, you will need a Gemini API key

## Detected evidence (automated analysis)

Indexed codebase: 76 recognized source files, 253 KB.
- CSS (language) — detected in the code
- Express (technology) — detected in the code
- Google Gemini (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- React (technology) — detected in the code
- Rust (language) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code

## Codebase structure (from repository index)

### Files (108 of 108)

```
.DS_Store
cosmiq-web/.gitignore
cosmiq-web/eslint.config.js
cosmiq-web/index.html
cosmiq-web/package.json
cosmiq-web/README.md
cosmiq-web/src/App.tsx
cosmiq-web/src/components/navbar.tsx
cosmiq-web/src/components/starfield.tsx
cosmiq-web/src/index.css
cosmiq-web/src/main.tsx
cosmiq-web/src/pages/Home.tsx
cosmiq-web/src/routes/AppRouter.tsx
cosmiq-web/src/vite-env.d.ts
cosmiq-web/tsconfig.app.json
cosmiq-web/tsconfig.json
cosmiq-web/tsconfig.node.json
cosmiq-web/vite.config.ts
cosmiq/.env
cosmiq/.gitignore
cosmiq/.prettierignore
cosmiq/.vscode/extensions.json
cosmiq/index.html
cosmiq/package.json
cosmiq/prettier.config.json
cosmiq/README.md
cosmiq/src-tauri/.gitignore
cosmiq/src-tauri/build.rs
cosmiq/src-tauri/capabilities/default.json
cosmiq/src-tauri/Cargo.lock
cosmiq/src-tauri/Cargo.toml
cosmiq/src-tauri/icons/icon.icns
cosmiq/src-tauri/src/lib.rs
cosmiq/src-tauri/src/main.rs
cosmiq/src-tauri/tauri.conf.json
cosmiq/src/App.css
cosmiq/src/App.tsx
cosmiq/src/components/directories.tsx
cosmiq/src/components/editor.tsx
cosmiq/src/components/file.tsx
cosmiq/src/components/folder.tsx
cosmiq/src/components/side-bar.tsx
cosmiq/src/components/starfield.tsx
cosmiq/src/components/sub-directory.tsx
cosmiq/src/components/toolbar.tsx
cosmiq/src/components/tooltip.tsx
cosmiq/src/lib/file-system.ts
cosmiq/src/lib/tiptap-plugins.ts
cosmiq/src/main.tsx
cosmiq/src/pages/Create.tsx
cosmiq/src/pages/Home.tsx
cosmiq/src/pages/quiz/Quiz.tsx
cosmiq/src/pages/summary/Summary.tsx
cosmiq/src/pages/workspaces/Workspace.tsx
cosmiq/src/routes/AppRoutes.tsx
cosmiq/src/utils/constants.ts
cosmiq/src/utils/debounceScroll.ts
cosmiq/src/vite-env.d.ts
cosmiq/tailwind.config.js
cosmiq/tsconfig.json
cosmiq/tsconfig.node.json
cosmiq/vite.config.ts
README.md
server/.dockerignore
server/.env.test
server/.gitignore
server/Dockerfile
server/package.json
server/README.md
server/server.js
server/src/features/api/gemini.js
server/src/features/auth/auth.js
server/src/utils/encryption.js
test-data/.DS_Store
test-data/cse130/.DS_Store
test-data/cse130/Lectures/.DS_Store
test-data/cse130/Lectures/lecture-03.md
test-data/cse130/Lectures/lecture-04.md
test-data/cse130/Notes/.DS_Store
test-data/cse130/Notes/chapter-00.md
test-data/cse130/Notes/chapter-01.md
test-data/cse130/Notes/chapter-02.md
test-data/cse130/Notes/chapter-08.md
test-data/cse40/CSE40 Final Cheat Sheet.md
test-data/cse40/CSE40 Q12.md
test-data/cse40/CSE40 Q34.md
test-data/cse40/CSE40 Q56.md
test-data/cse40/CSE40 Q78.md
test-data/cse40/HO5 Analysis.md
test-data/cse40/Template.md
test-data/dsa/bfs.md
test-data/dsa/bigint.md
test-data/dsa/binary-search-tree.md
test-data/dsa/binary-tree.md
test-data/dsa/dfs.md
test-data/dsa/graphs.md
test-data/dsa/heap.md
test-data/dsa/matrix.md
test-data/dsa/red-black-tree.md
test-data/linux/.DS_Store
test-data/linux/Bash - Born Again Shell.md
test-data/linux/File Permissions.md
test-data/linux/Linux 101.md
test-data/linux/networking/Networking Basics.md
test-data/linux/Path.md
test-data/linux/The File System.md
test-data/quizzes/binary-search-tree.json
test-data/quizzes/lecture-03.json
```

### Dependencies

- cosmiq-web/package.json: @eslint/js@^9.22.0, @tailwindcss/vite@^4.1.4, @types/react@^19.0.10, @types/react-dom@^19.0.4, @vitejs/plugin-react-swc@^3.8.0, eslint@^9.22.0, eslint-plugin-react-hooks@^5.2.0, eslint-plugin-react-refresh@^0.4.19, globals@^16.0.0, react@^19.0.0, react-dom@^19.0.0, react-icons@^5.5.0, react-router-dom@^7.5.2, tailwindcss@^4.1.4, tw-animate-css@^1.2.8, typescript@~5.7.2, typescript-eslint@^8.26.1, vite@^6.3.1
- cosmiq/package.json: @google/genai@^0.8.0, @google/generative-ai@^0.24.0, @tailwindcss/vite@^4.1.3, @tauri-apps/api@^2, @tauri-apps/cli@^2, @tauri-apps/plugin-fs@^2.2.1, @tauri-apps/plugin-opener@^2, @tiptap-pro/extension-mathematics@^2.17.8, @tiptap-pro/extension-unique-id@^2.17.8, @tiptap/core@^2.11.7, @tiptap/extension-code-block-lowlight@^2.11.7, @tiptap/react@^2.11.7, @tiptap/starter-kit@^2.11.7, @types/react@^18.3.1, @types/react-dom@^18.3.1, @vitejs/plugin-react@^4.3.4, highlight.js@^11.11.1, katex@^0.16.22, lowlight@^3.3.0, prettier@^3.5.3, react@^18.3.1, react-dom@^18.3.1, react-icons@^5.5.0, react-router-dom@^7.5.0, tailwindcss@^4.1.3, tiptap-markdown@^0.8.10, tw-animate-css@^1.2.5, typescript@~5.6.2, vite@^6.0.3, vite-tsconfig-paths@^5.1.4
- cosmiq/src-tauri/Cargo.toml: dotenvy@0.15.7, reqwest@0.11, serde@1, serde_json@1, tauri@2, tauri-build@2, tauri-plugin-fs@2, tauri-plugin-opener@2, tokio@1.0
- server/package.json: axios@^1.8.4, cors@^2.8.5, dotenv@^16.5.0, express@^5.1.0

### Recent commits (newest first)

- updates
- minor updates just to show the current standpoint of the code
- first commit
- fully up to date
- simplified the backend setup. still a WIP. needs more
- fixed home page size
- added logos
- updated icon
- minor fixes to ui
- updated padding
- updated macos window
- finally centered the caret
- fixed input for summaries
- clarified readme
- updated readme for server
- updated readme
- cleaned up UI
- added hidden sidebar anf fixed the look of the file system
- pushed app to vercel
- updated api calls and minor ui changes

## Key source files (fetched from GitHub, selected and truncated for size)

### test-data/linux/Path.md

```markdown
PATH is a special env var that defines paths to directories separated by colons
`/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin`

Path tells Linux where executables are located

`which` (binary executable) tells you which path the binary is in

```
$ which ls
/usr/bin/ls
```

When a command is executed it will execute the first found executable from the PATH

common to customize using `export PATH=some-dir/bin:$PATH` within the `.bashrc` or `.bash_profile` file


```

### test-data/linux/File Permissions.md

```markdown
Every file and directory is associated with an owner and a group

`rwx` - read / write / execute

`rwxrwxrwx` user-group-other

`chmod` change permissions
`chown` - change owner
`chgroup` - change group

`chmod [u/g/o][+/-/=][r/w/x][file]`

To give permissions to all user's use the following command:

`chmod u+rwx g+rwx o+rwx somefile.txt`
OR
`chmod 777 somefile.txt`

```
--- == 0
--x == 1
-w- == 2
-wx == 3
r-- == 4
r-x == 5
rw- == 6
rwx == 7
```

# SUDO
superuser do _
the superuser or root user has full control of the server

Additional users can be given sudo abilities in the `/etc/sudoers` file
```

### server/package.json

```
{
  "name": "node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"    
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "commonjs",
  "dependencies": {
    "axios": "^1.8.4",
    "cors": "^2.8.5",
    "dotenv": "^16.5.0",
    "express": "^5.1.0"
  }
}

```

### server/Dockerfile

```
# Use node version 22
FROM node:23.11.0-slim

# Set the working directory to /server/node
WORKDIR /node

# Copy the package.json and package-lock.json from the context (the root folder)
COPY package*.json ./

# Install the dependencies
RUN npm install

# Copy the rest of the app files from the root 'server' directory into the container
COPY . .

# Set environment variables (e.g., for the Node server)
ENV PORT=8080

# Expose the port so that the app can be accessed
EXPOSE 8080

# Command to run the app
CMD ["npm", "start"]

```

### cosmiq-web/package.json

```
{
  "name": "cosmiq-web",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint .",
    "preview": "vite preview"
  },
  "dependencies": {
    "@tailwindcss/vite": "^4.1.4",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "react-icons": "^5.5.0",
    "react-router-dom": "^7.5.2",
    "tailwindcss": "^4.1.4",
    "tw-animate-css": "^1.2.8"
  },
  "devDependencies": {
    "@eslint/js": "^9.22.0",
    "@types/react": "^19.0.10",
    "@types/react-dom": "^19.0.4",
    "@vitejs/plugin-react-swc": "^3.8.0",
    "eslint": "^9.22.0",
    "eslint-plugin-react-hooks": "^5.2.0",
    "eslint-plugin-react-refresh": "^0.4.19",
    "globals": "^16.0.0",
    "typescript": "~5.7.2",
    "typescript-eslint": "^8.26.1",
    "vite": "^6.3.1"
  }
}

```

### cosmiq/package.json

```
{
  "name": "cosmiq",
  "private": true,
  "version": "0.1.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "tauri": "tauri",
    "format": "prettier --write ."
  },
  "dependencies": {
    "@google/genai": "^0.8.0",
    "@google/generative-ai": "^0.24.0",
    "@tailwindcss/vite": "^4.1.3",
    "@tauri-apps/api": "^2",
    "@tauri-apps/plugin-fs": "^2.2.1",
    "@tauri-apps/plugin-opener": "^2",
    "@tiptap-pro/extension-mathematics": "^2.17.8",
    "@tiptap-pro/extension-unique-id": "^2.17.8",
    "@tiptap/core": "^2.11.7",
    "@tiptap/extension-code-block-lowlight": "^2.11.7",
    "@tiptap/react": "^2.11.7",
    "@tiptap/starter-kit": "^2.11.7",
    "highlight.js": "^11.11.1",
    "katex": "^0.16.22",
    "lowlight": "^3.3.0",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-icons": "^5.5.0",
    "react-router-dom": "^7.5.0",
    "tailwindcss": "^4.1.3",
    "tiptap-markdown": "^0.8.10",
    "tw-animate-css": "^1.2.5"
  },
  "devDependencies": {
    "@tauri-apps/cli": "^2",
    "@types/react": "^18.3.1",
    "@types/react-dom": "^18.3.1",
    "@vitejs/plugin-react": "^4.3.4",
    "prettier": "^3.5.3",
    "typescript": "~5.6.2",
    "vite": "^6.0.3",
    "vite-tsconfig-paths": "^5.1.4"
  }
}

```

### cosmiq/src-tauri/Cargo.toml

```
[package]
name = "cosmiq"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
# The `_lib` suffix may seem redundant but it is necessary
# to make the lib name unique and wouldn't conflict with the bin name.
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
name = "cosmiq_lib"
crate-type = ["staticlib", "cdylib", "rlib"]

[build-dependencies]
tauri-build = { version = "2", features = [] }

[dependencies]
tauri = { version = "2", features = [] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tauri-plugin-fs = "2"
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
dotenvy = "0.15.7"

[target."cfg(target_os = \"macos\")".dependencies]
cocoa = "0.26"

```

### server/server.js

```javascript
require('dotenv').config({path: ".env"});
const express = require('express');
const cors = require('cors');
const { generateSummary, generateQuiz } = require('./src/features/api/gemini');

const app = express();
app.use(cors());
app.use(express.json());

app.post('/generate-summary', async (req, res) => {
  try {
    const { content } = req.body;
    const summary = await generateSummary(content);
    res.json({ summary });
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Failed to generate summary' });
  }
});

app.post('/generate-quiz', async (req, res) => {
  const { prompt } = req.body;
  if (!prompt || typeof prompt !== 'string' || prompt.trim() === '') {
    return res.status(400).json({ error: 'Missing or invalid prompt in request body' });
  }
  try {
    const quiz = await generateQuiz(prompt);
    if (quiz) {
      res.json({ quiz });
    } else {
      res.status(400).json({ error: 'Invalid quiz format' });
    }
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Failed to generate quiz' });
  }
});

const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});

```

### cosmiq-web/src/App.tsx

```typescript
import AppRoutes from './routes/AppRouter';
import Starfield from "./components/starfield";
function App() {
  return (
    <>
      <Starfield/>
      <AppRoutes />
    </>
  );
}

export default App

```

### cosmiq/src/main.tsx

```typescript
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { BrowserRouter } from "react-router-dom";

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
);

```

[65 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]