Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
06564d8
edge code
AnkushMalaker Mar 15, 2026
891134e
tiny fixes
AnkushMalaker Mar 15, 2026
259007a
tiny fix again
AnkushMalaker Mar 15, 2026
9f23f62
minor fix
AnkushMalaker Mar 15, 2026
338fd88
auto discover
AnkushMalaker Mar 15, 2026
c7060eb
reworked
AnkushMalaker Mar 15, 2026
8c26529
fix
AnkushMalaker Mar 15, 2026
ed66c78
missing file
AnkushMalaker Mar 15, 2026
8667388
major fix
AnkushMalaker Mar 16, 2026
0b19d5c
input fix
AnkushMalaker Mar 16, 2026
12246e3
fix
AnkushMalaker Mar 16, 2026
3149339
fix docker
AnkushMalaker Mar 16, 2026
3377e76
fix
AnkushMalaker Mar 16, 2026
3d8b43b
ui tweak
AnkushMalaker Mar 16, 2026
fca6fcf
Add support for optional static ESPHome device IP configuration
AnkushMalaker Mar 16, 2026
5765f45
Merge branch 'dev' into feat/tailscale-discovery
AnkushMalaker Mar 20, 2026
19a8c5d
Refactor audio streaming and authentication handling
AnkushMalaker Mar 28, 2026
2eb1cd3
app reconnect update
AnkushMalaker Mar 28, 2026
6d518ce
add app updates
AnkushMalaker Mar 28, 2026
6044179
update package
AnkushMalaker Mar 28, 2026
35c3353
app: disable expo-updates and add file-based crash logging
AnkushMalaker Apr 21, 2026
792790b
deps: upgrade Expo SDK 53 -> 55 and bump Xcode 26 image
AnkushMalaker Apr 21, 2026
7027731
deps: bump react/react-dom to 19.2.5 so npm ci works on EAS
AnkushMalaker Apr 21, 2026
155f101
metro: remove disableHierarchicalLookup (SDK 55 needs it)
AnkushMalaker Apr 21, 2026
cfb72dd
fix: crash loop in index.tsx + logger now writes to disk on SDK 55
AnkushMalaker Apr 21, 2026
a3a0b98
refactor: replace Neo4j with FalkorDB in configuration and codebase
AnkushMalaker Apr 21, 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
73 changes: 73 additions & 0 deletions .easignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# .easignore at repo root — used by EAS because this is a monorepo and
# the git root is the upload root. Must cover both the monorepo top-level
# and the app/ subdir (EAS ignores .gitignore when this file exists).

# --- Sibling projects not needed for the Expo build ---
backends/
extras/
tests/
Docs/
sdk/
untracked/

# --- Root-level junk / non-code artifacts ---
*.log
*.env*
asc-api-key.p8
**/asc-api-key.p8
*.m4a
*.wav
plan.md
sample-voice-response.json
deepgram_response.json
init-feedback
*.ipa
*.apk
*.aab
connection-logging-*.md
memory-service-settings.md
docs-consolidation-analysis.md
BLE_OPTIMIZATION.md
.github/
.cursor/
.claude/

# --- Inside app/ (the EAS project) ---
# Dependencies — reinstalled on EAS build server
app/node_modules/
# Expo / Metro
app/.expo/
app/dist/
app/web-build/
app/.metro-health-check*
# Native build outputs — regenerated on EAS
app/android/.gradle/
app/android/build/
app/android/app/build/
app/android/app/.cxx/
app/ios/build/
app/ios/Pods/
app/ios/DerivedData/
app/ios/*.xcworkspace/xcuserdata/
app/ios/*.xcodeproj/xcuserdata/
app/ios/*.xcodeproj/project.xcworkspace/xcuserdata/
# Local artifacts
app/*.ipa
app/*.apk
app/*.aab
app/build-*.ipa
# Credentials (EAS uses server-side credentials)
app/*.jks
app/*.p8
app/*.p12
app/*.key
app/*.mobileprovision
app/*.pem
# Logs
app/npm-debug.*
app/yarn-debug.*
app/yarn-error.*

# --- OS / editor ---
.DS_Store
**/.DS_Store
7 changes: 3 additions & 4 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,9 @@ MONGODB_K8S_URI=mongodb://mongodb.${INFRASTRUCTURE_NAMESPACE}.svc.cluster.local:
QDRANT_BASE_URL=qdrant
QDRANT_K8S_URL=qdrant.${INFRASTRUCTURE_NAMESPACE}.svc.cluster.local

