refactor: update documentation, download system and code formatting improvements

- Update Claude rules with improved project overview and command documentation
- Enhance download screen with better architecture detection and formatting
- Improve device detection utilities with multi-architecture support
- Add skills system troubleshooting documentation
- Code formatting improvements with better line breaks and spacing
- Optimize GitHub release asset parsing for platform-specific downloads

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
cyrus
2026-02-02 18:23:42 +05:30
co-authored by Claude
parent ab5d8dc0bb
commit 5aeffc8ad7
5 changed files with 243 additions and 52 deletions
+28 -28
View File
@@ -18,42 +18,42 @@ This project is a **crypto-focused communication platform** built with Tauri v2,
## Technology Stack
| Layer | Technology | Version | Purpose |
| --------------------- | --------------- | ------- | ----------------------- |
| Layer | Technology | Version | Purpose |
| --------------------- | --------------- | ------- | ------------------------ |
| **Frontend Core** |
| UI Framework | React | 19.1.0 | Component-based UI |
| Language | TypeScript | 5.8.3 | Type safety |
| Build Tool | Vite | 7.0.4 | Fast development |
| UI Framework | React | 19.1.0 | Component-based UI |
| Language | TypeScript | 5.8.3 | Type safety |
| Build Tool | Vite | 7.0.4 | Fast development |
| **UI & Styling** |
| Styling | Tailwind CSS | Latest | Utility-first CSS |
| Components | Headless UI | Latest | Accessible components |
| Animation | Framer Motion | Latest | Smooth animations |
| Styling | Tailwind CSS | Latest | Utility-first CSS |
| Components | Headless UI | Latest | Accessible components |
| Animation | Framer Motion | Latest | Smooth animations |
| **State & Data** |
| State Management | Redux Toolkit | Latest | Predictable state mgmt |
| State Persistence | Redux Persist | Latest | State rehydration |
| Data Fetching | TanStack Query | Latest | Server state management |
| Form Handling | React Hook Form | Latest | Form validation |
| State Management | Redux Toolkit | Latest | Predictable state mgmt |
| State Persistence | Redux Persist | Latest | State rehydration |
| Data Fetching | TanStack Query | Latest | Server state management |
| Form Handling | React Hook Form | Latest | Form validation |
| **AI & Intelligence** |
| AI Memory | Custom System | Latest | Context & learning |
| Entity Graph | Neo4j | Latest | Knowledge relationships |
| Embeddings | OpenAI | Latest | Semantic search |
| AI Memory | Custom System | Latest | Context & learning |
| Entity Graph | Neo4j | Latest | Knowledge relationships |
| Embeddings | OpenAI | Latest | Semantic search |
| **Communication** |
| Real-time | Socket.io | Latest | Live messaging |
| Telegram Integration | MTProto | Latest | Deep Telegram access |
| MCP Protocol | JSON-RPC 2.0 | Latest | AI tool execution |
| Real-time | Socket.io | Latest | Live messaging |
| Telegram Integration | MTProto | Latest | Deep Telegram access |
| MCP Protocol | JSON-RPC 2.0 | Latest | AI tool execution |
| **Team & Skills** |
| Skills Platform | GitHub Sync | Latest | Dynamic skill loading |
| Team Management | REST API | Latest | Multi-user collaboration|
| Skills Platform | GitHub Sync | Latest | Dynamic skill loading |
| Team Management | REST API | Latest | Multi-user collaboration |
| **Backend Core** |
| Language | Rust | 1.93.0 | Performance & safety |
| Framework | Tauri | 2.x | Cross-platform apps |
| Language | Rust | 1.93.0 | Performance & safety |
| Framework | Tauri | 2.x | Cross-platform apps |
| **Backend Libraries** |
| Async Runtime | Tokio | Latest | Async operations |
| JSON Handling | Serde JSON | Latest | Serialization |
| Database | SQLx + SQLite | Latest | Local storage |
| HTTP Client | Reqwest | Latest | API requests |
| WebSocket | WebSocket crate | Latest | Real-time messaging |
| Utilities | UUID | Latest | Unique identifiers |
| Async Runtime | Tokio | Latest | Async operations |
| JSON Handling | Serde JSON | Latest | Serialization |
| Database | SQLx + SQLite | Latest | Local storage |
| HTTP Client | Reqwest | Latest | API requests |
| WebSocket | WebSocket crate | Latest | Real-time messaging |
| Utilities | UUID | Latest | Unique identifiers |
## Project Structure
+7 -7
View File
@@ -178,10 +178,10 @@ Get-Process | Where-Object {$_.ProcessName -match "tauri|vite|cargo|node"} | Sto
## Build Targets
| Platform | Command | Output |
| -------- | ------------------------------ | ------------------- |
| Windows | `yarn tauri build` | `.msi`, `.exe` |
| macOS | `yarn tauri build` | `.dmg`, `.app` |
| Linux | `yarn tauri build` | `.deb`, `.AppImage` |
| Android | `yarn tauri android build` | `.apk`, `.aab` |
| iOS | `yarn tauri ios build` | `.ipa` |
| Platform | Command | Output |
| -------- | -------------------------- | ------------------- |
| Windows | `yarn tauri build` | `.msi`, `.exe` |
| macOS | `yarn tauri build` | `.dmg`, `.app` |
| Linux | `yarn tauri build` | `.deb`, `.AppImage` |
| Android | `yarn tauri android build` | `.apk`, `.aab` |
| iOS | `yarn tauri ios build` | `.ipa` |
+160
View File
@@ -0,0 +1,160 @@
# Skills System Troubleshooting Guide
## Overview
The Skills System is a Python-based plugin architecture that allows AI agents to have domain-specific knowledge, tools, and automated behaviors. Skills run as isolated Python subprocesses and communicate with the main Tauri application via JSON-RPC.
## Common Issue: "Setup Failed" with Exit Code 1
### Symptoms
- Skills modal shows "Setup Failed" with "Skill process exited with code: 1"
- Console shows `ModuleNotFoundError: No module named 'pydantic'`
- Error paths like `/Users/cyrus/alphahuman/skills/skills/telegram/`
- Python import failures and subprocess stderr messages
### Root Cause Analysis
**Primary Issue: Missing Skills Git Submodule**
The main cause is that the `skills` Git submodule is not initialized. The system expects skills to be available in the `skills/skills/` directory structure but finds an empty directory.
**Secondary Issues:**
1. **Missing Python Virtual Environment**: No `.venv` directory in the skills folder
2. **Missing Python Dependencies**: Core packages like `pydantic`, `telethon`, `mcp` not installed
3. **Incorrect Python Paths**: PYTHONPATH configuration issues
### Skills System Architecture
```
skills/ # Git submodule root
├── .venv/ # Python virtual environment
├── requirements.txt # Shared dependencies
├── skills/ # Individual skill packages
│ ├── telegram/ # Telegram skill
│ │ ├── skill.py # Main skill logic
│ │ ├── manifest.json # Skill metadata
│ │ ├── requirements.txt # Skill-specific dependencies
│ │ └── ...
│ ├── browser/ # Browser automation skill
│ ├── calendar/ # Calendar integration skill
│ └── ... # Other skills
└── ...
```
### Solution Steps
#### 1. Initialize Git Submodule
```bash
git submodule init
git submodule update
```
This downloads the skills repository from `https://github.com/alphahumanxyz/skills`.
#### 2. Create Python Virtual Environment
```bash
cd skills
python3 -m venv .venv
.venv/bin/pip install --upgrade pip
```
#### 3. Install Dependencies
```bash
.venv/bin/pip install -r requirements.txt
```
This installs:
- **Core Dependencies**: `mcp>=1.0.0`, `pydantic>=2.0`, `aiosqlite>=0.20.0`
- **Skill-Specific Dependencies**: Each skill's requirements.txt (telegram, browser, etc.)
#### 4. Verify Installation
```bash
# Test core imports
.venv/bin/python -c "import pydantic, mcp; print('✅ Core dependencies OK')"
# Test skill import
.venv/bin/python -c "import skills.telegram; print('✅ Telegram skill OK')"
```
### How Skills System Works
#### Development vs Production Paths
- **Development**: Skills in git submodule at `./skills/skills/`
- **Production**: Skills in `~/.alphahuman/skills/`
- **Configuration**: `src/lib/skills/paths.ts` handles path resolution
#### Skill Execution Process
1. **Discovery**: `SkillProvider` scans for skill manifests
2. **Registration**: Skills registered in Redux store
3. **Startup**: Python subprocess spawned with proper environment
4. **Communication**: JSON-RPC transport over stdin/stdout
5. **Setup**: Interactive setup flow if required
#### Environment Variables
The system automatically configures:
- **PYTHONPATH**: Includes skills directory and virtual environment
- **Telegram API**: `TELEGRAM_API_ID`, `TELEGRAM_API_HASH`
- **Working Directory**: Skills submodule root
### Verification Commands
```bash
# Check submodule status
git submodule status
# Verify skills directory structure
ls -la skills/skills/telegram/
# Check virtual environment
ls -la skills/.venv/
# Test Python environment
cd skills && .venv/bin/python -c "import sys; print('\\n'.join(sys.path))"
```
### Prevention
To prevent this issue in fresh checkouts:
1. **Always initialize submodules**:
```bash
git clone --recurse-submodules <repo-url>
# or after clone:
git submodule update --init --recursive
```
2. **Setup script**: Consider adding to `package.json`:
```json
{
"scripts": {
"setup": "git submodule update --init && cd skills && python3 -m venv .venv && .venv/bin/pip install -r requirements.txt"
}
}
```
### Related Files
- **Frontend**: `src/lib/skills/` - Skills management system
- **Backend**: `src-tauri/src/commands/skills.rs` - Rust skill commands
- **Configuration**: `src/utils/config.ts` - Environment variables
- **Providers**: `src/providers/SkillProvider.tsx` - Skills lifecycle
### Expected Behavior After Fix
1. Skills modal should show "Connect Telegram" instead of error
2. No more Python import errors in console
3. Skill setup process should work correctly
4. Background GitHub sync should function properly
This fix resolves the fundamental infrastructure issue preventing skills from loading and running properly.
+16 -10
View File
@@ -1,14 +1,14 @@
import { useEffect, useState } from 'react';
import {
type Architecture,
type ArchitectureDownloadLink,
detectPlatform,
fetchLatestRelease,
getDownloadLink,
getPlatformDisplayName,
parseReleaseAssets,
parseReleaseAssetsByArchitecture,
type Architecture,
type ArchitectureDownloadLink,
type Platform,
type PlatformArchitectureLinks,
type PlatformDownloadLinks,
@@ -33,7 +33,9 @@ const DownloadScreen = () => {
const [selectedPlatform, setSelectedPlatform] = useState<Platform | null>(null);
const [selectedArchitecture, setSelectedArchitecture] = useState<Architecture | null>(null);
const [releaseLinks, setReleaseLinks] = useState<PlatformDownloadLinks | null>(null);
const [architectureLinks, setArchitectureLinks] = useState<PlatformArchitectureLinks | null>(null);
const [architectureLinks, setArchitectureLinks] = useState<PlatformArchitectureLinks | null>(
null
);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
@@ -63,7 +65,9 @@ const DownloadScreen = () => {
const platformArchLinks = archLinks[detected.platform as keyof PlatformArchitectureLinks];
if (platformArchLinks && platformArchLinks.length > 0) {
// Prefer detected architecture, otherwise use first available
const preferredLink = platformArchLinks.find(link => link.architecture === detected.architecture) || platformArchLinks[0];
const preferredLink =
platformArchLinks.find(link => link.architecture === detected.architecture) ||
platformArchLinks[0];
setSelectedArchitecture(preferredLink.architecture);
}
} catch (err) {
@@ -88,7 +92,8 @@ const DownloadScreen = () => {
return getDownloadLink(selectedPlatform || 'unknown', releaseLinks || undefined);
}
const platformArchLinks = architectureLinks[selectedPlatform as keyof PlatformArchitectureLinks];
const platformArchLinks =
architectureLinks[selectedPlatform as keyof PlatformArchitectureLinks];
if (platformArchLinks && selectedArchitecture) {
const link = platformArchLinks.find(l => l.architecture === selectedArchitecture);
if (link) {
@@ -139,9 +144,7 @@ const DownloadScreen = () => {
{error && !isLoading && (
<div className="mb-6">
<div className="bg-red-500/10 border border-red-500/20 rounded-xl p-4">
<p className="text-sm text-red-400">
{error}. Using fallback download links.
</p>
<p className="text-sm text-red-400">{error}. Using fallback download links.</p>
</div>
</div>
)}
@@ -209,9 +212,12 @@ const DownloadScreen = () => {
{downloadOptions
.filter(opt => opt.platform !== selectedPlatform)
.map(option => {
const platformArchLinks = architectureLinks?.[option.platform as keyof PlatformArchitectureLinks];
const platformArchLinks =
architectureLinks?.[option.platform as keyof PlatformArchitectureLinks];
const hasValidLink = platformArchLinks && platformArchLinks.length > 0;
const defaultLink = platformArchLinks?.[0]?.url || getDownloadLink(option.platform, releaseLinks || undefined);
const defaultLink =
platformArchLinks?.[0]?.url ||
getDownloadLink(option.platform, releaseLinks || undefined);
const hasMultipleArchs = platformArchLinks && platformArchLinks.length > 1;
return (
+32 -7
View File
@@ -141,7 +141,9 @@ export function detectPlatform(): PlatformInfo {
* Fetch the latest release from GitHub
*/
export async function fetchLatestRelease(): Promise<GitHubRelease> {
const response = await fetch('https://api.github.com/repos/alphahumanxyz/alphahuman/releases/latest');
const response = await fetch(
'https://api.github.com/repos/alphahumanxyz/alphahuman/releases/latest'
);
if (!response.ok) {
throw new Error(`Failed to fetch release: ${response.statusText}`);
}
@@ -185,7 +187,9 @@ export function getArchitectureDisplayName(arch: Architecture): string {
/**
* Parse GitHub release assets and map them to platforms with architecture support
*/
export function parseReleaseAssetsByArchitecture(assets: GitHubReleaseAsset[]): PlatformArchitectureLinks {
export function parseReleaseAssetsByArchitecture(
assets: GitHubReleaseAsset[]
): PlatformArchitectureLinks {
const links: PlatformArchitectureLinks = {};
// Use Maps to track unique architectures per platform
@@ -212,21 +216,39 @@ export function parseReleaseAssetsByArchitecture(assets: GitHubReleaseAsset[]):
};
// Windows: .exe, .msi, .zip (Windows)
if (name.includes('windows') || name.includes('.exe') || name.includes('.msi') || (name.includes('.zip') && !name.includes('macos'))) {
if (
name.includes('windows') ||
name.includes('.exe') ||
name.includes('.msi') ||
(name.includes('.zip') && !name.includes('macos'))
) {
// Only add if this architecture doesn't exist yet, or prefer more specific filenames
if (!windowsMap.has(architecture) || (name.includes('windows') && !windowsMap.get(architecture)?.fileName.toLowerCase().includes('windows'))) {
if (
!windowsMap.has(architecture) ||
(name.includes('windows') &&
!windowsMap.get(architecture)?.fileName.toLowerCase().includes('windows'))
) {
windowsMap.set(architecture, link);
}
}
// macOS: .dmg
else if (name.includes('macos') || name.includes('.dmg') || name.includes('darwin')) {
// Only add if this architecture doesn't exist yet, or prefer more specific filenames
if (!macosMap.has(architecture) || (name.includes('macos') && !macosMap.get(architecture)?.fileName.toLowerCase().includes('macos'))) {
if (
!macosMap.has(architecture) ||
(name.includes('macos') &&
!macosMap.get(architecture)?.fileName.toLowerCase().includes('macos'))
) {
macosMap.set(architecture, link);
}
}
// Linux: .AppImage, .deb, .rpm
else if (name.includes('linux') || name.includes('.appimage') || name.includes('.deb') || name.includes('.rpm')) {
else if (
name.includes('linux') ||
name.includes('.appimage') ||
name.includes('.deb') ||
name.includes('.rpm')
) {
// Prefer AppImage, then deb, then rpm for the same architecture
const existing = linuxMap.get(architecture);
if (!existing) {
@@ -267,7 +289,10 @@ export function parseReleaseAssetsByArchitecture(assets: GitHubReleaseAsset[]):
}
// Sort architectures: prefer detected architecture, then x64, then aarch64
const sortArchitectures = (archLinks: ArchitectureDownloadLink[], preferredArch?: Architecture) => {
const sortArchitectures = (
archLinks: ArchitectureDownloadLink[],
preferredArch?: Architecture
) => {
return archLinks.sort((a, b) => {
if (preferredArch && a.architecture === preferredArch) return -1;
if (preferredArch && b.architecture === preferredArch) return 1;