Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3d1c570
fixed tailscale-serve commit
thestumonkey Jan 28, 2026
ab48fd6
Merge pull request #141 from Ushadow-io/mainfix
thestumonkey Jan 28, 2026
eb201f5
Omi app logs (#142)
thestumonkey Jan 29, 2026
5588246
Omi app logs (#143)
thestumonkey Jan 29, 2026
c259226
Add debug logging for service deployment
thestumonkey Jan 29, 2026
ca2b0af
simplified to just use ushadow network
thestumonkey Jan 29, 2026
6fceb9a
added nbetwork fixes and chronicle combined audio
thestumonkey Jan 29, 2026
b709610
fixed chronicle port issue
thestumonkey Jan 30, 2026
4cdd66a
updated openmem
thestumonkey Jan 30, 2026
a9729e5
added pull logic if image not found
thestumonkey Jan 30, 2026
d6e34e8
added locked neo4j driver version
thestumonkey Jan 30, 2026
0616abf
added mobile session logger
thestumonkey Jan 30, 2026
7821266
added pixi
thestumonkey Jan 30, 2026
dc614b2
Convert chronicle to git submodule
thestumonkey Feb 1, 2026
75211c0
Remove orphaned vibe-kanban submodule entry
thestumonkey Feb 1, 2026
70a9ede
Add automatic sparse checkout configuration via git hooks
thestumonkey Feb 1, 2026
33b4236
Add Makefile targets for building/pushing Chronicle and Mycelia to GHCR
thestumonkey Feb 1, 2026
3f0b8f3
Add OpenMemory (mem0) as submodule with build support
thestumonkey Feb 1, 2026
5e75d85
chat and memories
thestumonkey Feb 1, 2026
9ba036d
new convo page
thestumonkey Feb 2, 2026
62d91b7
★ Insight ─────────────────────────────────────
thestumonkey Feb 2, 2026
f3431c8
Excellent! The implementation looks good. Let me create a summary doc…
thestumonkey Feb 2, 2026
232b40d
Excellent! The feature flag has been successfully added. Let me creat…
thestumonkey Feb 2, 2026
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
49 changes: 49 additions & 0 deletions .githooks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Git Hooks

This directory contains git hooks that are **committed to the repository**.

## Setup (One-Time)

After cloning, configure git to use these hooks:

```bash
git config core.hooksPath .githooks
```

## Automatic Setup

Add this to your `~/.gitconfig` to automatically use `.githooks` in all repos:

```ini
[init]
templateDir = ~/.git-templates
```

Then create `~/.git-templates/hooks/post-clone`:
```bash
#!/bin/bash
if [ -d .githooks ]; then
git config core.hooksPath .githooks
fi
```

## Available Hooks

### post-checkout
Automatically configures sparse checkout for chronicle and mycelia submodules to prevent circular dependencies.

**What it does:**
- Chronicle: Excludes `extras/mycelia/`
- Mycelia: Excludes `friend/`

**When it runs:**
- After `git checkout`
- After `git submodule update`
- After initial clone (with setup)

## Testing

Test the hook manually:
```bash
./.githooks/post-checkout
```
45 changes: 45 additions & 0 deletions .githooks/post-checkout
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash
# Post-checkout hook to configure sparse checkout for submodules
# This prevents circular dependencies between chronicle and mycelia

set -e

echo "🔧 Configuring sparse checkout for submodules..."

# Configure chronicle to exclude extras/mycelia
if [ -d "chronicle" ]; then
CHRONICLE_GIT="$(cd chronicle && git rev-parse --git-dir 2>/dev/null || echo "")"
if [ -n "$CHRONICLE_GIT" ] && [ -d "$CHRONICLE_GIT" ]; then
echo " 📁 Configuring chronicle (excluding extras/mycelia)"
mkdir -p "$CHRONICLE_GIT/info"
cat > "$CHRONICLE_GIT/info/sparse-checkout" <<'SPARSE'
/*
!extras/mycelia/
SPARSE
(cd chronicle && git config core.sparseCheckout true && git read-tree -mu HEAD 2>/dev/null || true)
fi
fi

# Configure mycelia to exclude friend
if [ -d "mycelia" ]; then
MYCELIA_GIT="$(cd mycelia && git rev-parse --git-dir 2>/dev/null || echo "")"
if [ -n "$MYCELIA_GIT" ] && [ -d "$MYCELIA_GIT" ]; then
echo " 📁 Configuring mycelia (excluding friend)"
mkdir -p "$MYCELIA_GIT/info"
cat > "$MYCELIA_GIT/info/sparse-checkout" <<'SPARSE'
/*
!friend/
SPARSE
(cd mycelia && git config core.sparseCheckout true && git read-tree -mu HEAD 2>/dev/null || true)
fi
fi

# Configure openmemory (no exclusions needed currently)
if [ -d "openmemory" ]; then
OPENMEMORY_GIT="$(cd openmemory && git rev-parse --git-dir 2>/dev/null || echo "")"
if [ -n "$OPENMEMORY_GIT" ] && [ -d "$OPENMEMORY_GIT" ]; then
echo " 📁 Openmemory configured (no exclusions)"
fi
fi

echo "✅ Sparse checkout configured successfully"
12 changes: 12 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[submodule "chronicle"]
path = chronicle
url = https://github.com/Ushadow-io/chronicle.git
update = checkout

[submodule "mycelia"]
path = mycelia
url = https://github.com/mycelia-tech/mycelia.git
update = checkout
[submodule "openmemory"]
path = openmemory
url = https://github.com/Ushadow-io/mem0.git
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
go install status health dev prod \
svc-list svc-restart svc-start svc-stop svc-status \
chronicle-env-export chronicle-build-local chronicle-up-local chronicle-down-local chronicle-dev \
chronicle-push mycelia-push openmemory-push \
release

# Read .env for display purposes only (actual logic is in run.py)
Expand Down Expand Up @@ -44,6 +45,11 @@ help:
@echo " make chronicle-down-local - Stop local Chronicle"
@echo " make chronicle-dev - Build + run (full dev cycle)"
@echo ""
@echo "Build & Push to GHCR:"
@echo " make chronicle-push [TAG=latest] - Build and push Chronicle (backend+workers+webui)"
@echo " make mycelia-push [TAG=latest] - Build and push Mycelia backend"
@echo " make openmemory-push [TAG=latest] - Build and push OpenMemory server"
@echo ""
@echo "Service management:"
@echo " make rebuild <service> - Rebuild service from compose/<service>-compose.yml"
@echo " (e.g., make rebuild mycelia, make rebuild chronicle)"
Expand Down Expand Up @@ -194,6 +200,24 @@ chronicle-down-local:
chronicle-dev: chronicle-build-local chronicle-up-local
@echo "🎉 Chronicle dev environment ready"

# =============================================================================
# Build & Push to GHCR
# =============================================================================
# Build and push multi-arch images to GitHub Container Registry
# Requires: docker login ghcr.io -u USERNAME --password-stdin

# Chronicle - Build and push backend + webui
chronicle-push:
@./scripts/build-push-images.sh chronicle $(TAG)

# Mycelia - Build and push backend
mycelia-push:
@./scripts/build-push-images.sh mycelia $(TAG)

# OpenMemory - Build and push server
openmemory-push:
@./scripts/build-push-images.sh openmemory $(TAG)

# =============================================================================
# Service Management (via ushadow API)
# =============================================================================
Expand Down
1 change: 1 addition & 0 deletions chronicle
Submodule chronicle added at c170a0
2 changes: 2 additions & 0 deletions compose/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ services:
- CONFIG_DIR=/config
- MONGODB_DATABASE=${MONGODB_DATABASE:-ushadow}
- CORS_ORIGINS=${CORS_ORIGINS:-http://localhost:5173,http://localhost:3000,http://localhost:${WEBUI_PORT}}
# Rich console width for logging (prevents log wrapping)
- COLUMNS=200
volumes:
- ../ushadow/backend:/app
- ../config:/config # Mount config directory (read-write for feature flags)
Expand Down
113 changes: 81 additions & 32 deletions compose/chronicle-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Chronicle backend service definition with sidecar workers
# Chronicle backend service definition with separate workers
# Environment variables are passed directly via docker compose subprocess env
# No .env files needed - CapabilityResolver provides all values

Expand All @@ -8,26 +8,20 @@
x-ushadow:
# Services share namespace with main ushadow for unified auth (AUTH_SECRET_KEY)
chronicle-backend:
display_name: "Chronicle"
display_name: "Chronicle api"
description: "AI-powered voice journal and life logger with transcription and LLM analysis"
requires: [llm, transcription, audio_input]
requires: [llm, transcription]
optional: [memory] # Uses memory if available, works without it
route_path: /chronicle # Tailscale Serve route - all /chronicle/* requests go here
# route_path: /chronicle # Tailscale Serve route - all /chronicle/* requests go here
exposes:
- name: audio_intake
type: audio
path: /ws_pcm
path: /ws
port: 8000 # Internal container port
metadata:
protocol: wyoming
formats: [pcm]
- name: audio_intake_opus
type: audio
path: /ws_omi
port: 8000 # Internal container port
metadata:
protocol: wyoming
formats: [opus]
formats: [pcm, opus]
codec_param: true # Clients specify codec via ?codec=pcm or ?codec=opus
- name: http_api
type: http
path: /
Expand All @@ -36,27 +30,26 @@ x-ushadow:
type: health
path: /health
port: 8000
chronicle-workers:
display_name: "Chronicle Workers"
description: "Background workers for Chronicle (transcription, memory, audio processing)"
requires: [llm, transcription]
chronicle-webui:
display_name: "Chronicle Web UI"
description: "Web interface for Chronicle voice journal"
requires: []

services:
chronicle-backend:
image: ghcr.io/ushadow-io/chronicle/backend:latest
build:
context: ../chronicle/backends/advanced
dockerfile: Dockerfile
target: dev
# image: ghcr.io/ushadow-io/chronicle/backend:latest
image: chronicle-backend:latest
container_name: ${COMPOSE_PROJECT_NAME:-ushadow}-chronicle-backend
# Sidecar mode: Run both workers and backend in same container
command:
- /bin/bash
- -c
- |
echo "🚀 Starting Chronicle with sidecar workers..."
./start-workers.sh &
sleep 3
echo "🌐 Starting FastAPI backend..."
exec uv run --extra deepgram python src/advanced_omi_backend/main.py
ports:
- "${CHRONICLE_PORT:-8080}:8000"
- "${CHRONICLE_BACKEND_PORT:-8090}:8000"
environment:
# Infrastructure connections (from CapabilityResolver or defaults)
- MONGODB_URI=${MONGODB_URI:-mongodb://mongo:27017}
Expand All @@ -76,6 +69,7 @@ services:
- TRANSCRIPTION_PROVIDER=${TRANSCRIPTION_PROVIDER:-deepgram}
# Memory capability (optional, from selected provider)
- MEMORY_SERVER_URL=${MEMORY_SERVER_URL:-}
- OPENMEMORY_USER_ID=${ADMIN_EMAIL:-admin@example.com}

# Security (from settings) - AUTH_SECRET_KEY is required for JWT auth
- AUTH_SECRET_KEY=${AUTH_SECRET_KEY}
Expand All @@ -84,16 +78,17 @@ services:
# CORS
- CORS_ORIGINS=${CORS_ORIGINS:-*}



volumes:
# Data persistence
- chronicle_audio:/app/audio_chunks
- chronicle_data:/app/data
- chronicle_debug:/app/debug_dir

# Model registry - defines available LLMs, embeddings, STT, TTS
# Use PROJECT_ROOT for absolute host paths (relative paths don't work from backend container)
- ${PROJECT_ROOT}/config/config.yml:/app/config/config.yml:ro
- ${PROJECT_ROOT}/config/defaults.yml:/app/config/defaults.yml:ro
# Config directory - contains config files, feature flags, secrets, etc.
# Mount entire ushadow config directory to override built-in configs
- ${PROJECT_ROOT}/config:/app/config:ro

networks:
- ushadow-network
Expand All @@ -118,14 +113,68 @@ services:
reservations:
memory: 2G

chronicle-workers:
# image: ghcr.io/ushadow-io/chronicle/backend:latest
image: chronicle-wworkers:latest
build:
context: ../chronicle/backends/advanced
dockerfile: Dockerfile
target: prod
container_name: ${COMPOSE_PROJECT_NAME:-ushadow}-chronicle-workers
command: ["uv", "run", "python", "worker_orchestrator.py"]
environment:
# Infrastructure connections
- AUTH_SECRET_KEY=${AUTH_SECRET_KEY}
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-}
- MONGODB_URI=${MONGODB_URI:-mongodb://mongo:27017}
- MONGODB_DATABASE=${MONGODB_DATABASE}
- REDIS_URL=${REDIS_URL:-redis://redis:6379/1}
- QDRANT_BASE_URL=${QDRANT_BASE_URL:-qdrant}
- QDRANT_PORT=${QDRANT_PORT:-6333}

# LLM capability
- OPENAI_API_KEY=${OPENAI_API_KEY}
- OPENAI_BASE_URL=${OPENAI_BASE_URL:-https://api.openai.com/v1}
- OPENAI_MODEL=${OPENAI_MODEL:-gpt-4o-mini}

# Transcription capability
- DEEPGRAM_API_KEY=${DEEPGRAM_API_KEY:-}
# - PARAKEET_ASR_URL=${PARAKEET_ASR_URL}
- TRANSCRIPTION_PROVIDER=${TRANSCRIPTION_PROVIDER:-deepgram}
- OPENMEMORY_USER_ID=${ADMIN_EMAIL:-admin@example.com}

# Worker orchestrator configuration
- WORKER_CHECK_INTERVAL=${WORKER_CHECK_INTERVAL:-10}
- MIN_RQ_WORKERS=${MIN_RQ_WORKERS:-6}
- WORKER_STARTUP_GRACE_PERIOD=${WORKER_STARTUP_GRACE_PERIOD:-30}
- WORKER_SHUTDOWN_TIMEOUT=${WORKER_SHUTDOWN_TIMEOUT:-30}

volumes:
# Data persistence (shared with backend)
- chronicle_audio:/app/audio_chunks
- chronicle_data:/app/data
- chronicle_debug:/app/debug_dir

# Config directory
- ${PROJECT_ROOT}/config:/app/config:ro

networks:
- ushadow-network

restart: unless-stopped

chronicle-webui:
image: ghcr.io/ushadow-io/chronicle/webui:nodeps2
# image: ghcr.io/ushadow-io/chronicle/webui:nodeps2
image: chronicle-webui:latest
build:
context: ../chronicle/backends/advanced/webui
dockerfile: Dockerfile
container_name: ${COMPOSE_PROJECT_NAME:-ushadow}-chronicle-webui
ports:
- "${CHRONICLE_WEBUI_PORT:-3080}:80"
environment:
- VITE_BACKEND_URL=http://localhost:${CHRONICLE_PORT:-8080}
- BACKEND_URL=${CHRONICLE_BACKEND_URL:-http://chronicle-backend:8080}
- VITE_BACKEND_URL=http://localhost:${CHRONICLE_PORT:-8090}
- BACKEND_URL=${CHRONICLE_BACKEND_URL:-http://chronicle-backend:8000}
networks:
- ushadow-network
depends_on:
Expand Down
5 changes: 4 additions & 1 deletion compose/docker-compose.infra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ services:
- "7474:7474" # HTTP
- "7687:7687" # Bolt
environment:
# - NEO4J_AUTH=${NEO4J_USERNAME:-neo4j}/${NEO4J_PASSWORD}
# Basic auth (JWT requires Neo4j Enterprise - use auth proxy for Community Edition)
- NEO4J_AUTH=${NEO4J_USERNAME:-neo4j}/${NEO4J_PASSWORD:-password}

# Plugins
- NEO4J_PLUGINS=["apoc"]
volumes:
- neo4j_data:/data
Expand Down
Loading
Loading