# Neo4j configuration (optional)
NEO4J_HOST=neo4j-mem0
NEO4J_USER=neo4j
NEO4J_PASSWORD=neo4j-password
# FalkorDB configuration (optional)
FALKORDB_HOST=falkordb
FALKORDB_PORT=6379

# ========================================
# MEMORY PROVIDER CONFIGURATION
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ extras/test-audios/*
extras/speaker-omni-experimental/data/*
extras/speaker-omni-experimental/cache/*

# Discovery agent PID file
edge/.discovery-agent.pid

# AI Stuff
.claude

Expand All @@ -88,7 +91,7 @@ extras/speaker-recognition/outputs/*

# my backup
backends/advanced/src/_webui_original/*
backends/advanced-backend/data/neo4j_data/*
backends/advanced-backend/data/falkordb_data/*
backends/advanced-backend/data/speaker_model_cache/

*.bin
Expand Down
46 changes: 46 additions & 0 deletions app/.easignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# NOTE: .easignore fully replaces .gitignore for EAS uploads.
# Must exclude everything we don't want in the build tarball.

# Dependencies — reinstalled on EAS build server
node_modules/

# Expo
.expo/
dist/
web-build/

# Native build outputs — regenerated on EAS build servers
android/.gradle/
android/build/
android/app/build/
android/app/.cxx/
ios/build/
ios/Pods/
ios/DerivedData/
ios/*.xcworkspace/xcuserdata/
ios/*.xcodeproj/xcuserdata/
ios/*.xcodeproj/project.xcworkspace/xcuserdata/

# Local artifacts
*.ipa
*.apk
*.aab
build-*.ipa

# Credentials (EAS uses server-side credentials)
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.pem

# Metro / debug
.metro-health-check*
npm-debug.*
yarn-debug.*
yarn-error.*

# OS / editor
.DS_Store
*.log
19 changes: 15 additions & 4 deletions app/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"expo": {
"name": "chronicle",
"slug": "friend-lite-app",
"version": "1.0.0",
"version": "1.0.3",
"scheme": "chronicle",
"orientation": "portrait",
"icon": "./assets/icon.png",
Expand Down Expand Up @@ -35,6 +35,15 @@
},
"package": "com.cupbearer5517.chronicle",
"permissions": [
"android.permission.BLUETOOTH",
"android.permission.BLUETOOTH_ADMIN",
"android.permission.BLUETOOTH_CONNECT",
"android.permission.ACCESS_NETWORK_STATE",
"android.permission.FOREGROUND_SERVICE",
"android.permission.FOREGROUND_SERVICE_DATA_SYNC",
"android.permission.POST_NOTIFICATIONS",
"android.permission.RECORD_AUDIO",
"android.permission.CAMERA",
"android.permission.BLUETOOTH",
"android.permission.BLUETOOTH_ADMIN",
"android.permission.BLUETOOTH_CONNECT",
Expand All @@ -44,10 +53,8 @@
"android.permission.POST_NOTIFICATIONS",
"android.permission.RECORD_AUDIO",
"android.permission.CAMERA"
],
"usesCleartextTraffic": true
]
},
"newArchEnabled": true,
"plugins": [
[
"@siteed/expo-audio-studio",
Expand Down Expand Up @@ -115,6 +122,10 @@
"eas": {
"projectId": "05d8598e-6fe7-4373-81e4-1654f3d8e181"
}
},
"runtimeVersion": "1.0.0",
"updates": {
"enabled": false
}
}
}
35 changes: 22 additions & 13 deletions app/app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import { useEffect } from "react";
import { Stack } from "expo-router";
import { useTheme } from "@/theme";
import { ConnectionLogProvider } from "@/contexts/ConnectionLogContext";
import ErrorBoundary from "@/components/ErrorBoundary";
import { initLogger, logInfo } from "@/utils/logger";

export default function RootLayout() {
const { colors, isDark } = useTheme();

useEffect(() => {
initLogger().then(() => logInfo('RootLayout', 'app mounted'));
}, []);

return (
<ConnectionLogProvider>
<Stack
screenOptions={{
headerStyle: { backgroundColor: colors.card },
headerTintColor: colors.text,
headerTitleStyle: { fontWeight: '600' },
contentStyle: { backgroundColor: colors.background },
}}
>
<Stack.Screen name="index" options={{ title: 'Chronicle', headerShown: false }} />
<Stack.Screen name="diagnostics" options={{ title: 'Diagnostics', presentation: 'card' }} />
</Stack>
</ConnectionLogProvider>
<ErrorBoundary>
<ConnectionLogProvider>
<Stack
screenOptions={{
headerStyle: { backgroundColor: colors.card },
headerTintColor: colors.text,
headerTitleStyle: { fontWeight: '600' },
contentStyle: { backgroundColor: colors.background },
}}
>
<Stack.Screen name="index" options={{ title: 'Chronicle', headerShown: false }} />
<Stack.Screen name="diagnostics" options={{ title: 'Diagnostics', presentation: 'card' }} />
</Stack>
</ConnectionLogProvider>
</ErrorBoundary>
);
}
69 changes: 68 additions & 1 deletion app/app/diagnostics.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import { View, Text, FlatList, TouchableOpacity, StyleSheet, SafeAreaView } from 'react-native';
import { View, Text, FlatList, TouchableOpacity, StyleSheet, SafeAreaView, Share, Platform, Alert } from 'react-native';
import { useTheme, ThemeColors } from '@/theme';
import { useConnectionLog, ConnectionEvent, ConnectionEventType } from '@/contexts/ConnectionLogContext';
import { getLogPath, readLog, clearLog } from '@/utils/logger';

const EVENT_BADGE_COLORS: Record<ConnectionEventType, string> = {
scan_start: '#007AFF',
Expand Down Expand Up @@ -87,8 +88,44 @@ export default function DiagnosticsScreen() {
const { colors } = useTheme();
const { events, clearEvents } = useConnectionLog();

const shareLogFile = async () => {
try {
const contents = await readLog();
if (!contents) {
Alert.alert('No log yet', 'The crash log file is empty.');
return;
}
if (Platform.OS === 'ios') {
await Share.share({ url: `file://${getLogPath()}`, message: contents.slice(-4000) });
} else {
await Share.share({ message: contents.slice(-4000) });
}
} catch (err) {
Alert.alert('Share failed', String(err));
}
};

const wipeLogFile = async () => {
Alert.alert('Clear crash log?', 'Removes the on-device crash log file.', [
{ text: 'Cancel', style: 'cancel' },
{ text: 'Clear', style: 'destructive', onPress: async () => { await clearLog(); } },
]);
};

return (
<SafeAreaView style={{ flex: 1, backgroundColor: colors.background }}>
<View style={[screenStyles.logBar, { borderBottomColor: colors.separator, backgroundColor: colors.card }]}>
<Text style={[screenStyles.logBarTitle, { color: colors.text }]}>Crash Log</Text>
<Text style={[screenStyles.logBarPath, { color: colors.textTertiary }]} numberOfLines={1}>{getLogPath()}</Text>
<View style={screenStyles.logBarRow}>
<TouchableOpacity onPress={shareLogFile} style={[screenStyles.logBtn, { backgroundColor: colors.inputBackground }]}>
<Text style={[screenStyles.logBtnText, { color: colors.text }]}>Share Log File</Text>
</TouchableOpacity>
<TouchableOpacity onPress={wipeLogFile} style={[screenStyles.logBtn, { backgroundColor: colors.inputBackground }]}>
<Text style={[screenStyles.logBtnText, { color: colors.danger }]}>Clear File</Text>
</TouchableOpacity>
</View>
</View>
<View style={[screenStyles.header, { borderBottomColor: colors.separator }]}>
<Text style={[screenStyles.title, { color: colors.text }]}>Connection Log ({events.length})</Text>
<TouchableOpacity onPress={clearEvents} style={[screenStyles.clearButton, { backgroundColor: colors.inputBackground }]}>
Expand Down Expand Up @@ -144,4 +181,34 @@ const screenStyles = StyleSheet.create({
fontSize: 15,
textAlign: 'center',
},
logBar: {
paddingHorizontal: 16,
paddingVertical: 10,
borderBottomWidth: 1,
},
logBarTitle: {
fontSize: 15,
fontWeight: '600',
},
logBarPath: {
fontSize: 10,
fontFamily: 'monospace',
marginTop: 2,
marginBottom: 8,
},
logBarRow: {
flexDirection: 'row',
gap: 8,
},
logBtn: {
flex: 1,
paddingHorizontal: 12,
paddingVertical: 8,
borderRadius: 6,
alignItems: 'center',
},
logBtnText: {
fontSize: 13,
fontWeight: '500',
},
});
Loading
Loading